# `History.group`

> 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 [`History`](History.md) · stable · since 2.0.0 · called as `session.history.group`

```ts
group(options?: HistoryGroupOptions): HistoryGroup;
```

Opens a group (immediate): every write called until `commit()` that makes an undo step (a
recorded change, or a labelled look write) is part of one undo step, also one that commits
after it (a gesture's last write still loading), unless an undo, a redo, a rebase or a step,
each made by a write called after the group ended (or by the [`undo()`](Session.undo.md) or [`redo()`](Session.redo.md) that ended
it), changed history first; then that write is its own step (spec section 6.1, O14). Groups
do not nest: opening one commits the open one.
It never holds the display and never rolls back. It ends by `commit()`, a call of [`undo()`](Session.undo.md) or
[`redo()`](Session.redo.md) (which then undoes or redoes its whole step), a 'shopper' write's call while an
'assistant' group is open (whatever that write's outcome, an equal tap or a write still
loading included; it is its own step), `timeoutMs` or its signal (spec section 6.1, O9, O14).
Not for: all-or-nothing changes, which are [`transaction()`](Session.transaction.md).

## Options

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

| Option | Type | Default | What it does |
| --- | --- | --- | --- |
| `actor` | `Actor` | 'app' | Writes passing this group as `expectGroup` default to this actor (one that passes `actor` keeps its own; a write that passes neither is 'app', a drag's… |
| `label` | `string` | 'Change' | The undo label of the group's one step. |
| `signal` | `AbortSignal` | undefined | Aborting commits the group. |
| `timeoutMs` | `number` | 60000 | Commits itself after this long. |

## 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-History.group.ts`):

```ts
import type { JsonPatchOp, Session } from '@holostep-configurators/runtime-client/contract';
declare const session: Session;
declare const signal: AbortSignal;
// One assistant turn: one undo step, and it stops as soon as the shopper acts.
type Step =
  | { kind: 'select'; group: string; material: string }
  | { kind: 'patch'; patch: JsonPatchOp[] };
export async function assistantTurn(steps: readonly Step[]): Promise<string> {
  const turn = session.history.group({ label: 'Assistant', actor: 'assistant', signal });
  let rev = session.revision;
  try {
    for (const step of steps) {
      // actor comes from the group
      const guard = { expectGroup: turn, expectRevision: rev, origin: 'assistant' };
      const r = step.kind === 'select'
        ? await session.select(step.group, step.material, guard)
        : await session.applyPatch(step.patch, guard);
      // 'conflict': the shopper acted (the group ended) or the revision moved;
      // 'busy': a write is pending.
      if (r.outcome !== 'committed') return `stopped: ${r.outcome} ${r.reason ?? ''}`;
      rev = r.revision;                                    // the turn's own commit moved it
    }
    return 'done';
  } finally {
    turn.commit();                                         // idempotent
  }
}
```

## Generic-API test (spec 3.1)

| Rule | Result |
| --- | --- |
| 1. Neutral name | pass: `group` names no product |
| 2. A precedent | pass: [Onshape mate connectors](https://cad.onshape.com/help/Content/mate_connector.htm) (row `K63`); [Unity Undo.CollapseUndoOperations](https://docs.unity3d.com/ScriptReference/Undo.CollapseUndoOperations.html) (row `X7`) |
| 3. Two apps, or labs | pass: 8 apps (ledger: app-04c2774145, app-37356bf09f, app-4762caacdc, app-bcb7ef21da, app-c1384707fc, app-f3598fad77, app-f9a32142f1; fleet cross-check: app-04c2774145, app-37356bf09f, app-4762caacdc, app-510d750508, app-bcb7ef21da, app-f3598fad77) |
| 4. The cheaper fix first | decided per need in Appendix B: rows `K63`, `X7` at tier app, stable (a member only where no rule, data, asset or app code serves the need) |
