ExportOptions.prepare ​

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.

Function property of ExportOptions · stable · since 2.0.0

ts
prepare?: (copy: Collection) => void | Promise<void>;

Edit a detached copy first (rest pose, simple glass, export opacities). The copy holds every part query matches, hidden ones included, with its committed look written in as values: the live session's rules are not carried, so a null reset on the copy releases nothing; write the value you want. Copied parts keep node, collection, key, name, tags and meta, so copy.root.find(q) with the query that matched them live finds them. copy.set() reconciles only what set() and load() added to the copy: it adds content and never removes a copied part. Reach the copy's parts through copy.root.find(q) or copy.part(key), never session.find(), which changes the live scene. Every write through the copy's handles belongs to the copy, whatever owner says: it never reaches the live scene, state(), the commit feed or history, and it ends with the export. copy.set(spec) and copy.load(url, placement) add content to the copy (a brand placard, a box standing in for a fabric): applied at the call, under the copy's root (placement.parent is not available on it), found by copy.part(key) and copy.root.find(q), and written to the file. copy.load resolves at the call with the item's part, which has no bounds on the copy: its GLB loads when the file is written, and one that fails is an 'asset-failed' in ExportResult.problems. Whatever you leave in it, the file stays well formed for the AR viewers (Session.export).

Default: undefined (export the committed look)

Abort (signal) ​

This call is neither a write, a registration, a wait nor a creator (SignalOption.signal, the kinds of call).

Cancels this call; the member's JSDoc says what an abort does.

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/16-ExportOptions.prepare.ts):

ts
import type { Query, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const doors: Query;                  // the view shows them open through a pose rule
declare const cutAway: Query;                // and see-through through a material rule
declare function offerDownload(file: Blob, name: string): void;
const { blob } = await session.export({
  format: 'glb',
  // The copy holds the look those rules gave, not the rules: write the canonical values.
  prepare: async (copy) => {
    for (const door of copy.root.find(doors).list()) {
      const { position, quaternion, scale } = door.restPose;
      await door.set({ pose: { position, quaternion, scale } });
    }
    await copy.root.find(cutAway).set({ material: { alpha: 1, alphaMode: 'opaque' } });
    // a placard only the file carries, above the copy's parts
    const top = copy.root.bounds()?.max.y ?? 0;
    await copy.set({ items: [{
      key: 'placard', name: 'placard', kind: 'mesh',
      shape: { kind: 'plane', size: { x: 0.4, y: 0.2 } },
      at: { position: { x: 0, y: top + 0.15, z: 0 }, rotationDeg: { x: 90, y: 0, z: 0 } },
      material: { baseColor: '#ffffff', lighting: 'unlit', side: 'double' },
    }] });
  },
  signal,
});
offerDownload(blob, 'design.glb');

Generic-API test (spec 3.1) ​

Rule Result
1. Neutral name pass: prepare names no product
2. A precedent pass: Babylon.js GLTF2Export (row K39); USDZ file format (row K39)
3. Two apps, or labs pass: 11 apps (ledger: app-4f16d2f6da, app-510d750508, app-bcb7ef21da, app-ceb4eccc72, app-f07e9033d9, app-fb16dd1985, app-fc07850558, app-fc306ec3dc and 1 more; fleet cross-check: app-4f16d2f6da, app-510d750508, app-59c5b5751e, app-ceb4eccc72, app-e61a0b42ad, app-f07e9033d9, app-fb16dd1985, app-fc07850558)
4. The cheaper fix first decided per need in Appendix B: rows K39 at tier stable (a member only where no rule, data, asset or app code serves the need)