docs / Runtime
Reactive Core
The runtime reactivity engine: cells, the microtask scheduler, block trees, scoped flushing, and the flushSync/tick escapes.
The runtime reactivity engine implements tracked cells, derived values, effects, and a block-tree scheduler. (The legacy `track.ts` module is dead code and must not be imported.)
Cells
- `track(value)` creates a tracked cell. Reads register a dependency on the active reaction; writes mark the owning block dirty and schedule it.
- `untrack(fn)` runs fn with tracking disabled; `peek(cell)` reads without registering a dependency.
- `derived(fn)` is a computed cell: fn runs under an effect and its result is written to the derived cell. Mutating tracked state inside a derived evaluation is forbidden.
Scheduler
- Default mode is microtask-batched: writes enqueue `queueMicrotask(flush_microtasks)`, and one flush runs all queued root blocks.
- More than 1001 consecutive flush rounds throw "Maximum update depth exceeded" — the effect read-write loop guard.
- `flushSync(fn)` switches to synchronous scheduling while fn runs; `tick()` resolves on the next requestAnimationFrame.
- Low-level control: `schedule_update`, `queue_microtask` are exported.
Blocks
Every component body and effect compiles to a block in a doubly-linked tree: render blocks, branch blocks, effect blocks, user effects, pre-effects, root blocks and try blocks. `destroy_block(pause/resume)`, `pause_block`, `is_destroyed`, and `on_destroy(fn)` manage lifecycle.
Scoped flushing
Each cell records its owning block. When a block reads a cell owned by another block the flush is scoped, unless the owner is not an ancestor (the `disable_scoped_flush` guard).