ilokesto

history

history records successful synchronous state changes and adds undo/redo controls to the prepared store.

Signature

history(options?: HistoryOptions): PipeAnyMiddleware

type HistoryOptions = {
  readonly limit?: number;
};

limit is the maximum number of undo entries and defaults to 300. It must be a finite non-negative integer. Use HistoryStore<State> when an API accepts a store with the controls, and HistoryControls when it accepts only the controls.

Example

import { history } from '@ilokesto/state/middleware';
import type { HistoryStore } from '@ilokesto/state/middleware';
import { pipe } from '@ilokesto/state/utils';

const store: HistoryStore<{ count: number }> = pipe
  .use(history({ limit: 20 }))
  .create({ count: 0 });

store.setState({ count: 1 });
store.undo();
store.redo();
store.clearHistory();

undo() and redo() apply the recorded state through the store, so compatible middleware can observe the replay. Replayed states are not recorded again. canUndo() and canRedo() report whether a replay is available; clearHistory() removes entries without changing current state.

Composition constraints

History needs a synchronous commit boundary. It cannot share a pipe chain with debounce() or throttle() in either declaration order. Those combinations throw PipeConfigurationError with code MIDDLEWARE_CONFLICT; pipe does not reorder middleware to make the chain valid.

History middleware itself does not own timers or subscriptions. If the same store also uses middleware that registers cleanup, call dispose(store) when that store is no longer needed. See Middleware for ownership and idempotency details.

Control collisions

History adds undo, redo, canUndo, canRedo, and clearHistory as immutable store properties. If the store already has one of those properties, setup throws HistoryConfigurationError with code CONTROL_COLLISION before installing controls.

On this page