or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

history-editor.mdhistory.mdindex.mdwith-history.md

history.mddocs/

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

```