Contract 2.0.0 · package sha256
a857eca95b35921109faf997094bb4192f12527d9d0fcd4be7e97f06425bad6e· generated fromexamples/section-5/5.11-capture-and-export.tsbyservices/onsite-scripter/scripts/build-contract-docs.mjs; edit the source, not this file.
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.
import { HoloBusyError } from '@holostep-configurators/runtime-client';
import type { CameraView, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const showroomView: CameraView;
declare function uploadThumbnail(image: Blob, meta: { sceneHash: string; complete: boolean }): Promise<void>;
const spec = { view: showroomView, size: { width: 800, height: 800 }, pixelRatio: 1, background: 'transparent' } as const;
async function thumbnail(signal: AbortSignal) {
try { return await session.capture(spec, { signal }); }
catch (e) {
if (!(e instanceof HoloBusyError)) throw e; // a transaction holds the display
await session.idle({ signal }); // bounded by the signal
return session.capture(spec, { signal });
}
}
// A pick made just before 'Kosárba' may still be loading: wait for it, at most 5 s.
async function settle(ms: number): Promise<boolean> {
try { await session.idle({ signal: AbortSignal.timeout(ms) }); return true; }
catch (e) { if (e instanceof DOMException && e.name === 'AbortError') return false; throw e; }
}
// A product GLB that failed stays in the model, unloaded and without parts, and capture() still
// reports completed (6.4): send no picture then, so the shop shows its own fallback.
function productDrawn(): boolean {
const model = session.getSceneModel();
if (!model || session.find({ role: 'product' }).bounds() === null) return false;
const inModel = new Set<string>();
const walk = (nodes: NonNullable<typeof model>['root']): void => {
for (const n of nodes) if (n.enabled) { inModel.add(n.nodeId); walk(n.children ?? []); }
};
walk(model.root);
return !session.info().problems.some((p) => p.code === 'asset-failed' && p.asset === 'model'
&& p.node !== undefined && inModel.has(p.node) && !session.node(p.node).exists);
}
const fresh = await settle(5000);
if (productDrawn()) {
const shot = await thumbnail(signal);
await uploadThumbnail(shot.image, { sceneHash: shot.snapshot.sceneHash, complete: shot.completed && fresh });
}
Back to the examples · llms.txt