# `Labs.geometry.read`

> 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 [`Labs.geometry`](Labs.geometry.md) · labs · since 2.0.0 · called as `session.labs.geometry.read`

```ts
read(query: Query, attributes: readonly GeometryAttribute[], options?: {
  from?: 'authored' | 'current';
  signal?: AbortSignal;
}): Promise<GeometryData<C>[]>;
```

Engine query (not an asset load, so it is allowed inside [`beforeCommit`](Session.beforeCommit.md); cache its result by
[`describe(node).asset.version`](AssetInfo.version.md), or by `asset.url` when the version is null (unstamped)).
Inside a [`beforeCommit`](Session.beforeCommit.md) hook it reads the parts the commit being prepared shows (spec section
6.1, O11). `from: 'authored'` reads the geometry as loaded, before your writes.
Async: resolves with one entry per matched mesh part. Through a `tx` it is enlisted.
Errors: rejects DOMException 'NotAllowedError' when [`permits('labs.geometry.read')`](Session.permits.md) is false.

**Default:** options.from 'current'; options.signal undefined

## Options

Through [`Session`](Session.md):

| Option | Type | Default | What it does |
| --- | --- | --- | --- |
| `from` | `'authored' \| 'current'` | — |  |
| `signal` | `AbortSignal` | — |  |

Through [`Tx`](Tx.md):

| Option | Type | Default | What it does |
| --- | --- | --- | --- |
| `from` | `'authored' \| 'current'` | — |  |
| `signal` | `AbortSignal` | — |  |

## 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/20-Labs.geometry.read.ts`):

```ts
import type { Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
declare const moduleId: string;                            // the placed module's nodeId
if (session.permits('labs.geometry.read')) {
  const [door] = await session.labs.geometry.read({ node: moduleId, name: 'door' }, ['position', 'index'], { from: 'authored' });
  const vertices = door?.position ? door.position.length / 3 : 0;   // x, y, z per vertex
  console.log(`door: ${vertices} vertices, ${(door?.index?.length ?? 0) / 3} triangles`);
}
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `read` names no product |
| 2. A precedent | pass (through its owner [`Labs.geometry`](Labs.geometry.md)): [Unity Mesh.vertices](https://docs.unity3d.com/ScriptReference/Mesh-vertices.html) (row `G9`); [Unity Mesh.GetIndices](https://docs.unity3d.com/ScriptReference/Mesh.GetIndices.html) (row `G9`); [Unity Mesh.SetVertices](https://docs.unity3d.com/ScriptReference/Mesh.SetVertices.html) (row `K54`) |
| 3. Two apps, or labs | labs: it graduates when a second app uses it; apps today: app-b362a81c85, app-bcb7ef21da, app-f9a32142f1 |
| 4. The cheaper fix first | decided per need in Appendix B: rows `G9`, `K54` (through its owner [`Labs.geometry`](Labs.geometry.md)) at tier asset, labs (a member only where no rule, data, asset or app code serves the need) |
