# undo-history

> Undo and redo as a value: a pure history of any document, with bursts (a drag is one entry), redo that drops on a new change, and a depth limit

```bash
npx shadcn@latest add @audio-ui/undo-history
```

```ts
import { HISTORY_LIMIT, emptyHistory, canUndo, canRedo, beginChange, /* … */ } from "@/lib/undo-history";
```

- Files: `lib/undo-history.ts`
- Depends on: nothing; npm: nothing
- Used by: `history`, `use-arrangement`, `use-undo-history`

| Export | Kind | What it is |
| --- | --- | --- |
| `History` | interface | Undo and redo as a value: every function takes the present and hands back the present, and holds no state of its own. |
| `HistoryStep` | interface |  |
| `HISTORY_LIMIT` | const | How many entries a history keeps: deep, not infinite. |
| `emptyHistory` | function |  |
| `canUndo` | function |  |
| `canRedo` | function |  |
| `beginChange` | function | Opens a burst, or joins the one already open. |
| `settleChange` | function | Closes a burst: everything it did becomes one entry on `past`. |
| `recordChange` | function | A change made in one go: a burst opened and closed. |
| `undo` | function | Takes back the latest change, or returns null when there is none. |
| `redo` | function | Puts back what undo took, or returns null when there is nothing to put back. |

## Usage

Undo and redo of any value, as a value: the steps behind it and after it, a gesture recorded as one step, and the last 100 kept.

```ts
import { canUndo, emptyHistory, recordChange, redo, undo } from "@/lib/undo-history";

let history = emptyHistory<Note[]>();
history = recordChange(history, notesBefore); // before an edit
const step = undo(history, notesNow); // { history, present } to go back to, null with nothing to undo
```

`beginChange` and `settleChange` make a drag one step. In React, [`useUndoHistory`](/docs/hooks/use-undo-history) holds it for you; the arrangement's undo is built on it.
