0
# Delta Operations
1
2
Delta-based document representation and operational transform system for tracking and applying changes to rich text content. Delta is Quill's native format for describing document content and changes, providing a JSON-based structure that supports operational transformation for real-time collaboration.
3
4
## Capabilities
5
6
### Delta Constructor
7
8
Creates a new Delta instance for representing document content or changes.
9
10
```typescript { .api }
11
/**
12
* Creates a new Delta instance
13
* @param ops - Array of operations or another Delta to copy
14
*/
15
constructor(ops?: Op[] | Delta);
16
17
interface Op {
18
/** Insert text or embed object */
19
insert?: string | object;
20
/** Delete specified number of characters */
21
delete?: number;
22
/** Retain specified number of characters, optionally with attributes */
23
retain?: number;
24
/** Formatting attributes to apply */
25
attributes?: AttributeMap;
26
}
27
28
interface AttributeMap {
29
[key: string]: unknown;
30
}
31
```
32
33
**Usage Examples:**
34
35
```typescript
36
import { Delta } from 'quill';
37
38
// Create empty Delta
39
const delta = new Delta();
40
41
// Create Delta from operations
42
const delta = new Delta([
43
{ insert: 'Hello ' },
44
{ insert: 'World', attributes: { bold: true } },
45
{ insert: '\n' }
46
]);
47
48
// Copy existing Delta
49
const copy = new Delta(existingDelta);
50
```
51
52
### Insert Operations
53
54
Methods for inserting text or embed content with optional formatting.
55
56
```typescript { .api }
57
/**
58
* Insert text at current position
59
* @param text - Text to insert
60
* @param attributes - Optional formatting attributes
61
* @returns This Delta instance for chaining
62
*/
63
insert(text: string, attributes?: AttributeMap): Delta;
64
65
/**
66
* Insert embed object at current position
67
* @param embed - Embed object (image, video, etc.)
68
* @param attributes - Optional formatting attributes
69
* @returns This Delta instance for chaining
70
*/
71
insert(embed: object, attributes?: AttributeMap): Delta;
72
```
73
74
**Usage Examples:**
75
76
```typescript
77
// Insert plain text
78
const delta = new Delta()
79
.insert('Hello World');
80
81
// Insert formatted text
82
const delta = new Delta()
83
.insert('Bold Text', { bold: true })
84
.insert('Red Text', { color: '#ff0000' });
85
86
// Insert embeds
87
const delta = new Delta()
88
.insert({ image: 'https://example.com/image.jpg' })
89
.insert({ video: 'https://youtube.com/watch?v=abc123' });
90
91
// Chain multiple inserts
92
const delta = new Delta()
93
.insert('Normal text ')
94
.insert('bold text ', { bold: true })
95
.insert('italic text', { italic: true })
96
.insert('\n');
97
```
98
99
### Delete Operations
100
101
Methods for deleting characters from the document.
102
103
```typescript { .api }
104
/**
105
* Delete specified number of characters
106
* @param length - Number of characters to delete
107
* @returns This Delta instance for chaining
108
*/
109
delete(length: number): Delta;
110
```
111
112
**Usage Examples:**
113
114
```typescript
115
// Delete 5 characters
116
const delta = new Delta()
117
.delete(5);
118
119
// Delete and insert (replacement)
120
const delta = new Delta()
121
.retain(10) // Skip first 10 characters
122
.delete(5) // Delete next 5 characters
123
.insert('new text'); // Insert replacement text
124
```
125
126
### Retain Operations
127
128
Methods for retaining (keeping) characters, optionally applying formatting changes.
129
130
```typescript { .api }
131
/**
132
* Retain specified number of characters
133
* @param length - Number of characters to retain
134
* @param attributes - Optional attributes to apply/change
135
* @returns This Delta instance for chaining
136
*/
137
retain(length: number, attributes?: AttributeMap): Delta;
138
```
139
140
**Usage Examples:**
141
142
```typescript
143
// Retain characters without changes
144
const delta = new Delta()
145
.retain(10);
146
147
// Retain and apply formatting
148
const delta = new Delta()
149
.retain(5, { bold: true }); // Make first 5 characters bold
150
151
// Complex formatting change
152
const delta = new Delta()
153
.retain(10) // Skip first 10 characters
154
.retain(5, { italic: true }) // Make next 5 characters italic
155
.retain(3, { bold: null }); // Remove bold from next 3 characters
156
```
157
158
### Delta Composition
159
160
Methods for combining Deltas using operational transform principles.
161
162
```typescript { .api }
163
/**
164
* Compose this Delta with another Delta
165
* @param other - Delta to compose with
166
* @returns New Delta representing the composition
167
*/
168
compose(other: Delta): Delta;
169
170
/**
171
* Transform this Delta against another Delta
172
* @param other - Delta to transform against
173
* @param priority - Whether this Delta has priority in conflicts
174
* @returns New transformed Delta
175
*/
176
transform(other: Delta, priority?: boolean): Delta;
177
178
/**
179
* Transform a cursor position against this Delta
180
* @param index - Cursor position to transform
181
* @param priority - Whether cursor has priority
182
* @returns New cursor position
183
*/
184
transformPosition(index: number, priority?: boolean): number;
185
186
/**
187
* Calculate difference between this Delta and another
188
* @param other - Delta to compare against
189
* @param cursor - Optional cursor position for optimization
190
* @returns Delta representing the difference
191
*/
192
diff(other: Delta, cursor?: number): Delta;
193
```
194
195
**Usage Examples:**
196
197
```typescript
198
// Compose two changes
199
const delta1 = new Delta().insert('Hello');
200
const delta2 = new Delta().retain(5).insert(' World');
201
const composed = delta1.compose(delta2);
202
// Result: Delta with "Hello World"
203
204
// Transform concurrent changes
205
const delta1 = new Delta().insert('A');
206
const delta2 = new Delta().insert('B');
207
const transformed = delta1.transform(delta2, true);
208
// Result: Delta accounting for concurrent insertion
209
210
// Transform cursor position
211
const delta = new Delta().insert('Hello ');
212
const newPosition = delta.transformPosition(0); // Position after "Hello "
213
214
// Calculate difference between documents
215
const oldDoc = new Delta().insert('Hello World');
216
const newDoc = new Delta().insert('Hello Beautiful World');
217
const diff = oldDoc.diff(newDoc);
218
// Result: Delta showing what changed
219
```
220
221
### Delta Utility Methods
222
223
Methods for analyzing and manipulating Delta content.
224
225
```typescript { .api }
226
/**
227
* Get total length of Delta content
228
* @returns Total number of characters
229
*/
230
length(): number;
231
232
/**
233
* Extract slice of Delta
234
* @param start - Starting index (default: 0)
235
* @param end - Ending index (default: end of Delta)
236
* @returns New Delta with sliced content
237
*/
238
slice(start?: number, end?: number): Delta;
239
240
/**
241
* Partition Delta based on predicate
242
* @param predicate - Function to test each operation
243
* @returns Tuple of [matching ops, non-matching ops] as Deltas
244
*/
245
partition(predicate: (op: Op) => boolean): [Delta, Delta];
246
247
/**
248
* Filter operations based on predicate
249
* @param predicate - Function to test each operation
250
* @returns Array of operations that match predicate
251
*/
252
filter(predicate: (op: Op, index: number) => boolean): Op[];
253
254
/**
255
* Execute function for each operation
256
* @param predicate - Function to execute for each operation
257
*/
258
forEach(predicate: (op: Op, index: number) => void): void;
259
260
/**
261
* Map operations to new values
262
* @param predicate - Function to transform each operation
263
* @returns Array of transformed values
264
*/
265
map<T>(predicate: (op: Op, index: number) => T): T[];
266
267
/**
268
* Reduce operations to single value
269
* @param predicate - Function to combine operations
270
* @param initialValue - Initial value for reduction
271
* @returns Final reduced value
272
*/
273
reduce<T>(predicate: (acc: T, curr: Op, index: number) => T, initialValue: T): T;
274
```
275
276
**Usage Examples:**
277
278
```typescript
279
const delta = new Delta()
280
.insert('Hello ')
281
.insert('World', { bold: true })
282
.insert('\n');
283
284
// Get length
285
const length = delta.length(); // 12 characters
286
287
// Slice content
288
const slice = delta.slice(0, 5); // Delta with "Hello"
289
const end = delta.slice(6); // Delta with "World\n" (bold)
290
291
// Partition by attributes
292
const [formatted, plain] = delta.partition(op => op.attributes && Object.keys(op.attributes).length > 0);
293
294
// Filter insert operations
295
const inserts = delta.filter(op => op.insert !== undefined);
296
297
// Process each operation
298
delta.forEach((op, index) => {
299
console.log(`Operation ${index}:`, op);
300
});
301
302
// Extract text content
303
const text = delta
304
.map(op => typeof op.insert === 'string' ? op.insert : '')
305
.join('');
306
307
// Count characters
308
const charCount = delta.reduce((count, op) => {
309
return count + (typeof op.insert === 'string' ? op.insert.length : 1);
310
}, 0);
311
```
312
313
### OpIterator
314
315
Iterator class for processing Delta operations sequentially.
316
317
```typescript { .api }
318
/**
319
* Iterator for processing Delta operations
320
* @param ops - Array of operations to iterate over
321
*/
322
class OpIterator {
323
constructor(ops: Op[]);
324
325
/**
326
* Check if there are more operations
327
* @returns True if more operations available
328
*/
329
hasNext(): boolean;
330
331
/**
332
* Get next operation, optionally consuming specific length
333
* @param length - Length to consume from current operation
334
* @returns Next operation or portion of operation
335
*/
336
next(length?: number): Op;
337
338
/**
339
* Peek at next operation without consuming it
340
* @returns Next operation
341
*/
342
peek(): Op;
343
344
/**
345
* Get length of next operation
346
* @returns Length of next operation
347
*/
348
peekLength(): number;
349
350
/**
351
* Get type of next operation
352
* @returns Type of next operation
353
*/
354
peekType(): 'insert' | 'delete' | 'retain';
355
356
/**
357
* Get remaining operations
358
* @returns Array of remaining operations
359
*/
360
rest(): Op[];
361
}
362
```
363
364
**Usage Examples:**
365
366
```typescript
367
import { OpIterator } from 'quill';
368
369
const delta = new Delta()
370
.insert('Hello')
371
.retain(5)
372
.delete(3);
373
374
const iter = new OpIterator(delta.ops);
375
376
while (iter.hasNext()) {
377
const op = iter.next();
378
console.log('Operation:', op);
379
380
// Process based on type
381
if (op.insert) {
382
console.log('Insert:', op.insert);
383
} else if (op.delete) {
384
console.log('Delete:', op.delete);
385
} else if (op.retain) {
386
console.log('Retain:', op.retain);
387
}
388
}
389
390
// Peek without consuming
391
const iter2 = new OpIterator(delta.ops);
392
console.log('Next type:', iter2.peekType());
393
console.log('Next length:', iter2.peekLength());
394
console.log('Next op:', iter2.peek());
395
396
// Get remaining operations
397
const remaining = iter2.rest();
398
```
399
400
### Delta JSON Serialization
401
402
Delta objects are JSON-serializable for storage and transmission.
403
404
```typescript { .api }
405
// Delta structure for JSON serialization
406
interface DeltaJSON {
407
ops: Op[];
408
}
409
410
interface Op {
411
insert?: string | object;
412
delete?: number;
413
retain?: number;
414
attributes?: AttributeMap;
415
}
416
```
417
418
**Usage Examples:**
419
420
```typescript
421
// Create Delta
422
const delta = new Delta()
423
.insert('Hello ')
424
.insert('World', { bold: true })
425
.insert('\n');
426
427
// Serialize to JSON
428
const json = JSON.stringify(delta);
429
console.log('JSON:', json);
430
// Output: {"ops":[{"insert":"Hello "},{"insert":"World","attributes":{"bold":true}},{"insert":"\n"}]}
431
432
// Deserialize from JSON
433
const parsed = JSON.parse(json);
434
const restored = new Delta(parsed.ops);
435
436
// Delta can be used directly as JSON
437
const delta2 = new Delta(parsed);
438
```
439
440
### Common Delta Patterns
441
442
Frequently used Delta operation patterns for content manipulation.
443
444
**Usage Examples:**
445
446
```typescript
447
// Document creation
448
const document = new Delta()
449
.insert('Heading', { header: 1 })
450
.insert('\n')
451
.insert('This is a paragraph with ')
452
.insert('bold text', { bold: true })
453
.insert(' and ')
454
.insert('italic text', { italic: true })
455
.insert('.\n');
456
457
// Text replacement
458
const replacement = new Delta()
459
.retain(startIndex)
460
.delete(lengthToDelete)
461
.insert(newText, formatting);
462
463
// Format application
464
const formatting = new Delta()
465
.retain(startIndex)
466
.retain(length, { bold: true, color: '#ff0000' });
467
468
// Format removal
469
const formatRemoval = new Delta()
470
.retain(startIndex)
471
.retain(length, { bold: null, italic: null });
472
473
// List creation
474
const list = new Delta()
475
.insert('Item 1', { list: 'bullet' })
476
.insert('\n')
477
.insert('Item 2', { list: 'bullet' })
478
.insert('\n');
479
480
// Link insertion
481
const link = new Delta()
482
.retain(textStart)
483
.retain(textLength, { link: 'https://example.com' });
484
485
// Image insertion
486
const image = new Delta()
487
.retain(insertPosition)
488
.insert({ image: 'https://example.com/image.jpg' });
489
```