stabilize architecture docs: address review findings and advance to stable
Critical fixes: - Restructure pointers.md: move setNode prop-key writes section under its own heading (was incorrectly nested under selectNode) - Add Context/Density/Direction/RenderContext documentation section to host-config.md (was only a brief constraint bullet) - Advance all 5 ADRs from Status: Proposed → Accepted and frontmatter from status: draft → status: stable (decisions are driving implementation) - Add error handling philosophy section to README Warning/suggestion fixes: - Add isUElement null check (node !== null) to schema.md discriminator table - Add UjsxEnvelope convenience type documentation to events.md - Add Direction Unicode arrow naming note to transforms.md - Standardize all cross-references from absolute docs/research/ paths to relative ../research/ paths across all architecture docs - Fix schema.md ADR references to use relative paths - Reduce redundancy between transforms.md and host-config.md Direction notes - Update all architecture doc frontmatter from draft → stable Deferred: - Performance model section (reconciler not yet built) - Concepts/glossary document (low ROI at current scale) - Line counts in source references (would date quickly)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
---
|
||||
status: draft
|
||||
status: stable
|
||||
last_updated: 2026-05-18
|
||||
---
|
||||
|
||||
@@ -78,19 +78,6 @@ If the current node is not a `UElement` (i.e., it's a `UPrimitive` — a string,
|
||||
|
||||
When a string segment resolves to a prop value that is a primitive (string, number, boolean, null), `selectNode` returns `undefined`. Only non-null object prop values — including arrays, since `typeof [] === "object"` — can be navigation targets. This means `props.items` where `items` is an array can be navigated into, but `props.title` where `title` is a string cannot.
|
||||
|
||||
`setNode` mirrors this behavior for writes: a non-numeric string segment sets `props[segment] = value`, performing a shallow merge of that key into the element's props. This allows targeted prop updates via path-based navigation.
|
||||
|
||||
### setNode prop-key writes
|
||||
|
||||
Non-numeric path segments in `setNode` set values into the `props` object:
|
||||
|
||||
```typescript
|
||||
setNode(root, ["title"], someNode)
|
||||
// Produces: { ...rootEl, props: { ...rootEl.props, title: someNode } }
|
||||
```
|
||||
|
||||
This shallow-merges a key into `props`. The `value` must be a valid `PropValue` (or `UNode`) for the result to remain type-safe.
|
||||
|
||||
## setNode
|
||||
|
||||
```typescript
|
||||
@@ -123,6 +110,19 @@ This structural sharing means `setNode` is O(depth) in allocations, not O(size o
|
||||
|
||||
When the head segment is a valid non-negative integer, `setNode` shallow-copies the `children` array and replaces the element at that index. Out-of-range indices are ignored — the copy is made but no element is replaced. This is a defensive choice: silent no-op is preferable to throwing or growing the array.
|
||||
|
||||
### Prop-key path writes
|
||||
|
||||
Non-numeric path segments set values into the `props` object:
|
||||
|
||||
```typescript
|
||||
setNode(root, ["title"], someValue)
|
||||
// Produces: { ...rootEl, props: { ...rootEl.props, title: someValue } }
|
||||
```
|
||||
|
||||
This shallow-merges a key into `props`. The `value` argument must be a valid `PropValue` (or `UNode`) for the result to remain type-safe. Unlike numeric segments (which navigate into `children`), non-numeric segments write to `props` at the current level without deeper navigation — the remaining path tail determines what happens next.
|
||||
|
||||
This mirrors `selectNode`'s resolution: where `selectNode` reads `props[segment]` and navigates into non-null object values, `setNode` writes `props[segment] = value` as a shallow merge.
|
||||
|
||||
## Relationship to the Reconciler
|
||||
|
||||
`ValuePointer`, `selectNode`, and `setNode` are **not** the reconciler's update mechanism. They are lower-level utilities that the reconciler can use internally. The reconciler's fiber tree manages structural changes (diffing, adding, removing children). Pointers handle targeted reads and writes at known positions — a finer granularity than the reconciler's subtree updates.
|
||||
@@ -159,4 +159,4 @@ Paths are exact sequences of segments. There is no support for `*` (any child),
|
||||
- Source: `src/core/pointer.ts`
|
||||
- UNode schema: `src/core/schema.ts`
|
||||
- Preact signals: `@preact/signals-core`
|
||||
- Reconciler research: `docs/research/reconciler/` (see 01-reactive-host-bridge.md and 02-key-based-children-reconciliation.md for how selectors and path-based targeting integrate with the fiber tree)
|
||||
- Reconciler research: `../research/reconciler/` (see 01-reactive-host-bridge.md and 02-key-based-children-reconciliation.md for how selectors and path-based targeting integrate with the fiber tree)
|
||||
Reference in New Issue
Block a user