loro-crdt 0.13.1 → 0.14.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.
package/src/index.ts CHANGED
@@ -8,41 +8,11 @@ import {
8
8
  LoroMap,
9
9
  LoroText,
10
10
  LoroTree,
11
- LoroTreeNode,
12
11
  OpId,
13
12
  TreeID,
14
13
  Value,
15
14
  } from "loro-wasm";
16
15
 
17
- Loro.prototype.getTypedMap = function (...args) {
18
- return this.getMap(...args);
19
- };
20
- Loro.prototype.getTypedList = function (...args) {
21
- return this.getList(...args);
22
- };
23
- LoroList.prototype.getTyped = function (loro, index) {
24
- const value = this.get(index);
25
- if (typeof value === "string" && isContainerId(value)) {
26
- return loro.getContainerById(value);
27
- } else {
28
- return value;
29
- }
30
- };
31
- LoroList.prototype.insertTyped = function (...args) {
32
- return this.insert(...args);
33
- };
34
- LoroMap.prototype.getTyped = function (loro, key) {
35
- const value = this.get(key);
36
- if (typeof value === "string" && isContainerId(value)) {
37
- return loro.getContainerById(value);
38
- } else {
39
- return value;
40
- }
41
- };
42
- LoroMap.prototype.setTyped = function (...args) {
43
- return this.set(...args);
44
- };
45
-
46
16
  export type Frontiers = OpId[];
47
17
 
48
18
  /**
@@ -56,18 +26,21 @@ export type Path = (number | string | TreeID)[];
56
26
  /**
57
27
  * A batch of events that created by a single `import`/`transaction`/`checkout`.
58
28
  *
59
- * @prop local - Indicates whether the event is local.
29
+ * @prop by - How the event is triggered.
60
30
  * @prop origin - (Optional) Provides information about the origin of the event.
61
31
  * @prop diff - Contains the differential information related to the event.
62
32
  * @prop target - Identifies the container ID of the event's target.
63
33
  * @prop path - Specifies the absolute path of the event's emitter, which can be an index of a list container or a key of a map container.
64
34
  */
65
35
  export interface LoroEventBatch {
66
- local: boolean;
67
36
  /**
68
- * If true, this event was triggered by a checkout.
37
+ * How the event is triggered.
38
+ *
39
+ * - `local`: The event is triggered by a local transaction.
40
+ * - `import`: The event is triggered by an import operation.
41
+ * - `checkout`: The event is triggered by a checkout operation.
69
42
  */
70
- fromCheckout: boolean;
43
+ by: "local" | "import" | "checkout";
71
44
  origin?: string;
72
45
  /**
73
46
  * The container ID of the current event receiver.
@@ -196,52 +169,211 @@ declare module "loro-wasm" {
196
169
  subscribe(listener: Listener): number;
197
170
  }
198
171
 
199
- interface Loro<T extends Record<string, any> = Record<string, any>> {
200
- getTypedMap<Key extends keyof T & string>(
172
+ interface Loro<
173
+ T extends Record<string, Container> = Record<string, Container>,
174
+ > {
175
+ /**
176
+ * Get a LoroMap by container id
177
+ *
178
+ * The object returned is a new js object each time because it need to cross
179
+ * the WASM boundary.
180
+ *
181
+ * @example
182
+ * ```ts
183
+ * import { Loro } from "loro-crdt";
184
+ *
185
+ * const doc = new Loro();
186
+ * const map = doc.getMap("map");
187
+ * ```
188
+ */
189
+ getMap<Key extends keyof T>(
190
+ name: Key,
191
+ ): T[Key] extends LoroMap ? T[Key] : LoroMap;
192
+ /**
193
+ * Get a LoroList by container id
194
+ *
195
+ * The object returned is a new js object each time because it need to cross
196
+ * the WASM boundary.
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * import { Loro } from "loro-crdt";
201
+ *
202
+ * const doc = new Loro();
203
+ * const list = doc.getList("list");
204
+ * ```
205
+ */
206
+ getList<Key extends keyof T>(
201
207
  name: Key,
202
- ): T[Key] extends LoroMap ? T[Key] : never;
203
- getTypedList<Key extends keyof T & string>(
208
+ ): T[Key] extends LoroList ? T[Key] : LoroList;
209
+ /**
210
+ * Get a LoroTree by container id
211
+ *
212
+ * The object returned is a new js object each time because it need to cross
213
+ * the WASM boundary.
214
+ *
215
+ * @example
216
+ * ```ts
217
+ * import { Loro } from "loro-crdt";
218
+ *
219
+ * const doc = new Loro();
220
+ * const tree = doc.getTree("tree");
221
+ * ```
222
+ */
223
+ getTree<Key extends keyof T>(
204
224
  name: Key,
205
- ): T[Key] extends LoroList ? T[Key] : never;
206
- getMap(key: string | ContainerID): LoroMap<T[string]>;
207
- getList(key: string | ContainerID): LoroList<T[string]>;
208
- getTree(key: string | ContainerID): LoroTree<T[string]>;
225
+ ): T[Key] extends LoroTree ? T[Key] : LoroTree;
209
226
  getText(key: string | ContainerID): LoroText;
