Model - Lanes
API reference for src/schema/lanes on @huukhanhnguyen/model, reachable from ..
See the Guide for the ModelJSON / evaluate pipeline.
API reference
Signatures are generated from the live package .d.ts - not hand-written.
LANE_BODY_FIELDS
const
The body fields a lane entry may carry — what an offline transform or a doc-wide walk has to visit. A node-entry lane has none: the entry itself is the node.
const LANE_BODY_FIELDS: readonly ["parameters", "operations", "opening", "columns"]LANE_NAMES
const
Every lane of a ModelJSON document. The two PSEUDO-lanes (parameters and scene, the root header and body) are deliberately absent: they are not arrays of entries, they are the root collection itself. references.ts adds them where an edge table needs to name them.
const LANE_NAMES: readonly ["materials", "layers", "styles", "textStyles", "annotationStyles", "cameras", "skeletons", "animations", "components", "textures", "tables", "views", "sheets"]LaneBodyFieldName
type
type LaneBodyFieldName
// = typeof LANE_BODY_FIELDS[number]LaneCarrier
type
Anything shaped like a document — a stored ModelJSON, or a live ModelScope paired with the Model fields. Indexed loosely on purpose: this is the one place lane names are read as data, and every caller has a different static type for the same arrays.
type LaneCarrier
// = Record<string, unknown>LaneChain
type
One lane entry reduced to the node lists a doc-wide walk must visit, plus the lane it came from. A node-entry lane yields the entry itself as a one-element operations list, so a consumer never special-cases it.
type LaneChain
// = {
lane: LaneName;
parameters?: unknown[];
operations?: unknown[];
opening?: unknown[];
columns?: unknown[];
/** NOT a node list — `Component.entities` is baked geometry (the
* static-geometry door for importers/AI). Carried here because a
* geometry migration has to reach it; a NODE walk ignores it. */
entities?: unknown[];
}laneChains
function
Every lane entry of a document, as node lists to walk. THE replacement for the hand-written [doc.components, doc.sheets, doc.textures, …] arrays that each offline transform used to carry — those are exactly the lists that fall behind when a lane is added.
filter narrows by descriptor (e.g. unit conversion takes only space === "model"), so a consumer states its RULE instead of its list.
laneChains(carrier: LaneCarrier, filter?: (descriptor: LaneDescriptor, lane: LaneName) => boolean): LaneChain[]LaneDescriptor
type
type LaneDescriptor
// = {
/** Which object owns the array. The FIELD NAME always equals the lane
* name, so a consumer resolves it as `scope[lane]` / `model[lane]`. */
storage: "scope" | "model";
/** `chain` — the entry is a mini-document (`parameters`/`operations`/…).
* `node` — the entry IS one authored node (a material, a light). */
entry: "chain" | "node";
/** `key` field, or a quoted string literal in a `name` arg. */
identity: "key" | "name";
/**
* Which SPACE the lengths inside this lane live in.
*
* `model` follows the document's display unit — switch mm→m and its
* literals are rewritten. `paper` is physical sheet millimetres and must
* NEVER be rescaled: an A3 sheet is 420 mm wide whether the model is
* measured in millimetres, metres or inches.
*/
space: "model" | "paper";
scope: LaneScope;
/**
* A STEP lane: every step in an entry's body returns exactly the lane's
* own singular type (`material`, `view`…), so
* `RETURN_LANE_OF` can map that return back to this lane.
*
* `false` marks a lane whose entries are NOT step chains and never will
* be: `components` is a lite MODEL (own parameters + an entity-stream
* body) and `sheets` is a PLACEMENT chain (it places views/tables by
* key). Neither has a `return: "<singular>"` node.
*
* Required, not optional, on purpose: adding a lane must not silently
* inherit either answer.
*/
stepLane: boolean;
/** Has a CollectionNode — its MEMBERSHIP is pullable as a dependency,
* separate from any entry's body. Wired only where a reader exists. */
collection?: true;
/** Base string for a minted identity ("view" → view1, view2…). */
base: string;
/** Empty arg input CLEARS the arg instead of storing "" (the cameras
* authoring convention). */
clearEmptyArgs?: true;
/** The by-name consumer that blocks a delete and is rewritten on rename.
* Only the three name-identified lanes have one. */
references?: {
method: string;
arg: string;
};
}LaneName
type
type LaneName
// = typeof LANE_NAMES[number]LANES
const
Missing a key here is a COMPILE error, which is the whole point: the descriptor cannot drift from the lane list it describes.
const LANES: Record<LaneName, LaneDescriptor>LaneScope
type
How deep a name resolves from inside the lane's body. See the long form in references.ts — porous climbs owner.parent to the model root, so the whole model shares one namespace; isolated has that link cut, so the lane is a FUNCTION whose own parameters are the only names its body sees.
type LaneScope
// = "porous" | "isolated"MODEL_SPACE_LANES
const
The lanes whose lengths follow the model's display unit.
const MODEL_SPACE_LANES: ("sheets" | "skeletons" | "animations" | "materials" | "layers" | "styles" | "textStyles" | "annotationStyles" | "cameras" | "views" | "components" | "textures" | "tables")[]STEP_LANES
const
The lanes whose entries are step chains — see LaneDescriptor.stepLane.
const STEP_LANES: ("sheets" | "skeletons" | "animations" | "materials" | "layers" | "styles" | "textStyles" | "annotationStyles" | "cameras" | "views" | "components" | "textures" | "tables")[]