loro-crdt 1.3.5 → 1.4.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.
@@ -155,36 +155,55 @@ interface LoroDoc {
155
155
  * ```
156
156
  */
157
157
  subscribeLocalUpdates(f: (bytes: Uint8Array) => void): () => void
158
+
158
159
  /**
159
160
  * Convert the document to a JSON value with a custom replacer function.
160
- *
161
+ *
161
162
  * This method works similarly to `JSON.stringify`'s replacer parameter.
162
163
  * The replacer function is called for each value in the document and can transform
163
164
  * how values are serialized to JSON.
164
- *
165
+ *
165
166
  * @param replacer - A function that takes a key and value, and returns how that value
166
- * should be serialized. Similar to JSON.stringify's replacer.
167
+ * should be serialized. Similar to JSON.stringify's replacer.
167
168
  * If return undefined, the value will be skipped.
168
169
  * @returns The JSON representation of the document after applying the replacer function.
169
- *
170
+ *
170
171
  * @example
171
172
  * ```ts
172
173
  * const doc = new LoroDoc();
173
174
  * const text = doc.getText("text");
174
175
  * text.insert(0, "Hello");
175
176
  * text.mark({ start: 0, end: 2 }, "bold", true);
176
- *
177
+ *
177
178
  * // Use delta to represent text
178
179
  * const json = doc.toJsonWithReplacer((key, value) => {
179
180
  * if (value instanceof LoroText) {
180
181
  * return value.toDelta();
181
- * }
182
- *
182
+ * }
183
+ *
183
184
  * return value;
184
185
  * });
