You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
DataFlowEngine.getComputeError(nodeId) — the error the node's last compute threw (sync) or rejected with (async), or undefined after a
successful run. Errors park there instead of aborting the flush, clear on
the node's next successful run, and both transitions notify change
listeners so hosts can render the failure.
A graph:replaced engine event, emitted when the whole nodes map is
swapped at once (undo / redo / deserialize) rather than mutated through the
granular node lifecycle events. Consumers that mirror per-node state — the
data-flow engine does — rebuild against the new graph on it.
Fixed
Deleting a node now recomputes its dependents immediately. The delete
handler marked them dirty but nothing scheduled the flush (node deletion
cascades the connected edges away without events), so stale outputs
survived until an unrelated event touched the graph.
A node recreated with a deleted node's id no longer accepts the dead
instance's late async result: generation counters bump on delete instead
of resetting, so an in-flight promise from the old instance can never
match the new one. Matters for serialized boards, where ids are
deterministic.
A fresh run supersedes an async run still in flight for the same node:
the superseded landing can no longer overwrite a newer result — or erase
the error a newer failing run parked.
One throwing compute no longer costs the rest of the flush its
recompute: sync throws are caught and parked per node instead of escaping
the flush microtask after the dirty set was already cleared, and async
rejections are handled the same way instead of surfacing as unhandled
rejections. Failed nodes keep their last good outputs.
dispose() now severs the SpatialEngine subscription itself — a host
that never called the connect() cleanup no longer keeps a recomputing
zombie — marks the engine inert (a flush already in progress stops, and
a late markDirty schedules nothing), and bumps the generation counters
so async computes still in flight resolve into nothing, even across a
dispose-and-reconnect revival.
setContainerSize ignores any measurement that is not at least one whole
pixel on both axes. A NaN/Infinity size from an unvalidated host measurement
used to flow into the maintain-center shift and poison the viewport (and the
stored size that later fit math reads); a hidden container's 0×0 measurement
used to shift the viewport by half the old size on re-show; and a sub-pixel
measurement while a panel animates open (e.g. 0.5×0.4) used to consume the
one-shot parked fit against a degenerate size. Such measurements now change
nothing, parked fits keep waiting, and the next real (≥1px) measurement
recovers everything. Measurements are coerced to numbers first, so untyped
hosts passing numeric strings keep working.
Undo, redo, and deserialize now replay the data flow. They replace the
whole nodes map at once, which arrives with no granular node events, so the
data-flow engine used to leave restored nodes stale and removed nodes'
values lingering until an unrelated edit; it now reconciles against the new
graph — dropping gone nodes' state and recomputing the rest — with no
manual touch. Ordinary edits are unaffected (no whole-graph recompute).
Deleting a node drops its whole stored state by id, not just the ports its
type resolves at delete time. A node whose port set is data-driven and was
narrowed before deletion used to leak the dropped ports' values onto a
later node reusing the same id.
A throwing onChange listener is isolated: it is reported and the
remaining listeners still run, on the synchronous and asynchronous notify
paths alike, instead of starving later listeners or surfacing as an
unhandled rejection.