Skip to content
Shapemetry

@huukhanhnguyen/model / core/evaluationStack

core/evaluationStack

dependOn()

dependOn(target): void

Register a real dependency edge from target to whichever node is currently evaluating — call this at the start of any cross-lane resolver, before (or after — the stack is unchanged either way once target's own resolve, if any, has popped back off) pulling target's value. No-op outside any evaluation, or when target is the node currently evaluating.

Also records the reverse edge on current._reads so the next dirty recompute can retract it (BaseNode.retractReads). Without the reverse index, a dynamic Table.get that later targets a different key would leave a permanent _dependents edge on the old table.

Parameters

target

BaseNode

Returns

void


linkRead()

linkRead(target, consumer): void

Register the same edge dependOn would, for a consumer that is NOT on the evaluation stack — an ISOLATED scope (a sheet's flat operations, a component body) evaluates through throwaway nodes built fresh inside it, so the stack's top is a node that gets discarded, and Model's scope hooks name the real outer consumer explicitly (see Model._sharedIsolatedHooks).

Use this rather than a bare target._dependents.add(consumer): without the reverse _reads entry the edge is permanent, and a sheet that repoints a tableEntity at another table keeps re-resolving on every edit to the table it stopped reading (pinned by tests/edgeCleanup.test.ts).

Parameters

target

BaseNode

consumer

BaseNode

Returns

void


withEvaluating()

withEvaluating<T>(node, fn): T

Run fn with node pushed as "currently evaluating". Always paired push/pop via try/finally so a thrown error still leaves the stack clean.

Type Parameters

T

T

Parameters

node

BaseNode

fn

() => T

Returns

T

Last updated: 📖 2 min readEdit on GitHub