ADRs
ADR 004 — Render adapter postMessage protocol
  • Date: 2026-05-20
  • Status: Accepted (v1)
  • Phase: 6 → 7

Context

Master spec §I.3.4 определяет "Render adapter" как protocol+bundle для рендера реальных React-компонентов в ARNO preview iframe. Реализуется как:

  • AlfaBank (или любой подключённый repo) собирает self-contained JS bundle с arno.entry.tsx
  • Bundle публикуется на gh-pages / GitHub Packages / любой CDN с CORS
  • ARNO грузит bundle в sandboxed iframe и общается через postMessage

Нужен typed contract, который выживет multiple bundle implementations.

Decision

Protocol v1 (см. @arno/render-adapter):

// ARNO → iframe
{ type: 'arno:render', tree: RenderNode[] }
 
// iframe → ARNO
{ type: 'arno:ready' }
{ type: 'arno:navigate', toScreenId: string }

RenderNode — composition tree node + optional navigations: Record<eventId, screenId>. При наличии navigation для event, bundle wrap'ает component в click handler и emit'ит arno:navigate при триггере.

Iframe sandbox: sandbox="allow-scripts" — нет same-origin, нет cookies, нет localStorage parent'а. Безопасно даже для untrusted bundle URLs.

Bundle inline: ARNO шлёт iframe через srcDoc (data URL), не через src. Это даёт null-origin iframe — bundle никогда не имеет credentialed access к чему-либо. Bundle URL остаётся origin'ом GitHub Pages для самого JS файла, но postMessage boundary всегда проверяет type discriminator.

Cross-repo sync

packages/render-adapter — source of truth для types в ARNO monorepo. Render bundles (AlfaBank arno.entry.tsx) дублируют типы вручную сейчас.

При breaking change протокола:

  1. Bump PROTOCOL_VERSION в packages/render-adapter/src/index.ts
  2. Bump в arno.entry.tsx каждого подключённого bundle
  3. ARNO может проверять version в arno:ready payload (TODO для v2)
  4. ADR на breaking change (replaces this one)

Post-MVP — npm publish @arno/render-adapter снимет ручную синхронизацию.

Consequences

Pros:

  • Bundle живёт в своём repo, своей сборке, своих зависимостях — ARNO не знает про @alfalab/core-components
  • postMessage protocol minimal — легко поддерживать в любом фреймворке (Vue/Solid bundle тоже можно)
  • sandbox isolation — bundle bug не может выкрасть ARNO cookies или scrape DOM

Cons:

  • Types дублируются между repos до first npm publish
  • postMessage stringify cost для больших composition trees (>10K nodes) — пока не upper bound
  • В preview нельзя сделать React DevTools attach на iframe content (sandbox блокирует)

Related files

  • packages/render-adapter/src/index.ts (types)
  • apps/web/src/components/preview-frame.tsx (ARNO parent)
  • AlfaBank arno.entry.tsx (consumer bundle)
  • AlfaBank vite.arno.config.ts (IIFE bundle config)
  • AlfaBank .github/workflows/arno-build.yml (deploy на gh-pages)