210
227
  }
211
228
 
212
- interface LoroList<
213
- T extends any[] = any[],
214
- > {
229
+ interface LoroList<T = unknown> {
215
230
  new (): LoroList<T>;
231
+ /**
232
+ * Get elements of the list. If the value is a child container, the corresponding
233
+ * `Container` will be returned.
234
+ *
235
+ * @example
236
+ * ```ts
237
+ * import { Loro } from "loro-crdt";
238
+ *
239
+ * const doc = new Loro();
240
+ * const list = doc.getList("list");
241
+ * list.insert(0, 100);
242
+ * list.insert(1, "foo");
243
+ * list.insert(2, true);
244
+ * list.insertContainer(3, new LoroText());
245
+ * console.log(list.value); // [100, "foo", true, LoroText];
246
+ * ```
247
+ */
248
+ toArray(): T[];
249
+ /**
250
+ * Insert a container at the index.
251
+ *
252
+ * @example
253
+ * ```ts
254
+ * import { Loro } from "loro-crdt";
255
+ *
256
+ * const doc = new Loro();
257
+ * const list = doc.getList("list");
258
+ * list.insert(0, 100);
259
+ * const text = list.insertContainer(1, new LoroText());
260
+ * text.insert(0, "Hello");
261
+ * console.log(list.getDeepValue()); // [100, "Hello"];
262
+ * ```
263
+ */
216
264
  insertContainer<C extends Container>(
217
265
  pos: number,
218
266
  child: C,
219
- ): C;
220
- get(index: number): undefined | Value | Container;
221
- getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];
222
- insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;
223
- insert(pos: number, value: Value): void;
267
+ ): T extends C ? T : C;
268
+ /**
269
+ * Get the value at the index. If the value is a container, the corresponding handler will be returned.
270
+ *
271
+ * @example
272
+ * ```ts
273
+ * import { Loro } from "loro-crdt";
274
+ *
275
+ * const doc = new Loro();
276
+ * const list = doc.getList("list");
277
+ * list.insert(0, 100);
278
+ * console.log(list.get(0)); // 100
279
+ * console.log(list.get(1)); // undefined
280
+ * ```
281
+ */
282
+ get(index: number): T;
283
+ /**
284
+ * Insert a value at index.
285
+ *
286
+ * @example
287
+ * ```ts
288
+ * import { Loro } from "loro-crdt";
289
+ *
290
+ * const doc = new Loro();
291
+ * const list = doc.getList("list");
292
+ * list.insert(0, 100);
293
+ * list.insert(1, "foo");
294
+ * list.insert(2, true);
295
+ * console.log(list.value); // [100, "foo", true];
296
+ * ```
297
+ */
298
+ insert(pos: number, value: Exclude<T, Container>): void;
224
299
  delete(pos: number, len: number): void;
225
300
  subscribe(txn: Loro, listener: Listener): number;
226
301
  getAttached(): undefined | LoroList<T>;
227
302
  }
228
303
 
229
304
  interface LoroMap<
