Skip to content
Shapemetry

@huukhanhnguyen/model / nodes/DataNode

nodes/DataNode

DataNode

Extends

Constructors

Constructor

new DataNode(method, definition?): DataNode

Parameters

method

string

definition?

DataDefinition | null

Returns

DataNode

Overrides

BaseNode.constructor

_dependents

_dependents: Set<BaseNode>

Inherited from

BaseNode._dependents

_epoch

_epoch: number = 0

Bumped on every dirty (see setDirty/markDirty) — a stale async settle compares its captured epoch against the current one and discards itself on mismatch (a newer edit superseded it while it was in flight).

Inherited from

BaseNode._epoch

_hooks?

optional _hooks?: NodeHooks

Lifecycle observers attached to THIS node — see nodes/hooks.ts. Also carried by an DataDefinition, the declaration surface a node's hooks can be attached to before the node exists.

Inherited from

BaseNode._hooks

_reads

_reads: Set<BaseNode>

Reverse index of nodes this node currently reads (static expression refs + dynamic dependOn edges). Cleared at the start of every dirty recompute and on dispose so a dropped Table.get/sampleTexture edge stops cascading markDirty (and a disposed node is not retained).

Inherited from

BaseNode._reads

_state

_state: ChainState | null = null

Cached output state of this step (stream after it).

args

args: ArgumentNode[] = []

Argument nodes that parametrize this node.

attributes

attributes: Record<string, unknown> = {}

Inherited from

BaseNode.attributes

claims

claims: ObjectClaims = {}

collection

collection: BaseCollection

Inherited from

BaseNode.collection

definition

definition: DataDefinition | null = null

Registry definition backing this operation (create/compute + args meta).

enabled

enabled: ArgumentNode | null = null

Optional enable expression — falsy = bypassed (input passes through).

error?

optional error?: string = ""

Last error message; empty string when valid, undefined after a successful eval.

Inherited from

BaseNode.error

id

id: string

Inherited from

BaseNode.id

isDirty

isDirty: boolean = true

True when the node needs re-evaluation before its value can be trusted.

Inherited from

BaseNode.isDirty

key

key: string = ""

Identifier naming this node's result in expressions.

label

label: ArgumentNode

Label argument rendered as the node's display name — always a live ArgumentNode (default expression '', matching ParameterNode.label's own "unset" sentinel) so the UI can always bind an editable field; hasLabelOf (KeyedNode.ts) is the content-based "was this authored" check, and toJSON() uses it to omit an untouched label.

method

method: string

Registry method name (e.g. "polyline", "move").

parent?

optional parent?: any

Inherited from

BaseNode.parent

pending

pending: boolean = false

True while an async compute() is in flight (its result hasn't settled yet).

Inherited from

BaseNode.pending

sourceId

sourceId: string = ""

Inherited from

BaseNode.sourceId

value

value: unknown = undefined

Cached evaluated value; undefined when the node is in an error state.

Inherited from

BaseNode.value

Accessors

dependents

Get Signature

get dependents(): Set<BaseNode>

Returns

Set<BaseNode>

Inherited from

BaseNode.dependents

errorLogPrefix

Get Signature

get protected errorLogPrefix(): string

console.error prefix on a compute failure — override to match a subclass's existing log message (includes node-specific context).

Returns

string

Inherited from

BaseNode.errorLogPrefix

isProducer

Get Signature

get isProducer(): boolean

True when this operation ADDS to the stream (create form / engine producer).

Returns

boolean

model

Get Signature

get model(): any

Returns

any

Inherited from

BaseNode.model

owner

Get Signature

get owner(): any

Walk up to the nearest owner that has a nodes collection (ModelScope).

Returns

any

Inherited from

BaseNode.owner

return

Get Signature

get return(): string | null

ObjectData kind this operation is documented to return (definition return).

Returns

string | null

symbol

Get Signature

get symbol(): string

Returns

string

Inherited from

BaseNode.symbol

valueType

Get Signature

get valueType(): string

Returns

string

Overrides

BaseNode.valueType

Methods

_commit()

protected _commit(raw, isAsync, settle?): void

Protected (not private): ExpressionNode/ContainerNode's evaluate() overrides call this directly to reuse the exact same commit path for a volatile step that bypasses the isDirty gate.

Parameters

raw

unknown

isAsync

boolean

settle?

EvaluateSettle

Returns

void

Inherited from

BaseNode._commit

_dispose()

_dispose(): void

Returns

void

Inherited from

BaseNode._dispose

_fail()

protected _fail(err, isAsync, settle?): void

Protected (not private) — see _commit's doc.

Parameters

err

unknown

isAsync

boolean

settle?

EvaluateSettle

Returns

void

Inherited from

BaseNode._fail

_syncLockedState()

_syncLockedState(merged): void

FoldRunner-only (nodes/ContainerNode.ts): after re-merging this step's own raw result (computed over a LOCKED sibling's shielded-out subset) back into the full stream, patch the corrected complete state onto this node's own cache — referenceValue()/ContainerNode.computeUntil must see the same complete stream every other consumer sees, not just what THIS step computed over its filtered input. ponytail: does not touch _inputState, so the next evaluate() always re-filters/re-merges from scratch while any lock is active downstream of it — full incremental caching under partitioned input would need the cache key itself to account for which documents are locked; not worth it until a model with many locked nodes shows measurable cost.

Parameters

merged

ChainState

Returns

void

addListener()

addListener(event, listener): () => void

Parameters

event

string

listener

Listener

Returns

() => void

Inherited from

BaseNode.addListener

compute()

compute(): unknown

Compute the raw value for this node; override in subclasses to produce actual output.

Returns

unknown

Overrides

BaseNode.compute

copy()

copy(): DataNode

Duplicate this operation in its collection, inserting it right after the original.

Returns

DataNode

Overrides

BaseNode.copy

display()

display(listener?): string

Return the human-readable display string for this node's value (or its error message).

Parameters

listener?

() => void

Returns

string

Inherited from

BaseNode.display

errorValue()

protected errorValue(): unknown

Value to fall back to when compute()/postCompute() throws. Override for a node whose "empty" isn't undefined (ContainerNode: []).

Returns

unknown

Inherited from

BaseNode.errorValue

evaluate()

evaluate(listener?): unknown

An operation never computes standalone — the owning fold pulls it through evaluateStep(), which is what CONSUMES isDirty. The inherited BaseNode.evaluate() would clear the flag around a stub compute() and silently drop the edit signal (the next fold pass would serve the stale cached step), so return the cached value without touching dirtiness.

Parameters

listener?

() => void

Returns

unknown

Overrides

BaseNode.evaluate

evaluateStep()

evaluateStep(input): ChainState | Promise<ChainState>

Run this step over the previous step's state, returning the cached output when neither this node nor its input changed. When the step's create/compute returns a thenable, the fold stays a Promise from here on; fail-soft applies identically whether the step throws synchronously or its promise rejects.

Parameters

input

ChainState

Returns

ChainState | Promise<ChainState>

finishInit()

finishInit(): void

Assembly is complete: this node has its full structure and its children. Every assembly path calls it at the point wiring is genuinely done, which is NOT one line:

  • the classes that take everything as constructor parameters (the LaneNode family, ExpressionNode, OptionNode, ArgumentNode) call it at the end of their own constructor;
  • DataNode calls it after its args are pushed — fromRegistry and copy, never its constructor, which sets only method+definition;
  • ContainerNode after its children are attached, ParameterNode after its args are wired (NodeCollection: createFromJSON, addContainer, addEntry).

Guarded to fire at most once. That is what makes NESTED assembly safe — createFromJSON delegates to fromRegistry, and one node must see one init, not two — and makes a redundant call harmless rather than wrong.