185
186
  * ```
186
187
  */
187
188
  toJsonWithReplacer(replacer: (key: string | index, value: Value | Container) => Value | Container | undefined): Value;
189
+
190
+ /**
191
+ * Calculate the differences between two frontiers
192
+ *
193
+ * The entries in the returned object are sorted by causal order: the creation of a child container will be
194
+ * presented before its use.
195
+ *
196
+ * @param from - The source frontier to diff from. A frontier represents a consistent version of the document.
197
+ * @param to - The target frontier to diff to. A frontier represents a consistent version of the document.
198
+ * @param for_json - Controls the diff format:
199
+ * - If true, returns JsonDiff format suitable for JSON serialization
200
+ * - If false, returns Diff format that shares the same type as LoroEvent
201
+ * - The default value is `true`
202
+ */
203
+ diff(from: OpId[], to: OpId[], for_json: false): [ContainerID, Diff][];
204
+ diff(from: OpId[], to: OpId[], for_json: true): [ContainerID, JsonDiff][];
205
+ diff(from: OpId[], to: OpId[], for_json: undefined): [ContainerID, JsonDiff][];
206
+ diff(from: OpId[], to: OpId[], for_json?: boolean): [ContainerID, JsonDiff|Diff][];
188
207
  }
189
208
 
190
209
  /**
@@ -672,6 +691,11 @@ export type ListDiff = {
672
691
  diff: Delta<(Value | Container)[]>[];
673
692
  };
674
693
 
694
+ export type ListJsonDiff = {
695
+ type: "list";
696
+ diff: Delta<(Value | JsonContainerID )[]>[];
697
+ };
698
+
675
699
  export type TextDiff = {
676
700
  type: "text";
677
701
  diff: Delta<string>[];
@@ -682,6 +706,11 @@ export type MapDiff = {
682
706
  updated: Record<string, Value | Container | undefined>;
683
707
  };
684
708
 
709
+ export type MapJsonDiff = {
710
+ type: "map";
711
+ updated: Record<string, Value | JsonContainerID | undefined>;
712
+ };
713
+
685
714
  export type TreeDiffItem =
686
715
  | {
687
716
  target: TreeID;
@@ -717,6 +746,7 @@ export type CounterDiff = {
717
746
  };
718
747
 
719
748
  export type Diff = ListDiff | TextDiff | MapDiff | TreeDiff | CounterDiff;
749
+ export type JsonDiff = ListJsonDiff | TextDiff | MapJsonDiff | CounterDiff | TreeDiff;
720
750
  export type Subscription = () => void;
721
751
  type NonNullableType<T> = Exclude<T, null | undefined>;
722
752
  export type AwarenessListener = (
@@ -1082,7 +1112,7 @@ interface LoroMap<T extends Record<string, unknown> = Record<string, unknown>> {
1082
1112
  * If the key already exists, its value will be updated. If the key doesn't exist,
1083
1113
  * a new key-value pair will be created.
1084
1114
  *
1085
- * > **Note**: When calling `map.set(key, value)` on a LoroMap, if `map.get(key)` already returns `value`,
1115
+ * > **Note**: When calling `map.set(key, value)` on a LoroMap, if `map.get(key)` already returns `value`,
1086
1116
  * > the operation will be a no-op (no operation recorded) to avoid unnecessary updates.
1087
1117
  *
1088
1118
  * @example
@@ -2318,20 +2348,34 @@ export class LoroDoc {
2318
2348
  */
2319
2349
  revertTo(frontiers: ({ peer: PeerID, counter: number })[]): void;
2320
2350
  /**
2321
- * Apply a diff batch to the document
2322
- * @param {Record<ContainerID, Diff>} diff
2323
- */
2324
- applyDiff(diff: Record<ContainerID, Diff>): void;
2325
- /**
2326
- * Calculate the differences between two frontiers
2351
+ * Apply a batch of diff to the document
2327
2352
  *
2328
- * The entries in the returned object are sorted by causal order: the creation of a child container will be
2329
- * presented before its use.
2330
- * @param {({ peer: PeerID, counter: number })[]} from
2331
- * @param {({ peer: PeerID, counter: number })[]} to
2332
- * @returns {Record<ContainerID, Diff>}
2353
+ * A diff batch represents a set of changes between two versions of the document.
2354
+ * You can calculate a diff batch using `doc.diff()`.
2355
+ *
2356
+ * Changes are associated with container IDs. During diff application, if new containers were created in the source
2357
+ * document, they will be assigned fresh IDs in the target document. Loro automatically handles remapping these
2358
+ * container IDs from their original IDs to the new IDs as the diff is applied.
2359
+ *
2360
+ * @example
2361
+ * ```ts
2362
+ * const doc1 = new LoroDoc();
2363
+ * const doc2 = new LoroDoc();
2364
+ *
2365
+ * // Make some changes to doc1
2366
+ * const text = doc1.getText("text");
2367
+ * text.insert(0, "Hello");
2368
+ *
2369
+ * // Calculate diff between empty and current state
2370
+ * const diff = doc1.diff([], doc1.frontiers());
2371
+ *
2372
+ * // Apply changes to doc2
2373
+ * doc2.applyDiff(diff);
2374
+ * console.log(doc2.getText("text").toString()); // "Hello"
2375
+ * ```
2376
+ * @param {[ContainerID, Diff|JsonDiff][]} diff
2333
2377
  */
2334
- diff(from: ({ peer: PeerID, counter: number })[], to: ({ peer: PeerID, counter: number })[]): Record<ContainerID, Diff>;
2378
+ applyDiff(diff: [ContainerID, Diff|JsonDiff][]): void;
2335
2379
  /**
2336
2380
  * Peer ID of the current writer.
2337
2381
  */
@@ -3691,7 +3735,7 @@ export interface InitOutput {
3691
3735
  readonly lorodoc_getChangedContainersIn: (a: number, b: number, c: number, d: number) => void;
3692
3736
  readonly lorodoc_revertTo: (a: number, b: number, c: number, d: number) => void;
3693
3737
  readonly lorodoc_applyDiff: (a: number, b: number, c: number) => void;
3694
- readonly lorodoc_diff: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
3738
+ readonly lorodoc_diff: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
3695
3739
  readonly __wbg_lorotext_free: (a: number) => void;
3696
3740
  readonly lorotext_new: () => number;
3697
3741
  readonly lorotext_kind: (a: number) => number;
package/web/loro_wasm.js CHANGED
@@ -2602,8 +2602,32 @@ export class LoroDoc {
2602
2602
  }
2603
2603
  }
2604
2604
  /**
2605
- * Apply a diff batch to the document
2606
- * @param {Record<ContainerID, Diff>} diff
2605
+ * Apply a batch of diff to the document
2606
+ *
2607
+ * A diff batch represents a set of changes between two versions of the document.
2608
+ * You can calculate a diff batch using `doc.diff()`.
2609
+ *
2610
+ * Changes are associated with container IDs. During diff application, if new containers were created in the source
2611
+ * document, they will be assigned fresh IDs in the target document. Loro automatically handles remapping these
2612
+ * container IDs from their original IDs to the new IDs as the diff is applied.
2613
+ *
2614
+ * @example
2615
+ * ```ts
2616
+ * const doc1 = new LoroDoc();
2617
+ * const doc2 = new LoroDoc();
2618
+ *
2619
+ * // Make some changes to doc1
2620
+ * const text = doc1.getText("text");
2621
+ * text.insert(0, "Hello");
2622
+ *
2623
+ * // Calculate diff between empty and current state
2624
+ * const diff = doc1.diff([], doc1.frontiers());
2625
+ *
2626
+ * // Apply changes to doc2
2627
+ * doc2.applyDiff(diff);
2628
+ * console.log(doc2.getText("text").toString()); // "Hello"
2629
+ * ```
2630
+ * @param {[ContainerID, Diff|JsonDiff][]} diff
2607
2631
  */
2608
2632
  applyDiff(diff) {
2609
2633
  try {
@@ -2625,16 +2649,17 @@ export class LoroDoc {
2625
2649
  * presented before its use.
2626
2650
  * @param {({ peer: PeerID, counter: number })[]} from
2627
2651
  * @param {({ peer: PeerID, counter: number })[]} to
2628
- * @returns {Record<ContainerID, Diff>}
2652
+ * @param {boolean | undefined} [for_json]
2653
+ * @returns {[ContainerID, Diff|JsonDiff][]}
2629
2654
  */
2630
- diff(from, to) {
2655
+ diff(from, to, for_json) {
2631
2656
  try {
2632
2657
  const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
2633
2658
  const ptr0 = passArrayJsValueToWasm0(from, wasm.__wbindgen_export_0);
2634
2659
  const len0 = WASM_VECTOR_LEN;
2635
2660
  const ptr1 = passArrayJsValueToWasm0(to, wasm.__wbindgen_export_0);
2636
2661
  const len1 = WASM_VECTOR_LEN;
2637
- wasm.lorodoc_diff(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1);
2662
+ wasm.lorodoc_diff(retptr, this.__wbg_ptr, ptr0, len0, ptr1, len1, isLikeNone(for_json) ? 0xFFFFFF : for_json ? 1 : 0);
2638
2663
  var r0 = getInt32Memory0()[retptr / 4 + 0];
2639
2664
  var r1 = getInt32Memory0()[retptr / 4 + 1];
2640
2665
  var r2 = getInt32Memory0()[retptr / 4 + 2];
@@ -6017,32 +6042,32 @@ function __wbg_get_imports() {
6017
6042
  const ret = LoroTreeNode.__wrap(arg0);
6018
6043
  return addHeapObject(ret);
6019
6044
  };
6020
- imports.wbg.__wbg_lorocounter_new = function(arg0) {
6021
- const ret = LoroCounter.__wrap(arg0);
6022
- return addHeapObject(ret);
6023
- };
6024
- imports.wbg.__wbg_lorotext_new = function(arg0) {
6025
- const ret = LoroText.__wrap(arg0);
6045
+ imports.wbg.__wbg_lorotree_new = function(arg0) {
6046
+ const ret = LoroTree.__wrap(arg0);
6026
6047
  return addHeapObject(ret);
6027
6048
  };
6028
6049
  imports.wbg.__wbg_lorolist_new = function(arg0) {
6029
6050
  const ret = LoroList.__wrap(arg0);
6030
6051
  return addHeapObject(ret);
6031
6052
  };
6032
- imports.wbg.__wbg_loromap_new = function(arg0) {
6033
- const ret = LoroMap.__wrap(arg0);
6053
+ imports.wbg.__wbg_lorocounter_new = function(arg0) {
6054
+ const ret = LoroCounter.__wrap(arg0);
6034
6055
  return addHeapObject(ret);
6035
6056
  };
6036
- imports.wbg.__wbg_cursor_new = function(arg0) {
6037
- const ret = Cursor.__wrap(arg0);
6057
+ imports.wbg.__wbg_loromap_new = function(arg0) {
6058
+ const ret = LoroMap.__wrap(arg0);
6038
6059
  return addHeapObject(ret);
6039
6060
  };
6040
6061
  imports.wbg.__wbg_loromovablelist_new = function(arg0) {
6041
6062
  const ret = LoroMovableList.__wrap(arg0);
6042
6063
  return addHeapObject(ret);
6043
6064
  };
6044
- imports.wbg.__wbg_lorotree_new = function(arg0) {
6045
- const ret = LoroTree.__wrap(arg0);
6065
+ imports.wbg.__wbg_lorotext_new = function(arg0) {
6066
+ const ret = LoroText.__wrap(arg0);
6067
+ return addHeapObject(ret);
6068
+ };
6069
+ imports.wbg.__wbg_cursor_new = function(arg0) {
6070
+ const ret = Cursor.__wrap(arg0);
6046
6071
  return addHeapObject(ret);
6047
6072
  };
6048
6073
  imports.wbg.__wbg_versionvector_new = function(arg0) {
@@ -6237,7 +6262,7 @@ function __wbg_get_imports() {
6237
6262
  wasm.__wbindgen_export_5(deferred0_0, deferred0_1, 1);
6238
6263
  }
6239
6264
  };
6240
- imports.wbg.__wbg_now_6dd635953150ee31 = typeof Date.now == 'function' ? Date.now : notDefined('Date.now');
6265
+ imports.wbg.__wbg_now_bc6f749123583eb9 = typeof Date.now == 'function' ? Date.now : notDefined('Date.now');
6241
6266
  imports.wbg.__wbg_crypto_1d1f22824a6a080c = function(arg0) {
6242
6267
  const ret = getObject(arg0).crypto;
6243
6268
  return addHeapObject(ret);
@@ -6501,11 +6526,11 @@ function __wbg_get_imports() {
6501
6526
  return addHeapObject(ret);
6502
6527
  };
6503
6528
  imports.wbg.__wbindgen_closure_wrapper482 = function(arg0, arg1, arg2) {
6504
- const ret = makeMutClosure(arg0, arg1, 8, __wbg_adapter_60);
6529
+ const ret = makeMutClosure(arg0, arg1, 10, __wbg_adapter_60);
6505
6530
  return addHeapObject(ret);
6506
6531
  };
6507
- imports.wbg.__wbindgen_closure_wrapper484 = function(arg0, arg1, arg2) {
6508
- const ret = makeMutClosure(arg0, arg1, 10, __wbg_adapter_63);
6532
+ imports.wbg.__wbindgen_closure_wrapper485 = function(arg0, arg1, arg2) {
6533
+ const ret = makeMutClosure(arg0, arg1, 8, __wbg_adapter_63);
6509
6534
  return addHeapObject(ret);
6510
6535
  };
6511
6536
 
Binary file
@@ -99,7 +99,7 @@ export function lorodoc_getCursorPos(a: number, b: number, c: number): void;
99
99
  export function lorodoc_getChangedContainersIn(a: number, b: number, c: number, d: number): void;
100
100
  export function lorodoc_revertTo(a: number, b: number, c: number, d: number): void;
101
101
  export function lorodoc_applyDiff(a: number, b: number, c: number): void;
102
- export function lorodoc_diff(a: number, b: number, c: number, d: number, e: number, f: number): void;
102
+ export function lorodoc_diff(a: number, b: number, c: number, d: number, e: number, f: number, g: number): void;
103
103
  export function __wbg_lorotext_free(a: number): void;
104
104
  export function lorotext_new(): number;
105
105
  export function lorotext_kind(a: number): number;