or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

delta-operations.mdeditor-core.mdformatting-system.mdindex.mdmodule-system.mdregistry-system.mdtheme-system.md

delta-operations.mddocs/

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

```