loro-crdt 0.2.6 → 0.2.8-alpha

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loro-crdt",
3
- "version": "0.2.6",
3
+ "version": "0.2.8-alpha",
4
4
  "description": "",
5
5
  "main": "dist/loro.js",
6
6
  "module": "dist/loro.mjs",
@@ -8,7 +8,7 @@
8
8
  "author": "",
9
9
  "license": "ISC",
10
10
  "dependencies": {
11
- "loro-wasm": "workspace"
11
+ "loro-wasm": "0.2.5"
12
12
  },
13
13
  "devDependencies": {
14
14
  "@rollup/plugin-node-resolve": "^15.0.1",
package/src/index.ts CHANGED
@@ -33,6 +33,27 @@ Loro.prototype.transact = function (cb, origin) {
33
33
  });
34
34
  };
35
35
 
36
+ Loro.prototype.getTypedMap = Loro.prototype.getMap;
37
+ Loro.prototype.getTypedList = Loro.prototype.getList;
38
+ LoroList.prototype.getTyped = function (loro, index) {
39
+ const value = this.get(index);
40
+ if (typeof value === "string" && isContainerId(value)) {
41
+ return loro.getContainerById(value);
42
+ } else {
43
+ return value;
44
+ }
45
+ };
46
+ LoroList.prototype.insertTyped = LoroList.prototype.insert;
47
+ LoroMap.prototype.getTyped = function (loro, key) {
48
+ const value = this.get(key);
49
+ if (typeof value === "string" && isContainerId(value)) {
50
+ return loro.getContainerById(value);
51
+ } else {
52
+ return value;
53
+ }
54
+ };
55
+ LoroMap.prototype.setTyped = LoroMap.prototype.set;
56
+
36
57
  LoroText.prototype.insert = function (txn, pos, text) {
37
58
  if (txn instanceof Loro) {
38
59
  this.__loro_insert(txn, pos, text);
@@ -173,7 +194,16 @@ declare module "loro-wasm" {
173
194
  transact(f: (tx: Transaction) => void, origin?: string): void;
174
195
  }
175
196
 
176
- interface LoroList {
197
+ interface Loro<T extends Record<string, any> = Record<string, any>> {
198
+ getTypedMap<Key extends (keyof T) & string>(
199
+ name: Key,
200
+ ): T[Key] extends LoroMap ? T[Key] : never;
201
+ getTypedList<Key extends (keyof T) & string>(
202
+ name: Key,
203
+ ): T[Key] extends LoroList ? T[Key] : never;
204
+ }
205
+
206
+ interface LoroList<T extends any[] = any[]> {
177
207
  insertContainer(
178
208
  txn: Transaction | Loro,
179
209
  pos: number,
@@ -196,6 +226,12 @@ declare module "loro-wasm" {
196
226
  ): never;
197
227
 
198
228
  get(index: number): Value;
229
+ getTyped<Key extends (keyof T) & number>(loro: Loro, index: Key): T[Key];
230
+ insertTyped<Key extends (keyof T) & number>(
231
+ txn: Transaction | Loro,
232
+ pos: Key,
233
+ value: T[Key],
234
+ ): void;
199
235
  insert(txn: Transaction | Loro, pos: number, value: Value | Prelim): void;
200
236
  delete(txn: Transaction | Loro, pos: number, len: number): void;
201
237
  subscribe(txn: Transaction | Loro, listener: Listener): number;
@@ -203,7 +239,7 @@ declare module "loro-wasm" {
203
239
  subscribeOnce(txn: Transaction | Loro, listener: Listener): number;
204
240
  }
205
241
 
206
- interface LoroMap {
242
+ interface LoroMap<T extends Record<string, any> = Record<string, any>> {
207
243
  insertContainer(
208
244
  txn: Transaction | Loro,
209
245
  key: string,
@@ -226,7 +262,16 @@ declare module "loro-wasm" {
226
262
  ): never;
227
263
 
228
264
  get(key: string): Value;
265
+ getTyped<Key extends (keyof T) & string>(
266
+ txn: Loro,
267
+ key: Key,
268
+ ): T[Key];
229
269
  set(txn: Transaction | Loro, key: string, value: Value | Prelim): void;
270
+ setTyped<Key extends (keyof T) & string>(
271
+ txn: Transaction | Loro,
272
+ key: Key,
273
+ value: T[Key],
274
+ ): void;
230
275
  delete(txn: Transaction | Loro, key: string): void;
231
276
  subscribe(txn: Transaction | Loro, listener: Listener): number;
232
277
  subscribeDeep(txn: Transaction | Loro, listener: Listener): number;
@@ -1,9 +1,10 @@
1
- import { describe, expect, it } from "vitest";
1
+ import { assertType, describe, expect, it } from "vitest";
2
2
  import {
3
3
  Delta,
4
4
  ListDiff,
5
5
  Loro,
6
6
  LoroEvent,
7
+ LoroList,
7
8
  LoroMap,
8
9
  MapDiff as MapDiff,
9
10
  PrelimList,
@@ -12,6 +13,7 @@ import {
12
13
  TextDiff,
13
14
  Transaction,
14
15
  } from "../src";
16
+ import { expectTypeOf } from "vitest";
15
17
 
16
18
  function assertEquals(a: any, b: any) {
17
19
  expect(a).toStrictEqual(b);
@@ -257,6 +259,35 @@ describe("wasm", () => {
257
259
  });
258
260
  });
259
261
 
262
+ describe("type", () => {
263
+ it("test map type", () => {
264
+ const loro = new Loro<{ map: LoroMap<{ name: "he" }> }>();
265
+ const map = loro.getTypedMap("map");
266
+ const v = map.getTyped(loro, "name");
267
+ expectTypeOf(v).toEqualTypeOf<"he">();
268
+ });
269
+
270
+ it("test recursive map type", () => {
271
+ const loro = new Loro<{ map: LoroMap<{ map: LoroMap<{ name: "he" }> }> }>();
272
+ const map = loro.getTypedMap("map");
273
+ map.insertContainer(loro, "map", "Map");
274
+ const subMap = map.getTyped(loro, "map");
275
+ const name = subMap.getTyped(loro, "name");
276
+ expectTypeOf(name).toEqualTypeOf<"he">();
277
+ });
278
+
279
+ it("works for list type", () => {
280
+ const loro = new Loro<{ list: LoroList<[string, number]> }>();
281
+ const list = loro.getTypedList("list");
282
+ list.insertTyped(loro, 0, "123");
283
+ list.insertTyped(loro, 1, 123);
284
+ const v0 = list.getTyped(loro, 0);
285
+ expectTypeOf(v0).toEqualTypeOf<string>();
286
+ const v1 = list.getTyped(loro, 1);
287
+ expectTypeOf(v1).toEqualTypeOf<number>();
288
+ });
289
+ });
290
+
260
291
  function one_ms(): Promise<void> {
261
292
  return new Promise((resolve) => setTimeout(resolve, 1));
262
293
  }