Pure DAG construction: a list of ReactiveDag.Cell → a ReactiveDag.Plan.
No live data — only the plan (cells, parent edges, depths). Validates that
every referenced input exists and the graph is acyclic (raises ArgumentError
on a dangling input or cycle; a host's DSL transformer should catch these at
compile time, but the runtime builder re-checks so a hand-built plan can't
wedge a cascade).
Summary
Functions
What each parent CLAIMS when child's keys change, applying the key rule
each parent DECLARED. The rule sees the parent, the specific child input, and
the changed keys, and returns :all (whole-cell recompute, the "*"
wildcard) or {:keys, mapped}.
Functions
@spec build([ReactiveDag.Cell.t()]) :: ReactiveDag.Plan.t()
@spec claims_for( ReactiveDag.Plan.t(), ReactiveDag.Cell.id(), [String.t()], module(), map() ) :: [ {ReactiveDag.Cell.id(), [String.t()]} ]
What each parent CLAIMS when child's keys change, applying the key rule
each parent DECLARED. The rule sees the parent, the specific child input, and
the changed keys, and returns :all (whole-cell recompute, the "*"
wildcard) or {:keys, mapped}.
Returns [{parent_id, [key]}]. key_rule defaults to
ReactiveDag.Node.KeyRule, which reads :identity | :all | :group off the
authored block. A cascade always uses that one; the parameter exists for a
host or test inspecting claims directly.
It is NOT a seam for a host rule module. apply_rule/6 picks the widest arity
the module exports, MODULE-WIDE — so a module implementing only rule/3
silently loses the diff path and tenant-scoped :group reads for every cell,
not only the ones it meant to answer for. What a node claims is declared on
the node (key_rule, recompute_by), where assembly resolves it and the
verifier checks it. See guides/seams.md.
A rule that returns anything outside its contract is answered :all and
logged, rather than passed on: an out-of-contract value used to travel into
the walk and fail several frames away, naming neither the rule nor the edge.
diffs maps a changed key to the DIFF of that change — both sides, as
captured by the payload write that produced it. A rule implementing rule/4
receives it and can derive a claim from a row that no longer exists; one
implementing only rule/3 is called exactly as before.