Skip to content
Shapemetry

@huukhanhnguyen/model / schema/components

schema/components

FlatComponentSource

FlatComponentSource = { key: string; operations: (Operation | Group)[]; parameters?: (Operation | Group)[]; }

key

key: string

operations

operations: (Operation | Group)[]

parameters?

optional parameters?: (Operation | Group)[]


FlatLaneExtras

FlatLaneExtras = { imageUrlOf?: (name) => string; listAnnotationStyles?: () => AnnotationStyle[]; listTextStyles?: () => TextStyle[]; onStepError?: (failure) => void; resolveMaterial?: (name) => unknown; resolvePlacedComponentBody?: (key, argsOverride?) => { data: ObjectData; flat: boolean; opening: BrepData[]; }; resolvePlacedNesting?: (parts, stock, spacing, seed, stockLength, kerfWidth) => ObjectData | undefined; resolvePlacedTable?: (key) => ObjectData | undefined; resolvePlacedView?: (key) => ObjectData | undefined; resolveTable?: (key) => unknown; }

Extra scope hooks an isolated evaluation may need beyond resolveComponent (the by-key lookup passed as a plain function argument) — viewObject's resolvePlacedView, tableEntity's resolvePlacedTable, imageData's imageUrlOf, Table.get()'s resolveTable, Material.get()'s resolveMaterial (settings-functions §B.2 — same wire as Table.get), and the TWO placeComponent hooks: resolvePlacedComponent (FLAT-mode — splices a gated, flattened result; wired for a truly-flat scope: sheets/rasterize) and resolvePlacedComponentBody (3D-mode — raw untransformed body+opening, no flatness gate; wired for the ROOT scope and a component's own "component"-lane scope). All Model-owned — absent when the caller has none (e.g. a standalone test), in which case each generator fails soft to empty/passthrough, and a bare Table.get(...) / Material.get(...) reference simply isn't defined (the same ReferenceError it always was before this hook existed).

imageUrlOf?

optional imageUrlOf?: (name) => string

Parameters

name

string

Returns

string

listAnnotationStyles?

optional listAnnotationStyles?: () => AnnotationStyle[]

Returns

AnnotationStyle[]

listTextStyles?

optional listTextStyles?: () => TextStyle[]

The two style lanes, RESOLVED — a drafting mark authored inside a component body or a sheet's own operations names a textStyles[] / annotationStyles[] record, and reaches it only through here (the root scope's own listTextStyles/listAnnotationStyles is unreachable from an isolated scope). Wired like resolveMaterial, and for the same reason it is legitimate in a component: a named shared record travels WITH the document, so the definition still renders identically after export — unlike resolveTable, which is host state.

Returns

TextStyle[]

onStepError?

optional onStepError?: (failure) => void

Called once per step whose fold FAILED, after the lane has run. DataNode._stepFailed is fail-soft by design — it records the error on the node, logs it, and passes the input through — so without this hook the only trace outside the node is a console line, and a caller (a sheet) cannot tell a placement that produced nothing from one that was never there. Reporting only; it must not change the fold.

Parameters

failure

StepFailure

Returns

void

resolveMaterial?

optional resolveMaterial?: (name) => unknown

Material.get(name) — resolved materials[] record by name (fail-soft null). Wired like resolveTable so component/flat isolated scopes register a materials-lane dependency edge (settings-functions §B.2).

Parameters

name

string

Returns

unknown

resolvePlacedComponentBody?

optional resolvePlacedComponentBody?: (key, argsOverride?) => { data: ObjectData; flat: boolean; opening: BrepData[]; }

3D-mode placeComponent hook (2026-07-17) — raw (untransformed) body + opening volumes, NO flatness gate: valid to place a flat component in a 3D chain. Wired at the ROOT scope (Model's constructor) AND a component's own isolated "component"-lane scope (nested 3D placement) — never at a truly-flat scope, where placeComponent goes through the FLAT-mode resolver instead: a declared-flat component splices (title-block furniture), a 3D one is refused because paper places a VIEW of it (see DataNode's dispatch, which checks owner.lane === "flat" OR the chain-level flat declaration). flat (the component's own Component.flat) rides along so a flat-declared CHAIN reaching this hook from a 3D lane can still splice the declared 2D representation (see DataNode._resolvePlacedComponentFlat).

Parameters

key

string

argsOverride?

Record<string, string>

Returns

{ data: ObjectData; flat: boolean; opening: BrepData[]; }

data

data: ObjectData

flat

flat: boolean

opening

opening: BrepData[]

resolvePlacedNesting?

optional resolvePlacedNesting?: (parts, stock, spacing, seed, stockLength, kerfWidth) => ObjectData | undefined

nesting's hook — a whole-scene-scan-capable flat-lane producer. Deliberately still NEVER wired onto the root scope, nor a component's own scope (a component's placed output can itself join the scene this would scan — same self-reference risk as at root) — UNLIKE resolvePlacedView/Table (see their own docs, and Model.ts's sceneFrame fold-depth guard), nesting's whole-scene scan has no per-key identity to name a cycle by (it reads the WHOLE scene unconditionally, never one keyed entry), so a blanket lane-placement ban stays the simplest correct rule here — not yet worth the same detection machinery. Post VIEW-REFACTOR the parts keys name components[] entries (their attributes.pattern content is what gets nested — see Model._partPatternOf). Args already coerced by the calling DataNode (parts array of {key,quantity}, stock object, spacing/seed numbers).

Parameters

parts

{ key: string; quantity: number; }[]

stock
height

number

width

number

spacing

number

seed

number

stockLength

number

kerfWidth

number

Returns

ObjectData | undefined

resolvePlacedTable?

optional resolvePlacedTable?: (key) => ObjectData | undefined

Parameters

key

string

Returns

ObjectData | undefined

resolvePlacedView?

optional resolvePlacedView?: (key) => ObjectData | undefined

Parameters

key

string

Returns

ObjectData | undefined

resolveTable?

optional resolveTable?: (key) => unknown

Parameters

key

string

Returns

unknown


IsolatedScopeOwner

IsolatedScopeOwner = { nodes: NodeCollectionHost; registry: RegistryHost; }

nodes

nodes: NodeCollectionHost

registry

registry: RegistryHost


StepFailure

StepFailure = { method: string; reason: string; step: string; }

One step whose fold FAILED, and why. step is the operation key (placedView, a table placement, …); method is what it tried to run; reason is that step's own error message.

Declared here, at the producer (reportStepErrors in lanes/components/components.ts), because the fold is what fails — the consumer that collects them into a partial sheet is one reader among possible others. It was SheetWarning in schema/sheets.ts, byte-identical to the inline shape onStepError already spelled: one shape, two names, one of them named after a consumer.

method

method: string

reason

reason: string

step

step: string

Last updated: 📖 6 min readEdit on GitHub