# Command history and edits

An undoable [Command](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-engine-commands-classes-a-r#command) packages a diagram edit so the engine can execute it, undo it, and put it on the shared history stack.

The [DiagramInstance](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-renderer-instance-diagraminstance#diagraminstance) exposes the mounted diagram's model and its engine. The [DiagramModel](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-engine-models-diagrammodel#diagrammodel) owns the diagram data; the [DiagramEngine](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-engine-engine#diagramengine) owns behavior, including command history. A user gesture goes through the command manager, while initial setup and loading can write to the model directly:

```mermaid
flowchart LR
  G["User gesture or user-directed edit"] --> C["CommandManager.execute(command)"]
  C --> H["Undo history"]
  H --> U["Undo / redo"]
  S["Setup or load"] --> M["DiagramModel operations"]
  M --> V["Diagram data, not an undo step"]
```

## Choose by intent

Use model operations to build or load the diagram: adding nodes directly to the model does not create a history entry. Use a command when your feature edits on the user's behalf, such as applying a toolbar action or suggestion; executing it records an undoable change.

This helper expects the instance from an already mounted diagram. It adds a starting node as setup, then adds a suggested node through the shipped [`AddNodeCommand`](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-engine-commands-classes-a-r#addnodecommand). After it completes, the mounted diagram contains both boxes; the setup node is not an undo step, while the suggestion is.

```ts
import { AddNodeCommand, NodeModel } from '@grafloria/engine';
import type { DiagramInstance } from '@grafloria/renderer';

export async function prepareAndSuggest(instance: DiagramInstance): Promise<void> {
  const diagram = instance.getModel();
  const start = new NodeModel({
    id: 'start',
    type: 'basic',
    position: { x: 80, y: 80 },
    size: { width: 160, height: 80 },
  });
  diagram.addNode(start);

  const suggestion = new NodeModel({
    id: 'suggestion',
    type: 'basic',
    position: { x: 300, y: 80 },
    size: { width: 160, height: 80 },
  });
  await instance.getEngine().commandManager.execute(new AddNodeCommand(suggestion));
}
```

The command manager's `execute()` returns a promise, so await it before checking the diagram or updating controls. To undo that edit later, call `undo()` on `instance.getEngine()`; `DiagramInstance` itself has no `undo()` method. The starting node remains because `diagram.addNode()` did not enter history. To combine several related edits into one undo step, use the shipped [`BatchCommand`](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/grafloria-engine-commands-classes-a-r#batchcommand).

## Gestures use the same history

Dragging, connecting, deleting, pasting, and grouping are user edits, so their completed actions are represented as commands on the same history stack as a programmatic feature edit. A completed drag is one history step rather than one step per pointer-position update. Undo and redo apply those commands to the model, so the rendered diagram reflects the reverted or replayed state.

Try the [live interaction demo](https://grafloria.com/demos/#interaction): drag an item, then use the platform's undo shortcut to see the gesture revert.

## Related

- [Undo and redo edits](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/undo-and-redo) — wire history controls into your app.
- [The graph model and document](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/graph-model-and-document) — learn what the commands change.
- [The instance and data flow](https://bench-grafloria-6l.atloria.app/p/bench-grafloria-6l-dqcsEdUbfS/developer/instance-and-data-flow) — follow data between the mounted canvas and your application.
