# History
URL: https://pro.rv-grid.com/api/history/
Source: src/content/docs/api/history.md
## Module Extensions

### `HTMLRevoGridElement` (Extended from `global`)

```ts
interface HTMLRevoGridElement {
  history?: HistoryConfig
}
```

---

### `HTMLRevoGridElementEventMap` (Extended from `global`)

```ts
interface HTMLRevoGridElementEventMap {
  /**
         * Event for undo
         *
         * @example
         * ```typescript
         * grid.addEventListener(BEFORE_UNDO_EVENT, (e) => {
         *   console.log(e);
         * });
         */
        [BEFORE_UNDO_EVENT]: {
          data: BeforeRangeSaveDataDetails['data'];
          type: DimensionRows;
          lastChange: EventManagerEvent;
        };
  /**
         * Event for redo
         *
         * @example
         * ```typescript
         * grid.addEventListener(BEFORE_REDO_EVENT, (e) => {
         *   console.log(e);
         * });
         */
        [BEFORE_REDO_EVENT]: {
          data: BeforeRangeSaveDataDetails['data'];
          type: DimensionRows;
          lastChange: EventManagerEvent;
        };
  /**
         *
         */
        [BEFORE_HIST_EDIT_EVENT]: {
          data: BeforeRangeSaveDataDetails['data'];
          type: DimensionRows;
          models: {[rowIndex: number]: DataType};
          previousData?: BeforeRangeSaveDataDetails['data'];
        };
  [HISTORY_CHANGED_EVENT]: HistoryState;
  [HISTORY_ERROR_EVENT]: HistoryError
}
```

---

### `AdditionalData` (Extended from `@revolist/revogrid`)

```ts
interface AdditionalData {
  /**
         * @deprecated Use the direct `grid.history` property instead.
         */
        history?: HistoryConfig
}
```

## Plugin API

### `createLocalStorageHistoryAdapter`

```ts
export function createLocalStorageHistoryAdapter(storageKey = DEFAULT_STORAGE_KEY): HistoryStorageAdapter;
```

---

### `HistoryPlugin`

The `HistoryPlugin` for RevoGrid provides undo and redo functionalities, allowing users to
navigate through their editing history within the grid. This plugin is essential for enhancing
user experience by offering flexibility to revert or reapply changes made during data manipulation.

**Key Features**:
- **Undo/Redo Stacks**: Maintains separate stacks for undo and redo operations, with a configurable
  (currently fixed at 200) maximum stack size to manage memory usage efficiently.
- **Event Handling**: Listens to `ON_EDIT_EVENT` to track changes and updates the undo stack
  accordingly. It also captures `Ctrl+Z` and `Ctrl+Y` (or `Cmd` on macOS) keystrokes via the
  `BEFORE_KEYDOWN_EVENT` to trigger undo and redo actions.
- **Event Emission**: Utilizes `BEFORE_UNDO_EVENT` and `BEFORE_REDO_EVENT` to allow pre-processing
  or cancellation of undo/redo actions. Replays accepted changes through `BEFORE_HIST_EDIT_EVENT`
  so EventManager integrations can apply them and downstream plugins can react consistently.
- **Disabling and Clearing**: Provides methods to disable the plugin (preventing changes from being
  added to stacks) and to clear both stacks, resetting the history.

**Usage**:
- Integrate the `HistoryPlugin` within the RevoGrid to enable robust undo/redo capabilities.
  This involves adding the plugin to the grid's plugin list, allowing automatic management of
  editing actions.

### Example
```typescript
import { HistoryPlugin } from '@revolist/revogrid-pro';

const grid = document.createElement('revo-grid');
grid.plugins = [HistoryPlugin];
```

This plugin is ideal for applications requiring reliable data editing workflows, providing users
with the ability to correct mistakes or revisit previous states seamlessly.

#### Dependencies

- **Event integration** `EventManagerPlugin`: Integrates with EventManagerPlugin edit events for normal edit history capture.

```ts
class HistoryPlugin {
  canUndo();

  canRedo();

  getUndoStackSize();

  getRedoStackSize();

  isDisabled();

  clear();

  disable(disable = true);

  undo();

  redo();

