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 the drain).
Summary
Functions
The parents whose keys should be dirtied when child changed, 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 dirty_parents( ReactiveDag.Plan.t(), ReactiveDag.Cell.id(), [String.t()], module(), map() ) :: [ {ReactiveDag.Cell.id(), [String.t()]} ]
The parents whose keys should be dirtied when child changed, 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 — the drain always uses that one, and the parameter exists so a
host calling this directly (to pre-mark a re-run, say) gets the same answer.
priors maps a changed key to the child row AS IT WAS when marked dirty (see
ReactiveDag.Frontier). A rule that implements 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.