---
sidebar_position: 2
title: "Contrato postMessage"
---

A comunicação entre a atividade HTML (dentro do iframe) e o React acontece exclusivamente via `postMessage`. Este é o contrato que toda atividade de letramento deve respeitar.

## Fluxo de comunicação

```mermaid
sequenceDiagram
    participant A as Atividade (iframe)
    participant F as AtividadeRuntimeFrame
    participant B as letramentoEventBus
    participant C as LetramentoStateContext
    participant S as letramentoStorage

    A->>F: postMessage({ type: 'started' })
    F->>B: emit('atividade:started')
    B->>C: atualiza estado → RUNNING

    A->>F: postMessage({ type: 'success', score: 100 })
    F->>B: emit('atividade:success', { score })
    B->>C: marca fase como concluída
    C->>S: persiste progresso no localStorage
```

## Estados válidos

| Tipo de mensagem | Significado |
|---|---|
| `started` | A atividade foi carregada e começou |
| `running` | A atividade está em progresso |
| `success` | A atividade foi concluída com sucesso |
| `failure` | A atividade terminou com falha |
| `completed` | Confirmação final de encerramento |

## Formato da mensagem

```javascript
// Dentro da atividade HTML (activity.js)
window.parent.postMessage({
  type: 'success',   // obrigatório: um dos estados acima
  score: 100,        // opcional: pontuação da atividade
  data: {}           // opcional: dados adicionais
}, '*');
```

## Mapeamento para ciclo de aprendizagem (LMS)

```mermaid
stateDiagram-v2
    [*] --> started: atividade carregada
    started --> running: interação do estudante
    running --> success: objetivo atingido
    running --> failure: tentativa inválida
    success --> completed: encerramento confirmado
    failure --> completed: encerramento com falha
```

| Mensagem | Interpretação no ciclo LMS |
|---|---|
| `started` | Tentativa iniciada |
| `running` | Tentativa em andamento |
| `success` | Objetivo pedagógico concluído |
| `failure` | Objetivo não concluído na tentativa |
| `completed` | Tentativa encerrada e registrada |

## Boas práticas de payload

Para rastreabilidade melhor (sem quebrar o contrato atual), recomenda-se incluir:

- `activityId`: identificador da atividade.
- `attemptId`: identificador da tentativa.
- `score`: pontuação normalizada.
- `data`: metadados pedagógicos (tempo, erros, dicas usadas).

Exemplo recomendado:

```javascript
window.parent.postMessage({
  type: 'success',
  activityId: 'rimas-fase-1',
  attemptId: 'att-2026-05-05-01',
  score: 100,
  data: {
    elapsedMs: 92340,
    hintsUsed: 1,
  },
}, '*');
```

## Adaptador AtividadeRuntimeFrame

O componente `AtividadeRuntimeFrame` escuta mensagens via `window.addEventListener('message', ...)` e as converte em eventos internos via `letramentoEventBus`. Isso isola o iframe do resto da aplicação React.

```mermaid
graph LR
    MSG["postMessage recebida"] --> VALID["Validação de origem"]
    VALID --> CONV["Conversão para evento interno"]
    CONV --> BUS["letramentoEventBus.emit(...)"]
```

Referências externas:

- postMessage API: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
- iframe sandbox: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe#sandbox
- Adapter pattern: https://refactoring.guru/design-patterns/adapter
