Phase 1 of SDD process: syncing docs/architecture/ to reflect the existing source code. Eight component documents describe WHAT and WHY (not HOW) for each module: schema, element factory, reactive layer, host config, transforms, events, pointers, and build distribution. Three ADRs capture key decisions (HTML-agnostic core, TypeBox Module as type registry, Preact signals-core for reactivity). Each doc documents known reconciler gaps and references the research in docs/research/reconciler/. Also adds docs/sdd_process.md (process reference shared across alkdev projects) matching the taskgraph_ts pattern.
2.1 KiB
2.1 KiB
status, last_updated
| status | last_updated |
|---|---|
| draft | 2026-05-18 |
ADR-003: Preact signals-core for reactivity
Status: Proposed
Context
UJSX needs a reactive primitive for propagating changes through element trees. The reactive layer (ReactiveRoot, reactiveComponent, reactiveElement) needs signal, computed, effect, and batch operations.
Alternatives Considered
- Custom reactive implementation: Write a signal/computed/effect system from scratch. Rejected because writing a correct implementation (cycle detection, batch scheduling, lazy evaluation) is non-trivial and Preact's implementation is battle-tested.
- Solid.js reactive primitives: Use Solid's reactive system. Rejected because they're coupled to Solid's render cycle and not published as a standalone package.
- Vue reactivity: Use Vue's reactive system. Rejected because it uses Proxy-based tracking which has different performance characteristics and isn't designed for tree-agnostic use.
- RxJS: Use observables for reactivity. Rejected because it's an observable/stream model, not a reactive state model. Different paradigm, much larger API surface.
Decision
Use @preact/signals-core as the reactive layer. Re-export its primitives (signal, computed, effect, batch) and types (Signal, ReadonlySignal) from the UJSX reactive module.
Consequences
Positive
- Proven implementation with ~800 lines of battle-tested code, used in Preact and adopted by other frameworks.
- Small dependency surface —
@preact/signals-corehas zero dependencies. - Batch scheduling is built-in, matching the reconciliation model planned for the reconciler.
- Future consumers (flowgraph reactive host) can use the same signal/computed/effect primitives without a different reactive library.
Negative
- UJSX re-exports Preact signals, creating a coupling. If Preact signals changes its scheduling model, UJSX is affected.
- The
effectreturn value (dispose function) is currently discarded in reactiveComponent/reactiveElement — the dispose functions are no-ops. This is a known gap that the reconciler work addresses.