Architecture

Architecture

Understand the internal architecture visually.

1. Core Runtime

signal(input)
immutable value storage
value getter
register current effect
value setter / mutation
run dependent effects synchronously

The core runtime is small on purpose:

  • `signal()` creates mutable source state
  • reading `.value` adds the current effect to the signal
  • writing `.value` or mutating arrays/objects triggers dependent effects immediately

2. Dependency Tracking

effect(fn)
_currentSignalEffect
signal.value getter
signal._effects

Tracking is global and temporary:

  • `effect()` sets a module-level current effect before executing the callback
  • each signal getter registers that effect in the signal's local `_effects` set
  • when execution ends, the current effect is cleared

3. Derived Signal Model

derive(fn)
internal derived source signal
internal updater effect
computed value
internal derived source signal

Derived signals are not a separate storage engine:

  • they are implemented using an internal source signal
  • an internal effect recomputes the value
  • the public derived signal exposes read-only `.value`, `prevValue`, and `dispose()`

4. Disposal

dispose() called
canDisposeNow = true
cleanup on next signal update
removed from signal._effects

Disposal is intentionally lazy:

  • calling `dispose()` marks the effect
  • the effect is removed on the next update cycle
  • this keeps disposal simple and synchronous with the rest of the runtime

5. Data Flow

source signal
derived signal
effect
side effects

The actual data flow is:

  • a source signal stores state
  • derived signals read source signals and recompute immediately
  • effects observe signals by reading `.value`
  • updates propagate synchronously through the dependency set

6. Internal State

  • Source signals store `_value` and `_effects`
  • The Effects store `canDisposeNow` and `dispose()`
  • Derived signals store an internal source signal plus an updater effect
  • Array and object signals add shape-specific helpers on top of the same source signal core

7. Why This Design

  • It keeps the runtime small and explicit
  • It avoids hidden batching or deferred execution
  • It matches the repository's semantics and behavioral tests exactly
  • It makes the signal graph easy to reason about because every dependency comes from an actual getter read