Internals · State
State
A running Program has exactly one kind of thing that changes: its state cells. Everything else — every binding, every rendered output — is derived from them and recomputed. This page follows a state cell from the canonical form it is stored in to the reactive value it becomes at runtime.
The canonical form is the source of truth
A module is stored as canonical CVJSON — the same
serialised command form the other
targets render from. It is the single source of truth: one
.program.json per module, kept in sync across every platform, with each target
(Dart, Swift, JavaScript, JSON) rendered from it rather than authored alongside it.
In that form a STATE declaration is one body command:
["$", "count", "Maths.Integer", 0]
The tag "$" marks it as a state cell; then its name, its type, and its initial value.
A cell that may start pending or carry an error — a
LOCKED state — carries a trailing
"LOCKED". Nothing about the cell is decided at this layer beyond those four facts; it is
just data.
The compiler renders it into a reactive cell
To run, the canonical form is compiled into a target — for the reference interpreter, into
JavaScript. The compiler walks each ["$", …] command and emits a reactive value:
var count = Reactive.State(0);
// a LOCKED cell is rendered lockable:
var saved = Reactive.State(null, /* lockable */ true);
A Reactive.State is the one place a value actually lives. Reading it inside the run body
subscribes whatever is reading; writing it is what makes a new value exist. Bindings and outputs
never hold state of their own — they read cells and are recomputed whenever a cell they read
changes.
State is what passes through each cycle
Because the cells are the only mutable thing, they are exactly what is handed in and out of the update cycle. Each cycle receives a set of value updates — a map from state cell to its new value — applies them, and re-derives everything downstream. On the first cycle the set is empty; on later cycles it holds whatever a driver fed back:
// one cycle: apply the pending state updates, recompute, produce the next program
program = Reactive.Run(program, { count: 1 });
So state is both the resting shape of a program — the cells named in its canonical form — and the currency of every update: the values in, and the new values out. How those cycles are driven is covered under Running.