Skip to content
Shapemetry

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.tsporous 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")[]
Last updated: 📖 2 min readEdit on GitHub