  replayChange(detail: HistoryReplayDetail): boolean;
}
```

---

### `HistoryReplayDetail`

```ts
export type HistoryReplayDetail = Pick<EventManagerEvent, 'data' | 'type' | 'models' | 'previousData'>;
```

---

### `HistoryStorageState`

```ts
export type HistoryStorageState = {
  undoStack?: EventManagerEvent[];
  redoStack?: EventManagerEvent[];
  updatedAt?: string;
  sourceId?: string;
  disabled?: boolean;
};
```

---

### `HistoryStorageAdapter`

```ts
export type HistoryStorageAdapter = {
  load?: () => HistoryStorageState | undefined | null | Promise<HistoryStorageState | undefined | null>;
  save?: (state: HistoryStorageState) => void | Promise<void>;
  clear?: () => void | Promise<void>;
};
```

---

### `HistoryError`

```ts
export type HistoryError = {
  phase: 'storage-load' | 'storage-save' | 'storage-clear' | 'storage-source-mismatch';
  error: unknown;
  state?: HistoryStorageState;
  providerIndex?: number;
};
```

---

### `HistoryConfig`

```ts
export type HistoryConfig = {
  /**
   * Initial undo stack used by the plugin.
   *
   * Use this when restoring history from an application-owned state object.
   * New edits are appended to this stack and trimmed to `maxStackSize`.
   *
   * @default []
   */
  undoStack?: EventManagerEvent[];
  /**
   * Initial redo stack used by the plugin.
   *
   * This stack is cleared when a new user edit is captured.
   *
   * @default []
   */
  redoStack?: EventManagerEvent[];
  /**
   * Maximum number of entries kept in each history stack.
   *
   * When a stack grows beyond this limit, the oldest entry is removed.
   *
   * @default 200
   */
  maxStackSize?: number;
  /**
   * Starts the plugin in a disabled state.
   *
   * Disabled history does not capture edits and does not run undo or redo.
   * The runtime state can also be changed with `HistoryPlugin.disable()`.
   *
   * @default false
   */
  disabled?: boolean;
  /**
   * Stable identifier for the dataset whose history is being stored.
   *
   * When loaded storage state contains a different `sourceId`, the plugin skips
   * that state and emits `historyerror` with the `storage-source-mismatch` phase.
   */
  sourceId?: string;
  /**
   * Built-in storage mode for undo and redo stacks.
   *
   * Use `memory` for in-memory history only, `localStorage` for the built-in
   * browser adapter, or `custom` with `storageAdapter`.
   *
   * @default 'memory'
   */
  storage?: 'memory' | 'localStorage' | 'custom';
  /**
   * Key used by the built-in localStorage adapter.
   *
   * Only applies when `storage` is `localStorage`.
   *
   * @default 'revogrid-history'
   */
  storageKey?: string;
  /**
   * Custom storage adapter for loading, saving, and clearing history state.
   *
   * Used when `storage` is `custom`, and also accepted with `memory` as an
   * explicit adapter source.
   */
  storageAdapter?: HistoryStorageAdapter;
  /**
   * Ordered storage adapters for cache/server provider chains.
   *
   * When provided, this takes precedence over `storage` and `storageAdapter`.
   * Providers are loaded in order, and newer compatible states can replace
   * earlier loaded states.
   */
  storageProviders?: HistoryStorageAdapter[];
  /**
   * Clears undo and redo stacks when the grid source is replaced.
   *
   * Defaults to `false` when persistent storage is configured so restored
   * history is not erased by the initial source load. Otherwise defaults to
   * `true`.
   */
  clearOnSourceChange?: boolean;
  /**
   * Clears undo and redo stacks after filter topology changes.
   *
   * Initial filter events before the first grid render do not clear restored
   * history.
   *
   * @default true
   */
  clearOnFilterChange?: boolean;
  /**
   * Clears undo and redo stacks after sorting topology changes.
   *
   * Initial sorting events before the first grid render do not clear restored
   * history.
   *
   * @default true
   */
  clearOnSortingChange?: boolean;
  /**
   * Clears undo and redo stacks after row order topology changes.
   *
   * Initial row order events before the first grid render do not clear restored
   * history.
   *
   * @default true
   */
  clearOnRowOrderChange?: boolean;
  /**
   * Allows undo/redo keyboard shortcuts to run from document keydown events even
   * when the grid does not currently report a focused cell.
   *
   * @default true
   */
  keyboardShortcutsWithoutFocus?: boolean;
};
```

---

### `HistoryState`

```ts
export type HistoryState = {
  undoStackSize: number;
  redoStackSize: number;
  canUndo: boolean;
  canRedo: boolean;
  disabled: boolean;
};
```

---

### `cloneValue`

```ts
export function cloneValue<T>(value: T): T;
```

---

### `cloneStack`

```ts
export function cloneStack(stack: EventManagerEvent[] | undefined): EventManagerEvent[];
```

---

### `cloneStorageState`

```ts
export function cloneStorageState(state: HistoryStorageState): HistoryStorageState;
```

---

### `isPromiseLike`

```ts
export function isPromiseLike(value: unknown): value is Promise<unknown>;
```

---

### `toTime`

```ts
export function toTime(value: string | undefined, fallback: number);
```

---

### `isHistoryStorageState`

```ts
export function isHistoryStorageState(value: unknown): value is HistoryStorageState;
```

---

### `hasHistoryStorage`

```ts
export function hasHistoryStorage(history: HistoryConfig | undefined);
```

---

### `HISTORY_STORAGE_KEY`

```ts
HISTORY_STORAGE_KEY: string;
```
