🎯 Stage 1 -- React Reconciler
Um react-reconciler customizado conecta o React ao DOM proprio do Ink, em vez do browser. Quando <Text> esta aninhado dentro de outro <Text>, o no interno se torna ink-virtual-text -- um no fantasma sem backing do Yoga.
Event Handlers
Event handlers sao armazenados separadamente em node._eventHandlers, prevenindo repinturas desnecessarias quando componentes pais re-renderizam com novas referencias de callback.
🌳 Stage 2 -- Virtual DOM
Arvore de objetos TypeScript simples com nos DOMElement. O dirty flag sinaliza se re-renderizacao e necessaria -- nos inalterados sao copiados do frame anterior, entregando performance O(celulas alteradas).
Tipos de Nos
📐 Stage 3 -- Yoga Layout
Yoga e um engine de Flexbox em C++ compilado para WebAssembly. A interface LayoutNode desacopla o codebase dos bindings WebAssembly do Yoga.
⚠️ Detalhe Critico
Como ink-virtual-text, ink-link e ink-progress nao possuem nos Yoga, DOM index != yoga index. Contagem manual de siblings precedentes com nos Yoga e necessaria.
🎨 Stage 4 -- renderNodeToOutput
Caminhada recursiva pela arvore convertendo nos com layout em operacoes de Output. O Blit Fast Path verifica: se o no esta limpo, posicao inalterada e prevScreen disponivel, emite uma unica chamada output.blit().
📊 ScrollBox Hardware Scroll
Emite sequencia DECSTBM + SU/SD para frames de scroll em O(1), aproveitando regioes de scroll do terminal em vez de repintar todo o conteudo.
📦 Stages 5-6 -- Output Queue & Screen Buffer
O Stage 5 e uma abstracao de command-buffer coletando operacoes: write, blit, clear, clip/unclip, shift, noSelect. Replay em dois passes: Pass 1 expande a bounding box de dano, Pass 2 executa operacoes.
Packed Int32Array -- Screen Buffer
2 words por celula (8 bytes total), eliminando alocacao per-cell de objetos:
| Word | Conteudo | Bits |
|---|---|---|
| word0 | charId | 32 bits |
| word1 | styleId [31:17] + hyperlinkId [16:2] + width [1:0] | 32 bits |
💡 Por que Int32Array?
Um terminal 200x120 alocaria 24.000 objetos por frame. Com Int32Array, zero pressao de GC. O StylePool faz intern, transition e cache. transition(fromId, toId) pre-computa strings de escape ANSI.
⚡ Stage 7 -- Cell Diff & Wide Characters
O diff caminha apenas pela damage bounding box. Para cada celula alterada, emite sequencia ANSI minima.
CellWidth Enum
🗺️ Pipeline Completo de Renderizacao
flowchart LR
A["Stage 1\nReact Reconciler\nreconciler.ts"] --> B["Stage 2\nVirtual DOM\ndom.ts"]
B --> C["Stage 3\nYoga Layout\nlayout/"]
C --> D["Stage 4\nrenderNodeToOutput\nrender-node-to-output.ts"]
D --> E["Stage 5\nOutput Queue\noutput.ts"]
E --> F["Stage 6\nScreen Buffer\nscreen.ts\nPacked Int32Array"]
F --> G["Stage 7\nCell Diff\nMinimal ANSI"]