230
- T extends Record<string, any> = Record<string, any>,
305
+ T extends Record<string, unknown> = Record<string, unknown>,
231
306
  > {
232
307
  new (): LoroMap<T>;
233
- getOrCreateContainer<C extends Container>(
234
- key: string,
235
- child: C,
236
- ): C;
237
- setContainer<C extends Container>(
238
- key: string,
308
+ /**
309
+ * Get the value of the key. If the value is a child container, the corresponding
310
+ * `Container` will be returned.
311
+ *
312
+ * The object returned is a new js object each time because it need to cross
313
+ *
314
+ * @example
315
+ * ```ts
316
+ * import { Loro } from "loro-crdt";
317
+ *
318
+ * const doc = new Loro();
319
+ * const map = doc.getMap("map");
320
+ * map.set("foo", "bar");
321
+ * const bar = map.get("foo");
322
+ * ```
323
+ */
324
+ getOrCreateContainer<C extends Container>(key: string, child: C): C;
325
+ /**
326
+ * Set the key with a container.
327
+ *
328
+ * @example
329
+ * ```ts
330
+ * import { Loro } from "loro-crdt";
331
+ *
332
+ * const doc = new Loro();
333
+ * const map = doc.getMap("map");
334
+ * map.set("foo", "bar");
335
+ * const text = map.setContainer("text", new LoroText());
336
+ * const list = map.setContainer("list", new LoroText());
337
+ * ```
338
+ */
339
+ setContainer<C extends Container, Key extends keyof T>(
340
+ key: Key,
239
341
  child: C,
240
- ): C;
241
- get(key: string): undefined | Value | Container;
242
- getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];
243
- set(key: string, value: Value): void;
244
- setTyped<Key extends keyof T & string>(key: Key, value: T[Key]): void;
342
+ ): NonNullableType<T[Key]> extends C ? NonNullableType<T[Key]> : C;
343
+ /**
344
+ * Get the value of the key. If the value is a child container, the corresponding
345
+ * `Container` will be returned.
346
+ *
347
+ * The object/value returned is a new js object/value each time because it need to cross
348
+ * the WASM boundary.
349
+ *
350
+ * @example
351
+ * ```ts
352
+ * import { Loro } from "loro-crdt";
353
+ *
354
+ * const doc = new Loro();
355
+ * const map = doc.getMap("map");
356
+ * map.set("foo", "bar");
357
+ * const bar = map.get("foo");
358
+ * ```
359
+ */
360
+ get<Key extends keyof T>(key: Key): T[Key];
361
+ /**
362
+ * Set the key with the value.
363
+ *
364
+ * If the value of the key is exist, the old value will be updated.
365
+ *
366
+ * @example
367
+ * ```ts
368
+ * import { Loro } from "loro-crdt";
369
+ *
370
+ * const doc = new Loro();
371
+ * const map = doc.getMap("map");
372
+ * map.set("foo", "bar");
373
+ * map.set("foo", "baz");
374
+ * ```
375
+ */
376
+ set<Key extends keyof T>(key: Key, value: Exclude<T[Key], Container>): void;
245
377
  delete(key: string): void;
246
378
  subscribe(txn: Loro, listener: Listener): number;
247
379
  }
@@ -254,7 +386,7 @@ declare module "loro-wasm" {
254
386
  }
255
387
 
256
388
  interface LoroTree<
257
- T extends Record<string, any> = Record<string, any>,
389
+ T extends Record<string, unknown> = Record<string, unknown>,
258
390
  > {
259
391
  new (): LoroTree<T>;
260
392
  createNode(parent: TreeID | undefined): LoroTreeNode<T>;
@@ -266,13 +398,18 @@ declare module "loro-wasm" {
266
398
  }
267
399
 
268
400
  interface LoroTreeNode<
269
- T extends Record<string, any> = Record<string, any>,
401
+ T extends Record<string, unknown> = Record<string, unknown>,
270
402
  > {
403
+ /**
404
+ * Get the associated metadata map container of a tree node.
405
+ */
271
406
  readonly data: LoroMap<T>;
272
407
  createNode(): LoroTreeNode<T>;
273
408
  setAsRoot(): void;
274
409
  moveTo(parent: LoroTreeNode<T>): void;
275
- parent(): LoroTreeNode | undefined;
410
+ parent(): LoroTreeNode<T> | undefined;
276
411
  children(): Array<LoroTreeNode<T>>;
277
412
  }
278
413
  }
414
+
415
+ type NonNullableType<T> = Exclude<T, null | undefined>;
package/tsconfig.json CHANGED
@@ -50,9 +50,9 @@
50
50
  // "sourceMap": true, /* Create source map files for emitted JavaScript files. */
51
51
  // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
52
52
  // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
53
- "outDir": "./dist", /* Specify an output folder for all emitted files. */
53
+ "outDir": "./dist" /* Specify an output folder for all emitted files. */,
54
54
  // "removeComments": true, /* Disable emitting comments. */
55
- // "noEmit": true, /* Disable emitting files from a compilation. */
55
+ "noEmit": true /* Disable emitting files from a compilation. */,
56
56
  // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
57
57
  // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
58
58
  // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */