loro-crdt 1.4.6 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +1,28 @@
1
1
  /* tslint:disable */
2
2
  /* eslint-disable */
3
3
  /**
4
- * Get the version of Loro
5
- * @returns {string}
6
- */
4
+ * Get the version of Loro
5
+ */
7
6
  export function LORO_VERSION(): string;
8
- /**
9
- */
10
7
  export function run(): void;
11
- /**
12
- * @param {({ peer: PeerID, counter: number })[]} frontiers
13
- * @returns {Uint8Array}
14
- */
15
8
  export function encodeFrontiers(frontiers: ({ peer: PeerID, counter: number })[]): Uint8Array;
16
- /**
17
- * @param {Uint8Array} bytes
18
- * @returns {{ peer: PeerID, counter: number }[]}
19
- */
20
9
  export function decodeFrontiers(bytes: Uint8Array): { peer: PeerID, counter: number }[];
21
10
  /**
22
- * Enable debug info of Loro
23
- */
11
+ * Enable debug info of Loro
12
+ */
24
13
  export function setDebug(): void;
25
14
  /**
26
- * Decode the metadata of the import blob.
27
- *
28
- * This method is useful to get the following metadata of the import blob:
29
- *
30
- * - startVersionVector
31
- * - endVersionVector
32
- * - startTimestamp
33
- * - endTimestamp
34
- * - mode
35
- * - changeNum
36
- * @param {Uint8Array} blob
37
- * @param {boolean} check_checksum
38
- * @returns {ImportBlobMetadata}
39
- */
15
+ * Decode the metadata of the import blob.
16
+ *
17
+ * This method is useful to get the following metadata of the import blob:
18
+ *
19
+ * - startVersionVector
20
+ * - endVersionVector
21
+ * - startTimestamp
22
+ * - endTimestamp
23
+ * - mode
24
+ * - changeNum
25
+ */
40
26
  export function decodeImportBlobMeta(blob: Uint8Array, check_checksum: boolean): ImportBlobMetadata;
41
27
 
42
28
  /**
@@ -161,6 +147,126 @@ interface LoroDoc {
161
147
  */
162
148
  subscribeLocalUpdates(f: (bytes: Uint8Array) => void): () => void
163
149
 
150
+ /**
151
+ * Subscribe to the first commit from a peer. Operations performed on the `LoroDoc` within this callback
152
+ * will be merged into the current commit.
153
+ *
154
+ * This is useful for managing the relationship between `PeerID` and user information.
155
+ * For example, you could store user names in a `LoroMap` using `PeerID` as the key and the `UserID` as the value.
156
+ *
157
+ * @param f - A callback function that receives a peer id.
158
+ *
159
+ * @example
160
+ * ```ts
161
+ * const doc = new LoroDoc();
162
+ * doc.setPeerId(0);
163
+ * const p = [];
164
+ * doc.subscribeFirstCommitFromPeer((peer) => {
165
+ * p.push(peer);
166
+ * doc.getMap("map").set(e.peer, "user-" + e.peer);
167
+ * });
168
+ * doc.getList("list").insert(0, 100);
169
+ * doc.commit();
170
+ * doc.getList("list").insert(0, 200);
171
+ * doc.commit();
172
+ * doc.setPeerId(1);
173
+ * doc.getList("list").insert(0, 300);
174
+ * doc.commit();
175
+ * expect(p).toEqual(["0", "1"]);
176
+ * expect(doc.getMap("map").get("0")).toBe("user-0");
177
+ * ```
178
+ **/
179
+ subscribeFirstCommitFromPeer(f: (e: { peer: PeerID }) => void): () => void
180
+
181
+ /**
182
+ * Subscribe to the pre-commit event.
183
+ *
184
+ * The callback will be called when the changes are committed but not yet applied to the OpLog.
185
+ * You can modify the commit message and timestamp in the callback by `ChangeModifier`.
186
+ *
187
+ * @example
188
+ * ```ts
189
+ * const doc = new LoroDoc();
190
+ * doc.subscribePreCommit((e) => {
191
+ * e.modifier.setMessage("test").setTimestamp(Date.now());
192
+ * });
193
+ * doc.getList("list").insert(0, 100);
194
+ * doc.commit();
195
+ * expect(doc.getChangeAt({ peer: "0", counter: 0 }).message).toBe("test");
196
+ * ```
197
+ *
198
+ * ### Advanced Example: Creating a Merkle DAG
199
+ *
200
+ * By combining `doc.subscribePreCommit` with `doc.exportJsonInIdSpan`, you can implement advanced features like representing Loro's editing history as a Merkle DAG:
201
+ *
202
+ * ```ts
203
+ * const doc = new LoroDoc();
204
+ * doc.setPeerId(0);
205
+ * doc.subscribePreCommit((e) => {
206
+ * const changes = doc.exportJsonInIdSpan(e.changeMeta)
207
+ * expect(changes).toHaveLength(1);
208
+ * const hash = crypto.createHash('sha256');
209
+ * const change = {
210
+ * ...changes[0],
211
+ * deps: changes[0].deps.map(d => {
212
+ * const depChange = doc.getChangeAt(idStrToId(d))
213
+ * return depChange.message;
214
+ * })
215
+ * }
216
+ * console.log(change); // The output is shown below
217
+ * hash.update(JSON.stringify(change));
218
+ * const sha256Hash = hash.digest('hex');
219
+ * e.modifier.setMessage(sha256Hash);
220
+ * });
221
+ *
222
+ * doc.getList("list").insert(0, 100);
223
+ * doc.commit();
224
+ * // Change 0
225
+ * // {
226
+ * // id: '0@0',
227
+ * // timestamp: 0,
228
+ * // deps: [],
229
+ * // lamport: 0,
230
+ * // msg: undefined,
231
+ * // ops: [
232
+ * // {
233
+ * // container: 'cid:root-list:List',
234
+ * // content: { type: 'insert', pos: 0, value: [100] },
235
+ * // counter: 0
236
+ * // }
237
+ * // ]
238
+ * // }
239
+ *
240
+ *
241
+ * doc.getList("list").insert(0, 200);
242
+ * doc.commit();
243
+ * // Change 1
244
+ * // {
245
+ * // id: '1@0',
246
+ * // timestamp: 0,
247
+ * // deps: [
248
+ * // '2af99cf93869173984bcf6b1ce5412610b0413d027a5511a8f720a02a4432853'
249
+ * // ],
250
+ * // lamport: 1,
251
+ * // msg: undefined,
252
+ * // ops: [
253
+ * // {
254
+ * // container: 'cid:root-list:List',
255
+ * // content: { type: 'insert', pos: 0, value: [200] },
256
+ * // counter: 1
257
+ * // }
258
+ * // ]
259
+ * // }
260
+ *
261
+ * expect(doc.getChangeAt({ peer: "0", counter: 0 }).message).toBe("2af99cf93869173984bcf6b1ce5412610b0413d027a5511a8f720a02a4432853");
262
+ * expect(doc.getChangeAt({ peer: "0", counter: 1 }).message).toBe("aedbb442c554ecf59090e0e8339df1d8febf647f25cc37c67be0c6e27071d37f");
263
+ * ```
264
+ *
265
+ * @param f - A callback function that receives a pre commit event.
266
+ *
267
+ **/
268
+ subscribePreCommit(f: (e: { changeMeta: Change, origin: string, modifier: ChangeModifier }) => void): () => void
269
+
164
270
  /**
165
271
  * Convert the document to a JSON value with a custom replacer function.
166
272
  *
@@ -759,7 +865,6 @@ export type AwarenessListener = (
759
865
  origin: "local" | "timeout" | "remote" | string,
760
866
  ) => void;
761
867
 
762
-
763
868
  interface Listener {
764
869
  (event: LoroEventBatch): void;
765
870
  }
@@ -856,10 +961,15 @@ interface LoroDoc<T extends Record<string, Container> = Record<string, Container
856
961
  */
857
962
  exportJsonUpdates(start?: VersionVector, end?: VersionVector, withPeerCompression?: boolean): JsonSchema;
858
963
  /**
859
- * Export the readable [`Change`]s in the given [`IdSpan`].
964
+ * Exports changes within the specified ID span to JSON schema format.
860
965
  *
861
- * The peers are not compressed in the returned changes.
966
+ * The JSON schema format produced by this method is identical to the one generated by `export_json_updates`.
967
+ * It ensures deterministic output, making it ideal for hash calculations and integrity checks.
862
968
  *
969
+ * This method can also export pending changes from the uncommitted transaction that have not yet been applied to the OpLog.
970
+ *
971
+ * This method will NOT trigger a new commit implicitly.
972
+ *
863
973
  * @param idSpan - The id span to export.
864
974
  * @returns The changes in the given id span.
865
975
  */
@@ -1274,2432 +1384,2246 @@ interface AwarenessWasm<T extends Value = Value> {
1274
1384
  removeOutdated(): PeerID[];
1275
1385
  }
1276
1386
 
1387
+ type EphemeralListener = (event: EphemeralStoreEvent) => void;
1388
+ type EphemeralLocalListener = (bytes: Uint8Array) => void;
1389
+
1390
+ interface EphemeralStoreWasm<T extends Value = Value> {
1391
+ set(key: string, value: T): void;
1392
+ get(key: string): T | undefined;
1393
+ getAllStates(): Record<string, T>;
1394
+ removeOutdated();
1395
+ subscribeLocalUpdates(f: EphemeralLocalListener): () => void;
1396
+ subscribe(f: EphemeralListener): () => void;
1397
+ }
1398
+
1399
+ interface EphemeralStoreEvent {
1400
+ by: "local" | "import" | "timeout";
1401
+ added: string[];
1402
+ updated: string[];
1403
+ removed: string[];
1404
+ }
1405
+
1277
1406
 
1278
1407
 
1279
1408
  /**
1280
- * `Awareness` is a structure that tracks the ephemeral state of peers.
1281
- *
1282
- * It can be used to synchronize cursor positions, selections, and the names of the peers.
1283
- *
1284
- * The state of a specific peer is expected to be removed after a specified timeout. Use
1285
- * `remove_outdated` to eliminate outdated states.
1286
- */
1409
+ * `Awareness` is a structure that tracks the ephemeral state of peers.
1410
+ *
1411
+ * It can be used to synchronize cursor positions, selections, and the names of the peers.
1412
+ *
1413
+ * The state of a specific peer is expected to be removed after a specified timeout. Use
1414
+ * `remove_outdated` to eliminate outdated states.
1415
+ */
1287
1416
  export class AwarenessWasm {
1288
1417
  free(): void;
1289
- /**
1290
- * Creates a new `Awareness` instance.
1291
- *
1292
- * The `timeout` parameter specifies the duration in milliseconds.
1293
- * A state of a peer is considered outdated, if the last update of the state of the peer
1294
- * is older than the `timeout`.
1295
- * @param {number | bigint | `${number}`} peer
1296
- * @param {number} timeout
1297
- */
1418
+ /**
1419
+ * Creates a new `Awareness` instance.
1420
+ *
1421
+ * The `timeout` parameter specifies the duration in milliseconds.
1422
+ * A state of a peer is considered outdated, if the last update of the state of the peer
1423
+ * is older than the `timeout`.
1424
+ */
1298
1425
  constructor(peer: number | bigint | `${number}`, timeout: number);
1299
- /**
1300
- * Encodes the state of the given peers.
1301
- * @param {Array<any>} peers
1302
- * @returns {Uint8Array}
1303
- */
1426
+ /**
1427
+ * Encodes the state of the given peers.
1428
+ */
1304
1429
  encode(peers: Array<any>): Uint8Array;
1305
- /**
1306
- * Encodes the state of all peers.
1307
- * @returns {Uint8Array}
1308
- */
1430
+ /**
1431
+ * Encodes the state of all peers.
1432
+ */
1309
1433
  encodeAll(): Uint8Array;
1310
- /**
1311
- * Applies the encoded state of peers.
1312
- *
1313
- * Each peer's deletion countdown will be reset upon update, requiring them to pass through the `timeout`
1314
- * interval again before being eligible for deletion.
1315
- * @param {Uint8Array} encoded_peers_info
1316
- * @returns {{ updated: PeerID[], added: PeerID[] }}
1317
- */
1434
+ /**
1435
+ * Applies the encoded state of peers.
1436
+ *
1437
+ * Each peer's deletion countdown will be reset upon update, requiring them to pass through the `timeout`
1438
+ * interval again before being eligible for deletion.
1439
+ */
1318
1440
  apply(encoded_peers_info: Uint8Array): { updated: PeerID[], added: PeerID[] };
1319
- /**
1320
- * Get the PeerID of the local peer.
1321
- * @returns {PeerID}
1322
- */
1441
+ /**
1442
+ * Get the PeerID of the local peer.
1443
+ */
1323
1444
  peer(): PeerID;
1324
- /**
1325
- * Get the timestamp of the state of a given peer.
1326
- * @param {number | bigint | `${number}`} peer
1327
- * @returns {number | undefined}
1328
- */
1445
+ /**
1446
+ * Get the timestamp of the state of a given peer.
1447
+ */
1329
1448
  getTimestamp(peer: number | bigint | `${number}`): number | undefined;
1330
- /**
1331
- * Remove the states of outdated peers.
1332
- * @returns {(PeerID)[]}
1333
- */
1334
- removeOutdated(): (PeerID)[];
1335
- /**
1336
- * Get the number of peers.
1337
- * @returns {number}
1338
- */
1449
+ /**
1450
+ * Remove the states of outdated peers.
1451
+ */
1452
+ removeOutdated(): PeerID[];
1453
+ /**
1454
+ * Get the number of peers.
1455
+ */
1339
1456
  length(): number;
1340
- /**
1341
- * If the state is empty.
1342
- * @returns {boolean}
1343
- */
1457
+ /**
1458
+ * If the state is empty.
1459
+ */
1344
1460
  isEmpty(): boolean;
1345
- /**
1346
- * Get all the peers
1347
- * @returns {(PeerID)[]}
1348
- */
1349
- peers(): (PeerID)[];
1461
+ /**
1462
+ * Get all the peers
1463
+ */
1464
+ peers(): PeerID[];
1465
+ }
1466
+ export class ChangeModifier {
1467
+ private constructor();
1468
+ free(): void;
1469
+ setMessage(message: string): ChangeModifier;
1470
+ setTimestamp(timestamp: number): ChangeModifier;
1350
1471
  }
1351
1472
  /**
1352
- * Cursor is a stable position representation in the doc.
1353
- * When expressing the position of a cursor, using "index" can be unstable
1354
- * because the cursor's position may change due to other deletions and insertions,
1355
- * requiring updates with each edit. To stably represent a position or range within
1356
- * a list structure, we can utilize the ID of each item/character on List CRDT or
1357
- * Text CRDT for expression.
1358
- *
1359
- * Loro optimizes State metadata by not storing the IDs of deleted elements. This
1360
- * approach complicates tracking cursors since they rely on these IDs. The solution
1361
- * recalculates position by replaying relevant history to update cursors
1362
- * accurately. To minimize the performance impact of history replay, the system
1363
- * updates cursor info to reference only the IDs of currently present elements,
1364
- * thereby reducing the need for replay.
1365
- *
1366
- * @example
1367
- * ```ts
1368
- *
1369
- * const doc = new LoroDoc();
1370
- * const text = doc.getText("text");
1371
- * text.insert(0, "123");
1372
- * const pos0 = text.getCursor(0, 0);
1373
- * {
1374
- * const ans = doc.getCursorPos(pos0!);
1375
- * expect(ans.offset).toBe(0);
1376
- * }
1377
- * text.insert(0, "1");
1378
- * {
1379
- * const ans = doc.getCursorPos(pos0!);
1380
- * expect(ans.offset).toBe(1);
1381
- * }
1382
- * ```
1383
- */
1473
+ * Cursor is a stable position representation in the doc.
1474
+ * When expressing the position of a cursor, using "index" can be unstable
1475
+ * because the cursor's position may change due to other deletions and insertions,
1476
+ * requiring updates with each edit. To stably represent a position or range within
1477
+ * a list structure, we can utilize the ID of each item/character on List CRDT or
1478
+ * Text CRDT for expression.
1479
+ *
1480
+ * Loro optimizes State metadata by not storing the IDs of deleted elements. This
1481
+ * approach complicates tracking cursors since they rely on these IDs. The solution
1482
+ * recalculates position by replaying relevant history to update cursors
1483
+ * accurately. To minimize the performance impact of history replay, the system
1484
+ * updates cursor info to reference only the IDs of currently present elements,
1485
+ * thereby reducing the need for replay.
1486
+ *
1487
+ * @example
1488
+ * ```ts
1489
+ *
1490
+ * const doc = new LoroDoc();
1491
+ * const text = doc.getText("text");
1492
+ * text.insert(0, "123");
1493
+ * const pos0 = text.getCursor(0, 0);
1494
+ * {
1495
+ * const ans = doc.getCursorPos(pos0!);
1496
+ * expect(ans.offset).toBe(0);
1497
+ * }
1498
+ * text.insert(0, "1");
1499
+ * {
1500
+ * const ans = doc.getCursorPos(pos0!);
1501
+ * expect(ans.offset).toBe(1);
1502
+ * }
1503
+ * ```
1504
+ */
1384
1505
  export class Cursor {
1506
+ private constructor();
1385
1507
  free(): void;
1386
- /**
1387
- * Get the id of the given container.
1388
- * @returns {ContainerID}
1389
- */
1508
+ /**
1509
+ * Get the id of the given container.
1510
+ */
1390
1511
  containerId(): ContainerID;
1391
- /**
1392
- * Get the ID that represents the position.
1393
- *
1394
- * It can be undefined if it's not bind into a specific ID.
1395
- * @returns {{ peer: PeerID, counter: number } | undefined}
1396
- */
1512
+ /**
1513
+ * Get the ID that represents the position.
1514
+ *
1515
+ * It can be undefined if it's not bind into a specific ID.
1516
+ */
1397
1517
  pos(): { peer: PeerID, counter: number } | undefined;
1398
- /**
1399
- * Get which side of the character/list item the cursor is on.
1400
- * @returns {Side}
1401
- */
1518
+ /**
1519
+ * Get which side of the character/list item the cursor is on.
1520
+ */
1402
1521
  side(): Side;
1403
- /**
1404
- * Encode the cursor into a Uint8Array.
1405
- * @returns {Uint8Array}
1406
- */
1522
+ /**
1523
+ * Encode the cursor into a Uint8Array.
1524
+ */
1407
1525
  encode(): Uint8Array;
1408
- /**
1409
- * Decode the cursor from a Uint8Array.
1410
- * @param {Uint8Array} data
1411
- * @returns {Cursor}
1412
- */
1526
+ /**
1527
+ * Decode the cursor from a Uint8Array.
1528
+ */
1413
1529
  static decode(data: Uint8Array): Cursor;
1414
- /**
1415
- * "Cursor"
1416
- * @returns {any}
1417
- */
1530
+ /**
1531
+ * "Cursor"
1532
+ */
1418
1533
  kind(): any;
1419
1534
  }
1535
+ export class EphemeralStoreWasm {
1536
+ free(): void;
1537
+ /**
1538
+ * Creates a new `EphemeralStore` instance.
1539
+ *
1540
+ * The `timeout` parameter specifies the duration in milliseconds.
1541
+ * A state of a peer is considered outdated, if the last update of the state of the peer
1542
+ * is older than the `timeout`.
1543
+ */
1544
+ constructor(timeout: number);
1545
+ set(key: string, value: any): void;
1546
+ delete(key: string): void;
1547
+ get(key: string): any;
1548
+ getAllStates(): any;
1549
+ encode(key: string): Uint8Array;
1550
+ encodeAll(): Uint8Array;
1551
+ apply(data: Uint8Array): void;
1552
+ removeOutdated(): void;
1553
+ /**
1554
+ * If the state is empty.
1555
+ */
1556
+ isEmpty(): boolean;
1557
+ keys(): string[];
1558
+ }
1420
1559
  /**
1421
- * The handler of a counter container.
1422
- */
1560
+ * The handler of a counter container.
1561
+ */
1423
1562
  export class LoroCounter {
1424
1563
  free(): void;
1425
- /**
1426
- * Create a new LoroCounter.
1427
- */
1564
+ /**
1565
+ * Create a new LoroCounter.
1566
+ */
1428
1567
  constructor();
1429
- /**
1430
- * "Counter"
1431
- * @returns {'Counter'}
1432
- */
1568
+ /**
1569
+ * "Counter"
1570
+ */
1433
1571
  kind(): 'Counter';
1434
- /**
1435
- * Increment the counter by the given value.
1436
- * @param {number} value
1437
- */
1572
+ /**
1573
+ * Increment the counter by the given value.
1574
+ */
1438
1575
  increment(value: number): void;
1439
- /**
1440
- * Decrement the counter by the given value.
1441
- * @param {number} value
1442
- */
1576
+ /**
1577
+ * Decrement the counter by the given value.
1578
+ */
1443
1579
  decrement(value: number): void;
1444
- /**
1445
- * Subscribe to the changes of the counter.
1446
- * @param {Function} f
1447
- * @returns {any}
1448
- */
1580
+ /**
1581
+ * Subscribe to the changes of the counter.
1582
+ */
1449
1583
  subscribe(f: Function): any;
1450
- /**
1451
- * Get the parent container of the counter container.
1452
- *
1453
- * - The parent container of the root counter is `undefined`.
1454
- * - The object returned is a new js object each time because it need to cross
1455
- * the WASM boundary.
1456
- * @returns {Container | undefined}
1457
- */
1584
+ /**
1585
+ * Get the parent container of the counter container.
1586
+ *
1587
+ * - The parent container of the root counter is `undefined`.
1588
+ * - The object returned is a new js object each time because it need to cross
1589
+ * the WASM boundary.
1590
+ */
1458
1591
  parent(): Container | undefined;
1459
- /**
1460
- * Whether the container is attached to a docuemnt.
1461
- *
1462
- * If it's detached, the operations on the container will not be persisted.
1463
- * @returns {boolean}
1464
- */
1592
+ /**
1593
+ * Whether the container is attached to a docuemnt.
1594
+ *
1595
+ * If it's detached, the operations on the container will not be persisted.
1596
+ */
1465
1597
  isAttached(): boolean;
1466
- /**
1467
- * Get the attached container associated with this.
1468
- *
1469
- * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
1470
- * @returns {LoroTree | undefined}
1471
- */
1598
+ /**
1599
+ * Get the attached container associated with this.
1600
+ *
1601
+ * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
1602
+ */
1472
1603
  getAttached(): LoroTree | undefined;
1473
- /**
1474
- * Get the value of the counter.
1475
- * @returns {number}
1476
- */
1604
+ /**
1605
+ * Get the value of the counter.
1606
+ */
1477
1607
  getShallowValue(): number;
1478
- /**
1479
- * The container id of this handler.
1480
- */
1608
+ /**
1609
+ * The container id of this handler.
1610
+ */
1481
1611
  readonly id: ContainerID;
1482
- /**
1483
- * Get the value of the counter.
1484
- */
1612
+ /**
1613
+ * Get the value of the counter.
1614
+ */
1485
1615
  readonly value: number;
1486
1616
  }
