0
# History Structure
1
2
The `History` object is the core data structure that manages undo and redo operation stacks. It contains batched operations and provides utilities for validating history objects.
3
4
## Capabilities
5
6
### History Interface
7
8
The main data structure for storing operation history in undo and redo stacks.
9
10
```typescript { .api }
11
interface History {
12
/** Array of operation batches for redo functionality */
13
redos: Batch[];
14
/** Array of operation batches for undo functionality */
15
undos: Batch[];
16
}
17
```
18
19
### Batch Structure
20
21
Internal structure representing a group of related operations that should be undone/redone together.
22
23
```typescript { .api }
24
interface Batch {
25
/** Array of Slate operations in this batch */
26
operations: Operation[];
27
/** Selection state before these operations were applied */
28
selectionBefore: Range | null;
29
}
30
```
31
32
**Batch Characteristics:**
33
- Operations are stored in the order they were applied
34
- Selection state is captured before the first operation in the batch
35
- Batches represent logical units for undo/redo (e.g., a word typed, a paste operation)
36
37
### Type Guards
38
39
Utility for validating History objects.
40
41
```typescript { .api }
42
/**
43
* Check if a value is a valid History object
44
* @param value - Value to check
45
* @returns True if value is a properly structured History object
46
*/
47
function isHistory(value: any): value is History;
48
```
49
50
**Usage Examples:**
51
52
```typescript
53
import { History } from "slate-history";
54
55
// Check if an object is a valid history
56
const historyData = { redos: [], undos: [] };
57
if (History.isHistory(historyData)) {
58
console.log("Valid history object");
59
}
60
61
// Access history from a history-enabled editor
62
if (HistoryEditor.isHistoryEditor(editor)) {
63
const history = editor.history;
64
65
// Check undo availability
66
const canUndo = history.undos.length > 0;
67
console.log(`Can undo: ${canUndo}`);
68
69
// Check redo availability
70
const canRedo = history.redos.length > 0;
71
console.log(`Can redo: ${canRedo}`);
72
73
// Get operation counts
74
console.log(`Undo batches: ${history.undos.length}`);
75
console.log(`Redo batches: ${history.redos.length}`);
76
}
77
```
78
79
## History Structure Details
80
81
### Operation Stacks
82
83
**Undos Stack:**
84
- Contains batches of operations that can be undone
85
- New operations are added to the end of the array
86
- Undo operations remove batches from the end (LIFO - Last In, First Out)
87
- Limited to 100 batches to prevent memory issues
88
89
**Redos Stack:**
90
- Contains batches of operations that can be redone
91
- Populated when undo operations are performed
92
- Cleared when new operations are applied to the editor
93
- Also follows LIFO ordering
94
95
### Stack Behavior
96
97
```typescript
98
// When operations are applied:
99
// 1. New batch is added to undos stack
100
// 2. Redos stack is cleared
101
102
// When undo is called:
103
// 1. Last batch is removed from undos stack
104
// 2. Inverse operations are applied
105
// 3. Original batch is added to redos stack
106
107
// When redo is called:
108
// 1. Last batch is removed from redos stack
109
// 2. Original operations are reapplied
110
// 3. Batch is added back to undos stack
111
```
112
113
### Batch Management
114
115
**Batch Creation:**
116
- New batches are created for each logical operation group
117
- Selection state is captured before applying operations
118
- Related operations (like consecutive text insertions) are merged into single batches
119
120
**Batch Limits:**
121
- Undo stack is limited to 100 batches maximum
122
- Oldest batches are removed when limit is exceeded
123
- This prevents unbounded memory growth in long editing sessions
124
125
### Validation Logic
126
127
The `History.isHistory` function performs comprehensive validation:
128
129
1. **Object Structure**: Checks that the value is an object with `redos` and `undos` properties
130
2. **Array Types**: Verifies both properties are arrays
131
3. **Batch Validation**: For non-empty stacks, validates that batches contain valid operation arrays
132
4. **Operation Validation**: Uses Slate's `Operation.isOperationList` to validate operation structure
133
134
**Example Validation:**
135
136
```typescript
137
import { History } from "slate-history";
138
139
// Valid history objects
140
History.isHistory({ redos: [], undos: [] }); // true
141
History.isHistory({
142
redos: [{ operations: [], selectionBefore: null }],
143
undos: []
144
}); // true
145
146
// Invalid history objects
147
History.isHistory(null); // false
148
History.isHistory({ redos: "not array" }); // false
149
History.isHistory({ redos: [], undos: [{ invalid: "batch" }] }); // false
150
```
151
152
## Integration with Editor
153
154
The History object is automatically managed by the `withHistory` plugin:
155
156
```typescript
157
import { withHistory, HistoryEditor } from "slate-history";
158
import { createEditor } from "slate";
159
160
const editor = withHistory(createEditor());
161
162
// History is automatically initialized
163
console.log(editor.history); // { redos: [], undos: [] }
164
165
// History is updated as operations are applied
166
editor.insertText("Hello");
167
console.log(editor.history.undos.length); // 1
168
169
// History stacks change with undo/redo
170
editor.undo();
171
console.log(editor.history.undos.length); // 0
172
console.log(editor.history.redos.length); // 1
173
```