Modules
Block document model, one-way SCXML compiler, and LiveView editor components for composing Statifier statecharts from typed blocks.
May this block land in this slot? Answered by two independent gates - structural admission by kind tag, and data-flow compatibility by opaque string identity plus a host-supplied widening relation (ADR-0003).
A host's widening relation. Consulted only after identity has failed, so an implementation can only widen, never narrow (ADR-0003 decision 6).
One node of a block document (ADR-0001).
The authoring-time extension seam. A host implements this behaviour once
per palette entry; the core.* structural vocabulary this package will
ship itself lands in a later record (ADR-0002 decision 10) and is not
present yet.
The join between a block document and the chart it compiled to (ADR-0004 decision 7).
What one successful compile produced (ADR-0004 decision 1).
The one-way compile: a block document plus a palette in, one artifact out (ADR-0004 decisions 1-4, 6-7).
Resolves each element of one block's emission to the block an author would recognise (ADR-0004 decision 5).
The Chart stage: run the generated SCXML through statifier's own pipeline and route every finding back to a block (ADR-0004 decisions 9 and 10).
What a block type is entitled to know while emitting, and nothing more (ADR-0004 decision 4).
One thing the compiler has to say about one block (ADR-0004 decision 10).
The two-registry gap, surfaced as data and linted only on request (ADR-0004 decision 8).
Turns an StatifierBlocks.Emission tree into SCXML bytes, and records
where every one of them came from (ADR-0004 decisions 5 and 6).
State ids derived from block ids by a pure function (ADR-0004 decision 3).
The core.* structural vocabulary: the block types this package ships
itself (ADR-0002 decision 10).
core.branch: one slot per condition arm, plus otherwise (ADR-0002
decision 10).
The SCXML shapes the core.* vocabulary compiles to (ADR-0004 decisions
2-4), and the small builders the seven types share.
core.group: a boundary around a run of steps that interrupt rules can
fire against.
core.on_event: an interrupt handler, valid inside an interrupts slot
and nowhere else (ADR-0002 decision 10).
core.parallel: one slot per lane, with no ordering between the lanes
(ADR-0002 decision 10).
core.resumable_group: a group whose config carries a history mode
(ADR-0002 decision 10).
core.sequence: an ordered run of steps, and the conventional document
root (ADR-0002 decision 10).
core.wait: a leaf whose whole meaning is its config (ADR-0002 decision
10).
A block document: one tree, one envelope (ADR-0001).
The editor's command algebra. Pure, serializable, invertible - and deliberately free of any UI framework dependency, so it is tested with no editor shell present at all (ADR-0005 decision 1).
Undo and redo over StatifierBlocks.Edit.t() commands (ADR-0005
decision 3), and the one funnel every editor command actually goes
through: commit/4 runs Edit.check_config/3 before Edit.apply/2, so
"invalid config never reaches the document" is a property of this
module, not a rule an editor shell has to remember to enforce itself.
Drop-target enumeration (ADR-0005 decision 5): which slots would accept a dragged block, at slot granularity rather than gap granularity.
The block editor: the only stateful module in the package's rendered half (ADR-0005 decisions 6, 8, 9, 13).
One block's chrome, dispatching to its slots (ADR-0005 decisions 10, 11, 12, 13).
The tree's root and the drag hook's element (ADR-0005 decisions 7, 13, 14).
The selected block's config form (ADR-0005 decisions 9 and 13).
One config field, dispatching on the closed field-type set (ADR-0005 decision 9, ADR-0002 decision 7).
The document-level findings panel (ADR-0005 decision 11).
The grouped, searchable, filterable palette (ADR-0005 decisions 8, 10, 13).
One named slot: its header, its children, its gaps, and its "+" buttons (ADR-0005 decisions 5, 6, 8, 11, 13).
One SCXML subtree, structurally (ADR-0004 decision 4).
A finding as the editor renders it: normalized for presentation, and the anchor routes it (ADR-0005 decision 11).
Mints block and document ids: "blk_" <> uxid and "bdoc_" <> uxid,
following the family's identifier convention (st-ADR-0008, as amended to
drop the uxid dependency and mint inline -
statifier-ex/lib/statifier/machine_state.ex:571-585).
A palette names the block types a host makes available: a map from a
block's type_name to the module implementing StatifierBlocks.BlockType
for it (ADR-0002 decision 2).
Which generated element came from which block (ADR-0004 decision 5).
Everything the editor renders, derived from {document, palette, findings} (ADR-0005 decisions 9, 10, 11, 12, 13).
One config field, its schema and its current value (ADR-0005 decision 9).
A resolved node's config form: its fields, plus any :config finding
whose key matched no field (ADR-0005 decision 11's fourth routing row).
One block, rendered: its resolved status, its presentation metadata, its slots (recursive), its form, and its own findings.
One palette section: types sharing entry.group, sorted by
entry.order then entry.label (ADR-0005 decision 10's grouping
rule).
One named slot: declared or raw, with its children and its own findings.