Architecture

Architecture

Understand the internal architecture visually.

1. Core Runtime

signal(input)
base-signal storage
value getter
EffectHook registration
value setter / mutation
run dependent effects synchronously

The core runtime is small on purpose:

  • `signal()` creates mutable source state
  • reading `.value` records the current EffectHook effect on the base signal
  • writing `.value` or using `.mutate` runs dependent effects immediately

2. Dependency Tracking

effect(fn)
EffectHook
signal.value getter
base signal effect Set

Tracking is global and temporary:

  • `effect()` places itself in the singleton EffectHook before the initial callback
  • each live signal getter records a two-way subscription between the signal and effect
  • a `finally` block clears the hook when initial execution ends

3. Derived Signal Model

derive(fn)
base-signal storage
internal updater effect
computed value
read-only public facade

Derived signals reuse the base-signal engine:

  • a base signal stores the current and previous computed values
  • an internal effect recomputes the value
  • the public derived signal exposes read-only `.value`, `prevValue`, and `dispose()`

4. Disposal

dispose() called
remove subscriptions now
clear effect bookkeeping
isDisposed = true

Disposal is immediate:

  • calling `dispose()` removes the effect from every captured stimulus signal
  • future writes cannot run the disposed effect
  • disposing the same live effect or derived signal twice throws

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 And Method Liveness

  • Source signals store `_value` and `_effects`
  • Effects store disposal state plus stimulus and dependent signal Sets
  • Derived signals combine base-signal storage, an updater effect, and a read-only setter
  • Live data methods return derived signals; dead-signal methods return snapshots
  • Source mutations for arrays, objects, strings, and booleans live under `.mutate`

7. Why This Design

  • It keeps the runtime small and explicit
  • It avoids hidden batching or deferred execution
  • It gives live and dead values a consistent projection vocabulary
  • It keeps dependency capture explicit: only initial live getter reads subscribe