Internals
This section builds this reactive framework from start to finish, so you understand exactly how it works.
The Build, in Order
Architecture →
The first decision: how a change becomes an update. We weigh three ways to build a reactive system. We take a dependency graph, recomputed in order.
Root →
The container that holds everything. A program is data, keyed by scope: a map of scopes, the root scope, and
an id counter. Reactive.Root runs a program and returns that data.
Values →
The first nodes: Constant and State. Each is an entry in the current scope, and
returns a reference of scope and index.
Calculations →
Calculate derives a value from others and records the dependency edges,
inputNodeRefs and listenersByScope, the graph the whole design depends on.
Pending →
State that is still loading. Pending holds a stand-in while it waits. The flag spreads through
every calculation over it. A derived chain reads as loading until a driver fills it.
Emissions →
Emit and Gather thread a scope's output up by name, in document order. Each named
stream carries its own pending flag, so one output can be loading without a delay to the rest.
Drivers →
The boundary to the outside. A driver takes a leftover emission stream and turns it into an effect: paint, a
timer, or a fetch. The driver gets set, the one way a write enters the graph from outside.
Scopes →
Nested scopes and the scope tree. Each scope records the node that owns it, its parentNodeRef.
A section nests inside another. The update can climb from each node to the root.
Context →
You provide a value by name in an outer scope. Use reads it in each nested scope, and goes up
the scope tree to find it. A deep block reads it, and no layer between must carry it.
If →
The first change of shape. If builds a block in its own scope when a condition
holds, and keeps what it needs to add or remove that block later.
Updates →
The walk: a change flows forward along the dependency edges and the scope tree, recomputed in order. It raises and removes blocks as conditions flip. No heap. This makes the graph react.
Reverse →
The write direction. A Reverse lens declares the state it writes and composes the new value. Each
write is a transaction; a pending counter holds an async one until the driver fills the Pending it
created. A write-lock threads up to whatever reads it, and setting something locked throws.
More pieces follow from here. Values and calculations sit over the dependency graph. Pending state, emissions, and the drivers that run them come next. Then conditionals and scope, the update walk that makes the graph react, and the reverse direction that writes to state. Each piece builds on the last.
One Idea Holds It Together
The whole running program is data: a set of nodes, each with a value, linked by a graph of who reads whom. A change walks that graph and recomputes only what depends on it, in dependency order, and re-executes a section when it structurally appears. That one model is what keeps updates proportional to the change. The architecture page starts there.