1487
1617
  /**
1488
- * The CRDTs document. Loro supports different CRDTs include [**List**](LoroList),
1489
- * [**RichText**](LoroText), [**Map**](LoroMap) and [**Movable Tree**](LoroTree),
1490
- * you could build all kind of applications by these.
1491
- *
1492
- * **Important:** Loro is a pure library and does not handle network protocols.
1493
- * It is the responsibility of the user to manage the storage, loading, and synchronization
1494
- * of the bytes exported by Loro in a manner suitable for their specific environment.
1495
- *
1496
- * @example
1497
- * ```ts
1498
- * import { LoroDoc } from "loro-crdt"
1499
- *
1500
- * const loro = new LoroDoc();
1501
- * const text = loro.getText("text");
1502
- * const list = loro.getList("list");
1503
- * const map = loro.getMap("Map");
1504
- * const tree = loro.getTree("tree");
1505
- * ```
1506
- */
1618
+ * The CRDTs document. Loro supports different CRDTs include [**List**](LoroList),
1619
+ * [**RichText**](LoroText), [**Map**](LoroMap) and [**Movable Tree**](LoroTree),
1620
+ * you could build all kind of applications by these.
1621
+ *
1622
+ * **Important:** Loro is a pure library and does not handle network protocols.
1623
+ * It is the responsibility of the user to manage the storage, loading, and synchronization
1624
+ * of the bytes exported by Loro in a manner suitable for their specific environment.
1625
+ *
1626
+ * @example
1627
+ * ```ts
1628
+ * import { LoroDoc } from "loro-crdt"
1629
+ *
1630
+ * const loro = new LoroDoc();
1631
+ * const text = loro.getText("text");
1632
+ * const list = loro.getList("list");
1633
+ * const map = loro.getMap("Map");
1634
+ * const tree = loro.getTree("tree");
1635
+ * ```
1636
+ */
1507
1637
  export class LoroDoc {
1508
1638
  free(): void;
1509
- /**
1510
- * Create a new loro document.
1511
- *
1512
- * New document will have a random peer id.
1513
- */
1639
+ /**
1640
+ * Create a new loro document.
1641
+ *
1642
+ * New document will have a random peer id.
1643
+ */
1514
1644
  constructor();
1515
- /**
1516
- * Enables editing in detached mode, which is disabled by default.
1517
- *
1518
- * The doc enter detached mode after calling `detach` or checking out a non-latest version.
1519
- *
1520
- * # Important Notes:
1521
- *
1522
- * - This mode uses a different PeerID for each checkout.
1523
- * - Ensure no concurrent operations share the same PeerID if set manually.
1524
- * - Importing does not affect the document's state or version; changes are
1525
- * recorded in the [OpLog] only. Call `checkout` to apply changes.
1526
- * @param {boolean} enable
1527
- */
1645
+ /**
1646
+ * Enables editing in detached mode, which is disabled by default.
1647
+ *
1648
+ * The doc enter detached mode after calling `detach` or checking out a non-latest version.
1649
+ *
1650
+ * # Important Notes:
1651
+ *
1652
+ * - This mode uses a different PeerID for each checkout.
1653
+ * - Ensure no concurrent operations share the same PeerID if set manually.
1654
+ * - Importing does not affect the document's state or version; changes are
1655
+ * recorded in the [OpLog] only. Call `checkout` to apply changes.
1656
+ */
1528
1657
  setDetachedEditing(enable: boolean): void;
1529
- /**
1530
- * Whether the editing is enabled in detached mode.
1531
- *
1532
- * The doc enter detached mode after calling `detach` or checking out a non-latest version.
1533
- *
1534
- * # Important Notes:
1535
- *
1536
- * - This mode uses a different PeerID for each checkout.
1537
- * - Ensure no concurrent operations share the same PeerID if set manually.
1538
- * - Importing does not affect the document's state or version; changes are
1539
- * recorded in the [OpLog] only. Call `checkout` to apply changes.
1540
- * @returns {boolean}
1541
- */
1658
+ /**
1659
+ * Whether the editing is enabled in detached mode.
1660
+ *
1661
+ * The doc enter detached mode after calling `detach` or checking out a non-latest version.
1662
+ *
1663
+ * # Important Notes:
1664
+ *
1665
+ * - This mode uses a different PeerID for each checkout.
1666
+ * - Ensure no concurrent operations share the same PeerID if set manually.
1667
+ * - Importing does not affect the document's state or version; changes are
1668
+ * recorded in the [OpLog] only. Call `checkout` to apply changes.
1669
+ */
1542
1670
  isDetachedEditingEnabled(): boolean;
1543
- /**
1544
- * Set whether to record the timestamp of each change. Default is `false`.
1545
- *
1546
- * If enabled, the Unix timestamp (in seconds) will be recorded for each change automatically.
1547
- *
1548
- * You can also set each timestamp manually when you commit a change.
1549
- * The timestamp manually set will override the automatic one.
1550
- *
1551
- * NOTE: Timestamps are forced to be in ascending order in the OpLog's history.
1552
- * If you commit a new change with a timestamp that is less than the existing one,
1553
- * the largest existing timestamp will be used instead.
1554
- * @param {boolean} auto_record
1555
- */
1671
+ /**
1672
+ * Set whether to record the timestamp of each change. Default is `false`.
1673
+ *
1674
+ * If enabled, the Unix timestamp (in seconds) will be recorded for each change automatically.
1675
+ *
1676
+ * You can also set each timestamp manually when you commit a change.
1677
+ * The timestamp manually set will override the automatic one.
1678
+ *
1679
+ * NOTE: Timestamps are forced to be in ascending order in the OpLog's history.
1680
+ * If you commit a new change with a timestamp that is less than the existing one,
1681
+ * the largest existing timestamp will be used instead.
1682
+ */
1556
1683
  setRecordTimestamp(auto_record: boolean): void;
1557
- /**
1558
- * If two continuous local changes are within (<=) the interval(**in seconds**), they will be merged into one change.
1559
- *
1560
- * The default value is 1_000 seconds.
1561
- *
1562
- * By default, we record timestamps in seconds for each change. So if the merge interval is 1, and changes A and B
1563
- * have timestamps of 3 and 4 respectively, then they will be merged into one change
1564
- * @param {number} interval
1565
- */
1684
+ /**
1685
+ * If two continuous local changes are within (<=) the interval(**in seconds**), they will be merged into one change.
1686
+ *
1687
+ * The default value is 1_000 seconds.
1688
+ *
1689
+ * By default, we record timestamps in seconds for each change. So if the merge interval is 1, and changes A and B
1690
+ * have timestamps of 3 and 4 respectively, then they will be merged into one change
1691
+ */
1566
1692
  setChangeMergeInterval(interval: number): void;
1567
- /**
1568
- * Set the rich text format configuration of the document.
1569
- *
1570
- * You need to config it if you use rich text `mark` method.
1571
- * Specifically, you need to config the `expand` property of each style.
1572
- *
1573
- * Expand is used to specify the behavior of expanding when new text is inserted at the
1574
- * beginning or end of the style.
1575
- *
1576
- * You can specify the `expand` option to set the behavior when inserting text at the boundary of the range.
1577
- *
1578
- * - `after`(default): when inserting text right after the given range, the mark will be expanded to include the inserted text
1579
- * - `before`: when inserting text right before the given range, the mark will be expanded to include the inserted text
1580
- * - `none`: the mark will not be expanded to include the inserted text at the boundaries
1581
- * - `both`: when inserting text either right before or right after the given range, the mark will be expanded to include the inserted text
1582
- *
1583
- * @example
1584
- * ```ts
1585
- * const doc = new LoroDoc();
1586
- * doc.configTextStyle({
1587
- * bold: { expand: "after" },
1588
- * link: { expand: "before" }
1589
- * });
1590
- * const text = doc.getText("text");
1591
- * text.insert(0, "Hello World!");
1592
- * text.mark({ start: 0, end: 5 }, "bold", true);
1593
- * expect(text.toDelta()).toStrictEqual([
1594
- * {
1595
- * insert: "Hello",
1596
- * attributes: {
1597
- * bold: true,
1598
- * },
1599
- * },
1600
- * {
1601
- * insert: " World!",
1602
- * },
1603
- * ] as Delta<string>[]);
1604
- * ```
1605
- * @param {{[key: string]: { expand: 'before'|'after'|'none'|'both' }}} styles
1606
- */
1693
+ /**
1694
+ * Set the rich text format configuration of the document.
1695
+ *
1696
+ * You need to config it if you use rich text `mark` method.
1697
+ * Specifically, you need to config the `expand` property of each style.
1698
+ *
1699
+ * Expand is used to specify the behavior of expanding when new text is inserted at the
1700
+ * beginning or end of the style.
1701
+ *
1702
+ * You can specify the `expand` option to set the behavior when inserting text at the boundary of the range.
1703
+ *
1704
+ * - `after`(default): when inserting text right after the given range, the mark will be expanded to include the inserted text
1705
+ * - `before`: when inserting text right before the given range, the mark will be expanded to include the inserted text
1706
+ * - `none`: the mark will not be expanded to include the inserted text at the boundaries
1707
+ * - `both`: when inserting text either right before or right after the given range, the mark will be expanded to include the inserted text
1708
+ *
1709
+ * @example
1710
+ * ```ts
1711
+ * const doc = new LoroDoc();
1712
+ * doc.configTextStyle({
1713
+ * bold: { expand: "after" },
1714
+ * link: { expand: "before" }
1715
+ * });
1716
+ * const text = doc.getText("text");
1717
+ * text.insert(0, "Hello World!");
1718
+ * text.mark({ start: 0, end: 5 }, "bold", true);
1719
+ * expect(text.toDelta()).toStrictEqual([
1720
+ * {
1721
+ * insert: "Hello",
1722
+ * attributes: {
1723
+ * bold: true,
1724
+ * },
1725
+ * },
1726
+ * {
1727
+ * insert: " World!",
1728
+ * },
1729
+ * ] as Delta<string>[]);
1730
+ * ```
1731
+ */
1607
1732
  configTextStyle(styles: {[key: string]: { expand: 'before'|'after'|'none'|'both' }}): void;
1608
- /**
1609
- * Configures the default text style for the document.
1610
- *
1611
- * This method sets the default text style configuration for the document when using LoroText.
1612
- * If `None` is provided, the default style is reset.
1613
- * @param {{ expand: 'before'|'after'|'none'|'both' } | undefined} style
1614
- */
1733
+ /**
1734
+ * Configures the default text style for the document.
1735
+ *
1736
+ * This method sets the default text style configuration for the document when using LoroText.
1737
+ * If `None` is provided, the default style is reset.
1738
+ */
1615
1739
  configDefaultTextStyle(style: { expand: 'before'|'after'|'none'|'both' } | undefined): void;
1616
- /**
1617
- * Create a loro document from the snapshot.
1618
- *
1619
- * @see You can learn more [here](https://loro.dev/docs/tutorial/encoding).
1620
- *
1621
- * @example
1622
- * ```ts
1623
- * import { LoroDoc } from "loro-crdt"
1624
- *
1625
- * const doc = new LoroDoc();
1626
- * // ...
1627
- * const bytes = doc.export({ mode: "snapshot" });
1628
- * const loro = LoroDoc.fromSnapshot(bytes);
1629
- * ```
1630
- * @param {Uint8Array} snapshot
1631
- * @returns {LoroDoc}
1632
- */
1740
+ /**
1741
+ * Create a loro document from the snapshot.
1742
+ *
1743
+ * @see You can learn more [here](https://loro.dev/docs/tutorial/encoding).
1744
+ *
1745
+ * @example
1746
+ * ```ts
1747
+ * import { LoroDoc } from "loro-crdt"
1748
+ *
1749
+ * const doc = new LoroDoc();
1750
+ * // ...
1751
+ * const bytes = doc.export({ mode: "snapshot" });
1752
+ * const loro = LoroDoc.fromSnapshot(bytes);
1753
+ * ```
1754
+ */
1633
1755
  static fromSnapshot(snapshot: Uint8Array): LoroDoc;
1634
- /**
1635
- * Attach the document state to the latest known version.
1636
- *
1637
- * > The document becomes detached during a `checkout` operation.
1638
- * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1639
- * > In a detached state, the document is not editable, and any `import` operations will be
1640
- * > recorded in the `OpLog` without being applied to the `DocState`.
1641
- *
1642
- * This method has the same effect as invoking `checkoutToLatest`.
1643
- *
1644
- * @example
1645
- * ```ts
1646
- * import { LoroDoc } from "loro-crdt";
1647
- *
1648
- * const doc = new LoroDoc();
1649
- * const text = doc.getText("text");
1650
- * const frontiers = doc.frontiers();
1651
- * text.insert(0, "Hello World!");
1652
- * doc.checkout(frontiers);
1653
- * // you need call `attach()` or `checkoutToLatest()` before changing the doc.
1654
- * doc.attach();
1655
- * text.insert(0, "Hi");
1656
- * ```
1657
- */
1756
+ /**
1757
+ * Attach the document state to the latest known version.
1758
+ *
1759
+ * > The document becomes detached during a `checkout` operation.
1760
+ * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1761
+ * > In a detached state, the document is not editable, and any `import` operations will be
1762
+ * > recorded in the `OpLog` without being applied to the `DocState`.
1763
+ *
1764
+ * This method has the same effect as invoking `checkoutToLatest`.
1765
+ *
1766
+ * @example
1767
+ * ```ts
1768
+ * import { LoroDoc } from "loro-crdt";
1769
+ *
1770
+ * const doc = new LoroDoc();
1771
+ * const text = doc.getText("text");
1772
+ * const frontiers = doc.frontiers();
1773
+ * text.insert(0, "Hello World!");
1774
+ * doc.checkout(frontiers);
1775
+ * // you need call `attach()` or `checkoutToLatest()` before changing the doc.
1776
+ * doc.attach();
1777
+ * text.insert(0, "Hi");
1778
+ * ```
1779
+ */
1658
1780
  attach(): void;
1659
- /**
1660
- * `detached` indicates that the `DocState` is not synchronized with the latest version of `OpLog`.
1661
- *
1662
- * > The document becomes detached during a `checkout` operation.
1663
- * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1664
- * > In a detached state, the document is not editable by default, and any `import` operations will be
1665
- * > recorded in the `OpLog` without being applied to the `DocState`.
1666
- *
1667
- * @example
1668
- * ```ts
1669
- * import { LoroDoc } from "loro-crdt";
1670
- *
1671
- * const doc = new LoroDoc();
1672
- * const text = doc.getText("text");
1673
- * const frontiers = doc.frontiers();
1674
- * text.insert(0, "Hello World!");
1675
- * console.log(doc.isDetached()); // false
1676
- * doc.checkout(frontiers);
1677
- * console.log(doc.isDetached()); // true
1678
- * doc.attach();
1679
- * console.log(doc.isDetached()); // false
1680
- * ```
1681
- * @returns {boolean}
1682
- */
1781
+ /**
1782
+ * `detached` indicates that the `DocState` is not synchronized with the latest version of `OpLog`.
1783
+ *
1784
+ * > The document becomes detached during a `checkout` operation.
1785
+ * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1786
+ * > In a detached state, the document is not editable by default, and any `import` operations will be
1787
+ * > recorded in the `OpLog` without being applied to the `DocState`.
1788
+ *
1789
+ * @example
1790
+ * ```ts
1791
+ * import { LoroDoc } from "loro-crdt";
1792
+ *
1793
+ * const doc = new LoroDoc();
1794
+ * const text = doc.getText("text");
1795
+ * const frontiers = doc.frontiers();
1796
+ * text.insert(0, "Hello World!");
1797
+ * console.log(doc.isDetached()); // false
1798
+ * doc.checkout(frontiers);
1799
+ * console.log(doc.isDetached()); // true
1800
+ * doc.attach();
1801
+ * console.log(doc.isDetached()); // false
1802
+ * ```
1803
+ */
1683
1804
  isDetached(): boolean;
1684
- /**
1685
- * Detach the document state from the latest known version.
1686
- *
1687
- * After detaching, all import operations will be recorded in the `OpLog` without being applied to the `DocState`.
1688
- * When `detached`, the document is not editable.
1689
- *
1690
- * @example
1691
- * ```ts
1692
- * import { LoroDoc } from "loro-crdt";
1693
- *
1694
- * const doc = new LoroDoc();
1695
- * doc.detach();
1696
- * console.log(doc.isDetached()); // true
1697
- * ```
1698
- */
1805
+ /**
1806
+ * Detach the document state from the latest known version.
1807
+ *
1808
+ * After detaching, all import operations will be recorded in the `OpLog` without being applied to the `DocState`.
1809
+ * When `detached`, the document is not editable.
1810
+ *
1811
+ * @example
1812
+ * ```ts
1813
+ * import { LoroDoc } from "loro-crdt";
1814
+ *
1815
+ * const doc = new LoroDoc();
1816
+ * doc.detach();
1817
+ * console.log(doc.isDetached()); // true
1818
+ * ```
1819
+ */
1699
1820
  detach(): void;
1700
- /**
1701
- * Duplicate the document with a different PeerID
1702
- *
1703
- * The time complexity and space complexity of this operation are both O(n),
1704
- *
1705
- * When called in detached mode, it will fork at the current state frontiers.
1706
- * It will have the same effect as `forkAt(&self.frontiers())`.
1707
- * @returns {LoroDoc}
1708
- */
1821
+ /**
1822
+ * Duplicate the document with a different PeerID
1823
+ *
1824
+ * The time complexity and space complexity of this operation are both O(n),
1825
+ *
1826
+ * When called in detached mode, it will fork at the current state frontiers.
1827
+ * It will have the same effect as `forkAt(&self.frontiers())`.
1828
+ */
1709
1829
  fork(): LoroDoc;
1710
- /**
1711
- * Creates a new LoroDoc at a specified version (Frontiers)
1712
- *
1713
- * The created doc will only contain the history before the specified frontiers.
1714
- * @param {({ peer: PeerID, counter: number })[]} frontiers
1715
- * @returns {LoroDoc}
1716
- */
1830
+ /**
1831
+ * Creates a new LoroDoc at a specified version (Frontiers)
1832
+ *
1833
+ * The created doc will only contain the history before the specified frontiers.
1834
+ */
1717
1835
  forkAt(frontiers: ({ peer: PeerID, counter: number })[]): LoroDoc;
1718
- /**
1719
- * Checkout the `DocState` to the latest version of `OpLog`.
1720
- *
1721
- * > The document becomes detached during a `checkout` operation.
1722
- * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1723
- * > In a detached state, the document is not editable by default, and any `import` operations will be
1724
- * > recorded in the `OpLog` without being applied to the `DocState`.
1725
- *
1726
- * This has the same effect as `attach`.
1727
- *
1728
- * @example
1729
- * ```ts
1730
- * import { LoroDoc } from "loro-crdt";
1731
- *
1732
- * const doc = new LoroDoc();
1733
- * const text = doc.getText("text");
1734
- * const frontiers = doc.frontiers();
1735
- * text.insert(0, "Hello World!");
1736
- * doc.checkout(frontiers);
1737
- * // you need call `checkoutToLatest()` or `attach()` before changing the doc.
1738
- * doc.checkoutToLatest();
1739
- * text.insert(0, "Hi");
1740
- * ```
1741
- */
1836
+ /**
1837
+ * Checkout the `DocState` to the latest version of `OpLog`.
1838
+ *
1839
+ * > The document becomes detached during a `checkout` operation.
1840
+ * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1841
+ * > In a detached state, the document is not editable by default, and any `import` operations will be
1842
+ * > recorded in the `OpLog` without being applied to the `DocState`.
1843
+ *
1844
+ * This has the same effect as `attach`.
1845
+ *
1846
+ * @example
1847
+ * ```ts
1848
+ * import { LoroDoc } from "loro-crdt";
1849
+ *
1850
+ * const doc = new LoroDoc();
1851
+ * const text = doc.getText("text");
1852
+ * const frontiers = doc.frontiers();
1853
+ * text.insert(0, "Hello World!");
1854
+ * doc.checkout(frontiers);
1855
+ * // you need call `checkoutToLatest()` or `attach()` before changing the doc.
1856
+ * doc.checkoutToLatest();
1857
+ * text.insert(0, "Hi");
1858
+ * ```
1859
+ */
1742
1860
  checkoutToLatest(): void;
1743
- /**
1744
- * Visit all the ancestors of the changes in causal order.
1745
- *
1746
- * @param ids - the changes to visit
1747
- * @param f - the callback function, return `true` to continue visiting, return `false` to stop
1748
- * @param {({ peer: PeerID, counter: number })[]} ids
1749
- * @param {(change: Change) => boolean} f
1750
- */
1861
+ /**
1862
+ * Visit all the ancestors of the changes in causal order.
1863
+ *
1864
+ * @param ids - the changes to visit
1865
+ * @param f - the callback function, return `true` to continue visiting, return `false` to stop
1866
+ */
1751
1867
  travelChangeAncestors(ids: ({ peer: PeerID, counter: number })[], f: (change: Change) => boolean): void;
1752
- /**
1753
- * Find the op id spans that between the `from` version and the `to` version.
1754
- *
1755
- * You can combine it with `exportJsonInIdSpan` to get the changes between two versions.
1756
- *
1757
- * You can use it to travel all the changes from `from` to `to`. `from` and `to` are frontiers,
1758
- * and they can be concurrent to each other. You can use it to find all the changes related to an event:
1759
- *
1760
- * @example
1761
- * ```ts
1762
- * import { LoroDoc } from "loro-crdt";
1763
- *
1764
- * const docA = new LoroDoc();
1765
- * docA.setPeerId("1");
1766
- * const docB = new LoroDoc();
1767
- *
1768
- * docA.getText("text").update("Hello");
1769
- * docA.commit();
1770
- * const snapshot = docA.export({ mode: "snapshot" });
1771
- * let done = false;
1772
- * docB.subscribe(e => {
1773
- * const spans = docB.findIdSpansBetween(e.from, e.to);
1774
- * const changes = docB.exportJsonInIdSpan(spans.forward[0]);
1775
- * console.log(changes);
1776
- * // [{
1777
- * // id: "0@1",
1778
- * // timestamp: expect.any(Number),
1779
- * // deps: [],
1780
- * // lamport: 0,
1781
- * // msg: undefined,
1782
- * // ops: [{
1783
- * // container: "cid:root-text:Text",
1784
- * // counter: 0,
1785
- * // content: {
1786
- * // type: "insert",
1787
- * // pos: 0,
1788
- * // text: "Hello"
1789
- * // }
1790
- * // }]
1791
- * // }]
1792
- * });
1793
- * docB.import(snapshot);
1794
- * ```
1795
- * @param {({ peer: PeerID, counter: number })[]} from
1796
- * @param {({ peer: PeerID, counter: number })[]} to
1797
- * @returns {VersionVectorDiff}
1798
- */
1868
+ /**
1869
+ * Find the op id spans that between the `from` version and the `to` version.
1870
+ *
1871
+ * You can combine it with `exportJsonInIdSpan` to get the changes between two versions.
1872
+ *
1873
+ * You can use it to travel all the changes from `from` to `to`. `from` and `to` are frontiers,
1874
+ * and they can be concurrent to each other. You can use it to find all the changes related to an event:
1875
+ *
1876
+ * @example
1877
+ * ```ts
1878
+ * import { LoroDoc } from "loro-crdt";
1879
+ *
1880
+ * const docA = new LoroDoc();
1881
+ * docA.setPeerId("1");
1882
+ * const docB = new LoroDoc();
1883
+ *
1884
+ * docA.getText("text").update("Hello");
1885
+ * docA.commit();
1886
+ * const snapshot = docA.export({ mode: "snapshot" });
1887
+ * let done = false;
1888
+ * docB.subscribe(e => {
1889
+ * const spans = docB.findIdSpansBetween(e.from, e.to);
1890
+ * const changes = docB.exportJsonInIdSpan(spans.forward[0]);
1891
+ * console.log(changes);
1892
+ * // [{
1893
+ * // id: "0@1",
1894
+ * // timestamp: expect.any(Number),
1895
+ * // deps: [],
1896
+ * // lamport: 0,
1897
+ * // msg: undefined,
1898
+ * // ops: [{
1899
+ * // container: "cid:root-text:Text",
1900
+ * // counter: 0,
1901
+ * // content: {
1902
+ * // type: "insert",
1903
+ * // pos: 0,
1904
+ * // text: "Hello"
1905
+ * // }
1906
+ * // }]
1907
+ * // }]
1908
+ * });
1909
+ * docB.import(snapshot);
1910
+ * ```
1911
+ */
1799
1912
  findIdSpansBetween(from: ({ peer: PeerID, counter: number })[], to: ({ peer: PeerID, counter: number })[]): VersionVectorDiff;
1800
- /**
1801
- * Checkout the `DocState` to a specific version.
1802
- *
1803
- * > The document becomes detached during a `checkout` operation.
1804
- * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1805
- * > In a detached state, the document is not editable, and any `import` operations will be
1806
- * > recorded in the `OpLog` without being applied to the `DocState`.
1807
- *
1808
- * You should call `attach` to attach the `DocState` to the latest version of `OpLog`.
1809
- *
1810
- * @param frontiers - the specific frontiers
1811
- *
1812
- * @example
1813
- * ```ts
1814
- * import { LoroDoc } from "loro-crdt";
1815
- *
1816
- * const doc = new LoroDoc();
1817
- * const text = doc.getText("text");
1818
- * const frontiers = doc.frontiers();
1819
- * text.insert(0, "Hello World!");
1820
- * doc.checkout(frontiers);
1821
- * console.log(doc.toJSON()); // {"text": ""}
1822
- * ```
1823
- * @param {({ peer: PeerID, counter: number })[]} frontiers
1824
- */
1913
+ /**
1914
+ * Checkout the `DocState` to a specific version.
1915
+ *
1916
+ * > The document becomes detached during a `checkout` operation.
1917
+ * > Being `detached` implies that the `DocState` is not synchronized with the latest version of the `OpLog`.
1918
+ * > In a detached state, the document is not editable, and any `import` operations will be
1919
+ * > recorded in the `OpLog` without being applied to the `DocState`.
1920
+ *
1921
+ * You should call `attach` to attach the `DocState` to the latest version of `OpLog`.
1922
+ *
1923
+ * @param frontiers - the specific frontiers
1924
+ *
1925
+ * @example
1926
+ * ```ts
1927
+ * import { LoroDoc } from "loro-crdt";
1928
+ *
1929
+ * const doc = new LoroDoc();
1930
+ * const text = doc.getText("text");
1931
+ * const frontiers = doc.frontiers();
1932
+ * text.insert(0, "Hello World!");
1933
+ * doc.checkout(frontiers);
1934
+ * console.log(doc.toJSON()); // {"text": ""}
1935
+ * ```
1936
+ */
1825
1937
  checkout(frontiers: ({ peer: PeerID, counter: number })[]): void;
1826
- /**
1827
- * Set the peer ID of the current writer.
1828
- *
1829
- * It must be a number, a BigInt, or a decimal string that can be parsed to a unsigned 64-bit integer.
1830
- *
1831
- * Note: use it with caution. You need to make sure there is not chance that two peers
1832
- * have the same peer ID. Otherwise, we cannot ensure the consistency of the document.
1833
- * @param {number | bigint | `${number}`} peer_id
1834
- */
1938
+ /**
1939
+ * Set the peer ID of the current writer.
1940
+ *
1941
+ * It must be a number, a BigInt, or a decimal string that can be parsed to a unsigned 64-bit integer.
1942
+ *
1943
+ * Note: use it with caution. You need to make sure there is not chance that two peers
1944
+ * have the same peer ID. Otherwise, we cannot ensure the consistency of the document.
1945
+ */
1835
1946
  setPeerId(peer_id: number | bigint | `${number}`): void;
1836
- /**
1837
- * Commit the cumulative auto-committed transaction.
1838
- *
1839
- * You can specify the `origin`, `timestamp`, and `message` of the commit.
1840
- *
1841
- * - The `origin` is used to mark the event
1842
- * - The `message` works like a git commit message, which will be recorded and synced to peers
1843
- * - The `timestamp` is the number of seconds that have elapsed since 00:00:00 UTC on January 1, 1970.
1844
- * It defaults to `Date.now() / 1000` when timestamp recording is enabled
1845
- *
1846
- * The events will be emitted after a transaction is committed. A transaction is committed when:
1847
- *
1848
- * - `doc.commit()` is called.
1849
- * - `doc.export(mode)` is called.
1850
- * - `doc.import(data)` is called.
1851
- * - `doc.checkout(version)` is called.
1852
- *
1853
- * NOTE: Timestamps are forced to be in ascending order.
1854
- * If you commit a new change with a timestamp that is less than the existing one,
1855
- * the largest existing timestamp will be used instead.
1856
- *
1857
- * NOTE: The `origin` will not be persisted, but the `message` will.
1858
- * @param {{ origin?: string, timestamp?: number, message?: string } | undefined} [options]
1859
- */
1860
- commit(options?: { origin?: string, timestamp?: number, message?: string }): void;
1861
- /**
1862
- * Get the number of operations in the pending transaction.
1863
- *
1864
- * The pending transaction is the one that is not committed yet. It will be committed
1865
- * automatically after calling `doc.commit()`, `doc.export(mode)` or `doc.checkout(version)`.
1866
- * @returns {number}
1867
- */
1947
+ /**
1948
+ * Commit the cumulative auto-committed transaction.
1949
+ *
1950
+ * You can specify the `origin`, `timestamp`, and `message` of the commit.
1951
+ *
1952
+ * - The `origin` is used to mark the event
1953
+ * - The `message` works like a git commit message, which will be recorded and synced to peers
1954
+ * - The `timestamp` is the number of seconds that have elapsed since 00:00:00 UTC on January 1, 1970.
1955
+ * It defaults to `Date.now() / 1000` when timestamp recording is enabled
1956
+ *
1957
+ * The events will be emitted after a transaction is committed. A transaction is committed when:
1958
+ *
1959
+ * - `doc.commit()` is called.
1960
+ * - `doc.export(mode)` is called.
1961
+ * - `doc.import(data)` is called.
1962
+ * - `doc.checkout(version)` is called.
1963
+ *
1964
+ * NOTE: Timestamps are forced to be in ascending order.
1965
+ * If you commit a new change with a timestamp that is less than the existing one,
1966
+ * the largest existing timestamp will be used instead.
1967
+ *
1968
+ * NOTE: The `origin` will not be persisted, but the `message` will.
1969
+ */
1970
+ commit(options?: { origin?: string, timestamp?: number, message?: string } | null): void;
1971
+ /**
1972
+ * Get the number of operations in the pending transaction.
1973
+ *
1974
+ * The pending transaction is the one that is not committed yet. It will be committed
1975
+ * automatically after calling `doc.commit()`, `doc.export(mode)` or `doc.checkout(version)`.
1976
+ */
1868
1977
  getPendingTxnLength(): number;
1869
- /**
1870
- * Get a LoroText by container id.
1871
- *
1872
- * The object returned is a new js object each time because it need to cross
1873
- * the WASM boundary.
1874
- *
1875
- * If the container does not exist, an error will be thrown.
1876
- *
1877
- * @example
1878
- * ```ts
1879
- * import { LoroDoc } from "loro-crdt";
1880
- *
1881
- * const doc = new LoroDoc();
1882
- * const text = doc.getText("text");
1883
- * ```
1884
- * @param {ContainerID | string} cid
1885
- * @returns {LoroText}
1886
- */
1978
+ /**
1979
+ * Get a LoroText by container id.
1980
+ *
1981
+ * The object returned is a new js object each time because it need to cross
1982
+ * the WASM boundary.
1983
+ *
1984
+ * If the container does not exist, an error will be thrown.
1985
+ *
1986
+ * @example
1987
+ * ```ts
1988
+ * import { LoroDoc } from "loro-crdt";
1989
+ *
1990
+ * const doc = new LoroDoc();
1991
+ * const text = doc.getText("text");
1992
+ * ```
1993
+ */
1887
1994
  getText(cid: ContainerID | string): LoroText;
1888
- /**
1889
- * Get a LoroCounter by container id
1890
- *
1891
- * If the container does not exist, an error will be thrown.
1892
- * @param {ContainerID | string} cid
1893
- * @returns {LoroCounter}
1894
- */
1995
+ /**
1996
+ * Get a LoroCounter by container id
1997
+ *
1998
+ * If the container does not exist, an error will be thrown.
1999
+ */
1895
2000
  getCounter(cid: ContainerID | string): LoroCounter;
1896
- /**
1897
- * Check if the doc contains the target container.
1898
- *
1899
- * A root container always exists, while a normal container exists
1900
- * if it has ever been created on the doc.
1901
- *
1902
- * @example
1903
- * ```ts
1904
- * import { LoroDoc, LoroMap, LoroText, LoroList } from "loro-crdt";
1905
- *
1906
- * const doc = new LoroDoc();
1907
- * doc.setPeerId("1");
1908
- * const text = doc.getMap("map").setContainer("text", new LoroText());
1909
- * const list = doc.getMap("map").setContainer("list", new LoroList());
1910
- * expect(doc.isContainerExists("cid:root-map:Map")).toBe(true);
1911
- * expect(doc.isContainerExists("cid:0@1:Text")).toBe(true);
1912
- * expect(doc.isContainerExists("cid:1@1:List")).toBe(true);
1913
- *
1914
- * const doc2 = new LoroDoc();
1915
- * // Containers exist, as long as the history or the doc state include it
1916
- * doc.detach();
1917
- * doc2.import(doc.export({ mode: "update" }));
1918
- * expect(doc2.isContainerExists("cid:root-map:Map")).toBe(true);
1919
- * expect(doc2.isContainerExists("cid:0@1:Text")).toBe(true);
1920
- * expect(doc2.isContainerExists("cid:1@1:List")).toBe(true);
1921
- * ```
1922
- * @param {ContainerID} container_id
1923
- * @returns {boolean}
1924
- */
2001
+ /**
2002
+ * Check if the doc contains the target container.
2003
+ *
2004
+ * A root container always exists, while a normal container exists
2005
+ * if it has ever been created on the doc.
2006
+ *
2007
+ * @example
2008
+ * ```ts
2009
+ * import { LoroDoc, LoroMap, LoroText, LoroList } from "loro-crdt";
2010
+ *
2011
+ * const doc = new LoroDoc();
2012
+ * doc.setPeerId("1");
2013
+ * const text = doc.getMap("map").setContainer("text", new LoroText());
2014
+ * const list = doc.getMap("map").setContainer("list", new LoroList());
2015
+ * expect(doc.isContainerExists("cid:root-map:Map")).toBe(true);
2016
+ * expect(doc.isContainerExists("cid:0@1:Text")).toBe(true);
2017
+ * expect(doc.isContainerExists("cid:1@1:List")).toBe(true);
2018
+ *
2019
+ * const doc2 = new LoroDoc();
2020
+ * // Containers exist, as long as the history or the doc state include it
2021
+ * doc.detach();
2022
+ * doc2.import(doc.export({ mode: "update" }));
2023
+ * expect(doc2.isContainerExists("cid:root-map:Map")).toBe(true);
2024
+ * expect(doc2.isContainerExists("cid:0@1:Text")).toBe(true);
2025
+ * expect(doc2.isContainerExists("cid:1@1:List")).toBe(true);
2026
+ * ```
2027
+ */
1925
2028
  hasContainer(container_id: ContainerID): boolean;
1926
- /**
1927
- * Set the commit message of the next commit
1928
- * @param {string} msg
1929
- */
2029
+ /**
2030
+ * Set the commit message of the next commit
2031
+ */
1930
2032
  setNextCommitMessage(msg: string): void;
1931
- /**
1932
- * Set the origin of the next commit
1933
- * @param {string} origin
1934
- */
2033
+ /**
2034
+ * Set the origin of the next commit
2035
+ */
1935
2036
  setNextCommitOrigin(origin: string): void;
1936
- /**
1937
- * Set the timestamp of the next commit
1938
- * @param {number} timestamp
1939
- */
2037
+ /**
2038
+ * Set the timestamp of the next commit
2039
+ */
1940
2040
  setNextCommitTimestamp(timestamp: number): void;
1941
- /**
1942
- * Set the options of the next commit
1943
- * @param {{ origin?: string, timestamp?: number, message?: string }} options
1944
- */
2041
+ /**
2042
+ * Set the options of the next commit
2043
+ */
1945
2044
  setNextCommitOptions(options: { origin?: string, timestamp?: number, message?: string }): void;
1946
- /**
1947
- * Clear the options of the next commit
1948
- */
2045
+ /**
2046
+ * Clear the options of the next commit
2047
+ */
1949
2048
  clearNextCommitOptions(): void;
1950
- /**
1951
- * Get deep value of the document with container id
1952
- * @returns {any}
1953
- */
2049
+ /**
2050
+ * Get deep value of the document with container id
2051
+ */
1954
2052
  getDeepValueWithID(): any;
1955
- /**
1956
- * Get the path from the root to the container
1957
- * @param {ContainerID} id
1958
- * @returns {(string|number)[] | undefined}
1959
- */
2053
+ /**
2054
+ * Get the path from the root to the container
2055
+ */
1960
2056
  getPathToContainer(id: ContainerID): (string|number)[] | undefined;
1961
- /**
1962
- * Evaluate JSONPath against a LoroDoc
1963
- * @param {string} jsonpath
1964
- * @returns {Array<any>}
1965
- */
2057
+ /**
2058
+ * Evaluate JSONPath against a LoroDoc
2059
+ */
1966
2060
  JSONPath(jsonpath: string): Array<any>;
1967
- /**
1968
- * Get the version vector of the current document state.
1969
- *
1970
- * If you checkout to a specific version, the version vector will change.
1971
- * @returns {VersionVector}
1972
- */
2061
+ /**
2062
+ * Get the version vector of the current document state.
2063
+ *
2064
+ * If you checkout to a specific version, the version vector will change.
2065
+ */
1973
2066
  version(): VersionVector;
1974
- /**
1975
- * The doc only contains the history since this version
1976
- *
1977
- * This is empty if the doc is not shallow.
1978
- *
1979
- * The ops included by the shallow history start version vector are not in the doc.
1980
- * @returns {VersionVector}
1981
- */
2067
+ /**
2068
+ * The doc only contains the history since this version
2069
+ *
2070
+ * This is empty if the doc is not shallow.
2071
+ *
2072
+ * The ops included by the shallow history start version vector are not in the doc.
2073
+ */
1982
2074
  shallowSinceVV(): VersionVector;
1983
- /**
1984
- * Check if the doc contains the full history.
1985
- * @returns {boolean}
1986
- */
2075
+ /**
2076
+ * Check if the doc contains the full history.
2077
+ */
1987
2078
  isShallow(): boolean;
1988
- /**
1989
- * The doc only contains the history since this version
1990
- *
1991
- * This is empty if the doc is not shallow.
1992
- *
1993
- * The ops included by the shallow history start frontiers are not in the doc.
1994
- * @returns {{ peer: PeerID, counter: number }[]}
1995
- */
2079
+ /**
2080
+ * The doc only contains the history since this version
2081
+ *
2082
+ * This is empty if the doc is not shallow.
2083
+ *
2084
+ * The ops included by the shallow history start frontiers are not in the doc.
2085
+ */
1996
2086
  shallowSinceFrontiers(): { peer: PeerID, counter: number }[];
1997
- /**
1998
- * Get the version vector of the latest known version in OpLog.
1999
- *
2000
- * If you checkout to a specific version, this version vector will not change.
2001
- * @returns {VersionVector}
2002
- */
2087
+ /**
2088
+ * Get the version vector of the latest known version in OpLog.
2089
+ *
2090
+ * If you checkout to a specific version, this version vector will not change.
2091
+ */
2003
2092
  oplogVersion(): VersionVector;
2004
- /**
2005
- * Get the [frontiers](https://loro.dev/docs/advanced/version_deep_dive) of the current document state.
2006
- *
2007
- * If you checkout to a specific version, this value will change.
2008
- * @returns {{ peer: PeerID, counter: number }[]}
2009
- */
2093
+ /**
2094
+ * Get the [frontiers](https://loro.dev/docs/advanced/version_deep_dive) of the current document state.
2095
+ *
2096
+ * If you checkout to a specific version, this value will change.
2097
+ */
2010
2098
  frontiers(): { peer: PeerID, counter: number }[];
2011
- /**
2012
- * Get the [frontiers](https://loro.dev/docs/advanced/version_deep_dive) of the latest version in OpLog.
2013
- *
2014
- * If you checkout to a specific version, this value will not change.
2015
- * @returns {{ peer: PeerID, counter: number }[]}
2016
- */
2099
+ /**
2100
+ * Get the [frontiers](https://loro.dev/docs/advanced/version_deep_dive) of the latest version in OpLog.
2101
+ *
2102
+ * If you checkout to a specific version, this value will not change.
2103
+ */
2017
2104
  oplogFrontiers(): { peer: PeerID, counter: number }[];
2018
- /**
2019
- * Compare the version of the OpLog with the specified frontiers.
2020
- *
2021
- * This method is useful to compare the version by only a small amount of data.
2022
- *
2023
- * This method returns an integer indicating the relationship between the version of the OpLog (referred to as 'self')
2024
- * and the provided 'frontiers' parameter:
2025
- *
2026
- * - -1: The version of 'self' is either less than 'frontiers' or is non-comparable (parallel) to 'frontiers',
2027
- * indicating that it is not definitively less than 'frontiers'.
2028
- * - 0: The version of 'self' is equal to 'frontiers'.
2029
- * - 1: The version of 'self' is greater than 'frontiers'.
2030
- *
2031
- * # Internal
2032
- *
2033
- * Frontiers cannot be compared without the history of the OpLog.
2034
- * @param {({ peer: PeerID, counter: number })[]} frontiers
2035
- * @returns {number}
2036
- */
2105
+ /**
2106
+ * Compare the version of the OpLog with the specified frontiers.
2107
+ *
2108
+ * This method is useful to compare the version by only a small amount of data.
2109
+ *
2110
+ * This method returns an integer indicating the relationship between the version of the OpLog (referred to as 'self')
2111
+ * and the provided 'frontiers' parameter:
2112
+ *
2113
+ * - -1: The version of 'self' is either less than 'frontiers' or is non-comparable (parallel) to 'frontiers',
2114
+ * indicating that it is not definitively less than 'frontiers'.
2115
+ * - 0: The version of 'self' is equal to 'frontiers'.
2116
+ * - 1: The version of 'self' is greater than 'frontiers'.
2117
+ *
2118
+ * # Internal
2119
+ *
2120
+ * Frontiers cannot be compared without the history of the OpLog.
2121
+ */
2037
2122
  cmpWithFrontiers(frontiers: ({ peer: PeerID, counter: number })[]): number;
2038
- /**
2039
- * Compare the ordering of two Frontiers.
2040
- *
2041
- * It's assumed that both Frontiers are included by the doc. Otherwise, an error will be thrown.
2042
- *
2043
- * Return value:
2044
- *
2045
- * - -1: a < b
2046
- * - 0: a == b
2047
- * - 1: a > b
2048
- * - undefined: a ∥ b: a and b are concurrent
2049
- * @param {({ peer: PeerID, counter: number })[]} a
2050
- * @param {({ peer: PeerID, counter: number })[]} b
2051
- * @returns {-1 | 1 | 0 | undefined}
2052
- */
2123
+ /**
2124
+ * Compare the ordering of two Frontiers.
2125
+ *
2126
+ * It's assumed that both Frontiers are included by the doc. Otherwise, an error will be thrown.
2127
+ *
2128
+ * Return value:
2129
+ *
2130
+ * - -1: a < b
2131
+ * - 0: a == b
2132
+ * - 1: a > b
2133
+ * - undefined: a ∥ b: a and b are concurrent
2134
+ */
2053
2135
  cmpFrontiers(a: ({ peer: PeerID, counter: number })[], b: ({ peer: PeerID, counter: number })[]): -1 | 1 | 0 | undefined;
2054
- /**
2055
- * Export the snapshot of current version.
2056
- * It includes all the history and the document state
2057
- *
2058
- * @deprecated Use `export({mode: "snapshot"})` instead
2059
- * @returns {Uint8Array}
2060
- */
2136
+ /**
2137
+ * Export the snapshot of current version.
2138
+ * It includes all the history and the document state
2139
+ *
2140
+ * @deprecated Use `export({mode: "snapshot"})` instead
2141
+ */
2061
2142
  exportSnapshot(): Uint8Array;
2062
- /**
2063
- * Export the document based on the specified ExportMode.
2064
- *
2065
- * @param mode - The export mode to use. Can be one of:
2066
- * - `{ mode: "snapshot" }`: Export a full snapshot of the document.
2067
- * - `{ mode: "update", from?: VersionVector }`: Export updates from the given version vector.
2068
- * - `{ mode: "updates-in-range", spans: { id: ID, len: number }[] }`: Export updates within the specified ID spans.
2069
- * - `{ mode: "shallow-snapshot", frontiers: Frontiers }`: Export a garbage-collected snapshot up to the given frontiers.
2070
- *
2071
- * @returns A byte array containing the exported data.
2072
- *
2073
- * @example
2074
- * ```ts
2075
- * import { LoroDoc, LoroText } from "loro-crdt";
2076
- *
2077
- * const doc = new LoroDoc();
2078
- * doc.setPeerId("1");
2079
- * doc.getText("text").update("Hello World");
2080
- *
2081
- * // Export a full snapshot
2082
- * const snapshotBytes = doc.export({ mode: "snapshot" });
2083
- *
2084
- * // Export updates from a specific version
2085
- * const vv = doc.oplogVersion();
2086
- * doc.getText("text").update("Hello Loro");
2087
- * const updateBytes = doc.export({ mode: "update", from: vv });
2088
- *
2089
- * // Export a shallow snapshot that only includes the history since the frontiers
2090
- * const shallowBytes = doc.export({ mode: "shallow-snapshot", frontiers: doc.oplogFrontiers() });
2091
- *
2092
- * // Export updates within specific ID spans
2093
- * const spanBytes = doc.export({
2094
- * mode: "updates-in-range",
2095
- * spans: [{ id: { peer: "1", counter: 0 }, len: 10 }]
2096
- * });
2097
- * ```
2098
- * @param {ExportMode} mode
2099
- * @returns {Uint8Array}
2100
- */
2143
+ /**
2144
+ * Export the document based on the specified ExportMode.
2145
+ *
2146
+ * @param mode - The export mode to use. Can be one of:
2147
+ * - `{ mode: "snapshot" }`: Export a full snapshot of the document.
2148
+ * - `{ mode: "update", from?: VersionVector }`: Export updates from the given version vector.
2149
+ * - `{ mode: "updates-in-range", spans: { id: ID, len: number }[] }`: Export updates within the specified ID spans.
2150
+ * - `{ mode: "shallow-snapshot", frontiers: Frontiers }`: Export a garbage-collected snapshot up to the given frontiers.
2151
+ *
2152
+ * @returns A byte array containing the exported data.
2153
+ *
2154
+ * @example
2155
+ * ```ts
2156
+ * import { LoroDoc, LoroText } from "loro-crdt";
2157
+ *
2158
+ * const doc = new LoroDoc();
2159
+ * doc.setPeerId("1");
2160
+ * doc.getText("text").update("Hello World");
2161
+ *
2162
+ * // Export a full snapshot
2163
+ * const snapshotBytes = doc.export({ mode: "snapshot" });
2164
+ *
2165
+ * // Export updates from a specific version
2166
+ * const vv = doc.oplogVersion();
2167
+ * doc.getText("text").update("Hello Loro");
2168
+ * const updateBytes = doc.export({ mode: "update", from: vv });
2169
+ *
2170
+ * // Export a shallow snapshot that only includes the history since the frontiers
2171
+ * const shallowBytes = doc.export({ mode: "shallow-snapshot", frontiers: doc.oplogFrontiers() });
2172
+ *
2173
+ * // Export updates within specific ID spans
2174
+ * const spanBytes = doc.export({
2175
+ * mode: "updates-in-range",
2176
+ * spans: [{ id: { peer: "1", counter: 0 }, len: 10 }]
2177
+ * });
2178
+ * ```
2179
+ */
2101
2180
  export(mode: ExportMode): Uint8Array;
2102
- /**
2103
- * Import updates from the JSON format.
2104
- *
2105
- * only supports backward compatibility but not forward compatibility.
2106
- * @param {string | JsonSchema} json
2107
- * @returns {ImportStatus}
2108
- */
2181
+ /**
2182
+ * Import updates from the JSON format.
2183
+ *
2184
+ * only supports backward compatibility but not forward compatibility.
2185
+ */
2109
2186
  importJsonUpdates(json: string | JsonSchema): ImportStatus;
2110
- /**
2111
- * Import snapshot or updates into current doc.
2112
- *
2113
- * Note:
2114
- * - Updates within the current version will be ignored
2115
- * - Updates with missing dependencies will be pending until the dependencies are received
2116
- *
2117
- * @example
2118
- * ```ts
2119
- * import { LoroDoc } from "loro-crdt";
2120
- *
2121
- * const doc = new LoroDoc();
2122
- * const text = doc.getText("text");
2123
- * text.insert(0, "Hello");
2124
- * // get all updates of the doc
2125
- * const updates = doc.export({ mode: "update" });
2126
- * const snapshot = doc.export({ mode: "snapshot" });
2127
- * const doc2 = new LoroDoc();
2128
- * // import snapshot
2129
- * doc2.import(snapshot);
2130
- * // or import updates
2131
- * doc2.import(updates);
2132
- * ```
2133
- * @param {Uint8Array} update_or_snapshot
2134
- * @returns {ImportStatus}
2135
- */
2187
+ /**
2188
+ * Import snapshot or updates into current doc.
2189
+ *
2190
+ * Note:
2191
+ * - Updates within the current version will be ignored
2192
+ * - Updates with missing dependencies will be pending until the dependencies are received
2193
+ *
2194
+ * @example
2195
+ * ```ts
2196
+ * import { LoroDoc } from "loro-crdt";
2197
+ *
2198
+ * const doc = new LoroDoc();
2199
+ * const text = doc.getText("text");
2200
+ * text.insert(0, "Hello");
2201
+ * // get all updates of the doc
2202
+ * const updates = doc.export({ mode: "update" });
2203
+ * const snapshot = doc.export({ mode: "snapshot" });
2204
+ * const doc2 = new LoroDoc();
2205
+ * // import snapshot
2206
+ * doc2.import(snapshot);
2207
+ * // or import updates
2208
+ * doc2.import(updates);
2209
+ * ```
2210
+ */
2136
2211
  import(update_or_snapshot: Uint8Array): ImportStatus;
2137
- /**
2138
- * Import a batch of updates and snapshots.
2139
- *
2140
- * It's more efficient than importing updates one by one.
2141
- *
2142
- * @deprecated Use `importBatch` instead.
2143
- *
2144
- * @example
2145
- * ```ts
2146
- * import { LoroDoc } from "loro-crdt";
2147
- *
2148
- * const doc = new LoroDoc();
2149
- * const text = doc.getText("text");
2150
- * text.insert(0, "Hello");
2151
- * const updates = doc.export({ mode: "update" });
2152
- * const snapshot = doc.export({ mode: "snapshot" });
2153
- * const doc2 = new LoroDoc();
2154
- * doc2.importBatch([snapshot, updates]);
2155
- * ```
2156
- * @param {Uint8Array[]} data
2157
- * @returns {ImportStatus}
2158
- */
2212
+ /**
2213
+ * Import a batch of updates and snapshots.
2214
+ *
2215
+ * It's more efficient than importing updates one by one.
2216
+ *
2217
+ * @deprecated Use `importBatch` instead.
2218
+ *
2219
+ * @example
2220
+ * ```ts
2221
+ * import { LoroDoc } from "loro-crdt";
2222
+ *
2223
+ * const doc = new LoroDoc();
2224
+ * const text = doc.getText("text");
2225
+ * text.insert(0, "Hello");
2226
+ * const updates = doc.export({ mode: "update" });
2227
+ * const snapshot = doc.export({ mode: "snapshot" });
2228
+ * const doc2 = new LoroDoc();
2229
+ * doc2.importBatch([snapshot, updates]);
2230
+ * ```
2231
+ */
2159
2232
  importUpdateBatch(data: Uint8Array[]): ImportStatus;
2160
- /**
2161
- * Import a batch of updates or snapshots.
2162
- *
2163
- * It's more efficient than importing updates one by one.
2164
- *
2165
- * @example
2166
- * ```ts
2167
- * import { LoroDoc } from "loro-crdt";
2168
- *
2169
- * const doc = new LoroDoc();
2170
- * const text = doc.getText("text");
2171
- * text.insert(0, "Hello");
2172
- * const updates = doc.export({ mode: "update" });
2173
- * const snapshot = doc.export({ mode: "snapshot" });
2174
- * const doc2 = new LoroDoc();
2175
- * doc2.importBatch([snapshot, updates]);
2176
- * ```
2177
- * @param {Uint8Array[]} data
2178
- * @returns {ImportStatus}
2179
- */
2233
+ /**
2234
+ * Import a batch of updates or snapshots.
2235
+ *
2236
+ * It's more efficient than importing updates one by one.
2237
+ *
2238
+ * @example
2239
+ * ```ts
2240
+ * import { LoroDoc } from "loro-crdt";
2241
+ *
2242
+ * const doc = new LoroDoc();
2243
+ * const text = doc.getText("text");
2244
+ * text.insert(0, "Hello");
2245
+ * const updates = doc.export({ mode: "update" });
2246
+ * const snapshot = doc.export({ mode: "snapshot" });
2247
+ * const doc2 = new LoroDoc();
2248
+ * doc2.importBatch([snapshot, updates]);
2249
+ * ```
2250
+ */
2180
2251
  importBatch(data: Uint8Array[]): ImportStatus;
2181
- /**
2182
- * Get the shallow json format of the document state.
2183
- *
2184
- * Unlike `toJSON()` which recursively resolves all containers to their values,
2185
- * `getShallowValue()` returns container IDs as strings for any nested containers.
2186
- *
2187
- * @example
2188
- * ```ts
2189
- * import { LoroDoc } from "loro-crdt";
2190
- *
2191
- * const doc = new LoroDoc();
2192
- * const list = doc.getList("list");
2193
- * const tree = doc.getTree("tree");
2194
- * const map = doc.getMap("map");
2195
- * const shallowValue = doc.getShallowValue();
2196
- * console.log(shallowValue);
2197
- * // {
2198
- * // list: 'cid:root-list:List',
2199
- * // tree: 'cid:root-tree:Tree',
2200
- * // map: 'cid:root-map:Map'
2201
- * // }
2202
- *
2203
- * // It points to the same container as `list`
2204
- * const listB = doc.getContainerById(shallowValue.list);
2205
- * ```
2206
- * @returns {Record<string, ContainerID>}
2207
- */
2252
+ /**
2253
+ * Get the shallow json format of the document state.
2254
+ *
2255
+ * Unlike `toJSON()` which recursively resolves all containers to their values,
2256
+ * `getShallowValue()` returns container IDs as strings for any nested containers.
2257
+ *
2258
+ * @example
2259
+ * ```ts
2260
+ * import { LoroDoc } from "loro-crdt";
2261
+ *
2262
+ * const doc = new LoroDoc();
2263
+ * const list = doc.getList("list");
2264
+ * const tree = doc.getTree("tree");
2265
+ * const map = doc.getMap("map");
2266
+ * const shallowValue = doc.getShallowValue();
2267
+ * console.log(shallowValue);
2268
+ * // {
2269
+ * // list: 'cid:root-list:List',
2270
+ * // tree: 'cid:root-tree:Tree',
2271
+ * // map: 'cid:root-map:Map'
2272
+ * // }
2273
+ *
2274
+ * // It points to the same container as `list`
2275
+ * const listB = doc.getContainerById(shallowValue.list);
2276
+ * ```
2277
+ */
2208
2278
  getShallowValue(): Record<string, ContainerID>;
2209
- /**
2210
- * Get the json format of the entire document state.
2211
- *
2212
- * Unlike `getShallowValue()` which returns container IDs as strings,
2213
- * `toJSON()` recursively resolves all containers to their actual values.
2214
- *
2215
- * @example
2216
- * ```ts
2217
- * import { LoroDoc, LoroText, LoroMap } from "loro-crdt";
2218
- *
2219
- * const doc = new LoroDoc();
2220
- * const list = doc.getList("list");
2221
- * list.insert(0, "Hello");
2222
- * const text = list.insertContainer(0, new LoroText());
2223
- * text.insert(0, "Hello");
2224
- * const map = list.insertContainer(1, new LoroMap());
2225
- * map.set("foo", "bar");
2226
- * console.log(doc.toJSON());
2227
- * // {"list": ["Hello", {"foo": "bar"}]}
2228
- * ```
2229
- * @returns {any}
2230
- */
2279
+ /**
2280
+ * Get the json format of the entire document state.
2281
+ *
2282
+ * Unlike `getShallowValue()` which returns container IDs as strings,
2283
+ * `toJSON()` recursively resolves all containers to their actual values.
2284
+ *
2285
+ * @example
2286
+ * ```ts
2287
+ * import { LoroDoc, LoroText, LoroMap } from "loro-crdt";
2288
+ *
2289
+ * const doc = new LoroDoc();
2290
+ * const list = doc.getList("list");
2291
+ * list.insert(0, "Hello");
2292
+ * const text = list.insertContainer(0, new LoroText());
2293
+ * text.insert(0, "Hello");
2294
+ * const map = list.insertContainer(1, new LoroMap());
2295
+ * map.set("foo", "bar");
2296
+ * console.log(doc.toJSON());
2297
+ * // {"list": ["Hello", {"foo": "bar"}]}
2298
+ * ```
2299
+ */
2231
2300
  toJSON(): any;
2232
- /**
2233
- * Debug the size of the history
2234
- */
2301
+ /**
2302
+ * Debug the size of the history
2303
+ */
2235
2304
  debugHistory(): void;
2236
- /**
2237
- * Get the number of changes in the oplog.
2238
- * @returns {number}
2239
- */
2305
+ /**
2306
+ * Get the number of changes in the oplog.
2307
+ */
2240
2308
  changeCount(): number;
2241
- /**
2242
- * Get the number of ops in the oplog.
2243
- * @returns {number}
2244
- */
2309
+ /**
2310
+ * Get the number of ops in the oplog.
2311
+ */
2245
2312
  opCount(): number;
2246
- /**
2247
- * Get all of changes in the oplog.
2248
- *
2249
- * Note: this method is expensive when the oplog is large. O(n)
2250
- *
2251
- * @example
2252
- * ```ts
2253
- * import { LoroDoc, LoroText } from "loro-crdt";
2254
- *
2255
- * const doc = new LoroDoc();
2256
- * const text = doc.getText("text");
2257
- * text.insert(0, "Hello");
2258
- * const changes = doc.getAllChanges();
2259
- *
2260
- * for (let [peer, c] of changes.entries()){
2261
- * console.log("peer: ", peer);
2262
- * for (let change of c){
2263
- * console.log("change: ", change);
2264
- * }
2265
- * }
2266
- * ```
2267
- * @returns {Map<PeerID, Change[]>}
2268
- */
2313
+ /**
2314
+ * Get all of changes in the oplog.
2315
+ *
2316
+ * Note: this method is expensive when the oplog is large. O(n)
2317
+ *
2318
+ * @example
2319
+ * ```ts
2320
+ * import { LoroDoc, LoroText } from "loro-crdt";
2321
+ *
2322
+ * const doc = new LoroDoc();
2323
+ * const text = doc.getText("text");
2324
+ * text.insert(0, "Hello");
2325
+ * const changes = doc.getAllChanges();
2326
+ *
2327
+ * for (let [peer, c] of changes.entries()){
2328
+ * console.log("peer: ", peer);
2329
+ * for (let change of c){
2330
+ * console.log("change: ", change);
2331
+ * }
2332
+ * }
2333
+ * ```
2334
+ */
2269
2335
  getAllChanges(): Map<PeerID, Change[]>;
2270
- /**
2271
- * Get the change that contains the specific ID
2272
- * @param {{ peer: PeerID, counter: number }} id
2273
- * @returns {Change}
2274
- */
2336
+ /**
2337
+ * Get the change that contains the specific ID
2338
+ */
2275
2339
  getChangeAt(id: { peer: PeerID, counter: number }): Change;
2276
- /**
2277
- * Get the change of with specific peer_id and lamport <= given lamport
2278
- * @param {string} peer_id
2279
- * @param {number} lamport
2280
- * @returns {Change | undefined}
2281
- */
2282
- getChangeAtLamport(peer_id: string, lamport: number): Change | undefined;
2283
- /**
2284
- * Get all ops of the change that contains the specific ID
2285
- * @param {{ peer: PeerID, counter: number }} id
2286
- * @returns {any[]}
2287
- */
2288
- getOpsInChange(id: { peer: PeerID, counter: number }): any[];
2289
- /**
2290
- * Convert frontiers to a version vector
2291
- *
2292
- * Learn more about frontiers and version vector [here](https://loro.dev/docs/advanced/version_deep_dive)
2293
- *
2294
- * @example
2295
- * ```ts
2296
- * import { LoroDoc } from "loro-crdt";
2297
- *
2298
- * const doc = new LoroDoc();
2299
- * const text = doc.getText("text");
2300
- * text.insert(0, "Hello");
2301
- * const frontiers = doc.frontiers();
2302
- * const version = doc.frontiersToVV(frontiers);
2303
- * ```
2304
- * @param {({ peer: PeerID, counter: number })[]} frontiers
2305
- * @returns {VersionVector}
2306
- */
2340
+ /**
2341
+ * Get the change of with specific peer_id and lamport <= given lamport
2342
+ */
2343
+ getChangeAtLamport(peer_id: string, lamport: number): Change | undefined;
2344
+ /**
2345
+ * Get all ops of the change that contains the specific ID
2346
+ */
2347
+ getOpsInChange(id: { peer: PeerID, counter: number }): any[];
2348
+ /**
2349
+ * Convert frontiers to a version vector
2350
+ *
2351
+ * Learn more about frontiers and version vector [here](https://loro.dev/docs/advanced/version_deep_dive)
2352
+ *
2353
+ * @example
2354
+ * ```ts
2355
+ * import { LoroDoc } from "loro-crdt";
2356
+ *
2357
+ * const doc = new LoroDoc();
2358
+ * const text = doc.getText("text");
2359
+ * text.insert(0, "Hello");
2360
+ * const frontiers = doc.frontiers();
2361
+ * const version = doc.frontiersToVV(frontiers);
2362
+ * ```
2363
+ */
2307
2364
  frontiersToVV(frontiers: ({ peer: PeerID, counter: number })[]): VersionVector;
2308
- /**
2309
- * Convert a version vector to frontiers
2310
- *
2311
- * @example
2312
- * ```ts
2313
- * import { LoroDoc } from "loro-crdt";
2314
- *
2315
- * const doc = new LoroDoc();
2316
- * const text = doc.getText("text");
2317
- * text.insert(0, "Hello");
2318
- * const version = doc.version();
2319
- * const frontiers = doc.vvToFrontiers(version);
2320
- * ```
2321
- * @param {VersionVector} vv
2322
- * @returns {{ peer: PeerID, counter: number }[]}
2323
- */
2365
+ /**
2366
+ * Convert a version vector to frontiers
2367
+ *
2368
+ * @example
2369
+ * ```ts
2370
+ * import { LoroDoc } from "loro-crdt";
2371
+ *
2372
+ * const doc = new LoroDoc();
2373
+ * const text = doc.getText("text");
2374
+ * text.insert(0, "Hello");
2375
+ * const version = doc.version();
2376
+ * const frontiers = doc.vvToFrontiers(version);
2377
+ * ```
2378
+ */
2324
2379
  vvToFrontiers(vv: VersionVector): { peer: PeerID, counter: number }[];
2325
- /**
2326
- * Get the value or container at the given path
2327
- *
2328
- * The path can be specified in different ways depending on the container type:
2329
- *
2330
- * For Tree:
2331
- * 1. Using node IDs: `tree/{node_id}/property`
2332
- * 2. Using indices: `tree/0/1/property`
2333
- *
2334
- * For List and MovableList:
2335
- * - Using indices: `list/0` or `list/1/property`
2336
- *
2337
- * For Map:
2338
- * - Using keys: `map/key` or `map/nested/property`
2339
- *
2340
- * For tree structures, index-based paths follow depth-first traversal order.
2341
- * The indices start from 0 and represent the position of a node among its siblings.
2342
- *
2343
- * @example
2344
- * ```ts
2345
- * import { LoroDoc } from "loro-crdt";
2346
- *
2347
- * const doc = new LoroDoc();
2348
- * const map = doc.getMap("map");
2349
- * map.set("key", 1);
2350
- * console.log(doc.getByPath("map/key")); // 1
2351
- * console.log(doc.getByPath("map")); // LoroMap
2352
- * ```
2353
- * @param {string} path
2354
- * @returns {Value | Container | undefined}
2355
- */
2380
+ /**
2381
+ * Get the value or container at the given path
2382
+ *
2383
+ * The path can be specified in different ways depending on the container type:
2384
+ *
2385
+ * For Tree:
2386
+ * 1. Using node IDs: `tree/{node_id}/property`
2387
+ * 2. Using indices: `tree/0/1/property`
2388
+ *
2389
+ * For List and MovableList:
2390
+ * - Using indices: `list/0` or `list/1/property`
2391
+ *
2392
+ * For Map:
2393
+ * - Using keys: `map/key` or `map/nested/property`
2394
+ *
2395
+ * For tree structures, index-based paths follow depth-first traversal order.
2396
+ * The indices start from 0 and represent the position of a node among its siblings.
2397
+ *
2398
+ * @example
2399
+ * ```ts
2400
+ * import { LoroDoc } from "loro-crdt";
2401
+ *
2402
+ * const doc = new LoroDoc();
2403
+ * const map = doc.getMap("map");
2404
+ * map.set("key", 1);
2405
+ * console.log(doc.getByPath("map/key")); // 1
2406
+ * console.log(doc.getByPath("map")); // LoroMap
2407
+ * ```
2408
+ */
2356
2409
  getByPath(path: string): Value | Container | undefined;
2357
- /**
2358
- * Get the absolute position of the given Cursor
2359
- *
2360
- * @example
2361
- * ```ts
2362
- * const doc = new LoroDoc();
2363
- * const text = doc.getText("text");
2364
- * text.insert(0, "123");
2365
- * const pos0 = text.getCursor(0, 0);
2366
- * {
2367
- * const ans = doc.getCursorPos(pos0!);
2368
- * expect(ans.offset).toBe(0);
2369
- * }
2370
- * text.insert(0, "1");
2371
- * {
2372
- * const ans = doc.getCursorPos(pos0!);
2373
- * expect(ans.offset).toBe(1);
2374
- * }
2375
- * ```
2376
- * @param {Cursor} cursor
2377
- * @returns {{ update?: Cursor, offset: number, side: Side }}
2378
- */
2410
+ /**
2411
+ * Get the absolute position of the given Cursor
2412
+ *
2413
+ * @example
2414
+ * ```ts
2415
+ * const doc = new LoroDoc();
2416
+ * const text = doc.getText("text");
2417
+ * text.insert(0, "123");
2418
+ * const pos0 = text.getCursor(0, 0);
2419
+ * {
2420
+ * const ans = doc.getCursorPos(pos0!);
2421
+ * expect(ans.offset).toBe(0);
2422
+ * }
2423
+ * text.insert(0, "1");
2424
+ * {
2425
+ * const ans = doc.getCursorPos(pos0!);
2426
+ * expect(ans.offset).toBe(1);
2427
+ * }
2428
+ * ```
2429
+ */
2379
2430
  getCursorPos(cursor: Cursor): { update?: Cursor, offset: number, side: Side };
2380
- /**
2381
- * Gets container IDs modified in the given ID range.
2382
- *
2383
- * **NOTE:** This method will implicitly commit.
2384
- *
2385
- * This method identifies which containers were affected by changes in a given range of operations.
2386
- * It can be used together with `doc.travelChangeAncestors()` to analyze the history of changes
2387
- * and determine which containers were modified by each change.
2388
- *
2389
- * @param id - The starting ID of the change range
2390
- * @param len - The length of the change range to check
2391
- * @returns An array of container IDs that were modified in the given range
2392
- * @param {{ peer: PeerID, counter: number }} id
2393
- * @param {number} len
2394
- * @returns {(ContainerID)[]}
2395
- */
2396
- getChangedContainersIn(id: { peer: PeerID, counter: number }, len: number): (ContainerID)[];
2397
- /**
2398
- * Revert the document to the given frontiers.
2399
- *
2400
- * The doc will not become detached when using this method. Instead, it will generate a series
2401
- * of operations to revert the document to the given version.
2402
- *
2403
- * @example
2404
- * ```ts
2405
- * const doc = new LoroDoc();
2406
- * doc.setPeerId("1");
2407
- * const text = doc.getText("text");
2408
- * text.insert(0, "Hello");
2409
- * doc.commit();
2410
- * doc.revertTo([{ peer: "1", counter: 1 }]);
2411
- * expect(doc.getText("text").toString()).toBe("He");
2412
- * ```
2413
- * @param {({ peer: PeerID, counter: number })[]} frontiers
2414
- */
2431
+ /**
2432
+ * Gets container IDs modified in the given ID range.
2433
+ *
2434
+ * **NOTE:** This method will implicitly commit.
2435
+ *
2436
+ * This method identifies which containers were affected by changes in a given range of operations.
2437
+ * It can be used together with `doc.travelChangeAncestors()` to analyze the history of changes
2438
+ * and determine which containers were modified by each change.
2439
+ *
2440
+ * @param id - The starting ID of the change range
2441
+ * @param len - The length of the change range to check
2442
+ * @returns An array of container IDs that were modified in the given range
2443
+ */
2444
+ getChangedContainersIn(id: { peer: PeerID, counter: number }, len: number): ContainerID[];
2445
+ /**
2446
+ * Revert the document to the given frontiers.
2447
+ *
2448
+ * The doc will not become detached when using this method. Instead, it will generate a series
2449
+ * of operations to revert the document to the given version.
2450
+ *
2451
+ * @example
2452
+ * ```ts
2453
+ * const doc = new LoroDoc();
2454
+ * doc.setPeerId("1");
2455
+ * const text = doc.getText("text");
2456
+ * text.insert(0, "Hello");
2457
+ * doc.commit();
2458
+ * doc.revertTo([{ peer: "1", counter: 1 }]);
2459
+ * expect(doc.getText("text").toString()).toBe("He");
2460
+ * ```
2461
+ */
2415
2462
  revertTo(frontiers: ({ peer: PeerID, counter: number })[]): void;
2416
- /**
2417
- * Apply a batch of diff to the document
2418
- *
2419
- * A diff batch represents a set of changes between two versions of the document.
2420
- * You can calculate a diff batch using `doc.diff()`.
2421
- *
2422
- * Changes are associated with container IDs. During diff application, if new containers were created in the source
2423
- * document, they will be assigned fresh IDs in the target document. Loro automatically handles remapping these
2424
- * container IDs from their original IDs to the new IDs as the diff is applied.
2425
- *
2426
- * @example
2427
- * ```ts
2428
- * const doc1 = new LoroDoc();
2429
- * const doc2 = new LoroDoc();
2430
- *
2431
- * // Make some changes to doc1
2432
- * const text = doc1.getText("text");
2433
- * text.insert(0, "Hello");
2434
- *
2435
- * // Calculate diff between empty and current state
2436
- * const diff = doc1.diff([], doc1.frontiers());
2437
- *
2438
- * // Apply changes to doc2
2439
- * doc2.applyDiff(diff);
2440
- * console.log(doc2.getText("text").toString()); // "Hello"
2441
- * ```
2442
- * @param {[ContainerID, Diff|JsonDiff][]} diff
2443
- */
2463
+ /**
2464
+ * Apply a batch of diff to the document
2465
+ *
2466
+ * A diff batch represents a set of changes between two versions of the document.
2467
+ * You can calculate a diff batch using `doc.diff()`.
2468
+ *
2469
+ * Changes are associated with container IDs. During diff application, if new containers were created in the source
2470
+ * document, they will be assigned fresh IDs in the target document. Loro automatically handles remapping these
2471
+ * container IDs from their original IDs to the new IDs as the diff is applied.
2472
+ *
2473
+ * @example
2474
+ * ```ts
2475
+ * const doc1 = new LoroDoc();
2476
+ * const doc2 = new LoroDoc();
2477
+ *
2478
+ * // Make some changes to doc1
2479
+ * const text = doc1.getText("text");
2480
+ * text.insert(0, "Hello");
2481
+ *
2482
+ * // Calculate diff between empty and current state
2483
+ * const diff = doc1.diff([], doc1.frontiers());
2484
+ *
2485
+ * // Apply changes to doc2
2486
+ * doc2.applyDiff(diff);
2487
+ * console.log(doc2.getText("text").toString()); // "Hello"
2488
+ * ```
2489
+ */
2444
2490
  applyDiff(diff: [ContainerID, Diff|JsonDiff][]): void;
2445
- /**
2446
- * Peer ID of the current writer.
2447
- */
2491
+ /**
2492
+ * Get the pending operations from the current transaction in JSON format
2493
+ *
2494
+ * This method returns a JSON representation of operations that have been applied
2495
+ * but not yet committed in the current transaction.
2496
+ *
2497
+ * It will use the same data format as `doc.exportJsonUpdates()`
2498
+ *
2499
+ * @example
2500
+ * ```ts
2501
+ * const doc = new LoroDoc();
2502
+ * const text = doc.getText("text");
2503
+ * text.insert(0, "Hello");
2504
+ * // Get pending ops before commit
2505
+ * const pendingOps = doc.getPendingOpsFromCurrentTxnAsJson();
2506
+ * doc.commit();
2507
+ * const emptyOps = doc.getPendingOpsFromCurrentTxnAsJson(); // this is undefined
2508
+ * ```
2509
+ */
2510
+ getUncommittedOpsAsJson(): JsonSchema | undefined;
2511
+ /**
2512
+ * Peer ID of the current writer.
2513
+ */
2448
2514
  readonly peerId: bigint;
2449
- /**
2450
- * Get peer id in decimal string.
2451
- */
2515
+ /**
2516
+ * Get peer id in decimal string.
2517
+ */
2452
2518
  readonly peerIdStr: PeerID;
2453
2519
  }
2454
2520
  /**
2455
- * The handler of a list container.
2456
- *
2457
- * Learn more at https://loro.dev/docs/tutorial/list
2458
- */
2521
+ * The handler of a list container.
2522
+ *
2523
+ * Learn more at https://loro.dev/docs/tutorial/list
2524
+ */
2459
2525
  export class LoroList {
2460
2526
  free(): void;
2461
- /**
2462
- * Create a new detached LoroList (not attached to any LoroDoc).
2463
- *
2464
- * The edits on a detached container will not be persisted.
2465
- * To attach the container to the document, please insert it into an attached container.
2466
- */
2527
+ /**
2528
+ * Create a new detached LoroList (not attached to any LoroDoc).
2529
+ *
2530
+ * The edits on a detached container will not be persisted.
2531
+ * To attach the container to the document, please insert it into an attached container.
2532
+ */
2467
2533
  constructor();
2468
- /**
2469
- * "List"
2470
- * @returns {'List'}
2471
- */
2534
+ /**
2535
+ * "List"
2536
+ */
2472
2537
  kind(): 'List';
2473
- /**
2474
- * Delete elements from index to index + len.
2475
- *
2476
- * @example
2477
- * ```ts
2478
- * import { LoroDoc } from "loro-crdt";
2479
- *
2480
- * const doc = new LoroDoc();
2481
- * const list = doc.getList("list");
2482
- * list.insert(0, 100);
2483
- * list.delete(0, 1);
2484
- * console.log(list.value); // []
2485
- * ```
2486
- * @param {number} index
2487
- * @param {number} len
2488
- */
2538
+ /**
2539
+ * Delete elements from index to index + len.
2540
+ *
2541
+ * @example
2542
+ * ```ts
2543
+ * import { LoroDoc } from "loro-crdt";
2544
+ *
2545
+ * const doc = new LoroDoc();
2546
+ * const list = doc.getList("list");
2547
+ * list.insert(0, 100);
2548
+ * list.delete(0, 1);
2549
+ * console.log(list.value); // []
2550
+ * ```
2551
+ */
2489
2552
  delete(index: number, len: number): void;
2490
- /**
2491
- * Get elements of the list. If the type of a element is a container, it will be
2492
- * resolved recursively.
2493
- *
2494
- * @example
2495
- * ```ts
2496
- * import { LoroDoc, LoroText } from "loro-crdt";
2497
- *
2498
- * const doc = new LoroDoc();
2499
- * const list = doc.getList("list");
2500
- * list.insert(0, 100);
2501
- * const text = list.insertContainer(1, new LoroText());
2502
- * text.insert(0, "Hello");
2503
- * console.log(list.toJSON()); // [100, "Hello"];
2504
- * ```
2505
- * @returns {any}
2506
- */
2553
+ /**
2554
+ * Get elements of the list. If the type of a element is a container, it will be
2555
+ * resolved recursively.
2556
+ *
2557
+ * @example
2558
+ * ```ts
2559
+ * import { LoroDoc, LoroText } from "loro-crdt";
2560
+ *
2561
+ * const doc = new LoroDoc();
2562
+ * const list = doc.getList("list");
2563
+ * list.insert(0, 100);
2564
+ * const text = list.insertContainer(1, new LoroText());
2565
+ * text.insert(0, "Hello");
2566
+ * console.log(list.toJSON()); // [100, "Hello"];
2567
+ * ```
2568
+ */
2507
2569
  toJSON(): any;
2508
- /**
2509
- * Get the parent container.
2510
- *
2511
- * - The parent container of the root tree is `undefined`.
2512
- * - The object returned is a new js object each time because it need to cross
2513
- * the WASM boundary.
2514
- * @returns {Container | undefined}
2515
- */
2570
+ /**
2571
+ * Get the parent container.
2572
+ *
2573
+ * - The parent container of the root tree is `undefined`.
2574
+ * - The object returned is a new js object each time because it need to cross
2575
+ * the WASM boundary.
2576
+ */
2516
2577
  parent(): Container | undefined;
2517
- /**
2518
- * Whether the container is attached to a document.
2519
- *
2520
- * If it's detached, the operations on the container will not be persisted.
2521
- * @returns {boolean}
2522
- */
2578
+ /**
2579
+ * Whether the container is attached to a document.
2580
+ *
2581
+ * If it's detached, the operations on the container will not be persisted.
2582
+ */
2523
2583
  isAttached(): boolean;
2524
- /**
2525
- * Get the attached container associated with this.
2526
- *
2527
- * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2528
- * @returns {LoroList | undefined}
2529
- */
2584
+ /**
2585
+ * Get the attached container associated with this.
2586
+ *
2587
+ * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2588
+ */
2530
2589
  getAttached(): LoroList | undefined;
2531
- /**
2532
- * Pop a value from the end of the list.
2533
- * @returns {Value | undefined}
2534
- */
2590
+ /**
2591
+ * Pop a value from the end of the list.
2592
+ */
2535
2593
  pop(): Value | undefined;
2536
- /**
2537
- * Delete all elements in the list.
2538
- */
2594
+ /**
2595
+ * Delete all elements in the list.
2596
+ */
2539
2597
  clear(): void;
2540
- /**
2541
- * @param {number} pos
2542
- * @returns {{ peer: PeerID, counter: number } | undefined}
2543
- */
2544
2598
  getIdAt(pos: number): { peer: PeerID, counter: number } | undefined;
2545
- /**
2546
- * Check if the container is deleted
2547
- * @returns {boolean}
2548
- */
2599
+ /**
2600
+ * Check if the container is deleted
2601
+ */
2549
2602
  isDeleted(): boolean;
2550
- /**
2551
- * Get the shallow value of the list.
2552
- *
2553
- * Unlike `toJSON()` which recursively resolves all containers to their values,
2554
- * `getShallowValue()` returns container IDs as strings for any nested containers.
2555
- *
2556
- * ```js
2557
- * const doc = new LoroDoc();
2558
- * doc.setPeerId("1");
2559
- * const list = doc.getList("list");
2560
- * list.insert(0, 1);
2561
- * list.insert(1, "two");
2562
- * const subList = list.insertContainer(2, new LoroList());
2563
- * subList.insert(0, "sub");
2564
- * list.getShallowValue(); // [1, "two", "cid:2@1:List"]
2565
- * list.toJSON(); // [1, "two", ["sub"]]
2566
- * ```
2567
- * @returns {Value[]}
2568
- */
2603
+ /**
2604
+ * Get the shallow value of the list.
2605
+ *
2606
+ * Unlike `toJSON()` which recursively resolves all containers to their values,
2607
+ * `getShallowValue()` returns container IDs as strings for any nested containers.
2608
+ *
2609
+ * ```js
2610
+ * const doc = new LoroDoc();
2611
+ * doc.setPeerId("1");
2612
+ * const list = doc.getList("list");
2613
+ * list.insert(0, 1);
2614
+ * list.insert(1, "two");
2615
+ * const subList = list.insertContainer(2, new LoroList());
2616
+ * subList.insert(0, "sub");
2617
+ * list.getShallowValue(); // [1, "two", "cid:2@1:List"]
2618
+ * list.toJSON(); // [1, "two", ["sub"]]
2619
+ * ```
2620
+ */
2569
2621
  getShallowValue(): Value[];
2570
- /**
2571
- * Get the id of this container.
2572
- */
2622
+ /**
2623
+ * Get the id of this container.
2624
+ */
2573
2625
  readonly id: ContainerID;
2574
- /**
2575
- * Get the length of list.
2576
- *
2577
- * @example
2578
- * ```ts
2579
- * import { LoroDoc } from "loro-crdt";
2580
- *
2581
- * const doc = new LoroDoc();
2582
- * const list = doc.getList("list");
2583
- * list.insert(0, 100);
2584
- * list.insert(1, "foo");
2585
- * list.insert(2, true);
2586
- * console.log(list.length); // 3
2587
- * ```
2588
- */
2626
+ /**
2627
+ * Get the length of list.
2628
+ *
2629
+ * @example
2630
+ * ```ts
2631
+ * import { LoroDoc } from "loro-crdt";
2632
+ *
2633
+ * const doc = new LoroDoc();
2634
+ * const list = doc.getList("list");
2635
+ * list.insert(0, 100);
2636
+ * list.insert(1, "foo");
2637
+ * list.insert(2, true);
2638
+ * console.log(list.length); // 3
2639
+ * ```
2640
+ */
2589
2641
  readonly length: number;
2590
2642
  }
2591
2643
  /**
2592
- * The handler of a map container.
2593
- *
2594
- * Learn more at https://loro.dev/docs/tutorial/map
2595
- */
2644
+ * The handler of a map container.
2645
+ *
2646
+ * Learn more at https://loro.dev/docs/tutorial/map
2647
+ */
2596
2648
  export class LoroMap {
2597
2649
  free(): void;
2598
- /**
2599
- * Create a new detached LoroMap (not attached to any LoroDoc).
2600
- *
2601
- * The edits on a detached container will not be persisted.
2602
- * To attach the container to the document, please insert it into an attached container.
2603
- */
2650
+ /**
2651
+ * Create a new detached LoroMap (not attached to any LoroDoc).
2652
+ *
2653
+ * The edits on a detached container will not be persisted.
2654
+ * To attach the container to the document, please insert it into an attached container.
2655
+ */
2604
2656
  constructor();
2605
- /**
2606
- * "Map"
2607
- * @returns {'Map'}
2608
- */
2657
+ /**
2658
+ * "Map"
2659
+ */
2609
2660
  kind(): 'Map';
2610
- /**
2611
- * Remove the key from the map.
2612
- *
2613
- * @example
2614
- * ```ts
2615
- * import { LoroDoc } from "loro-crdt";
2616
- *
2617
- * const doc = new LoroDoc();
2618
- * const map = doc.getMap("map");
2619
- * map.set("foo", "bar");
2620
- * map.delete("foo");
2621
- * ```
2622
- * @param {string} key
2623
- */
2661
+ /**
2662
+ * Remove the key from the map.
2663
+ *
2664
+ * @example
2665
+ * ```ts
2666
+ * import { LoroDoc } from "loro-crdt";
2667
+ *
2668
+ * const doc = new LoroDoc();
2669
+ * const map = doc.getMap("map");
2670
+ * map.set("foo", "bar");
2671
+ * map.delete("foo");
2672
+ * ```
2673
+ */
2624
2674
  delete(key: string): void;
2625
- /**
2626
- * Get the keys of the map.
2627
- *
2628
- * @example
2629
- * ```ts
2630
- * import { LoroDoc } from "loro-crdt";
2631
- *
2632
- * const doc = new LoroDoc();
2633
- * const map = doc.getMap("map");
2634
- * map.set("foo", "bar");
2635
- * map.set("baz", "bar");
2636
- * const keys = map.keys(); // ["foo", "baz"]
2637
- * ```
2638
- * @returns {any[]}
2639
- */
2675
+ /**
2676
+ * Get the keys of the map.
2677
+ *
2678
+ * @example
2679
+ * ```ts
2680
+ * import { LoroDoc } from "loro-crdt";
2681
+ *
2682
+ * const doc = new LoroDoc();
2683
+ * const map = doc.getMap("map");
2684
+ * map.set("foo", "bar");
2685
+ * map.set("baz", "bar");
2686
+ * const keys = map.keys(); // ["foo", "baz"]
2687
+ * ```
2688
+ */
2640
2689
  keys(): any[];
2641
- /**
2642
- * Get the values of the map. If the value is a child container, the corresponding
2643
- * `Container` will be returned.
2644
- *
2645
- * @example
2646
- * ```ts
2647
- * import { LoroDoc } from "loro-crdt";
2648
- *
2649
- * const doc = new LoroDoc();
2650
- * const map = doc.getMap("map");
2651
- * map.set("foo", "bar");
2652
- * map.set("baz", "bar");
2653
- * const values = map.values(); // ["bar", "bar"]
2654
- * ```
2655
- * @returns {any[]}
2656
- */
2690
+ /**
2691
+ * Get the values of the map. If the value is a child container, the corresponding
2692
+ * `Container` will be returned.
2693
+ *
2694
+ * @example
2695
+ * ```ts
2696
+ * import { LoroDoc } from "loro-crdt";
2697
+ *
2698
+ * const doc = new LoroDoc();
2699
+ * const map = doc.getMap("map");
2700
+ * map.set("foo", "bar");
2701
+ * map.set("baz", "bar");
2702
+ * const values = map.values(); // ["bar", "bar"]
2703
+ * ```
2704
+ */
2657
2705
  values(): any[];
2658
- /**
2659
- * Get the entries of the map. If the value is a child container, the corresponding
2660
- * `Container` will be returned.
2661
- *
2662
- * @example
2663
- * ```ts
2664
- * import { LoroDoc } from "loro-crdt";
2665
- *
2666
- * const doc = new LoroDoc();
2667
- * const map = doc.getMap("map");
2668
- * map.set("foo", "bar");
2669
- * map.set("baz", "bar");
2670
- * const entries = map.entries(); // [["foo", "bar"], ["baz", "bar"]]
2671
- * ```
2672
- * @returns {([string, Value | Container])[]}
2673
- */
2706
+ /**
2707
+ * Get the entries of the map. If the value is a child container, the corresponding
2708
+ * `Container` will be returned.
2709
+ *
2710
+ * @example
2711
+ * ```ts
2712
+ * import { LoroDoc } from "loro-crdt";
2713
+ *
2714
+ * const doc = new LoroDoc();
2715
+ * const map = doc.getMap("map");
2716
+ * map.set("foo", "bar");
2717
+ * map.set("baz", "bar");
2718
+ * const entries = map.entries(); // [["foo", "bar"], ["baz", "bar"]]
2719
+ * ```
2720
+ */
2674
2721
  entries(): ([string, Value | Container])[];
2675
- /**
2676
- * Get the keys and the values. If the type of value is a child container,
2677
- * it will be resolved recursively.
2678
- *
2679
- * @example
2680
- * ```ts
2681
- * import { LoroDoc, LoroText } from "loro-crdt";
2682
- *
2683
- * const doc = new LoroDoc();
2684
- * const map = doc.getMap("map");
2685
- * map.set("foo", "bar");
2686
- * const text = map.setContainer("text", new LoroText());
2687
- * text.insert(0, "Hello");
2688
- * console.log(map.toJSON()); // {"foo": "bar", "text": "Hello"}
2689
- * ```
2690
- * @returns {any}
2691
- */
2722
+ /**
2723
+ * Get the keys and the values. If the type of value is a child container,
2724
+ * it will be resolved recursively.
2725
+ *
2726
+ * @example
2727
+ * ```ts
2728
+ * import { LoroDoc, LoroText } from "loro-crdt";
2729
+ *
2730
+ * const doc = new LoroDoc();
2731
+ * const map = doc.getMap("map");
2732
+ * map.set("foo", "bar");
2733
+ * const text = map.setContainer("text", new LoroText());
2734
+ * text.insert(0, "Hello");
2735
+ * console.log(map.toJSON()); // {"foo": "bar", "text": "Hello"}
2736
+ * ```
2737
+ */
2692
2738
  toJSON(): any;
2693
- /**
2694
- * Get the parent container.
2695
- *
2696
- * - The parent container of the root tree is `undefined`.
2697
- * - The object returned is a new js object each time because it need to cross
2698
- * the WASM boundary.
2699
- * @returns {Container | undefined}
2700
- */
2739
+ /**
2740
+ * Get the parent container.
2741
+ *
2742
+ * - The parent container of the root tree is `undefined`.
2743
+ * - The object returned is a new js object each time because it need to cross
2744
+ * the WASM boundary.
2745
+ */
2701
2746
  parent(): Container | undefined;
2702
- /**
2703
- * Whether the container is attached to a document.
2704
- *
2705
- * If it's detached, the operations on the container will not be persisted.
2706
- * @returns {boolean}
2707
- */
2747
+ /**
2748
+ * Whether the container is attached to a document.
2749
+ *
2750
+ * If it's detached, the operations on the container will not be persisted.
2751
+ */
2708
2752
  isAttached(): boolean;
2709
- /**
2710
- * Get the attached container associated with this.
2711
- *
2712
- * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2713
- * @returns {LoroMap | undefined}
2714
- */
2753
+ /**
2754
+ * Get the attached container associated with this.
2755
+ *
2756
+ * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2757
+ */
2715
2758
  getAttached(): LoroMap | undefined;
2716
- /**
2717
- * Delete all key-value pairs in the map.
2718
- */
2759
+ /**
2760
+ * Delete all key-value pairs in the map.
2761
+ */
2719
2762
  clear(): void;
2720
- /**
2721
- * Get the peer id of the last editor on the given entry
2722
- * @param {string} key
2723
- * @returns {PeerID | undefined}
2724
- */
2763
+ /**
2764
+ * Get the peer id of the last editor on the given entry
2765
+ */
2725
2766
  getLastEditor(key: string): PeerID | undefined;
2726
- /**
2727
- * Check if the container is deleted
2728
- * @returns {boolean}
2729
- */
2767
+ /**
2768
+ * Check if the container is deleted
2769
+ */
2730
2770
  isDeleted(): boolean;
2731
- /**
2732
- * Get the shallow value of the map.
2733
- *
2734
- * Unlike `toJSON()` which recursively resolves all containers to their values,
2735
- * `getShallowValue()` returns container IDs as strings for any nested containers.
2736
- *
2737
- * @example
2738
- * ```ts
2739
- * import { LoroDoc, LoroText } from "loro-crdt";
2740
- *
2741
- * const doc = new LoroDoc();
2742
- * doc.setPeerId("1");
2743
- * const map = doc.getMap("map");
2744
- * map.set("key", "value");
2745
- * const subText = map.setContainer("text", new LoroText());
2746
- * subText.insert(0, "Hello");
2747
- *
2748
- * // Get shallow value - nested containers are represented by their IDs
2749
- * console.log(map.getShallowValue());
2750
- * // Output: { key: "value", text: "cid:1@1:Text" }
2751
- *
2752
- * // Get full value with nested containers resolved by `toJSON()`
2753
- * console.log(map.toJSON());
2754
- * // Output: { key: "value", text: "Hello" }
2755
- * ```
2756
- * @returns {Record<string, Value>}
2757
- */
2771
+ /**
2772
+ * Get the shallow value of the map.
2773
+ *
2774
+ * Unlike `toJSON()` which recursively resolves all containers to their values,
2775
+ * `getShallowValue()` returns container IDs as strings for any nested containers.
2776
+ *
2777
+ * @example
2778
+ * ```ts
2779
+ * import { LoroDoc, LoroText } from "loro-crdt";
2780
+ *
2781
+ * const doc = new LoroDoc();
2782
+ * doc.setPeerId("1");
2783
+ * const map = doc.getMap("map");
2784
+ * map.set("key", "value");
2785
+ * const subText = map.setContainer("text", new LoroText());
2786
+ * subText.insert(0, "Hello");
2787
+ *
2788
+ * // Get shallow value - nested containers are represented by their IDs
2789
+ * console.log(map.getShallowValue());
2790
+ * // Output: { key: "value", text: "cid:1@1:Text" }
2791
+ *
2792
+ * // Get full value with nested containers resolved by `toJSON()`
2793
+ * console.log(map.toJSON());
2794
+ * // Output: { key: "value", text: "Hello" }
2795
+ * ```
2796
+ */
2758
2797
  getShallowValue(): Record<string, Value>;
2759
- /**
2760
- * The container id of this handler.
2761
- */
2798
+ /**
2799
+ * The container id of this handler.
2800
+ */
2762
2801
  readonly id: ContainerID;
2763
- /**
2764
- * Get the size of the map.
2765
- *
2766
- * @example
2767
- * ```ts
2768
- * import { LoroDoc } from "loro-crdt";
2769
- *
2770
- * const doc = new LoroDoc();
2771
- * const map = doc.getMap("map");
2772
- * map.set("foo", "bar");
2773
- * console.log(map.size); // 1
2774
- * ```
2775
- */
2802
+ /**
2803
+ * Get the size of the map.
2804
+ *
2805
+ * @example
2806
+ * ```ts
2807
+ * import { LoroDoc } from "loro-crdt";
2808
+ *
2809
+ * const doc = new LoroDoc();
2810
+ * const map = doc.getMap("map");
2811
+ * map.set("foo", "bar");
2812
+ * console.log(map.size); // 1
2813
+ * ```
2814
+ */
2776
2815
  readonly size: number;
2777
2816
  }