Returns

void

Inherited from

BaseNode.finishInit

fromRegistry()

static fromRegistry(registry, method, argsMap?, key?, enabled?, label?): DataNode

Construct an operation from the registry by (globally unique) method.

Parameters

registry

Registry

method

string

argsMap?

Record<string, string> = {}

key?

string

enabled?

string

label?

string

Returns

DataNode

getError()

getError(listener?): string | undefined

Parameters

listener?

() => void

Returns

string | undefined

Inherited from

BaseNode.getError

invalidateCreated()

invalidateCreated(): void

Force the created part to rebuild on the next pull (used after structural cache invalidation, e.g. a replaced sub-model).

Returns

void

isPending()

isPending(listener?): boolean

True while an async compute() is still settling (see pending).

Parameters

listener?

() => void

Returns

boolean

Inherited from

BaseNode.isPending

isValid()

isValid(listener?): boolean

Parameters

listener?

() => void

Returns

boolean

Inherited from

BaseNode.isValid

notify()

notify(event, ...args): void

Parameters

event

string

args

...unknown[]

Returns

void

Inherited from

BaseNode.notify

postCompute()

protected postCompute(raw): unknown

Post-process compute()'s raw result into this.value; throw to signal a failure (caught by evaluate()'s template, same as a compute() throw). Override for a node whose value isn't a sanitizer-typed scalar: ContainerNode returns the data list as-is; ArgumentNode routes through the domain coercion pipeline (nodeMethods/parameter.ts + data/ asset resolution) instead of convert/validate.

Parameters

raw

unknown

Returns

unknown

Inherited from

BaseNode.postCompute

referenceValue()

referenceValue(): ObjectData | undefined

The baked data list of this step's cached state — what an expression referencing this node's key receives. Pulls the owning fold first so the state is fresh.

Returns

ObjectData | undefined

remove()

remove(): void

The removal door. BaseObject.remove() detaches from the collection and notifies "remove"; the pair brackets that, so beforeRemove still sees the node in its collection with its read edges intact.

afterRemove means "AFTER THE NODE LEFT ITS COLLECTION" — it does NOT promise the node's read edges are gone. Deliberately does not retractReads(): removing a node does not retract its edges today, only the disposal call sites do (tables.ts), and adding it here would be a behaviour change rather than an observation point.

Not anchored at retractReads() — that runs on EVERY dirty recompute (3 of its 6 call sites: evaluate, LaneNode.pull, evaluateStep), so hooks there would report a live node as removed on every evaluate.

Returns

void

Inherited from

BaseNode.remove

removeListener()

removeListener(event, listener): void

Parameters

event

string

listener

Listener

Returns

void

Inherited from

BaseNode.removeListener

retractReads()

retractReads(): void

Drop every reverse read edge recorded in _reads.

Returns

void

Inherited from

BaseNode.retractReads

setEnabled()

setEnabled(expr): void

Parameters

expr

string | null

Returns

void

setError()

setError(message): void

Set an error message on this node and notify listeners. Fires "error" (specific) and "change" (the universal event — see ParameterNode.setKey's doc).

Parameters

message

string

Returns

void

Inherited from

BaseNode.setError

setKey()

setKey(key): void

Parameters

key

string

Returns

void

setLabel()

setLabel(expr): void

Parameters

expr

string | null

Returns

void

toJSON()

toJSON(): { args: Argument[]; attributes: Record<string, unknown>; enabled?: string; id: string; key?: string; label?: string; method: string; }

Returns

{ args: Argument[]; attributes: Record<string, unknown>; enabled?: string; id: string; key?: string; label?: string; method: string; }

args

args: Argument[]

attributes

attributes: Record<string, unknown>

enabled?

optional enabled?: string

id

id: string

key?

optional key?: string

label?

optional label?: string

method

method: string

Overrides

BaseNode.toJSON

Last updated: 📖 11 min readEdit on GitHub