Tasks follow the architecture spec phases: - Phase 0: key field on UElement (2 tasks + review) - Phase 1: reactive-host bridge / fiber tree (4 tasks + review) - Phase 2: key-based children reconciliation (3 tasks + review) - Phase 3: unmount & dispose support (4 tasks) - Phase 4: TypeBox value optimizations (4 tasks) Validated with taskgraph CLI: no cycles, 15 parallel generations, 3 high-risk tasks identified (signal-driven-updates, commit-mutations, fiber-disposal).
2.5 KiB
2.5 KiB
id, name, status, depends_on, created, modified, scope, risk, impact, level
| id | name | status | depends_on | created | modified | scope | risk | impact | level | |
|---|---|---|---|---|---|---|---|---|---|---|
| signal-driven-updates | Wire signal changes to prepareUpdate/commitUpdate | pending |
|
2026-05-18T16:22:57.167895441Z | 2026-05-18T16:22:57.167895878Z | moderate | high | phase | implementation |
Description
Bridge the reactive layer to the host layer by wiring signal changes to HostConfig.prepareUpdate/commitUpdate via fibers. This is the core of ADR-005: signals handle 90% of updates (property changes), reconciliation handles structural changes.
When a signal that drives a ReactiveNode changes, the computed recomputes and an effect fires. This effect should:
- Compare the fiber's current props to the new element's props via
host.prepareUpdate - If
prepareUpdatereturns a non-null payload, queue an "update" effect on the fiber - Call
host.commitUpdatewith the payload
Multiple signal changes within a batch are collapsed into one reconciliation pass (Preact signals already batch within batch() calls). Updates are committed top-down (parent before child) to ensure parent state is consistent when child updates fire.
Acceptance Criteria
- Signal change triggers
scheduleUpdate(fiber, nextNode)on the associated fiber scheduleUpdatebatches pending updates and queuesflushUpdatesvia microtaskflushUpdatescallshost.prepareUpdate(fiber.instance, fiber.tag, fiber.props, nextNode.props, ctx)- If
prepareUpdatereturns non-null payload, fiber getseffect: { type: "update", payload } commitEffectscallshost.commitUpdate(fiber.instance, payload, tag, prevProps, nextProps, ctx)- Commit order is top-down (parent before child)
- Signal effect disposers are stored in
fiber.signalDisposersfor later cleanup host.prepareUpdateandhost.commitUpdateare optional — if not implemented, update is a no-op- Existing tests pass
- New test: signal change on a reactive element triggers
prepareUpdate+commitUpdate - New test: batch of signal changes results in single reconciliation pass
References
- docs/architecture/reconciler.md — Step 1 (Schedule Update), Step 2 (Reconcile Props), Step 4 (Commit Effects)
- docs/architecture/decisions/005-signal-driven-updates-over-tree-diffing.md — ADR-005
- docs/architecture/reactive-layer.md — ReactiveNode, ReactiveRoot, signal/computed/effect
- docs/architecture/host-config.md — prepareUpdate, commitUpdate methods
Notes
To be filled by implementation agent
Summary
To be filled on completion