Files
yawn/docs/guide/architecture.md
T

41 lines
2.9 KiB
Markdown

# How Yawn fits together
Yawn has two public boundaries: **worker communication** for small, infrequent operations and **shared render data** for values that change often. Everything else is an authoring or convenience layer outside core.
```text
JSO / fluent builder ─┐
├──▶ canonical DAG AST ─▶ S-expression ─▶ render worker
FXNode snapshot ─────┘ │
├─ graph compiler
glTF import worker ───── shared upload array ────────────────────┤
├─ transient allocator
any browser thread ─── lifecycle messages ──────────────────────┤
any browser thread ─── atomic SOA writes ────────────────────────┘
```
## What core owns
`@yawn/core` owns only the protocol client for render data and render graphs. The worker behind it owns graph validation, loadout preparation, transient lifetime analysis, GPU allocation, and rendering.
Core does **not** own a camera module, scene object model, glTF parser, shader library, editor, or picking system. Camera and material values are ordinary render-data columns. Higher-level objects are optional addon views over those columns.
## The graph is the program
Every frontend must produce `@yawn/render-graph-ast` data. A node is named, while an input contains one or more `{ node, socket }` references. Reusing the same reference creates fan-out, so the format describes a DAG instead of duplicating a tree.
Render and compute pipeline declarations are part of that AST. Their WGSL and state are compiled into a prepared loadout, not linked into core.
## The SOA is the mutable scene
Shared arrays are 64-byte aligned and each row stride is a multiple of 16 bytes. The standard columns cover mesh, instance, camera, and material data. Applications can request additional mesh-, instance-, or fixed-domain arrays; domain arrays grow with the corresponding render-data capacity.
Lifecycle operations such as allocating a column, importing an asset, compiling a graph, or creating an instance cross the command boundary. A frame-rate transform, camera, classification, or material update writes the existing SAB row directly.
## Thread placement is a choice
The JS client only requires a Worker-like endpoint. A main thread can own it, or another worker can connect through a `MessagePort`. Shared descriptors can be passed to additional workers, which can then read or write the same SOA data without proxying every update through the main thread.
::: warning Cross-origin isolation is required
Serve the application with `Cross-Origin-Opener-Policy: same-origin` and `Cross-Origin-Embedder-Policy: require-corp`. `npm run examples` supplies both headers.
:::