2778
2817
  /**
2779
- * The handler of a list container.
2780
- *
2781
- * Learn more at https://loro.dev/docs/tutorial/list
2782
- */
2818
+ * The handler of a list container.
2819
+ *
2820
+ * Learn more at https://loro.dev/docs/tutorial/list
2821
+ */
2783
2822
  export class LoroMovableList {
2784
2823
  free(): void;
2785
- /**
2786
- * Create a new detached LoroMovableList (not attached to any LoroDoc).
2787
- *
2788
- * The edits on a detached container will not be persisted.
2789
- * To attach the container to the document, please insert it into an attached container.
2790
- */
2824
+ /**
2825
+ * Create a new detached LoroMovableList (not attached to any LoroDoc).
2826
+ *
2827
+ * The edits on a detached container will not be persisted.
2828
+ * To attach the container to the document, please insert it into an attached container.
2829
+ */
2791
2830
  constructor();
2792
- /**
2793
- * "MovableList"
2794
- * @returns {'MovableList'}
2795
- */
2831
+ /**
2832
+ * "MovableList"
2833
+ */
2796
2834
  kind(): 'MovableList';
2797
- /**
2798
- * Delete elements from index to index + len.
2799
- *
2800
- * @example
2801
- * ```ts
2802
- * import { LoroDoc } from "loro-crdt";
2803
- *
2804
- * const doc = new LoroDoc();
2805
- * const list = doc.getList("list");
2806
- * list.insert(0, 100);
2807
- * list.delete(0, 1);
2808
- * console.log(list.value); // []
2809
- * ```
2810
- * @param {number} index
2811
- * @param {number} len
2812
- */
2835
+ /**
2836
+ * Delete elements from index to index + len.
2837
+ *
2838
+ * @example
2839
+ * ```ts
2840
+ * import { LoroDoc } from "loro-crdt";
2841
+ *
2842
+ * const doc = new LoroDoc();
2843
+ * const list = doc.getList("list");
2844
+ * list.insert(0, 100);
2845
+ * list.delete(0, 1);
2846
+ * console.log(list.value); // []
2847
+ * ```
2848
+ */
2813
2849
  delete(index: number, len: number): void;
2814
- /**
2815
- * Get elements of the list. If the type of a element is a container, it will be
2816
- * resolved recursively.
2817
- *
2818
- * @example
2819
- * ```ts
2820
- * import { LoroDoc, LoroText } from "loro-crdt";
2821
- *
2822
- * const doc = new LoroDoc();
2823
- * const list = doc.getList("list");
2824
- * list.insert(0, 100);
2825
- * const text = list.insertContainer(1, new LoroText());
2826
- * text.insert(0, "Hello");
2827
- * console.log(list.toJSON()); // [100, "Hello"];
2828
- * ```
2829
- * @returns {any}
2830
- */
2850
+ /**
2851
+ * Get elements of the list. If the type of a element is a container, it will be
2852
+ * resolved recursively.
2853
+ *
2854
+ * @example
2855
+ * ```ts
2856
+ * import { LoroDoc, LoroText } from "loro-crdt";
2857
+ *
2858
+ * const doc = new LoroDoc();
2859
+ * const list = doc.getList("list");
2860
+ * list.insert(0, 100);
2861
+ * const text = list.insertContainer(1, new LoroText());
2862
+ * text.insert(0, "Hello");
2863
+ * console.log(list.toJSON()); // [100, "Hello"];
2864
+ * ```
2865
+ */
2831
2866
  toJSON(): any;
2832
- /**
2833
- * Get the parent container.
2834
- *
2835
- * - The parent container of the root tree is `undefined`.
2836
- * - The object returned is a new js object each time because it need to cross
2837
- * the WASM boundary.
2838
- * @returns {Container | undefined}
2839
- */
2867
+ /**
2868
+ * Get the parent container.
2869
+ *
2870
+ * - The parent container of the root tree is `undefined`.
2871
+ * - The object returned is a new js object each time because it need to cross
2872
+ * the WASM boundary.
2873
+ */
2840
2874
  parent(): Container | undefined;
2841
- /**
2842
- * Whether the container is attached to a document.
2843
- *
2844
- * If it's detached, the operations on the container will not be persisted.
2845
- * @returns {boolean}
2846
- */
2875
+ /**
2876
+ * Whether the container is attached to a document.
2877
+ *
2878
+ * If it's detached, the operations on the container will not be persisted.
2879
+ */
2847
2880
  isAttached(): boolean;
2848
- /**
2849
- * Get the attached container associated with this.
2850
- *
2851
- * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2852
- * @returns {LoroList | undefined}
2853
- */
2881
+ /**
2882
+ * Get the attached container associated with this.
2883
+ *
2884
+ * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
2885
+ */
2854
2886
  getAttached(): LoroList | undefined;
2855
- /**
2856
- * Move the element from `from` to `to`.
2857
- *
2858
- * The new position of the element will be `to`.
2859
- * Move the element from `from` to `to`.
2860
- *
2861
- * The new position of the element will be `to`. This method is optimized to prevent redundant
2862
- * operations that might occur with a naive remove and insert approach. Specifically, it avoids
2863
- * creating surplus values in the list, unlike a delete followed by an insert, which can lead to
2864
- * additional values in cases of concurrent edits. This ensures more efficient and accurate
2865
- * operations in a MovableList.
2866
- * @param {number} from
2867
- * @param {number} to
2868
- */
2887
+ /**
2888
+ * Move the element from `from` to `to`.
2889
+ *
2890
+ * The new position of the element will be `to`.
2891
+ * Move the element from `from` to `to`.
2892
+ *
2893
+ * The new position of the element will be `to`. This method is optimized to prevent redundant
2894
+ * operations that might occur with a naive remove and insert approach. Specifically, it avoids
2895
+ * creating surplus values in the list, unlike a delete followed by an insert, which can lead to
2896
+ * additional values in cases of concurrent edits. This ensures more efficient and accurate
2897
+ * operations in a MovableList.
2898
+ */
2869
2899
  move(from: number, to: number): void;
2870
- /**
2871
- * Pop a value from the end of the list.
2872
- * @returns {Value | undefined}
2873
- */
2900
+ /**
2901
+ * Pop a value from the end of the list.
2902
+ */
2874
2903
  pop(): Value | undefined;
2875
- /**
2876
- * Delete all elements in the list.
2877
- */
2904
+ /**
2905
+ * Delete all elements in the list.
2906
+ */
2878
2907
  clear(): void;
2879
- /**
2880
- * Get the creator of the list item at the given position.
2881
- * @param {number} pos
2882
- * @returns {PeerID | undefined}
2883
- */
2908
+ /**
2909
+ * Get the creator of the list item at the given position.
2910
+ */
2884
2911
  getCreatorAt(pos: number): PeerID | undefined;
2885
- /**
2886
- * Get the last mover of the list item at the given position.
2887
- * @param {number} pos
2888
- * @returns {PeerID | undefined}
2889
- */
2912
+ /**
2913
+ * Get the last mover of the list item at the given position.
2914
+ */
2890
2915
  getLastMoverAt(pos: number): PeerID | undefined;
2891
- /**
2892
- * Get the last editor of the list item at the given position.
2893
- * @param {number} pos
2894
- * @returns {PeerID | undefined}
2895
- */
2916
+ /**
2917
+ * Get the last editor of the list item at the given position.
2918
+ */
2896
2919
  getLastEditorAt(pos: number): PeerID | undefined;
2897
- /**
2898
- * Check if the container is deleted
2899
- * @returns {boolean}
2900
- */
2920
+ /**
2921
+ * Check if the container is deleted
2922
+ */
2901
2923
  isDeleted(): boolean;
2902
- /**
2903
- * Get the shallow value of the movable list.
2904
- *
2905
- * Unlike `toJSON()` which recursively resolves all containers to their values,
2906
- * `getShallowValue()` returns container IDs as strings for any nested containers.
2907
- *
2908
- * ```js
2909
- * const doc = new LoroDoc();
2910
- * doc.setPeerId("1");
2911
- * const list = doc.getMovableList("list");
2912
- * list.insert(0, 1);
2913
- * list.insert(1, "two");
2914
- * const subList = list.insertContainer(2, new LoroList());
2915
- * subList.insert(0, "sub");
2916
- * list.getShallowValue(); // [1, "two", "cid:2@1:List"]
2917
- * list.toJSON(); // [1, "two", ["sub"]]
2918
- * ```
2919
- * @returns {Value[]}
2920
- */
2924
+ /**
2925
+ * Get the shallow value of the movable list.
2926
+ *
2927
+ * Unlike `toJSON()` which recursively resolves all containers to their values,
2928
+ * `getShallowValue()` returns container IDs as strings for any nested containers.
2929
+ *
2930
+ * ```js
2931
+ * const doc = new LoroDoc();
2932
+ * doc.setPeerId("1");
2933
+ * const list = doc.getMovableList("list");
2934
+ * list.insert(0, 1);
2935
+ * list.insert(1, "two");
2936
+ * const subList = list.insertContainer(2, new LoroList());
2937
+ * subList.insert(0, "sub");
2938
+ * list.getShallowValue(); // [1, "two", "cid:2@1:List"]
2939
+ * list.toJSON(); // [1, "two", ["sub"]]
2940
+ * ```
2941
+ */
2921
2942
  getShallowValue(): Value[];
2922
- /**
2923
- * Get the id of this container.
2924
- */
2943
+ /**
2944
+ * Get the id of this container.
2945
+ */
2925
2946
  readonly id: ContainerID;
2926
- /**
2927
- * Get the length of list.
2928
- *
2929
- * @example
2930
- * ```ts
2931
- * import { LoroDoc } from "loro-crdt";
2932
- *
2933
- * const doc = new LoroDoc();
2934
- * const list = doc.getList("list");
2935
- * list.insert(0, 100);
2936
- * list.insert(1, "foo");
2937
- * list.insert(2, true);
2938
- * console.log(list.length); // 3
2939
- * ```
2940
- */
2947
+ /**
2948
+ * Get the length of list.
2949
+ *
2950
+ * @example
2951
+ * ```ts
2952
+ * import { LoroDoc } from "loro-crdt";
2953
+ *
2954
+ * const doc = new LoroDoc();
2955
+ * const list = doc.getList("list");
2956
+ * list.insert(0, 100);
2957
+ * list.insert(1, "foo");
2958
+ * list.insert(2, true);
2959
+ * console.log(list.length); // 3
2960
+ * ```
2961
+ */
2941
2962
  readonly length: number;
2942
2963
  }
