Skip to content
Shapemetry

@huukhanhnguyen/model / nodes/OptionNode

nodes/OptionNode

OptionNode

Extends

Constructors

Constructor

new OptionNode(parent, label, expr?): OptionNode

Parameters

parent

unknown

label

string

expr?

string = "''"

Returns

OptionNode

Overrides

ExpressionNode.constructor

_dependents

_dependents: Set<BaseNode>

Inherited from

ExpressionNode._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

ExpressionNode._epoch

_evaluating

static _evaluating: Set<ExpressionNode>

Inherited from

ExpressionNode._evaluating

_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

ExpressionNode._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

ExpressionNode._reads

_valueType

_valueType: string

Inherited from

ExpressionNode._valueType

attributes

attributes: Record<string, unknown> = {}

Inherited from

ExpressionNode.attributes

collection

collection: BaseCollection

Inherited from

ExpressionNode.collection

error?

optional error?: string = ""

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

Inherited from

ExpressionNode.error

expression

expression: string

The raw JS expression string that this node evaluates.

Inherited from

ExpressionNode.expression

id

id: string

Inherited from

ExpressionNode.id

isDirty

isDirty: boolean = true

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

Inherited from

ExpressionNode.isDirty

label

label: string

Display label shown in the UI for this select option.

locals?

optional locals?: Record<string, unknown>

Extra names visible to THIS expression only, layered on top of the owning collection's keys. A CHAIN-LOCAL parameter (a texture chain's own parameters) is not a graph node, so it never appears in keyedNodes() — an editor rendering a chain STEP sets this to the chain's resolved parameter values so imageWidth reads the same way it does inside the chain's own evaluator. ponytail: layered ON TOP of the root names rather than REPLACING them — a chain scope is isolated in the engine, so an editor field naming a root parameter still previews a value the engine would reject. Swap the merge for a replace when the editor needs full isolation fidelity.

Inherited from

ExpressionNode.locals

name

name: string

Inherited from

ExpressionNode.name

parent?

optional parent?: any

Inherited from

ExpressionNode.parent

pending

pending: boolean = false

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

Inherited from

ExpressionNode.pending

sourceId

sourceId: string = ""

Inherited from

ExpressionNode.sourceId

value

value: unknown = undefined

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

Inherited from

ExpressionNode.value

Accessors

dependents

Get Signature

get dependents(): Set<any>

Returns

Set<any>

Overrides

ExpressionNode.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

ExpressionNode.errorLogPrefix

model

Get Signature

get model(): any

Returns

any

Inherited from

ExpressionNode.model

owner

Get Signature

get owner(): any

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

Returns

any

Inherited from

ExpressionNode.owner

ownerNodes

Get Signature

get ownerNodes(): { elements?: unknown; evaluate: () => void; notify?: (event, value) => void; } | undefined

The owning node collection (the ModelScope's nodes), or undefined when this expression isn't mounted under an owner yet. UI uses this only to re-evaluate the graph after an edit (see requestEvaluate).

Returns

{ elements?: unknown; evaluate: () => void; notify?: (event, value) => void; } | undefined

Inherited from

ExpressionNode.ownerNodes

symbol

Get Signature

get symbol(): string

Returns

string

Inherited from

ExpressionNode.symbol

valueType

Get Signature

get valueType(): string

Returns

string

Overrides

ExpressionNode.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

ExpressionNode._commit

_dispose()

_dispose(): void

Returns

void

Inherited from

ExpressionNode._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

ExpressionNode._fail

addListener()

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

Parameters

event

string

listener

Listener

Returns

() => void

Inherited from

ExpressionNode.addListener

buildContext()

buildContext(): EvalContext

Public eval scope for this expression (the same scope compute() uses).

Returns

EvalContext

Inherited from

ExpressionNode.buildContext

compute()

compute(): unknown

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

Returns

unknown

Inherited from

ExpressionNode.compute

copy()

copy(): OptionNode

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

Returns

OptionNode

Overrides

ExpressionNode.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

ExpressionNode.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

ExpressionNode.errorValue

evaluate()

evaluate(listener?): unknown

Evaluate this node, cache the result, and notify dependents; returns the cached value. When compute() returns a thenable, this returns the prior (stale) value synchronously and settles later — see core/maybeAsync.ts.

Parameters

listener?

() => void

Returns

unknown

Inherited from

ExpressionNode.evaluate

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

ExpressionNode.finishInit

getError()

getError(listener?): string | undefined

Parameters

listener?

() => void

Returns

string | undefined

Inherited from

ExpressionNode.getError

getInput()

getInput(listener?): string

Parameters

listener?

(...args) => void

Returns

string

Inherited from

ExpressionNode.getInput

getOverride()

getOverride(): string | null

Live override currently applied for evaluation, or null when none.

Returns

string | null

Inherited from

ExpressionNode.getOverride

isPending()

isPending(listener?): boolean

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

Parameters

listener?

() => void

Returns

boolean

Inherited from

ExpressionNode.isPending

isValid()

isValid(listener?): boolean

Parameters

listener?

() => void

Returns

boolean

Inherited from

ExpressionNode.isValid

notify()

notify(event, ...args): void

Parameters

event

string

args

...unknown[]

Returns

void

Inherited from

ExpressionNode.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

ExpressionNode.postCompute

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

ExpressionNode.remove

removeListener()

removeListener(event, listener): void

Parameters

event

string

listener

Listener

Returns

void

Inherited from

ExpressionNode.removeListener

requestEvaluate()

requestEvaluate(): void

Re-evaluate the whole owning graph. Called by the UI after it writes a new expression (field blur / array row edit) so dependent nodes + geometry refresh. No-op when not yet mounted under an owner.

evaluate() alone is NOT enough for a ROOT-LEVEL operation step: DataNode.evaluate() deliberately returns its cached value (the owning fold pulls the step through evaluateStep), so the per-element loop re-runs nothing and nothing notifies. The root fold only runs from the render collect (Model.ts's rootFoldSlices), and that collect is scheduled by the collection's own "change" — so an edit to e.g. faceMaterial/applyVisible at the root used to land in the document and then sit there invisible until some unrelated edit forced a resync. Firing that "change" here is the same signal the lane editors already send through touch(owner).

Returns

void

Inherited from

ExpressionNode.requestEvaluate

resolveNodeValue()

static resolveNodeValue(node): unknown

Shared with NodeCollection.sharedEvalContext getters.

Parameters

node
evaluate

() => unknown

return?

string | null

Returns

unknown

Inherited from

ExpressionNode.resolveNodeValue

retractReads()

retractReads(): void

Drop every reverse read edge recorded in _reads.

Returns

void

Inherited from

ExpressionNode.retractReads

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

ExpressionNode.setError

setInput()

setInput(expr): void

Update the expression string and propagate dirty flags to all dependents.

Parameters

expr

string

Returns

void

Inherited from

ExpressionNode.setInput

setOverride()

setOverride(expr): void

Set or clear a live evaluation override. Marks dirty like setInput so dependents re-evaluate; does NOT touch the stored expression string.

Parameters

expr

string | null

Returns

void

Inherited from

ExpressionNode.setOverride

toJSON()

toJSON(): { attributes: Record<string, unknown>; id: string; input: string; label: string; }

Returns

{ attributes: Record<string, unknown>; id: string; input: string; label: string; }

attributes

attributes: Record<string, unknown>

id

id: string

input

input: string

label

label: string

Overrides

ExpressionNode.toJSON

Last updated: 📖 11 min readEdit on GitHub