address architecture review findings and add review document
Fixes from architecture review (4 critical, 10 warnings):
Critical:
- Fix selectNode/setNode docs to accurately describe prop-key
navigation behavior including array support and prop-key writes
- Document RenderContext/Density exported types in host-config
- Resolve ADR dual status ambiguity with clarifying note in README
(frontmatter status = editorial, body Status = decision)
- Effect types already addressed in prior commit
Warnings addressed:
- Add Fragment re-export note to jsx-runtime section in
build-distribution
- Document childCtx/transformCtx helper functions in transforms.md
- Document render() accepting non-root UNode in host-config
- Add Value.Hash re-entrancy constraint to reconciler.md
- Add true-passthrough constraint and h('root') special case
to element-factory constraints
- Add _idCounter bundling caveat note
Review document added at docs/reviews/architecture-review-2026-05-18.md
with full findings, source verification table, and recommendations.
This commit is contained in:
@@ -190,8 +190,10 @@ The reconciler solves this by maintaining a fiber tree alongside the instance tr
|
||||
- **`HostConfig` is the sole host integration point** — all platform-specific logic lives behind this interface. UJSX never calls DOM APIs, Three.js APIs, or any other platform API directly.
|
||||
- **`TTag` constrains element types** — hosts declare the tags they support. Attempting to render an unsupported tag is a type error at compile time. At runtime, the host receives any string as `tag` and must handle unknowns.
|
||||
- **`render()` is not idempotent** — calling `render()` twice on the same root creates two independent instance trees. It does not update the first tree.
|
||||
- **`render()` accepts any `UNode`** — if the node is a `URoot`, its children are mounted directly. If the node is any other `UNode` (element or primitive), it is wrapped in an array and mounted as a single top-level element without a root container.
|
||||
- **Function components are synchronous and transparent** — they receive props and children, return a `UNode`, and produce no host instance. The reconciler research discusses how to handle components that return different tree shapes across renders.
|
||||
- **`Context` is always present** — `createRoot()` guarantees a `Context` exists on the `Root`. If none is provided, a default is created with `density: "full"`, `target: "markdown"`, and empty `metadata`.
|
||||
- **`RenderContext` extends `ContextValue`** — the `Direction` type (`"ujsx→mdast" | "mdast→ujsx" | "ujsx→jpath" | "jpath→ujsx" | "ujsx→hast" | "hast→ujsx"`) and `RenderContext` interface (which adds `direction` to `ContextValue`) are exported from the `context` sub-path. `RenderContext` is primarily used by the transform system to specify conversion direction. `Density` (`"full" | "compact" | "minimal"`) controls rendering granularity for hosts that support adaptive output.
|
||||
- **`container` is opaque** — UJSX passes it to `createRootContext` and stores it on `Root`, but never inspects it. The host defines what it means.
|
||||
- **Mount is depth-first, post-order** — children are fully constructed before being appended to their parent. Hosts can rely on this ordering invariant.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user