2943
2964
  /**
2944
- * The handler of a text container. It supports rich text CRDT.
2945
- *
2946
- * Learn more at https://loro.dev/docs/tutorial/text
2947
- */
2965
+ * The handler of a text container. It supports rich text CRDT.
2966
+ *
2967
+ * Learn more at https://loro.dev/docs/tutorial/text
2968
+ */
2948
2969
  export class LoroText {
2949
2970
  free(): void;
2950
- /**
2951
- * Create a new detached LoroText (not attached to any LoroDoc).
2952
- *
2953
- * The edits on a detached container will not be persisted.
2954
- * To attach the container to the document, please insert it into an attached container.
2955
- */
2971
+ /**
2972
+ * Create a new detached LoroText (not attached to any LoroDoc).
2973
+ *
2974
+ * The edits on a detached container will not be persisted.
2975
+ * To attach the container to the document, please insert it into an attached container.
2976
+ */
2956
2977
  constructor();
2957
- /**
2958
- * "Text"
2959
- * @returns {'Text'}
2960
- */
2978
+ /**
2979
+ * "Text"
2980
+ */
2961
2981
  kind(): 'Text';
2962
- /**
2963
- * Iterate each text span(internal storage unit)
2964
- *
2965
- * The callback function will be called for each span in the text.
2966
- * If the callback returns `false`, the iteration will stop.
2967
- *
2968
- * Limitation: you cannot access or alter the doc state when iterating (this is for performance consideration).
2969
- * If you need to access or alter the doc state, please use `toString` instead.
2970
- *
2971
- * @example
2972
- * ```ts
2973
- * import { LoroDoc } from "loro-crdt";
2974
- *
2975
- * const doc = new LoroDoc();
2976
- * const text = doc.getText("text");
2977
- * text.insert(0, "Hello");
2978
- * text.iter((str) => (console.log(str), true));
2979
- * ```
2980
- * @param {(string) => boolean} callback
2981
- */
2982
+ /**
2983
+ * Iterate each text span(internal storage unit)
2984
+ *
2985
+ * The callback function will be called for each span in the text.
2986
+ * If the callback returns `false`, the iteration will stop.
2987
+ *
2988
+ * Limitation: you cannot access or alter the doc state when iterating (this is for performance consideration).
2989
+ * If you need to access or alter the doc state, please use `toString` instead.
2990
+ *
2991
+ * @example
2992
+ * ```ts
2993
+ * import { LoroDoc } from "loro-crdt";
2994
+ *
2995
+ * const doc = new LoroDoc();
2996
+ * const text = doc.getText("text");
2997
+ * text.insert(0, "Hello");
2998
+ * text.iter((str) => (console.log(str), true));
2999
+ * ```
3000
+ */
2982
3001
  iter(callback: (string) => boolean): void;
2983
- /**
2984
- * Insert the string at the given index (utf-16 index).
2985
- *
2986
- * @example
2987
- * ```ts
2988
- * import { LoroDoc } from "loro-crdt";
2989
- *
2990
- * const doc = new LoroDoc();
2991
- * const text = doc.getText("text");
2992
- * text.insert(0, "Hello");
2993
- * ```
2994
- * @param {number} index
2995
- * @param {string} content
2996
- */
3002
+ /**
3003
+ * Insert the string at the given index (utf-16 index).
3004
+ *
3005
+ * @example
3006
+ * ```ts
3007
+ * import { LoroDoc } from "loro-crdt";
3008
+ *
3009
+ * const doc = new LoroDoc();
3010
+ * const text = doc.getText("text");
3011
+ * text.insert(0, "Hello");
3012
+ * ```
3013
+ */
2997
3014
  insert(index: number, content: string): void;
2998
- /**
2999
- * Get a string slice (utf-16 index).
3000
- *
3001
- * @example
3002
- * ```ts
3003
- * import { LoroDoc } from "loro-crdt";
3004
- *
3005
- * const doc = new LoroDoc();
3006
- * const text = doc.getText("text");
3007
- * text.insert(0, "Hello");
3008
- * text.slice(0, 2); // "He"
3009
- * ```
3010
- * @param {number} start_index
3011
- * @param {number} end_index
3012
- * @returns {string}
3013
- */
3015
+ /**
3016
+ * Get a string slice (utf-16 index).
3017
+ *
3018
+ * @example
3019
+ * ```ts
3020
+ * import { LoroDoc } from "loro-crdt";
3021
+ *
3022
+ * const doc = new LoroDoc();
3023
+ * const text = doc.getText("text");
3024
+ * text.insert(0, "Hello");
3025
+ * text.slice(0, 2); // "He"
3026
+ * ```
3027
+ */
3014
3028
  slice(start_index: number, end_index: number): string;
3015
- /**
3016
- * Get the character at the given position (utf-16 index).
3017
- *
3018
- * @example
3019
- * ```ts
3020
- * import { LoroDoc } from "loro-crdt";
3021
- *
3022
- * const doc = new LoroDoc();
3023
- * const text = doc.getText("text");
3024
- * text.insert(0, "Hello");
3025
- * text.charAt(0); // "H"
3026
- * ```
3027
- * @param {number} pos
3028
- * @returns {string}
3029
- */
3029
+ /**
3030
+ * Get the character at the given position (utf-16 index).
3031
+ *
3032
+ * @example
3033
+ * ```ts
3034
+ * import { LoroDoc } from "loro-crdt";
3035
+ *
3036
+ * const doc = new LoroDoc();
3037
+ * const text = doc.getText("text");
3038
+ * text.insert(0, "Hello");
3039
+ * text.charAt(0); // "H"
3040
+ * ```
3041
+ */
3030
3042
  charAt(pos: number): string;
3031
- /**
3032
- * Delete and return the string at the given range and insert a string at the same position (utf-16 index).
3033
- *
3034
- * @example
3035
- * ```ts
3036
- * import { LoroDoc } from "loro-crdt";
3037
- *
3038
- * const doc = new LoroDoc();
3039
- * const text = doc.getText("text");
3040
- * text.insert(0, "Hello");
3041
- * text.splice(2, 3, "llo"); // "llo"
3042
- * ```
3043
- * @param {number} pos
3044
- * @param {number} len
3045
- * @param {string} s
3046
- * @returns {string}
3047
- */
3043
+ /**
3044
+ * Delete and return the string at the given range and insert a string at the same position (utf-16 index).
3045
+ *
3046
+ * @example
3047
+ * ```ts
3048
+ * import { LoroDoc } from "loro-crdt";
3049
+ *
3050
+ * const doc = new LoroDoc();
3051
+ * const text = doc.getText("text");
3052
+ * text.insert(0, "Hello");
3053
+ * text.splice(2, 3, "llo"); // "llo"
3054
+ * ```
3055
+ */
3048
3056
  splice(pos: number, len: number, s: string): string;
3049
- /**
3050
- * Insert some string at utf-8 index.
3051
- *
3052
- * @example
3053
- * ```ts
3054
- * import { LoroDoc } from "loro-crdt";
3055
- *
3056
- * const doc = new LoroDoc();
3057
- * const text = doc.getText("text");
3058
- * text.insertUtf8(0, "Hello");
3059
- * ```
3060
- * @param {number} index
3061
- * @param {string} content
3062
- */
3057
+ /**
3058
+ * Insert some string at utf-8 index.
3059
+ *
3060
+ * @example
3061
+ * ```ts
3062
+ * import { LoroDoc } from "loro-crdt";
3063
+ *
3064
+ * const doc = new LoroDoc();
3065
+ * const text = doc.getText("text");
3066
+ * text.insertUtf8(0, "Hello");
3067
+ * ```
3068
+ */
3063
3069
  insertUtf8(index: number, content: string): void;
3064
- /**
3065
- * Delete elements from index to index + len (utf-16 index).
3066
- *
3067
- * @example
3068
- * ```ts
3069
- * import { LoroDoc } from "loro-crdt";
3070
- *
3071
- * const doc = new LoroDoc();
3072
- * const text = doc.getText("text");
3073
- * text.insert(0, "Hello");
3074
- * text.delete(1, 3);
3075
- * const s = text.toString();
3076
- * console.log(s); // "Ho"
3077
- * ```
3078
- * @param {number} index
3079
- * @param {number} len
3080
- */
3070
+ /**
3071
+ * Delete elements from index to index + len (utf-16 index).
3072
+ *
3073
+ * @example
3074
+ * ```ts
3075
+ * import { LoroDoc } from "loro-crdt";
3076
+ *
3077
+ * const doc = new LoroDoc();
3078
+ * const text = doc.getText("text");
3079
+ * text.insert(0, "Hello");
3080
+ * text.delete(1, 3);
3081
+ * const s = text.toString();
3082
+ * console.log(s); // "Ho"
3083
+ * ```
3084
+ */
3081
3085
  delete(index: number, len: number): void;
3082
- /**
3083
- * Delete elements from index to utf-8 index + len
3084
- *
3085
- * @example
3086
- * ```ts
3087
- * import { LoroDoc } from "loro-crdt";
3088
- *
3089
- * const doc = new LoroDoc();
3090
- * const text = doc.getText("text");
3091
- * text.insertUtf8(0, "Hello");
3092
- * text.deleteUtf8(1, 3);
3093
- * const s = text.toString();
3094
- * console.log(s); // "Ho"
3095
- * ```
3096
- * @param {number} index
3097
- * @param {number} len
3098
- */
3086
+ /**
3087
+ * Delete elements from index to utf-8 index + len
3088
+ *
3089
+ * @example
3090
+ * ```ts
3091
+ * import { LoroDoc } from "loro-crdt";
3092
+ *
3093
+ * const doc = new LoroDoc();
3094
+ * const text = doc.getText("text");
3095
+ * text.insertUtf8(0, "Hello");
3096
+ * text.deleteUtf8(1, 3);
3097
+ * const s = text.toString();
3098
+ * console.log(s); // "Ho"
3099
+ * ```
3100
+ */
3099
3101
  deleteUtf8(index: number, len: number): void;
3100
- /**
3101
- * Mark a range of text with a key and a value (utf-16 index).
3102
- *
3103
- * > You should call `configTextStyle` before using `mark` and `unmark`.
3104
- *
3105
- * You can use it to create a highlight, make a range of text bold, or add a link to a range of text.
3106
- *
3107
- * Note: this is not suitable for unmergeable annotations like comments.
3108
- *
3109
- * @example
3110
- * ```ts
3111
- * import { LoroDoc } from "loro-crdt";
3112
- *
3113
- * const doc = new LoroDoc();
3114
- * doc.configTextStyle({bold: {expand: "after"}});
3115
- * const text = doc.getText("text");
3116
- * text.insert(0, "Hello World!");
3117
- * text.mark({ start: 0, end: 5 }, "bold", true);
3118
- * ```
3119
- * @param {{ start: number, end: number }} range
3120
- * @param {string} key
3121
- * @param {any} value
3122
- */
3102
+ /**
3103
+ * Mark a range of text with a key and a value (utf-16 index).
3104
+ *
3105
+ * > You should call `configTextStyle` before using `mark` and `unmark`.
3106
+ *
3107
+ * You can use it to create a highlight, make a range of text bold, or add a link to a range of text.
3108
+ *
3109
+ * @example
3110
+ * ```ts
3111
+ * import { LoroDoc } from "loro-crdt";
3112
+ *
3113
+ * const doc = new LoroDoc();
3114
+ * doc.configTextStyle({bold: {expand: "after"}});
3115
+ * const text = doc.getText("text");
3116
+ * text.insert(0, "Hello World!");
3117
+ * text.mark({ start: 0, end: 5 }, "bold", true);
3118
+ * ```
3119
+ */
3123
3120
  mark(range: { start: number, end: number }, key: string, value: any): void;
3124
- /**
3125
- * Unmark a range of text with a key and a value (utf-16 index).
3126
- *
3127
- * > You should call `configTextStyle` before using `mark` and `unmark`.
3128
- *
3129
- * You can use it to remove highlights, bolds or links
3130
- *
3131
- * @example
3132
- * ```ts
3133
- * import { LoroDoc } from "loro-crdt";
3134
- *
3135
- * const doc = new LoroDoc();
3136
- * doc.configTextStyle({bold: {expand: "after"}});
3137
- * const text = doc.getText("text");
3138
- * text.insert(0, "Hello World!");
3139
- * text.mark({ start: 0, end: 5 }, "bold", true);
3140
- * text.unmark({ start: 0, end: 5 }, "bold");
3141
- * ```
3142
- * @param {{ start: number, end: number }} range
3143
- * @param {string} key
3144
- */
3121
+ /**
3122
+ * Unmark a range of text with a key and a value (utf-16 index).
3123
+ *
3124
+ * > You should call `configTextStyle` before using `mark` and `unmark`.
3125
+ *
3126
+ * You can use it to remove highlights, bolds or links
3127
+ *
3128
+ * @example
3129
+ * ```ts
3130
+ * import { LoroDoc } from "loro-crdt";
3131
+ *
3132
+ * const doc = new LoroDoc();
3133
+ * doc.configTextStyle({bold: {expand: "after"}});
3134
+ * const text = doc.getText("text");
3135
+ * text.insert(0, "Hello World!");
3136
+ * text.mark({ start: 0, end: 5 }, "bold", true);
3137
+ * text.unmark({ start: 0, end: 5 }, "bold");
3138
+ * ```
3139
+ */
3145
3140
  unmark(range: { start: number, end: number }, key: string): void;
3146
- /**
3147
- * Convert the text to a string
3148
- * @returns {string}
3149
- */
3141
+ /**
3142
+ * Convert the text to a string
3143
+ */
3150
3144
  toString(): string;
3151
- /**
3152
- * Get the text in [Delta](https://quilljs.com/docs/delta/) format.
3153
- *
3154
- * The returned value will include the rich text information.
3155
- *
3156
- * @example
3157
- * ```ts
3158
- * import { LoroDoc } from "loro-crdt";
3159
- *
3160
- * const doc = new LoroDoc();
3161
- * const text = doc.getText("text");
3162
- * doc.configTextStyle({bold: {expand: "after"}});
3163
- * text.insert(0, "Hello World!");
3164
- * text.mark({ start: 0, end: 5 }, "bold", true);
3165
- * console.log(text.toDelta()); // [ { insert: 'Hello', attributes: { bold: true } } ]
3166
- * ```
3167
- * @returns {Delta<string>[]}
3168
- */
3145
+ /**
3146
+ * Get the text in [Delta](https://quilljs.com/docs/delta/) format.
3147
+ *
3148
+ * The returned value will include the rich text information.
3149
+ *
3150
+ * @example
3151
+ * ```ts
3152
+ * import { LoroDoc } from "loro-crdt";
3153
+ *
3154
+ * const doc = new LoroDoc();
3155
+ * const text = doc.getText("text");
3156
+ * doc.configTextStyle({bold: {expand: "after"}});
3157
+ * text.insert(0, "Hello World!");
3158
+ * text.mark({ start: 0, end: 5 }, "bold", true);
3159
+ * console.log(text.toDelta()); // [ { insert: 'Hello', attributes: { bold: true } } ]
3160
+ * ```
3161
+ */
3169
3162
  toDelta(): Delta<string>[];
3170
- /**
3171
- * Change the state of this text by delta.
3172
- *
3173
- * If a delta item is `insert`, it should include all the attributes of the inserted text.
3174
- * Loro's rich text CRDT may make the inserted text inherit some styles when you use
3175
- * `insert` method directly. However, when you use `applyDelta` if some attributes are
3176
- * inherited from CRDT but not included in the delta, they will be removed.
3177
- *
3178
- * Another special property of `applyDelta` is if you format an attribute for ranges out of
3179
- * the text length, Loro will insert new lines to fill the gap first. It's useful when you
3180
- * build the binding between Loro and rich text editors like Quill, which might assume there
3181
- * is always a newline at the end of the text implicitly.
3182
- *
3183
- * @example
3184
- * ```ts
3185
- * const doc = new LoroDoc();
3186
- * const text = doc.getText("text");
3187
- * doc.configTextStyle({bold: {expand: "after"}});
3188
- * text.insert(0, "Hello World!");
3189
- * text.mark({ start: 0, end: 5 }, "bold", true);
3190
- * const delta = text.toDelta();
3191
- * const text2 = doc.getText("text2");
3192
- * text2.applyDelta(delta);
3193
- * expect(text2.toDelta()).toStrictEqual(delta);
3194
- * ```
3195
- * @param {Delta<string>[]} delta
3196
- */
3163
+ /**
3164
+ * Change the state of this text by delta.
3165
+ *
3166
+ * If a delta item is `insert`, it should include all the attributes of the inserted text.
3167
+ * Loro's rich text CRDT may make the inserted text inherit some styles when you use
3168
+ * `insert` method directly. However, when you use `applyDelta` if some attributes are
3169
+ * inherited from CRDT but not included in the delta, they will be removed.
3170
+ *
3171
+ * Another special property of `applyDelta` is if you format an attribute for ranges out of
3172
+ * the text length, Loro will insert new lines to fill the gap first. It's useful when you
3173
+ * build the binding between Loro and rich text editors like Quill, which might assume there
3174
+ * is always a newline at the end of the text implicitly.
3175
+ *
3176
+ * @example
3177
+ * ```ts
3178
+ * const doc = new LoroDoc();
3179
+ * const text = doc.getText("text");
3180
+ * doc.configTextStyle({bold: {expand: "after"}});
3181
+ * text.insert(0, "Hello World!");
3182
+ * text.mark({ start: 0, end: 5 }, "bold", true);
3183
+ * const delta = text.toDelta();
3184
+ * const text2 = doc.getText("text2");
3185
+ * text2.applyDelta(delta);
3186
+ * expect(text2.toDelta()).toStrictEqual(delta);
3187
+ * ```
3188
+ */
3197
3189
  applyDelta(delta: Delta<string>[]): void;
3198
- /**
3199
- * Get the parent container.
3200
- *
3201
- * - The parent of the root is `undefined`.
3202
- * - The object returned is a new js object each time because it need to cross
3203
- * the WASM boundary.
3204
- * @returns {Container | undefined}
3205
- */
3190
+ /**
3191
+ * Get the parent container.
3192
+ *
3193
+ * - The parent of the root is `undefined`.
3194
+ * - The object returned is a new js object each time because it need to cross
3195
+ * the WASM boundary.
3196
+ */
3206
3197
  parent(): Container | undefined;
3207
- /**
3208
- * Whether the container is attached to a LoroDoc.
3209
- *
3210
- * If it's detached, the operations on the container will not be persisted.
3211
- * @returns {boolean}
3212
- */
3198
+ /**
3199
+ * Whether the container is attached to a LoroDoc.
3200
+ *
3201
+ * If it's detached, the operations on the container will not be persisted.
3202
+ */
3213
3203
  isAttached(): boolean;
3214
- /**
3215
- * Get the attached container associated with this.
3216
- *
3217
- * Returns an attached `Container` that is equal to this or created by this; otherwise, it returns `undefined`.
3218
- * @returns {LoroText | undefined}
3219
- */
3204
+ /**
3205
+ * Get the attached container associated with this.
3206
+ *
3207
+ * Returns an attached `Container` that is equal to this or created by this; otherwise, it returns `undefined`.
3208
+ */
3220
3209
  getAttached(): LoroText | undefined;
3221
- /**
3222
- * Push a string to the end of the text.
3223
- * @param {string} s
3224
- */
3210
+ /**
3211
+ * Push a string to the end of the text.
3212
+ */
3225
3213
  push(s: string): void;
3226
- /**
3227
- * Get the editor of the text at the given position.
3228
- * @param {number} pos
3229
- * @returns {PeerID | undefined}
3230
- */
3214
+ /**
3215
+ * Get the editor of the text at the given position.
3216
+ */
3231
3217
  getEditorOf(pos: number): PeerID | undefined;
3232
- /**
3233
- * Check if the container is deleted
3234
- * @returns {boolean}
3235
- */
3218
+ /**
3219
+ * Check if the container is deleted
3220
+ */
3236
3221
  isDeleted(): boolean;
3237
- /**
3238
- * Get the shallow value of the text. This equals to `text.toString()`.
3239
- * @returns {string}
3240
- */
3222
+ /**
3223
+ * Get the shallow value of the text. This equals to `text.toString()`.
3224
+ */
3241
3225
  getShallowValue(): string;
3242
- /**
3243
- * Get the JSON representation of the text.
3244
- * @returns {any}
3245
- */
3226
+ /**
3227
+ * Get the JSON representation of the text.
3228
+ */
3246
3229
  toJSON(): any;
3247
- /**
3248
- * Get the container id of the text.
3249
- */
3230
+ /**
3231
+ * Get the container id of the text.
3232
+ */
3250
3233
  readonly id: ContainerID;
3251
- /**
3252
- * Get the length of text (utf-16 length).
3253
- */
3234
+ /**
3235
+ * Get the length of text (utf-16 length).
3236
+ */
3254
3237
  readonly length: number;
3255
3238
  }
