Skip to main content

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

ts
import { createBoardEngine } from '@lupinum/board-core'
import { historyPlugin } from '@lupinum/board-history'

const engine = createBoardEngine({
  plugins: [historyPlugin({ maxSteps: 100 })],
})

Plugin options

OptionTypeDefaultPurpose
maxStepsnumber200Maximum undo steps to keep. Older entries are dropped.

Undo and redo

ts
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()

History entries are available synchronously after a successful outer command. Read methods such as canUndo(), canRedo(), and getState() never mutate history state.

Keyboard shortcuts: + Z to undo, + Shift + Z or + Y to redo.

When both 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

ts
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'))