Writer.apply ​

Contract 2.0.0 · package sha256 a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e · generated from configurator-runtime.d.ts by services/onsite-scripter/scripts/build-contract-docs.mjs; edit the source, not this file.

Method of Writer · inherited by Tx, Session, testing.FakeSession · stable · since 2.0.0 · called as session.apply

ts
apply(scene: SceneSpec, options?: C & SignalOption): Promise<Report>;

Replaces the look's apply() block atomically (spec section 6.10, R2). Each key of scene that is present replaces that part: the named materials, apply()'s ordered rules, and the listed collections. An omitted key leaves that part unchanged; rules: [] clears only apply()'s rules. Rules made through find().set form a later block it never removes. Outcome: one commit; look-only, so no undo step unless labelled. Timing: resolves at the commit point, after its loads and readiness (≤ readyTimeoutMs); in the write queue. New content loads hidden while the old scene keeps drawing; everything swaps in one frame. Merging and in the write queue: never superseded, so pending calls commit in call order. Not for: a priced material choice (select) or a saved position (setSceneModel, applyPatch); nor for standing rules that later apply() calls must leave alone, which are find(q).set. Errors: rejects HoloInputError on an invalid spec (validate('scene', spec) checks its shape and its collections' keys and parents; { dryRun: true } checks all this call checks and changes nothing), and 'duplicate-rule-id' when two of rules share an id (spec section 6.10, R3). Asset failures are problems ('asset-failed'); a rule that matches nothing records 'target-unmatched'.

Options ​

Through Session:

Option Type Default What it does
actor Actor the expectGroup's actor when one is given, else 'app' Who made the write.
dryRun boolean false Runs and reports, then rolls back by design ('dry-run').
expectGroup HistoryGroup undefined A guard, checked at the call: this write belongs to the undo group you are running.
expectRevision number undefined (no check) If-match on session.revision.
origin string null Your tag, echoed unchanged in Report.origin and cause.origin.
signal AbortSignal undefined Cancels this call; the member's JSDoc says what an abort does.
supersede boolean false (the write is queued behind the transaction and applies after it closes) While a transaction is open: roll it back (it resolves 'superseded'); the writes queued behind it apply in call order, then this one, which supersedes an…
undo 'rebase' | (string & {}) a recorded-state change gets one step labelled 'Change'; a look-only write gets none; the session's first model (cause 'load') gets none, whatever the label: it is the floor of history An undo label makes this write one undo step.

Through Tx:

Option Type Default What it does
signal AbortSignal undefined Cancels this call; the member's JSDoc says what an abort does.

Refused here (typed never, so passing one fails to compile): actor, checkpoint, dryRun, expectGroup, expectRevision, origin, supersede, undo.

Abort (signal) ​

This call is a write (SignalOption.signal, the kinds of call).

A write: before the commit point it rolls back and rejects AbortError; after it, no effect, except that a running camera move stops where the last frame drew it (CameraMoveOptions).

Through a tx the commit point is the transaction's: aborting a write still loading rejects AbortError and stages nothing (catch it: unobserved, it rolls the transaction back, spec section 6.1, O6); aborting one already staged unstages it, its paths keeping the latest other write to them as after a failed savepoint (O7), and its Promise stays resolved 'staged'.

Example ​

Imports: values (has, validate, the Holo*Error classes, the pure helpers) from @holostep-configurators/runtime-client, types from @holostep-configurators/runtime-client/contract, /math and /testing names from those entries; boot from the runtime module the root's loadRuntimeAtFloor resolves to. A type your page defines is your app's: declare it there, never import it from the package.

Compiled under the contract's strict settings (examples/declaration/05-Writer.apply.ts):

ts
import type { MaterialSpec, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const finishes: Readonly<Record<string, MaterialSpec>>;      // 'oak', 'walnut', …
// The find() block: set once. apply() never removes or reorders it.
await session.find([{ name: 'mp-l*' }, { name: 'mp-r*' }]).set({ visible: false });
// The apply() block: the whole look, built from app state and replaced on every call.
export const applyLook = (finish: string) => session.apply({
  materials: finishes,
  rules: [
    // in array order
    { query: { tag: 'carcass' }, set: { material: { ref: finish } } },
    {
      query: { node: 'cab:42', tag: 'front' },
      set: { material: { baseColor: '#2b2b2b', maps: { baseColor: 'none' } } },
    },
  ],
});
await applyLook('oak');
// omitted keys are unchanged: both blocks of rules stay
await session.apply({ materials: finishes });

Generic-API test (spec 3.1) ​

Rule Result
1. Neutral name pass: apply names no product
2. A precedent pass: CSS cascade (ordered, persistent rules) (row G32)
3. Two apps, or labs pass: 6 apps (ledger: app-fc306ec3dc; fleet cross-check: app-378d190f1b, app-4f16d2f6da, app-510d750508, app-ceb4eccc72, app-fb16dd1985)
4. The cheaper fix first decided per need in Appendix B: rows G32 at tier stable (a member only where no rule, data, asset or app code serves the need)