Model - View chain
API reference for src/lanes/views/viewChain, src/schema/viewChain 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.
chainView
function
Test/UI helper: build a chain View from a record-shaped description.
chainView(key: string, record?: { label?: string; family?: ViewFamily; camera?: CameraBase; window?: ViewWindow; filter?: ViewFilterRule[]; style?: string; }): ViewclearViewArg
function
clearViewArg(node: Operation, key: string): voidfindSectionPlane
function
A sectionPlane entity by its producing node key (sourceKey, stamped by tessellateScene) — authoring-time + viewSection.plane resolve. Falls back to the first section plane in the scene. Same helper views.ts re-exports.
findSectionPlane(entities: Entity[], key: string): SectionEntity | undefinedFoldedView
type
SavedView (@huukhanhnguyen/types) plus the head method that produced it — everything else is exactly that type: camera folds the projection POSE (absent for a headless preset and for viewDetail, which frames 2D content 1); window folds the head's crop rectangle; source is viewDetail-only, the components[] key whose flat content IS this view's drawing (views.ts resolves it through ResolveViewOptions.resolveDetail); placeable is true when the head is plan/section/elevation (paper-placeable).
type FoldedView
// = SavedView & { /** Head method when present (undefined = headless). */ headMethod?: ViewHeadMethod; }foldViewChain
function
Config-fold a views[] chain into a resolved definition.
foldViewChain(view: View, options?: FoldViewOptions): FoldedViewFoldViewOptions
type
type FoldViewOptions
// = {
/** Evaluate one expression arg. Default = empty-context parse/eval
* (literals and param-free formulas). Model.evaluateView passes a
* scope-backed evaluator so cut/pose track live parameters. */
evaluateArg?: (input: string) => unknown;
/** enabled expression evaluator; default truthy unless evaluates falsy. */
isEnabled?: (node: Operation) => boolean;
/** For viewSection.plane — the scene's entity stream, searched for the
* named sectionPlane entity (findSectionPlane). */
sectionEntities?: Entity[];
/** For view3d's `camera` arg — resolve a `camera` cameras[] entry by key
* (fail-soft: a missing/unresolvable key falls through to the inline
* pose args, same as an absent arg). Undefined when the caller has no
* cameras lane (e.g. a standalone test). */
resolveCamera?: (key: string) => EvaluatedCamera | undefined;
}isViewPlaceable
function
True when the chain has a paper-placeable head (plan/section/elevation).
isViewPlaceable(view: View): booleanoperationsFromRecordView
function
Inverse of the fold: a resolved view definition (family + pose + crop) back into the chain operations that produce it. The authoring UI and tests build fixtures through it, so a fixture can still think in projection terms.
family picks the head — it is NOT inferred from camera fields any more (the type tag it used to read is gone, and a pose alone cannot say whether an author meant a plan or a 3D bookmark). Everything else about the head is still derived from the pose: which principal elevation it faces, whether a plan is cut, where the section plane sits.
operationsFromRecordView(record: { family?: ViewFamily; camera?: CameraBase; window?: ViewWindow; filter?: ViewFilterRule[]; style?: string; }): (Operation | Container)[]setViewArg
function
setViewArg(node: Operation, key: string, input: string): voidsetViewStyleStep
function
Set/replace the viewStyle step (last wins; creates one when missing).
setViewStyleStep(view: View, styleName: string | undefined): voidVIEW_EYE_DISTANCE_MM
const
Stable eye-to-cut distance for plan/section heads that synthesize a camera from a cut height / cut point (matches the views camera/style EYE_DISTANCE_MM so offline migration round-trips).
const VIEW_EYE_DISTANCE_MM = 1000VIEW_FAMILY_OF
const
Head methods → family. SSOT in schema (SPEC §5.3).
const VIEW_FAMILY_OF: { readonly viewPlan: "plan"VIEW_FILTER_METHOD
const
const VIEW_FILTER_METHOD: "viewFilter"VIEW_HEAD_METHODS
const
Head methods → family. Lookup only — never camera-field inference.
The FAMILY is view semantics and lives here, but the method NAMES are type-pinned to the lane's one vocabulary declaration (schema/vocabulary/laneMethods.ts, which the catalog derives its nodeType "view" entries from): a head naming a method that table does not declare stops compiling (step 7, 2026-07-27).
const VIEW_HEAD_METHODS: Set<string>VIEW_METHODS
const
Every declared view method — heads AND steps, straight off the vocabulary table, so a method added to the catalog is legal here the same moment.
const VIEW_METHODS: Set<string>VIEW_PLACEABLE_METHODS
const
Paper placement accepts every HEAD; only a HEADLESS chain (a filter/style preset, which frames nothing) is unplaceable.
view3d joined the set 2026-07-27. It used to be excluded on the theory that a perspective bookmark cannot be drawn — but the drawing pipeline projects in PARALLEL from whatever direction the camera looks (views.ts's basisFromForward handles an arbitrary forward vector), and a parallel projection down an oblique direction is exactly an AXONOMETRIC drawing: the isometric that every drawing set carries next to its plans. So a placed view3d renders as an axonometric; its fov/zoom are ignored on paper, since a drawing has no perspective.
const VIEW_PLACEABLE_METHODS: Set<string>VIEW_STEP_METHODS
const
const VIEW_STEP_METHODS: Set<string>VIEW_STYLE_METHOD
const
const VIEW_STYLE_METHOD: "viewStyle"viewArgInput
function
Arg get/set on a view operation node.
viewArgInput(node: Operation, key: string): string | undefinedviewExprJson
function
viewExprJson(value: unknown): stringviewExprNumber
function
Expression-literal helpers for authoring ops (UI + tests + migration).
viewExprNumber(n: number): stringviewExprPoint
function
viewExprPoint(p: [number, number, number]): stringviewExprString
function
viewExprString(s: string): stringviewExprWindow
function
viewExprWindow(w: [number, number, number, number]): stringViewHeadMethod
type
type ViewHeadMethod
// = keyof typeof VIEW_FAMILY_OFviewHeadOf
function
First head operation in a view chain (skipping containers / disabled not checked).
viewHeadOf(view: View): Operation | undefinedviewStyleNameLiteral
function
Style name from the last viewStyle step (literal or any — no eval).
viewStyleNameLiteral(view: View): string | undefined