History
Record state changes and navigate them with the history plugin.
The history plugin stores references to committed structural roots. Undo and redo restore those roots atomically, without inverse actions, replay ordering, or timers. A completed gesture or explicit batch is one deterministic undo step.
Setup
import { createBoardEngine } from '@lupinum/board-core'
import { historyPlugin } from '@lupinum/board-history'
const engine = createBoardEngine({
plugins: [historyPlugin({ maxSteps: 100 })],
})Render the shortcut component inside the matching board root:
<script setup lang="ts">
import { createBoardEngine } from '@lupinum/board-core'
import { historyPlugin } from '@lupinum/board-history'
import { BoardHistoryShortcuts } from '@lupinum/board-history/vue'
const engine = createBoardEngine({ plugins: [historyPlugin()] })
</script>
<template>
<BoardRoot :engine="engine">
<BoardHistoryShortcuts :history="engine.plugins.history" />
</BoardRoot>
</template>Plugin options
| Option | Type | Default | Purpose |
|---|---|---|---|
maxSteps | number | 200 | Maximum undo steps to keep. Older entries are dropped. |
Undo and redo
engine.plugins.history.undo()
engine.plugins.history.redo()
if (engine.plugins.history.canUndo()) {
/* ... */
}
const state = engine.plugins.history.getState()
// { undoDepth, redoDepth }
engine.plugins.history.clear()Call undo() and redo() outside engine.batch(). Replay with a retained frame inside a batch throws BoardConflictError before changing the document or history. If that error leaves the batch, preceding edits roll back. Group new edits in a batch, then undo or redo the completed batch as one operation.
A rejected undo or redo retains its frame. Replay completes its history bookkeeping before notifying listeners, so an edit from a listener starts a new branch and clears redo.
History entries are available synchronously after a successful outer command. Read methods such as canUndo(), canRedo(), and getState() never mutate history state.
BoardHistoryShortcuts handles ⌘ + Z to undo and ⌘ + Shift + Z or ⌘ + Y to redo. Pass the matching board's history API through its required history prop. It handles only events from its enclosing board.
historyPlugin and connectionsPlugin are installed, undoing a node deletion also restores its connected edges.Implementation detail
Ignored commands
History capture follows command metadata emitted by the engine and first-party features. Camera movement, transient interaction setup/teardown, imports, and selection-only commands are ignored; geometry and content mutations are recorded.
Implementation detail
Events
engine.on('history:push', (entry) => console.log('New step:', entry.label))
engine.on('history:undo', () => console.log('Undo'))
engine.on('history:redo', () => console.log('Redo'))
engine.on('history:clear', () => console.log('History cleared'))