3256
3239
  /**
3257
- * The handler of a tree(forest) container.
3258
- *
3259
- * Learn more at https://loro.dev/docs/tutorial/tree
3260
- */
3240
+ * The handler of a tree(forest) container.
3241
+ *
3242
+ * Learn more at https://loro.dev/docs/tutorial/tree
3243
+ */
3261
3244
  export class LoroTree {
3262
3245
  free(): void;
3263
- /**
3264
- * Create a new detached LoroTree (not attached to any LoroDoc).
3265
- *
3266
- * The edits on a detached container will not be persisted.
3267
- * To attach the container to the document, please insert it into an attached container.
3268
- */
3246
+ /**
3247
+ * Create a new detached LoroTree (not attached to any LoroDoc).
3248
+ *
3249
+ * The edits on a detached container will not be persisted.
3250
+ * To attach the container to the document, please insert it into an attached container.
3251
+ */
3269
3252
  constructor();
3270
- /**
3271
- * "Tree"
3272
- * @returns {'Tree'}
3273
- */
3253
+ /**
3254
+ * "Tree"
3255
+ */
3274
3256
  kind(): 'Tree';
3275
- /**
3276
- * Move the target tree node to be a child of the parent.
3277
- * It's not allowed that the target is an ancestor of the parent
3278
- * or the target and the parent are the same node.
3279
- *
3280
- * @example
3281
- * ```ts
3282
- * import { LoroDoc } from "loro-crdt";
3283
- *
3284
- * const doc = new LoroDoc();
3285
- * const tree = doc.getTree("tree");
3286
- * const root = tree.createNode();
3287
- * const node = root.createNode();
3288
- * const node2 = node.createNode();
3289
- * tree.move(node2.id, root.id);
3290
- * // Error will be thrown if move operation creates a cycle
3291
- * // tree.move(root.id, node.id);
3292
- * ```
3293
- * @param {TreeID} target
3294
- * @param {TreeID | undefined} parent
3295
- * @param {number | undefined} [index]
3296
- */
3297
- move(target: TreeID, parent: TreeID | undefined, index?: number): void;
3298
- /**
3299
- * Delete a tree node from the forest.
3300
- *
3301
- * @example
3302
- * ```ts
3303
- * import { LoroDoc } from "loro-crdt";
3304
- *
3305
- * const doc = new LoroDoc();
3306
- * const tree = doc.getTree("tree");
3307
- * const root = tree.createNode();
3308
- * const node = root.createNode();
3309
- * tree.delete(node.id);
3310
- * ```
3311
- * @param {TreeID} target
3312
- */
3257
+ /**
3258
+ * Move the target tree node to be a child of the parent.
3259
+ * It's not allowed that the target is an ancestor of the parent
3260
+ * or the target and the parent are the same node.
3261
+ *
3262
+ * @example
3263
+ * ```ts
3264
+ * import { LoroDoc } from "loro-crdt";
3265
+ *
3266
+ * const doc = new LoroDoc();
3267
+ * const tree = doc.getTree("tree");
3268
+ * const root = tree.createNode();
3269
+ * const node = root.createNode();
3270
+ * const node2 = node.createNode();
3271
+ * tree.move(node2.id, root.id);
3272
+ * // Error will be thrown if move operation creates a cycle
3273
+ * // tree.move(root.id, node.id);
3274
+ * ```
3275
+ */
3276
+ move(target: TreeID, parent: TreeID | undefined, index?: number | null): void;
3277
+ /**
3278
+ * Delete a tree node from the forest.
3279
+ *
3280
+ * @example
3281
+ * ```ts
3282
+ * import { LoroDoc } from "loro-crdt";
3283
+ *
3284
+ * const doc = new LoroDoc();
3285
+ * const tree = doc.getTree("tree");
3286
+ * const root = tree.createNode();
3287
+ * const node = root.createNode();
3288
+ * tree.delete(node.id);
3289
+ * ```
3290
+ */
3313
3291
  delete(target: TreeID): void;
3314
- /**
3315
- * Return `true` if the tree contains the TreeID, include deleted node.
3316
- * @param {TreeID} target
3317
- * @returns {boolean}
3318
- */
3292
+ /**
3293
+ * Return `true` if the tree contains the TreeID, include deleted node.
3294
+ */
3319
3295
  has(target: TreeID): boolean;
3320
- /**
3321
- * Return `None` if the node is not exist, otherwise return `Some(true)` if the node is deleted.
3322
- * @param {TreeID} target
3323
- * @returns {boolean}
3324
- */
3296
+ /**
3297
+ * Return `None` if the node is not exist, otherwise return `Some(true)` if the node is deleted.
3298
+ */
3325
3299
  isNodeDeleted(target: TreeID): boolean;
3326
- /**
3327
- * Get the hierarchy array with metadata of the forest.
3328
- *
3329
- * @example
3330
- * ```ts
3331
- * import { LoroDoc } from "loro-crdt";
3332
- *
3333
- * const doc = new LoroDoc();
3334
- * const tree = doc.getTree("tree");
3335
- * const root = tree.createNode();
3336
- * root.data.set("color", "red");
3337
- * // [ { id: '0@F2462C4159C4C8D1', parent: null, meta: { color: 'red' }, children: [] } ]
3338
- * console.log(tree.toJSON());
3339
- * ```
3340
- * @returns {any}
3341
- */
3300
+ /**
3301
+ * Get the hierarchy array with metadata of the forest.
3302
+ *
3303
+ * @example
3304
+ * ```ts
3305
+ * import { LoroDoc } from "loro-crdt";
3306
+ *
3307
+ * const doc = new LoroDoc();
3308
+ * const tree = doc.getTree("tree");
3309
+ * const root = tree.createNode();
3310
+ * root.data.set("color", "red");
3311
+ * // [ { id: '0@F2462C4159C4C8D1', parent: null, meta: { color: 'red' }, children: [] } ]
3312
+ * console.log(tree.toJSON());
3313
+ * ```
3314
+ */
3342
3315
  toJSON(): any;
3343
- /**
3344
- * Get all tree nodes of the forest, including deleted nodes.
3345
- *
3346
- * @example
3347
- * ```ts
3348
- * import { LoroDoc } from "loro-crdt";
3349
- *
3350
- * const doc = new LoroDoc();
3351
- * const tree = doc.getTree("tree");
3352
- * const root = tree.createNode();
3353
- * const node = root.createNode();
3354
- * const node2 = node.createNode();
3355
- * console.log(tree.nodes());
3356
- * ```
3357
- * @returns {(LoroTreeNode)[]}
3358
- */
3359
- nodes(): (LoroTreeNode)[];
3360
- /**
3361
- * Get the root nodes of the forest.
3362
- * @returns {(LoroTreeNode)[]}
3363
- */
3364
- roots(): (LoroTreeNode)[];
3365
- /**
3366
- * Get the parent container of the tree container.
3367
- *
3368
- * - The parent container of the root tree is `undefined`.
3369
- * - The object returned is a new js object each time because it need to cross
3370
- * the WASM boundary.
3371
- * @returns {Container | undefined}
3372
- */
3316
+ /**
3317
+ * Get all tree nodes of the forest, including deleted nodes.
3318
+ *
3319
+ * @example
3320
+ * ```ts
3321
+ * import { LoroDoc } from "loro-crdt";
3322
+ *
3323
+ * const doc = new LoroDoc();
3324
+ * const tree = doc.getTree("tree");
3325
+ * const root = tree.createNode();
3326
+ * const node = root.createNode();
3327
+ * const node2 = node.createNode();
3328
+ * console.log(tree.nodes());
3329
+ * ```
3330
+ */
3331
+ nodes(): LoroTreeNode[];
3332
+ /**
3333
+ * Get the root nodes of the forest.
3334
+ */
3335
+ roots(): LoroTreeNode[];
3336
+ /**
3337
+ * Get the parent container of the tree container.
3338
+ *
3339
+ * - The parent container of the root tree is `undefined`.
3340
+ * - The object returned is a new js object each time because it need to cross
3341
+ * the WASM boundary.
3342
+ */
3373
3343
  parent(): Container | undefined;
3374
- /**
3375
- * Whether the container is attached to a document.
3376
- *
3377
- * If it's detached, the operations on the container will not be persisted.
3378
- * @returns {boolean}
3379
- */
3344
+ /**
3345
+ * Whether the container is attached to a document.
3346
+ *
3347
+ * If it's detached, the operations on the container will not be persisted.
3348
+ */
3380
3349
  isAttached(): boolean;
3381
- /**
3382
- * Get the attached container associated with this.
3383
- *
3384
- * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
3385
- * @returns {LoroTree | undefined}
3386
- */
3350
+ /**
3351
+ * Get the attached container associated with this.
3352
+ *
3353
+ * Returns an attached `Container` that equals to this or created by this, otherwise `undefined`.
3354
+ */
3387
3355
  getAttached(): LoroTree | undefined;
3388
- /**
3389
- * Set whether to generate a fractional index for moving and creating.
3390
- *
3391
- * A fractional index can be used to determine the position of tree nodes among their siblings.
3392
- *
3393
- * The jitter is used to avoid conflicts when multiple users are creating a node at the same position.
3394
- * A value of 0 is the default, which means no jitter; any value larger than 0 will enable jitter.
3395
- *
3396
- * Generally speaking, higher jitter value will increase the size of the operation
3397
- * [Read more about it](https://www.loro.dev/blog/movable-tree#implementation-and-encoding-size)
3398
- * @param {number} jitter
3399
- */
3356
+ /**
3357
+ * Set whether to generate a fractional index for moving and creating.
3358
+ *
3359
+ * A fractional index can be used to determine the position of tree nodes among their siblings.
3360
+ *
3361
+ * The jitter is used to avoid conflicts when multiple users are creating a node at the same position.
3362
+ * A value of 0 is the default, which means no jitter; any value larger than 0 will enable jitter.
3363
+ *
3364
+ * Generally speaking, higher jitter value will increase the size of the operation
3365
+ * [Read more about it](https://www.loro.dev/blog/movable-tree#implementation-and-encoding-size)
3366
+ */
3400
3367
  enableFractionalIndex(jitter: number): void;
3401
- /**
3402
- * Disable the fractional index generation when you don't need the Tree's siblings to be sorted.
3403
- * The fractional index will always be set to the same default value 0.
3404
- *
3405
- * After calling this, you cannot use `tree.moveTo()`, `tree.moveBefore()`, `tree.moveAfter()`,
3406
- * and `tree.createAt()`.
3407
- */
3368
+ /**
3369
+ * Disable the fractional index generation when you don't need the Tree's siblings to be sorted.
3370
+ * The fractional index will always be set to the same default value 0.
3371
+ *
3372
+ * After calling this, you cannot use `tree.moveTo()`, `tree.moveBefore()`, `tree.moveAfter()`,
3373
+ * and `tree.createAt()`.
3374
+ */
3408
3375
  disableFractionalIndex(): void;
3409
- /**
3410
- * Whether the tree enables the fractional index generation.
3411
- * @returns {boolean}
3412
- */
3376
+ /**
3377
+ * Whether the tree enables the fractional index generation.
3378
+ */
3413
3379
  isFractionalIndexEnabled(): boolean;
3414
- /**
3415
- * Check if the container is deleted
3416
- * @returns {boolean}
3417
- */
3380
+ /**
3381
+ * Check if the container is deleted
3382
+ */
3418
3383
  isDeleted(): boolean;
3419
- /**
3420
- * Get the shallow value of the tree.
3421
- *
3422
- * Unlike `toJSON()` which recursively resolves nested containers to their values,
3423
- * `getShallowValue()` returns container IDs as strings for any nested containers.
3424
- *
3425
- * @example
3426
- * ```ts
3427
- * const doc = new LoroDoc();
3428
- * doc.setPeerId("1");
3429
- * const tree = doc.getTree("tree");
3430
- * const root = tree.createNode();
3431
- * root.data.set("name", "root");
3432
- * const text = root.data.setContainer("content", new LoroText());
3433
- * text.insert(0, "Hello");
3434
- *
3435
- * console.log(tree.getShallowValue());
3436
- * // [{
3437
- * // id: "0@1",
3438
- * // parent: null,
3439
- * // index: 0,
3440
- * // fractional_index: "80",
3441
- * // meta: "cid:0@1:Map",
3442
- * // children: []
3443
- * // }]
3444
- *
3445
- * console.log(tree.toJSON());
3446
- * // [{
3447
- * // id: "0@1",
3448
- * // parent: null,
3449
- * // index: 0,
3450
- * // fractional_index: "80",
3451
- * // meta: {
3452
- * // name: "root",
3453
- * // content: "Hello"
3454
- * // },
3455
- * // children: []
3456
- * // }]
3457
- * ```
3458
- * @returns {TreeNodeShallowValue[]}
3459
- */
3384
+ /**
3385
+ * Get the shallow value of the tree.
3386
+ *
3387
+ * Unlike `toJSON()` which recursively resolves nested containers to their values,
3388
+ * `getShallowValue()` returns container IDs as strings for any nested containers.
3389
+ *
3390
+ * @example
3391
+ * ```ts
3392
+ * const doc = new LoroDoc();
3393
+ * doc.setPeerId("1");
3394
+ * const tree = doc.getTree("tree");
3395
+ * const root = tree.createNode();
3396
+ * root.data.set("name", "root");
3397
+ * const text = root.data.setContainer("content", new LoroText());
3398
+ * text.insert(0, "Hello");
3399
+ *
3400
+ * console.log(tree.getShallowValue());
3401
+ * // [{
3402
+ * // id: "0@1",
3403
+ * // parent: null,
3404
+ * // index: 0,
3405
+ * // fractional_index: "80",
3406
+ * // meta: "cid:0@1:Map",
3407
+ * // children: []
3408
+ * // }]
3409
+ *
3410
+ * console.log(tree.toJSON());
3411
+ * // [{
3412
+ * // id: "0@1",
3413
+ * // parent: null,
3414
+ * // index: 0,
3415
+ * // fractional_index: "80",
3416
+ * // meta: {
3417
+ * // name: "root",
3418
+ * // content: "Hello"
3419
+ * // },
3420
+ * // children: []
3421
+ * // }]
3422
+ * ```
3423
+ */
3460
3424
  getShallowValue(): TreeNodeShallowValue[];
3461
- /**
3462
- * Get the id of the container.
3463
- */
3425
+ /**
3426
+ * Get the id of the container.
3427
+ */
3464
3428
  readonly id: ContainerID;
3465
3429
  }
