loro-crdt 0.4.2 → 0.5.0

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/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [0.5.0](https://github.com/loro-dev/loro/compare/v0.4.3...v0.5.0) (2023-11-27)
6
+
7
+
8
+ ### ⚠ BREAKING CHANGES
9
+
10
+ * encoding schema is changed
11
+
12
+ ### Bug Fixes
13
+
14
+ * [#181](https://github.com/loro-dev/loro/issues/181) importing should use inherent arena ([8e901cf](https://github.com/loro-dev/loro/commit/8e901cf00cc8469da136f18f13d2affc78e08e64))
15
+ * deno dirname in windows ([#183](https://github.com/loro-dev/loro/issues/183)) ([c04dc34](https://github.com/loro-dev/loro/commit/c04dc344f5413b5135354c9652a70b5d698f04ac))
16
+ * from snapshot should enable auto commit ([b940214](https://github.com/loro-dev/loro/commit/b94021498571cf7ac42f2896ca0abc82f15d823a))
17
+ * keep strong ref to doc in handlers [#190](https://github.com/loro-dev/loro/issues/190) ([#191](https://github.com/loro-dev/loro/issues/191)) ([e23ef43](https://github.com/loro-dev/loro/commit/e23ef4362d69430601728f40b730e72a183ac4ea))
18
+ * remove compress feature ([#184](https://github.com/loro-dev/loro/issues/184)) ([899270c](https://github.com/loro-dev/loro/commit/899270c6de065852d6e26a07b94b3d923cb83459))
19
+ * typo in lib.rs ([#176](https://github.com/loro-dev/loro/issues/176)) ([83b0e8c](https://github.com/loro-dev/loro/commit/83b0e8cc7f8bccd9d7c152c0e5a59437bebe6c87))
20
+
21
+ ### [0.4.3](https://github.com/loro-dev/loro/compare/v0.4.2...v0.4.3) (2023-11-16)
22
+
23
+
24
+ ### Bug Fixes
25
+
26
+ * avoid i32 overflow ([f799da9](https://github.com/loro-dev/loro/commit/f799da9abbdf369ea1f120c700078bb87f27212b))
27
+
5
28
  ### [0.4.2](https://github.com/loro-dev/loro/compare/v0.4.1...v0.4.2) (2023-11-16)
6
29
 
7
30
 
package/dist/loro.d.ts CHANGED
@@ -1,15 +1,9 @@
1
- import { LoroTree, ContainerID, LoroList, LoroMap, LoroText, PrelimList, PrelimMap, PrelimText, Delta, TreeID } from 'loro-wasm';
1
+ import { Value, Container, PrelimList, PrelimMap, PrelimText, OpId, ContainerID, Delta, TreeID, ContainerType } from 'loro-wasm';
2
2
  export * from 'loro-wasm';
3
3
  export { Loro } from 'loro-wasm';
4
4
 
5
- /**
6
- * Data types supported by loro
7
- */
8
- type Value = ContainerID | string | number | boolean | null | {
9
- [key: string]: Value;
10
- } | Uint8Array | Value[];
11
- type Container = LoroList | LoroMap | LoroText | LoroTree;
12
5
  type Prelim = PrelimList | PrelimMap | PrelimText;
6
+ type Frontiers = OpId[];
13
7
  /**
14
8
  * Represents a path to identify the exact location of an event's target.
15
9
  * The path is composed of numbers (e.g., indices of a list container) and strings
@@ -73,6 +67,8 @@ interface Listener {
73
67
  }
74
68
  declare function isContainerId(s: string): s is ContainerID;
75
69
 
70
+ declare function isContainer(value: any): value is Container;
71
+ declare function valueType(value: any): "Json" | ContainerType;
76
72
  declare module "loro-wasm" {
77
73
  interface Loro {
78
74
  subscribe(listener: Listener): number;
@@ -114,4 +110,4 @@ declare module "loro-wasm" {
114
110
  }
115
111
  }
116
112
 
117
- export { Container, Diff, ListDiff, LoroEvent, MapDiff, Path, Prelim, TextDiff, TreeDiff, Value, isContainerId };
113
+ export { Diff, Frontiers, ListDiff, LoroEvent, MapDiff, Path, Prelim, TextDiff, TreeDiff, isContainer, isContainerId, valueType };
package/dist/loro.js CHANGED
@@ -30,15 +30,31 @@ loroWasm.LoroMap.prototype.getTyped = function(loro, key) {
30
30
  loroWasm.LoroMap.prototype.setTyped = function(...args) {
31
31
  return this.set(...args);
32
32
  };
33
+ const CONTAINER_TYPES = ["Map", "Text", "List", "Tree"];
33
34
  function isContainerId(s) {
34
35
  return s.startsWith("cid:");
35
36
  }
37
+ function isContainer(value) {
38
+ if (typeof value !== "object" || value == null) {
39
+ return false;
40
+ }
41
+ const p = value.__proto__;
42
+ return p.hasOwnProperty("kind") && CONTAINER_TYPES.includes(value.kind());
43
+ }
44
+ function valueType(value) {
45
+ if (isContainer(value)) {
46
+ return value.kind();
47
+ }
48
+ return "Json";
49
+ }
36
50
 
37
51
  Object.defineProperty(exports, 'Loro', {
38
52
  enumerable: true,
39
53
  get: function () { return loroWasm.Loro; }
40
54
  });
55
+ exports.isContainer = isContainer;
41
56
  exports.isContainerId = isContainerId;
57
+ exports.valueType = valueType;
42
58
  Object.keys(loroWasm).forEach(function (k) {
43
59
  if (k !== 'default' && !exports.hasOwnProperty(k)) Object.defineProperty(exports, k, {
44
60
  enumerable: true,
package/dist/loro.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"loro.js","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport { Delta } from \"loro-wasm\";\nimport { PrelimText, PrelimList, PrelimMap } from \"loro-wasm\";\nimport {\n ContainerID,\n Loro,\n LoroList,\n LoroMap,\n LoroText,\n LoroTree,\n TreeID,\n} from \"loro-wasm\";\n\nLoro.prototype.getTypedMap = function (...args) {\n return this.getMap(...args);\n};\nLoro.prototype.getTypedList = function (...args) {\n return this.getList(...args);\n};\nLoroList.prototype.getTyped = function (loro, index) {\n const value = this.get(index);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroList.prototype.insertTyped = function (...args) {\n return this.insert(...args);\n};\nLoroMap.prototype.getTyped = function (loro, key) {\n const value = this.get(key);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroMap.prototype.setTyped = function (...args) {\n return this.set(...args);\n};\n\n/**\n * Data types supported by loro\n */\nexport type Value =\n | ContainerID\n | string\n | number\n | boolean\n | null\n | { [key: string]: Value }\n | Uint8Array\n | Value[];\n\nexport type Container = LoroList | LoroMap | LoroText | LoroTree;\nexport type Prelim = PrelimList | PrelimMap | PrelimText;\n\n/**\n * Represents a path to identify the exact location of an event's target.\n * The path is composed of numbers (e.g., indices of a list container) and strings\n * (e.g., keys of a map container), indicating the absolute position of the event's source\n * within a loro document.\n */\nexport type Path = (number | string)[];\n\n/**\n * The event of Loro.\n * @prop local - Indicates whether the event is local.\n * @prop origin - (Optional) Provides information about the origin of the event.\n * @prop diff - Contains the differential information related to the event.\n * @prop target - Identifies the container ID of the event's target.\n * @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.\n */\nexport interface LoroEvent {\n /**\n * The unique ID of the event.\n */\n id: bigint;\n local: boolean;\n origin?: string;\n /**\n * If true, this event was triggered by a child container.\n */\n fromChildren: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n diff: Diff;\n target: ContainerID;\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<Value[]>[];\n};\n\nexport type TextDiff = {\n type: \"text\";\n diff: Delta<string>[];\n};\n\nexport type MapDiff = {\n type: \"map\";\n updated: Record<string, Value | undefined>;\n};\n\nexport type TreeDiff = {\n type: \"tree\";\n diff:\n | { target: TreeID; action: \"create\" | \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID };\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEvent): void;\n}\n\nconst CONTAINER_TYPES = [\"Map\", \"Text\", \"List\", \"Tree\"];\n\nexport function isContainerId(s: string): s is ContainerID {\n return s.startsWith(\"cid:\");\n}\n\nexport { Loro };\n\ndeclare module \"loro-wasm\" {\n interface Loro {\n subscribe(listener: Listener): number;\n }\n\n interface Loro<T extends Record<string, any> = Record<string, any>> {\n getTypedMap<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroMap ? T[Key] : never;\n getTypedList<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroList ? T[Key] : never;\n }\n\n interface LoroList<T extends any[] = any[]> {\n insertContainer(pos: number, container: \"Map\"): LoroMap;\n insertContainer(pos: number, container: \"List\"): LoroList;\n insertContainer(pos: number, container: \"Text\"): LoroText;\n insertContainer(pos: number, container: \"Tree\"): LoroTree;\n insertContainer(pos: number, container: string): never;\n\n get(index: number): undefined | Value | Container;\n getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];\n insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;\n insert(pos: number, value: Value | Prelim): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroMap<T extends Record<string, any> = Record<string, any>> {\n setContainer(key: string, container_type: \"Map\"): LoroMap;\n setContainer(key: string, container_type: \"List\"): LoroList;\n setContainer(key: string, container_type: \"Text\"): LoroText;\n setContainer(key: string, container_type: \"Tree\"): LoroTree;\n setContainer(key: string, container_type: string): never;\n\n get(key: string): undefined | Value | Container;\n getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];\n set(key: string, value: Value | Prelim): void;\n setTyped<Key extends keyof T & string>(key: Key, value: T[Key]): void;\n delete(key: string): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroText {\n insert(pos: number, text: string): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n}\n"],"names":["Loro","LoroList","LoroMap"],"mappings":";;;;AAaAA,aAAK,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACAA,aAAK,CAAA,SAAA,CAAU,YAAe,GAAA,SAAA,GAAa,IAAM,EAAA;AAC/C,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAA,CAAA;AAC7B,CAAA,CAAA;AACAC,iBAAA,CAAS,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,KAAO,EAAA;AACnD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AAC5B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACAA,iBAAS,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAClD,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACAC,gBAAA,CAAQ,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,GAAK,EAAA;AAChD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC1B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACAA,gBAAQ,CAAA,SAAA,CAAU,QAAW,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,GAAI,CAAA,GAAG,IAAI,CAAA,CAAA;AACzB,CAAA,CAAA;AAoFO,SAAS,cAAc,CAA6B,EAAA;AACzD,EAAO,OAAA,CAAA,CAAE,WAAW,MAAM,CAAA,CAAA;AAC5B;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"loro.js","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport { Container, ContainerType, Delta, OpId, Value } from \"loro-wasm\";\nimport { PrelimText, PrelimList, PrelimMap } from \"loro-wasm\";\nimport {\n ContainerID,\n Loro,\n LoroList,\n LoroMap,\n TreeID,\n} from \"loro-wasm\";\n\nLoro.prototype.getTypedMap = function (...args) {\n return this.getMap(...args);\n};\nLoro.prototype.getTypedList = function (...args) {\n return this.getList(...args);\n};\nLoroList.prototype.getTyped = function (loro, index) {\n const value = this.get(index);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroList.prototype.insertTyped = function (...args) {\n return this.insert(...args);\n};\nLoroMap.prototype.getTyped = function (loro, key) {\n const value = this.get(key);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroMap.prototype.setTyped = function (...args) {\n return this.set(...args);\n};\n\nexport type Prelim = PrelimList | PrelimMap | PrelimText;\nexport type Frontiers = OpId[];\n\n/**\n * Represents a path to identify the exact location of an event's target.\n * The path is composed of numbers (e.g., indices of a list container) and strings\n * (e.g., keys of a map container), indicating the absolute position of the event's source\n * within a loro document.\n */\nexport type Path = (number | string)[];\n\n/**\n * The event of Loro.\n * @prop local - Indicates whether the event is local.\n * @prop origin - (Optional) Provides information about the origin of the event.\n * @prop diff - Contains the differential information related to the event.\n * @prop target - Identifies the container ID of the event's target.\n * @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.\n */\nexport interface LoroEvent {\n /**\n * The unique ID of the event.\n */\n id: bigint;\n local: boolean;\n origin?: string;\n /**\n * If true, this event was triggered by a child container.\n */\n fromChildren: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n diff: Diff;\n target: ContainerID;\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<Value[]>[];\n};\n\nexport type TextDiff = {\n type: \"text\";\n diff: Delta<string>[];\n};\n\nexport type MapDiff = {\n type: \"map\";\n updated: Record<string, Value | undefined>;\n};\n\nexport type TreeDiff = {\n type: \"tree\";\n diff:\n | { target: TreeID; action: \"create\" | \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID };\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEvent): void;\n}\n\nconst CONTAINER_TYPES = [\"Map\", \"Text\", \"List\", \"Tree\"];\n\nexport function isContainerId(s: string): s is ContainerID {\n return s.startsWith(\"cid:\");\n}\n\nexport { Loro };\n\nexport function isContainer(value: any): value is Container {\n if (typeof value !== \"object\" || value == null) {\n return false;\n }\n\n const p = value.__proto__;\n return p.hasOwnProperty(\"kind\") && CONTAINER_TYPES.includes(value.kind());\n}\n\nexport function valueType(value: any): \"Json\" | ContainerType {\n if (isContainer(value)) {\n return value.kind();\n }\n\n return \"Json\";\n}\n\ndeclare module \"loro-wasm\" {\n interface Loro {\n subscribe(listener: Listener): number;\n }\n\n interface Loro<T extends Record<string, any> = Record<string, any>> {\n getTypedMap<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroMap ? T[Key] : never;\n getTypedList<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroList ? T[Key] : never;\n }\n\n interface LoroList<T extends any[] = any[]> {\n insertContainer(pos: number, container: \"Map\"): LoroMap;\n insertContainer(pos: number, container: \"List\"): LoroList;\n insertContainer(pos: number, container: \"Text\"): LoroText;\n insertContainer(pos: number, container: \"Tree\"): LoroTree;\n insertContainer(pos: number, container: string): never;\n\n get(index: number): undefined | Value | Container;\n getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];\n insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;\n insert(pos: number, value: Value | Prelim): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroMap<T extends Record<string, any> = Record<string, any>> {\n setContainer(key: string, container_type: \"Map\"): LoroMap;\n setContainer(key: string, container_type: \"List\"): LoroList;\n setContainer(key: string, container_type: \"Text\"): LoroText;\n setContainer(key: string, container_type: \"Tree\"): LoroTree;\n setContainer(key: string, container_type: string): never;\n\n get(key: string): undefined | Value | Container;\n getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];\n set(key: string, value: Value | Prelim): void;\n setTyped<Key extends keyof T & string>(key: Key, value: T[Key]): void;\n delete(key: string): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroText {\n insert(pos: number, text: string): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n}\n"],"names":["Loro","LoroList","LoroMap"],"mappings":";;;;AAWAA,aAAK,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACAA,aAAK,CAAA,SAAA,CAAU,YAAe,GAAA,SAAA,GAAa,IAAM,EAAA;AAC/C,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAA,CAAA;AAC7B,CAAA,CAAA;AACAC,iBAAA,CAAS,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,KAAO,EAAA;AACnD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AAC5B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACAA,iBAAS,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAClD,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACAC,gBAAA,CAAQ,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,GAAK,EAAA;AAChD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC1B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACAA,gBAAQ,CAAA,SAAA,CAAU,QAAW,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,GAAI,CAAA,GAAG,IAAI,CAAA,CAAA;AACzB,CAAA,CAAA;AAqEA,MAAM,eAAkB,GAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAM,CAAA,CAAA;AAE/C,SAAS,cAAc,CAA6B,EAAA;AACzD,EAAO,OAAA,CAAA,CAAE,WAAW,MAAM,CAAA,CAAA;AAC5B,CAAA;AAIO,SAAS,YAAY,KAAgC,EAAA;AAC1D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,KAAA,IAAS,IAAM,EAAA;AAC9C,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAA,MAAM,IAAI,KAAM,CAAA,SAAA,CAAA;AAChB,EAAO,OAAA,CAAA,CAAE,eAAe,MAAM,CAAA,IAAK,gBAAgB,QAAS,CAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AAC1E,CAAA;AAEO,SAAS,UAAU,KAAoC,EAAA;AAC5D,EAAI,IAAA,WAAA,CAAY,KAAK,CAAG,EAAA;AACtB,IAAA,OAAO,MAAM,IAAK,EAAA,CAAA;AAAA,GACpB;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;;;;;;;;;;;;;"}
package/dist/loro.mjs CHANGED
@@ -30,9 +30,23 @@ LoroMap.prototype.getTyped = function(loro, key) {
30
30
  LoroMap.prototype.setTyped = function(...args) {
31
31
  return this.set(...args);
32
32
  };
33
+ const CONTAINER_TYPES = ["Map", "Text", "List", "Tree"];
33
34
  function isContainerId(s) {
34
35
  return s.startsWith("cid:");
35
36
  }
37
+ function isContainer(value) {
38
+ if (typeof value !== "object" || value == null) {
39
+ return false;
40
+ }
41
+ const p = value.__proto__;
42
+ return p.hasOwnProperty("kind") && CONTAINER_TYPES.includes(value.kind());
43
+ }
44
+ function valueType(value) {
45
+ if (isContainer(value)) {
46
+ return value.kind();
47
+ }
48
+ return "Json";
49
+ }
36
50
 
37
- export { isContainerId };
51
+ export { isContainer, isContainerId, valueType };
38
52
  //# sourceMappingURL=loro.mjs.map
package/dist/loro.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"loro.mjs","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport { Delta } from \"loro-wasm\";\nimport { PrelimText, PrelimList, PrelimMap } from \"loro-wasm\";\nimport {\n ContainerID,\n Loro,\n LoroList,\n LoroMap,\n LoroText,\n LoroTree,\n TreeID,\n} from \"loro-wasm\";\n\nLoro.prototype.getTypedMap = function (...args) {\n return this.getMap(...args);\n};\nLoro.prototype.getTypedList = function (...args) {\n return this.getList(...args);\n};\nLoroList.prototype.getTyped = function (loro, index) {\n const value = this.get(index);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroList.prototype.insertTyped = function (...args) {\n return this.insert(...args);\n};\nLoroMap.prototype.getTyped = function (loro, key) {\n const value = this.get(key);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroMap.prototype.setTyped = function (...args) {\n return this.set(...args);\n};\n\n/**\n * Data types supported by loro\n */\nexport type Value =\n | ContainerID\n | string\n | number\n | boolean\n | null\n | { [key: string]: Value }\n | Uint8Array\n | Value[];\n\nexport type Container = LoroList | LoroMap | LoroText | LoroTree;\nexport type Prelim = PrelimList | PrelimMap | PrelimText;\n\n/**\n * Represents a path to identify the exact location of an event's target.\n * The path is composed of numbers (e.g., indices of a list container) and strings\n * (e.g., keys of a map container), indicating the absolute position of the event's source\n * within a loro document.\n */\nexport type Path = (number | string)[];\n\n/**\n * The event of Loro.\n * @prop local - Indicates whether the event is local.\n * @prop origin - (Optional) Provides information about the origin of the event.\n * @prop diff - Contains the differential information related to the event.\n * @prop target - Identifies the container ID of the event's target.\n * @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.\n */\nexport interface LoroEvent {\n /**\n * The unique ID of the event.\n */\n id: bigint;\n local: boolean;\n origin?: string;\n /**\n * If true, this event was triggered by a child container.\n */\n fromChildren: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n diff: Diff;\n target: ContainerID;\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<Value[]>[];\n};\n\nexport type TextDiff = {\n type: \"text\";\n diff: Delta<string>[];\n};\n\nexport type MapDiff = {\n type: \"map\";\n updated: Record<string, Value | undefined>;\n};\n\nexport type TreeDiff = {\n type: \"tree\";\n diff:\n | { target: TreeID; action: \"create\" | \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID };\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEvent): void;\n}\n\nconst CONTAINER_TYPES = [\"Map\", \"Text\", \"List\", \"Tree\"];\n\nexport function isContainerId(s: string): s is ContainerID {\n return s.startsWith(\"cid:\");\n}\n\nexport { Loro };\n\ndeclare module \"loro-wasm\" {\n interface Loro {\n subscribe(listener: Listener): number;\n }\n\n interface Loro<T extends Record<string, any> = Record<string, any>> {\n getTypedMap<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroMap ? T[Key] : never;\n getTypedList<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroList ? T[Key] : never;\n }\n\n interface LoroList<T extends any[] = any[]> {\n insertContainer(pos: number, container: \"Map\"): LoroMap;\n insertContainer(pos: number, container: \"List\"): LoroList;\n insertContainer(pos: number, container: \"Text\"): LoroText;\n insertContainer(pos: number, container: \"Tree\"): LoroTree;\n insertContainer(pos: number, container: string): never;\n\n get(index: number): undefined | Value | Container;\n getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];\n insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;\n insert(pos: number, value: Value | Prelim): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroMap<T extends Record<string, any> = Record<string, any>> {\n setContainer(key: string, container_type: \"Map\"): LoroMap;\n setContainer(key: string, container_type: \"List\"): LoroList;\n setContainer(key: string, container_type: \"Text\"): LoroText;\n setContainer(key: string, container_type: \"Tree\"): LoroTree;\n setContainer(key: string, container_type: string): never;\n\n get(key: string): undefined | Value | Container;\n getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];\n set(key: string, value: Value | Prelim): void;\n setTyped<Key extends keyof T & string>(key: Key, value: T[Key]): void;\n delete(key: string): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroText {\n insert(pos: number, text: string): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n}\n"],"names":[],"mappings":";;;;AAaA,IAAK,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACA,IAAK,CAAA,SAAA,CAAU,YAAe,GAAA,SAAA,GAAa,IAAM,EAAA;AAC/C,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAA,CAAA;AAC7B,CAAA,CAAA;AACA,QAAA,CAAS,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,KAAO,EAAA;AACnD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AAC5B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,QAAS,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAClD,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACA,OAAA,CAAQ,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,GAAK,EAAA;AAChD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC1B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,OAAQ,CAAA,SAAA,CAAU,QAAW,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,GAAI,CAAA,GAAG,IAAI,CAAA,CAAA;AACzB,CAAA,CAAA;AAoFO,SAAS,cAAc,CAA6B,EAAA;AACzD,EAAO,OAAA,CAAA,CAAE,WAAW,MAAM,CAAA,CAAA;AAC5B;;;;"}
1
+ {"version":3,"file":"loro.mjs","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport { Container, ContainerType, Delta, OpId, Value } from \"loro-wasm\";\nimport { PrelimText, PrelimList, PrelimMap } from \"loro-wasm\";\nimport {\n ContainerID,\n Loro,\n LoroList,\n LoroMap,\n TreeID,\n} from \"loro-wasm\";\n\nLoro.prototype.getTypedMap = function (...args) {\n return this.getMap(...args);\n};\nLoro.prototype.getTypedList = function (...args) {\n return this.getList(...args);\n};\nLoroList.prototype.getTyped = function (loro, index) {\n const value = this.get(index);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroList.prototype.insertTyped = function (...args) {\n return this.insert(...args);\n};\nLoroMap.prototype.getTyped = function (loro, key) {\n const value = this.get(key);\n if (typeof value === \"string\" && isContainerId(value)) {\n return loro.getContainerById(value);\n } else {\n return value;\n }\n};\nLoroMap.prototype.setTyped = function (...args) {\n return this.set(...args);\n};\n\nexport type Prelim = PrelimList | PrelimMap | PrelimText;\nexport type Frontiers = OpId[];\n\n/**\n * Represents a path to identify the exact location of an event's target.\n * The path is composed of numbers (e.g., indices of a list container) and strings\n * (e.g., keys of a map container), indicating the absolute position of the event's source\n * within a loro document.\n */\nexport type Path = (number | string)[];\n\n/**\n * The event of Loro.\n * @prop local - Indicates whether the event is local.\n * @prop origin - (Optional) Provides information about the origin of the event.\n * @prop diff - Contains the differential information related to the event.\n * @prop target - Identifies the container ID of the event's target.\n * @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.\n */\nexport interface LoroEvent {\n /**\n * The unique ID of the event.\n */\n id: bigint;\n local: boolean;\n origin?: string;\n /**\n * If true, this event was triggered by a child container.\n */\n fromChildren: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n diff: Diff;\n target: ContainerID;\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<Value[]>[];\n};\n\nexport type TextDiff = {\n type: \"text\";\n diff: Delta<string>[];\n};\n\nexport type MapDiff = {\n type: \"map\";\n updated: Record<string, Value | undefined>;\n};\n\nexport type TreeDiff = {\n type: \"tree\";\n diff:\n | { target: TreeID; action: \"create\" | \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID };\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEvent): void;\n}\n\nconst CONTAINER_TYPES = [\"Map\", \"Text\", \"List\", \"Tree\"];\n\nexport function isContainerId(s: string): s is ContainerID {\n return s.startsWith(\"cid:\");\n}\n\nexport { Loro };\n\nexport function isContainer(value: any): value is Container {\n if (typeof value !== \"object\" || value == null) {\n return false;\n }\n\n const p = value.__proto__;\n return p.hasOwnProperty(\"kind\") && CONTAINER_TYPES.includes(value.kind());\n}\n\nexport function valueType(value: any): \"Json\" | ContainerType {\n if (isContainer(value)) {\n return value.kind();\n }\n\n return \"Json\";\n}\n\ndeclare module \"loro-wasm\" {\n interface Loro {\n subscribe(listener: Listener): number;\n }\n\n interface Loro<T extends Record<string, any> = Record<string, any>> {\n getTypedMap<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroMap ? T[Key] : never;\n getTypedList<Key extends keyof T & string>(\n name: Key,\n ): T[Key] extends LoroList ? T[Key] : never;\n }\n\n interface LoroList<T extends any[] = any[]> {\n insertContainer(pos: number, container: \"Map\"): LoroMap;\n insertContainer(pos: number, container: \"List\"): LoroList;\n insertContainer(pos: number, container: \"Text\"): LoroText;\n insertContainer(pos: number, container: \"Tree\"): LoroTree;\n insertContainer(pos: number, container: string): never;\n\n get(index: number): undefined | Value | Container;\n getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];\n insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;\n insert(pos: number, value: Value | Prelim): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroMap<T extends Record<string, any> = Record<string, any>> {\n setContainer(key: string, container_type: \"Map\"): LoroMap;\n setContainer(key: string, container_type: \"List\"): LoroList;\n setContainer(key: string, container_type: \"Text\"): LoroText;\n setContainer(key: string, container_type: \"Tree\"): LoroTree;\n setContainer(key: string, container_type: string): never;\n\n get(key: string): undefined | Value | Container;\n getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];\n set(key: string, value: Value | Prelim): void;\n setTyped<Key extends keyof T & string>(key: Key, value: T[Key]): void;\n delete(key: string): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroText {\n insert(pos: number, text: string): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n }\n}\n"],"names":[],"mappings":";;;;AAWA,IAAK,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACA,IAAK,CAAA,SAAA,CAAU,YAAe,GAAA,SAAA,GAAa,IAAM,EAAA;AAC/C,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,GAAG,IAAI,CAAA,CAAA;AAC7B,CAAA,CAAA;AACA,QAAA,CAAS,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,KAAO,EAAA;AACnD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AAC5B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,QAAS,CAAA,SAAA,CAAU,WAAc,GAAA,SAAA,GAAa,IAAM,EAAA;AAClD,EAAO,OAAA,IAAA,CAAK,MAAO,CAAA,GAAG,IAAI,CAAA,CAAA;AAC5B,CAAA,CAAA;AACA,OAAA,CAAQ,SAAU,CAAA,QAAA,GAAW,SAAU,IAAA,EAAM,GAAK,EAAA;AAChD,EAAM,MAAA,KAAA,GAAQ,IAAK,CAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAC1B,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,aAAA,CAAc,KAAK,CAAG,EAAA;AACrD,IAAO,OAAA,IAAA,CAAK,iBAAiB,KAAK,CAAA,CAAA;AAAA,GAC7B,MAAA;AACL,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AACF,CAAA,CAAA;AACA,OAAQ,CAAA,SAAA,CAAU,QAAW,GAAA,SAAA,GAAa,IAAM,EAAA;AAC9C,EAAO,OAAA,IAAA,CAAK,GAAI,CAAA,GAAG,IAAI,CAAA,CAAA;AACzB,CAAA,CAAA;AAqEA,MAAM,eAAkB,GAAA,CAAC,KAAO,EAAA,MAAA,EAAQ,QAAQ,MAAM,CAAA,CAAA;AAE/C,SAAS,cAAc,CAA6B,EAAA;AACzD,EAAO,OAAA,CAAA,CAAE,WAAW,MAAM,CAAA,CAAA;AAC5B,CAAA;AAIO,SAAS,YAAY,KAAgC,EAAA;AAC1D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,KAAA,IAAS,IAAM,EAAA;AAC9C,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAA,MAAM,IAAI,KAAM,CAAA,SAAA,CAAA;AAChB,EAAO,OAAA,CAAA,CAAE,eAAe,MAAM,CAAA,IAAK,gBAAgB,QAAS,CAAA,KAAA,CAAM,MAAM,CAAA,CAAA;AAC1E,CAAA;AAEO,SAAS,UAAU,KAAoC,EAAA;AAC5D,EAAI,IAAA,WAAA,CAAY,KAAK,CAAG,EAAA;AACtB,IAAA,OAAO,MAAM,IAAK,EAAA,CAAA;AAAA,GACpB;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "loro-crdt",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "Loro CRDTs is a high-performance CRDT framework that makes your app state synchronized, collaborative and maintainable effortlessly.",
5
5
  "keywords": [
6
6
  "crdt",
@@ -17,7 +17,7 @@
17
17
  "homepage": "https://loro.dev",
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
- "loro-wasm": "0.4.2"
20
+ "loro-wasm": "0.5.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@rollup/plugin-node-resolve": "^15.0.1",
package/src/index.ts CHANGED
@@ -1,13 +1,11 @@
1
1
  export * from "loro-wasm";
2
- import { Delta } from "loro-wasm";
2
+ import { Container, ContainerType, Delta, OpId, Value } from "loro-wasm";
3
3
  import { PrelimText, PrelimList, PrelimMap } from "loro-wasm";
4
4
  import {
5
5
  ContainerID,
6
6
  Loro,
7
7
  LoroList,
8
8
  LoroMap,
9
- LoroText,
10
- LoroTree,
11
9
  TreeID,
12
10
  } from "loro-wasm";
13
11
 
@@ -40,21 +38,8 @@ LoroMap.prototype.setTyped = function (...args) {
40
38
  return this.set(...args);
41
39
  };
42
40
 
43
- /**
44
- * Data types supported by loro
45
- */
46
- export type Value =
47
- | ContainerID
48
- | string
49
- | number
50
- | boolean
51
- | null
52
- | { [key: string]: Value }
53
- | Uint8Array
54
- | Value[];
55
-
56
- export type Container = LoroList | LoroMap | LoroText | LoroTree;
57
41
  export type Prelim = PrelimList | PrelimMap | PrelimText;
42
+ export type Frontiers = OpId[];
58
43
 
59
44
  /**
60
45
  * Represents a path to identify the exact location of an event's target.
@@ -110,8 +95,8 @@ export type MapDiff = {
110
95
  export type TreeDiff = {
111
96
  type: "tree";
112
97
  diff:
113
- | { target: TreeID; action: "create" | "delete" }
114
- | { target: TreeID; action: "move"; parent: TreeID };
98
+ | { target: TreeID; action: "create" | "delete" }
99
+ | { target: TreeID; action: "move"; parent: TreeID };
115
100
  };
116
101
 
117
102
  export type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;
@@ -128,6 +113,23 @@ export function isContainerId(s: string): s is ContainerID {
128
113
 
129
114
  export { Loro };
130
115
 
116
+ export function isContainer(value: any): value is Container {
117
+ if (typeof value !== "object" || value == null) {
118
+ return false;
119
+ }
120
+
121
+ const p = value.__proto__;
122
+ return p.hasOwnProperty("kind") && CONTAINER_TYPES.includes(value.kind());
123
+ }
124
+
125
+ export function valueType(value: any): "Json" | ContainerType {
126
+ if (isContainer(value)) {
127
+ return value.kind();
128
+ }
129
+
130
+ return "Json";
131
+ }
132
+
131
133
  declare module "loro-wasm" {
132
134
  interface Loro {
133
135
  subscribe(listener: Listener): number;