# `Session.export`

> 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 [`Session`](Session.md) · inherited by [`testing.FakeSession`](testing.FakeSession.md) · stable · since 2.0.0 · called as `session.export`

```ts
export(options: ExportOptions, extra?: SignalOption): Promise<ExportResult>;
```

Exports the matched parts (role 'product' by default) as a GLB or USDZ file. Resolves with the
file and a list of what the format couldn't carry. Like [`capture`](Session.capture.md), it first waits for an
autocommit write's running [`beforeCommit`](Session.beforeCommit.md) functions to finish, then for readiness
and the committed state's pending late swaps, together ≤ readyTimeoutMs; a detail map still
pending then is written as its stand-in and listed in [`dropped`](ExportResult.dropped.md). It never joins or waits for a
transaction and, unlike [`capture`](Session.capture.md), never rejects for a hold: the file is the newest committed
state, without a transaction's staged writes (spec section 6.8).
The file is well formed for both AR viewers, whatever `prepare` leaves in the copy (spec
section 5.11): every part has a mesh and a material, every primitive is indexed, a mirrored
world transform is flipped into the geometry, an `instances` item is one node per instance
(no `EXT_mesh_gpu_instancing`) sharing one mesh per reflection parity (its mirrored instances
share one flipped copy, triangle order reversed) and [`Shape.transform`](Shape.md) is baked into the
vertices. A skinned part keeps its skin in a GLB, at its exported pose; in a USDZ it is plain
geometry baked to that pose, its joints dropped ([`dropped`](ExportResult.dropped.md) reason 'lowered'). No animation
clip is written, so no AR viewer plays one: the file is a still of the copy's pose.
A placed ModelNode or `kind: 'model'` item whose asset is unloaded has no parts, so it is not
in the file; [`problems`](ExportResult.problems.md) names it ('asset-failed', [`ExportResult.problems`](ExportResult.problems.md)).
Errors: rejects DOMException 'NotAllowedError' when [`permits('export')`](Session.permits.md) is false (problem
'not-permitted'). Unlike a capture, an export not yet resolved at [`destroy()`](Session.destroy.md) rejects
AbortError: its file is written after the call, from scene data [`destroy()`](Session.destroy.md) frees. Aborting
`signal` rejects AbortError at once, also while `prepare` runs or the file is written.
`extra` (since 2.0.0, additive): `{ signal }` as [`capture`](Session.capture.md), [`idle`](Session.idle.md) and [`applyDocument`](Session.applyDocument.md) take it,
honoured as `options.signal`; a signal in both places rejects 'invalid-input' (pass it once),
and another key 'unknown-field'.

## Abort (`signal`)

This call is neither a write, a registration, a wait nor a creator (`SignalOption.signal`, [the kinds of call](../read-this-first.md#conventions)).

> 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/05-Session.export.ts`):

```ts
import type { Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare function offerDownload(file: Blob, name: string): void;
if (session.permits('export')) {
  const { blob, dropped } = await session.export({ format: 'glb', maxTextureSize: 1024, signal });
  for (const d of dropped) console.warn('not in the file:', d.name, d.reason);
  offerDownload(blob, 'design.glb');
}
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `export` names no product |
| 2. A precedent | pass: [Babylon.js GLTF2Export](https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/serializers/src/glTF/2.0/glTFSerializer.ts) (row `K39`); [USDZ file format](https://openusd.org/release/spec_usdz.html) (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) |