3466
3430
  /**
3467
- * The handler of a tree node.
3468
- */
3431
+ * The handler of a tree node.
3432
+ */
3469
3433
  export class LoroTreeNode {
3434
+ private constructor();
3470
3435
  free(): void;
3471
- /**
3472
- * @returns {string}
3473
- */
3474
3436
  __getClassname(): string;
3475
- /**
3476
- * Move the tree node to be after the target node.
3477
- *
3478
- * @example
3479
- * ```ts
3480
- * import { LoroDoc } from "loro-crdt";
3481
- *
3482
- * const doc = new LoroDoc();
3483
- * const tree = doc.getTree("tree");
3484
- * const root = tree.createNode();
3485
- * const node = root.createNode();
3486
- * const node2 = root.createNode();
3487
- * node2.moveAfter(node);
3488
- * // root
3489
- * // / \
3490
- * // node node2
3491
- * ```
3492
- * @param {LoroTreeNode} target
3493
- */
3437
+ /**
3438
+ * Move the tree node to be after the target node.
3439
+ *
3440
+ * @example
3441
+ * ```ts
3442
+ * import { LoroDoc } from "loro-crdt";
3443
+ *
3444
+ * const doc = new LoroDoc();
3445
+ * const tree = doc.getTree("tree");
3446
+ * const root = tree.createNode();
3447
+ * const node = root.createNode();
3448
+ * const node2 = root.createNode();
3449
+ * node2.moveAfter(node);
3450
+ * // root
3451
+ * // / \
3452
+ * // node node2
3453
+ * ```
3454
+ */
3494
3455
  moveAfter(target: LoroTreeNode): void;
3495
- /**
3496
- * Move the tree node to be before the target node.
3497
- *
3498
- * @example
3499
- * ```ts
3500
- * import { LoroDoc } from "loro-crdt";
3501
- *
3502
- * const doc = new LoroDoc();
3503
- * const tree = doc.getTree("tree");
3504
- * const root = tree.createNode();
3505
- * const node = root.createNode();
3506
- * const node2 = root.createNode();
3507
- * node2.moveBefore(node);
3508
- * // root
3509
- * // / \
3510
- * // node2 node
3511
- * ```
3512
- * @param {LoroTreeNode} target
3513
- */
3456
+ /**
3457
+ * Move the tree node to be before the target node.
3458
+ *
3459
+ * @example
3460
+ * ```ts
3461
+ * import { LoroDoc } from "loro-crdt";
3462
+ *
3463
+ * const doc = new LoroDoc();
3464
+ * const tree = doc.getTree("tree");
3465
+ * const root = tree.createNode();
3466
+ * const node = root.createNode();
3467
+ * const node2 = root.createNode();
3468
+ * node2.moveBefore(node);
3469
+ * // root
3470
+ * // / \
3471
+ * // node2 node
3472
+ * ```
3473
+ */
3514
3474
  moveBefore(target: LoroTreeNode): void;
3515
- /**
3516
- * Get the index of the node in the parent's children.
3517
- * @returns {number | undefined}
3518
- */
3475
+ /**
3476
+ * Get the index of the node in the parent's children.
3477
+ */
3519
3478
  index(): number | undefined;
3520
- /**
3521
- * Get the `Fractional Index` of the node.
3522
- *
3523
- * Note: the tree container must be attached to the document.
3524
- * @returns {string | undefined}
3525
- */
3479
+ /**
3480
+ * Get the `Fractional Index` of the node.
3481
+ *
3482
+ * Note: the tree container must be attached to the document.
3483
+ */
3526
3484
  fractionalIndex(): string | undefined;
3527
- /**
3528
- * Check if the node is deleted.
3529
- * @returns {boolean}
3530
- */
3485
+ /**
3486
+ * Check if the node is deleted.
3487
+ */
3531
3488
  isDeleted(): boolean;
3532
- /**
3533
- * Get the last mover of this node.
3534
- * @returns {{ peer: PeerID, counter: number } | undefined}
3535
- */
3489
+ /**
3490
+ * Get the last mover of this node.
3491
+ */
3536
3492
  getLastMoveId(): { peer: PeerID, counter: number } | undefined;
3537
- /**
3538
- * Get the creation id of this node.
3539
- * @returns {{ peer: PeerID, counter: number }}
3540
- */
3493
+ /**
3494
+ * Get the creation id of this node.
3495
+ */
3541
3496
  creationId(): { peer: PeerID, counter: number };
3542
- /**
3543
- * Get the creator of this node.
3544
- * @returns {PeerID}
3545
- */
3497
+ /**
3498
+ * Get the creator of this node.
3499
+ */
3546
3500
  creator(): PeerID;
3547
- /**
3548
- * The TreeID of the node.
3549
- */
3501
+ /**
3502
+ * The TreeID of the node.
3503
+ */
3550
3504
  readonly id: TreeID;
3551
3505
  }
3552
3506
  /**
3553
- * `UndoManager` is responsible for handling undo and redo operations.
3554
- *
3555
- * By default, the maxUndoSteps is set to 100, mergeInterval is set to 1000 ms.
3556
- *
3557
- * Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
3558
- * Undo steps can be merged if they occur within a specified merge interval.
3559
- *
3560
- * Note that undo operations are local and cannot revert changes made by other peers.
3561
- * To undo changes made by other peers, consider using the time travel feature.
3562
- *
3563
- * Once the `peerId` is bound to the `UndoManager` in the document, it cannot be changed.
3564
- * Otherwise, the `UndoManager` may not function correctly.
3565
- */
3507
+ * `UndoManager` is responsible for handling undo and redo operations.
3508
+ *
3509
+ * By default, the maxUndoSteps is set to 100, mergeInterval is set to 1000 ms.
3510
+ *
3511
+ * Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
3512
+ * Undo steps can be merged if they occur within a specified merge interval.
3513
+ *
3514
+ * Note that undo operations are local and cannot revert changes made by other peers.
3515
+ * To undo changes made by other peers, consider using the time travel feature.
3516
+ *
3517
+ * Once the `peerId` is bound to the `UndoManager` in the document, it cannot be changed.
3518
+ * Otherwise, the `UndoManager` may not function correctly.
3519
+ */
3566
3520
  export class UndoManager {
3567
3521
  free(): void;
3568
- /**
3569
- * `UndoManager` is responsible for handling undo and redo operations.
3570
- *
3571
- * PeerID cannot be changed during the lifetime of the UndoManager.
3572
- *
3573
- * Note that undo operations are local and cannot revert changes made by other peers.
3574
- * To undo changes made by other peers, consider using the time travel feature.
3575
- *
3576
- * Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
3577
- * Undo steps can be merged if they occur within a specified merge interval.
3578
- *
3579
- * ## Config
3580
- *
3581
- * - `mergeInterval`: Optional. The interval in milliseconds within which undo steps can be merged. Default is 1000 ms.
3582
- * - `maxUndoSteps`: Optional. The maximum number of undo steps to retain. Default is 100.
3583
- * - `excludeOriginPrefixes`: Optional. An array of string prefixes. Events with origins matching these prefixes will be excluded from undo steps.
3584
- * - `onPush`: Optional. A callback function that is called when an undo/redo step is pushed.
3585
- * The function can return a meta data value that will be attached to the given stack item.
3586
- * - `onPop`: Optional. A callback function that is called when an undo/redo step is popped.
3587
- * The function will have a meta data value that was attached to the given stack item when
3588
- * `onPush` was called.
3589
- * @param {LoroDoc} doc
3590
- * @param {UndoConfig} config
3591
- */
3522
+ /**
3523
+ * `UndoManager` is responsible for handling undo and redo operations.
3524
+ *
3525
+ * PeerID cannot be changed during the lifetime of the UndoManager.
3526
+ *
3527
+ * Note that undo operations are local and cannot revert changes made by other peers.
3528
+ * To undo changes made by other peers, consider using the time travel feature.
3529
+ *
3530
+ * Each commit made by the current peer is recorded as an undo step in the `UndoManager`.
3531
+ * Undo steps can be merged if they occur within a specified merge interval.
3532
+ *
3533
+ * ## Config
3534
+ *
3535
+ * - `mergeInterval`: Optional. The interval in milliseconds within which undo steps can be merged. Default is 1000 ms.
3536
+ * - `maxUndoSteps`: Optional. The maximum number of undo steps to retain. Default is 100.
3537
+ * - `excludeOriginPrefixes`: Optional. An array of string prefixes. Events with origins matching these prefixes will be excluded from undo steps.
3538
+ * - `onPush`: Optional. A callback function that is called when an undo/redo step is pushed.
3539
+ * The function can return a meta data value that will be attached to the given stack item.
3540
+ * - `onPop`: Optional. A callback function that is called when an undo/redo step is popped.
3541
+ * The function will have a meta data value that was attached to the given stack item when
3542
+ * `onPush` was called.
3543
+ */
3592
3544
  constructor(doc: LoroDoc, config: UndoConfig);
3593
- /**
3594
- * Undo the last operation.
3595
- * @returns {boolean}
3596
- */
3545
+ /**
3546
+ * Undo the last operation.
3547
+ */
3597
3548
  undo(): boolean;
3598
- /**
3599
- * Redo the last undone operation.
3600
- * @returns {boolean}
3601
- */
3549
+ /**
3550
+ * Redo the last undone operation.
3551
+ */
3602
3552
  redo(): boolean;
3603
- /**
3604
- * Can undo the last operation.
3605
- * @returns {boolean}
3606
- */
3553
+ /**
3554
+ * Can undo the last operation.
3555
+ */
3607
3556
  canUndo(): boolean;
3608
- /**
3609
- * Can redo the last operation.
3610
- * @returns {boolean}
3611
- */
3557
+ /**
3558
+ * Can redo the last operation.
3559
+ */
3612
3560
  canRedo(): boolean;
3613
- /**
3614
- * The number of max undo steps.
3615
- * If the number of undo steps exceeds this number, the oldest undo step will be removed.
3616
- * @param {number} steps
3617
- */
3561
+ /**
3562
+ * The number of max undo steps.
3563
+ * If the number of undo steps exceeds this number, the oldest undo step will be removed.
3564
+ */
3618
3565
  setMaxUndoSteps(steps: number): void;
3619
- /**
3620
- * Set the merge interval (in ms).
3621
- *
3622
- * If the interval is set to 0, the undo steps will not be merged.
3623
- * Otherwise, the undo steps will be merged if the interval between the two steps is less than the given interval.
3624
- * @param {number} interval
3625
- */
3566
+ /**
3567
+ * Set the merge interval (in ms).
3568
+ *
3569
+ * If the interval is set to 0, the undo steps will not be merged.
3570
+ * Otherwise, the undo steps will be merged if the interval between the two steps is less than the given interval.
3571
+ */
3626
3572
  setMergeInterval(interval: number): void;
3627
- /**
3628
- * If a local event's origin matches the given prefix, it will not be recorded in the
3629
- * undo stack.
3630
- * @param {string} prefix
3631
- */
3573
+ /**
3574
+ * If a local event's origin matches the given prefix, it will not be recorded in the
3575
+ * undo stack.
3576
+ */
3632
3577
  addExcludeOriginPrefix(prefix: string): void;
3633
- /**
3634
- */
3635
3578
  clear(): void;
3636
3579
  }
3637
3580
  /**
3638
- * [VersionVector](https://en.wikipedia.org/wiki/Version_vector)
3639
- * is a map from [PeerID] to [Counter]. Its a right-open interval.
3640
- *
3641
- * i.e. a [VersionVector] of `{A: 1, B: 2}` means that A has 1 atomic op and B has 2 atomic ops,
3642
- * thus ID of `{client: A, counter: 1}` is out of the range.
3643
- */
3581
+ * [VersionVector](https://en.wikipedia.org/wiki/Version_vector)
3582
+ * is a map from [PeerID] to [Counter]. Its a right-open interval.
3583
+ *
3584
+ * i.e. a [VersionVector] of `{A: 1, B: 2}` means that A has 1 atomic op and B has 2 atomic ops,
3585
+ * thus ID of `{client: A, counter: 1}` is out of the range.
3586
+ */
3644
3587
  export class VersionVector {
3645
3588
  free(): void;
3646
- /**
3647
- * Create a new version vector.
3648
- * @param {Map<PeerID, number> | Uint8Array | VersionVector | undefined | null} value
3649
- */
3589
+ /**
3590
+ * Create a new version vector.
3591
+ */
3650
3592
  constructor(value: Map<PeerID, number> | Uint8Array | VersionVector | undefined | null);
3651
- /**
3652
- * Create a new version vector from a Map.
3653
- * @param {Map<PeerID, number>} version
3654
- * @returns {VersionVector}
3655
- */
3593
+ /**
3594
+ * Create a new version vector from a Map.
3595
+ */
3656
3596
  static parseJSON(version: Map<PeerID, number>): VersionVector;
3657
- /**
3658
- * Convert the version vector to a Map
3659
- * @returns {Map<PeerID, number>}
3660
- */
3597
+ /**
3598
+ * Convert the version vector to a Map
3599
+ */
3661
3600
  toJSON(): Map<PeerID, number>;
3662
- /**
3663
- * Encode the version vector into a Uint8Array.
3664
- * @returns {Uint8Array}
3665
- */
3601
+ /**
3602
+ * Encode the version vector into a Uint8Array.
3603
+ */
3666
3604
  encode(): Uint8Array;
3667
- /**
3668
- * Decode the version vector from a Uint8Array.
3669
- * @param {Uint8Array} bytes
3670
- * @returns {VersionVector}
3671
- */
3605
+ /**
3606
+ * Decode the version vector from a Uint8Array.
3607
+ */
3672
3608
  static decode(bytes: Uint8Array): VersionVector;
3673
- /**
3674
- * Get the counter of a peer.
3675
- * @param {number | bigint | `${number}`} peer_id
3676
- * @returns {number | undefined}
3677
- */
3609
+ /**
3610
+ * Get the counter of a peer.
3611
+ */
3678
3612
  get(peer_id: number | bigint | `${number}`): number | undefined;
3679
- /**
3680
- * Compare the version vector with another version vector.
3681
- *
3682
- * If they are concurrent, return undefined.
3683
- * @param {VersionVector} other
3684
- * @returns {number | undefined}
3685
- */
3613
+ /**
3614
+ * Compare the version vector with another version vector.
3615
+ *
3616
+ * If they are concurrent, return undefined.
3617
+ */
3686
3618
  compare(other: VersionVector): number | undefined;
3687
- /**
3688
- * set the exclusive ending point. target id will NOT be included by self
3689
- * @param {{ peer: PeerID, counter: number }} id
3690
- */
3619
+ /**
3620
+ * set the exclusive ending point. target id will NOT be included by self
3621
+ */
3691
3622
  setEnd(id: { peer: PeerID, counter: number }): void;
3692
- /**
3693
- * set the inclusive ending point. target id will be included
3694
- * @param {{ peer: PeerID, counter: number }} id
3695
- */
3623
+ /**
3624
+ * set the inclusive ending point. target id will be included
3625
+ */
3696
3626
  setLast(id: { peer: PeerID, counter: number }): void;
3697
- /**
3698
- * @param {PeerID} peer
3699
- */
3700
3627
  remove(peer: PeerID): void;
3701
- /**
3702
- * @returns {number}
3703
- */
3704
3628
  length(): number;
3705
3629
  }