loro-crdt 0.12.0 → 0.13.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/CHANGELOG.md +27 -0
- package/dist/loro.d.ts +21 -24
- package/dist/loro.js.map +1 -1
- package/dist/loro.mjs.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +48 -41
- package/tsconfig.json +1 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Fix type errors and conversion from js->rust error
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- loro-wasm@0.13.1
|
|
10
|
+
|
|
11
|
+
## 0.13.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- BREAKING CHANGE: `detached` mode for Containers #300
|
|
16
|
+
|
|
17
|
+
Now creating sub-containers is much easier.
|
|
18
|
+
|
|
19
|
+
A container can be either attached to a document or detached. When it's detached, its history/state is not persisted. You can attach a container to a document by inserting it into an existing attached container. Once a container is attached, its state, along with all of its descendants's states, will be recreated in the document. After attaching, the container and its descendants will each have their corresponding "attached" version of themselves.
|
|
20
|
+
|
|
21
|
+
When a detached container x is attached to a document, you can use `x.getAttached()` to obtain the corresponding attached container.
|
|
22
|
+
|
|
23
|
+
When we use const text = new LoroList(), it's not attached to a doc. But we can insert it into a doc by map.insertContainer(”t”, text), where the map is attached. But if we want the operations on the text to be recorded to the doc, we now need to get its attached version. So we can use “let attachedText = text.getAttached()”
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- Updated dependencies
|
|
28
|
+
- loro-wasm@0.13.0
|
|
29
|
+
|
|
3
30
|
## 0.12.0
|
|
4
31
|
|
|
5
32
|
### Minor Changes
|
package/dist/loro.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ContainerID, Container, Value, TreeID, OpId, Delta, LoroText, LoroMap, LoroTree, LoroList } from 'loro-wasm';
|
|
2
2
|
export * from 'loro-wasm';
|
|
3
3
|
export { Loro } from 'loro-wasm';
|
|
4
4
|
|
|
@@ -115,7 +115,7 @@ declare function isContainer(value: any): value is Container;
|
|
|
115
115
|
* getType({}); // "Json"
|
|
116
116
|
* ```
|
|
117
117
|
*/
|
|
118
|
-
declare function getType<T>(value: T): T extends LoroText ? "Text" : T extends LoroMap ? "Map" : T extends LoroTree ? "Tree" : T extends LoroList ? "List" : "Json";
|
|
118
|
+
declare function getType<T>(value: T): T extends LoroText ? "Text" : T extends LoroMap<any> ? "Map" : T extends LoroTree<any> ? "Tree" : T extends LoroList<any> ? "List" : "Json";
|
|
119
119
|
declare module "loro-wasm" {
|
|
120
120
|
interface Loro {
|
|
121
121
|
subscribe(listener: Listener): number;
|
|
@@ -123,31 +123,26 @@ declare module "loro-wasm" {
|
|
|
123
123
|
interface Loro<T extends Record<string, any> = Record<string, any>> {
|
|
124
124
|
getTypedMap<Key extends keyof T & string>(name: Key): T[Key] extends LoroMap ? T[Key] : never;
|
|
125
125
|
getTypedList<Key extends keyof T & string>(name: Key): T[Key] extends LoroList ? T[Key] : never;
|
|
126
|
+
getMap(key: string | ContainerID): LoroMap<T[string]>;
|
|
127
|
+
getList(key: string | ContainerID): LoroList<T[string]>;
|
|
128
|
+
getTree(key: string | ContainerID): LoroTree<T[string]>;
|
|
129
|
+
getText(key: string | ContainerID): LoroText;
|
|
126
130
|
}
|
|
127
131
|
interface LoroList<T extends any[] = any[]> {
|
|
128
|
-
|
|
129
|
-
insertContainer(pos: number,
|
|
130
|
-
insertContainer(pos: number, container: "Text"): LoroText;
|
|
131
|
-
insertContainer(pos: number, container: "Tree"): LoroTree;
|
|
132
|
-
insertContainer(pos: number, container: string): never;
|
|
132
|
+
new (): LoroList<T>;
|
|
133
|
+
insertContainer<C extends Container>(pos: number, child: C): C;
|
|
133
134
|
get(index: number): undefined | Value | Container;
|
|
134
135
|
getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];
|
|
135
136
|
insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;
|
|
136
137
|
insert(pos: number, value: Value): void;
|
|
137
138
|
delete(pos: number, len: number): void;
|
|
138
139
|
subscribe(txn: Loro, listener: Listener): number;
|
|
140
|
+
getAttached(): undefined | LoroList<T>;
|
|
139
141
|
}
|
|
140
142
|
interface LoroMap<T extends Record<string, any> = Record<string, any>> {
|
|
141
|
-
|
|
142
|
-
getOrCreateContainer(key: string,
|
|
143
|
-
|
|
144
|
-
getOrCreateContainer(key: string, container_type: "Tree"): LoroTree;
|
|
145
|
-
getOrCreateContainer(key: string, container_type: string): never;
|
|
146
|
-
setContainer(key: string, container_type: "Map"): LoroMap;
|
|
147
|
-
setContainer(key: string, container_type: "List"): LoroList;
|
|
148
|
-
setContainer(key: string, container_type: "Text"): LoroText;
|
|
149
|
-
setContainer(key: string, container_type: "Tree"): LoroTree;
|
|
150
|
-
setContainer(key: string, container_type: string): never;
|
|
143
|
+
new (): LoroMap<T>;
|
|
144
|
+
getOrCreateContainer<C extends Container>(key: string, child: C): C;
|
|
145
|
+
setContainer<C extends Container>(key: string, child: C): C;
|
|
151
146
|
get(key: string): undefined | Value | Container;
|
|
152
147
|
getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];
|
|
153
148
|
set(key: string, value: Value): void;
|
|
@@ -156,25 +151,27 @@ declare module "loro-wasm" {
|
|
|
156
151
|
subscribe(txn: Loro, listener: Listener): number;
|
|
157
152
|
}
|
|
158
153
|
interface LoroText {
|
|
154
|
+
new (): LoroText;
|
|
159
155
|
insert(pos: number, text: string): void;
|
|
160
156
|
delete(pos: number, len: number): void;
|
|
161
157
|
subscribe(txn: Loro, listener: Listener): number;
|
|
162
158
|
}
|
|
163
|
-
interface LoroTree {
|
|
164
|
-
|
|
159
|
+
interface LoroTree<T extends Record<string, any> = Record<string, any>> {
|
|
160
|
+
new (): LoroTree<T>;
|
|
161
|
+
createNode(parent: TreeID | undefined): LoroTreeNode<T>;
|
|
165
162
|
move(target: TreeID, parent: TreeID | undefined): void;
|
|
166
163
|
delete(target: TreeID): void;
|
|
167
164
|
has(target: TreeID): boolean;
|
|
168
165
|
getNodeByID(target: TreeID): LoroTreeNode;
|
|
169
166
|
subscribe(txn: Loro, listener: Listener): number;
|
|
170
167
|
}
|
|
171
|
-
interface LoroTreeNode {
|
|
172
|
-
readonly data: LoroMap
|
|
173
|
-
createNode(): LoroTreeNode
|
|
168
|
+
interface LoroTreeNode<T extends Record<string, any> = Record<string, any>> {
|
|
169
|
+
readonly data: LoroMap<T>;
|
|
170
|
+
createNode(): LoroTreeNode<T>;
|
|
174
171
|
setAsRoot(): void;
|
|
175
|
-
moveTo(parent: LoroTreeNode): void;
|
|
172
|
+
moveTo(parent: LoroTreeNode<T>): void;
|
|
176
173
|
parent(): LoroTreeNode | undefined;
|
|
177
|
-
children(): Array<LoroTreeNode
|
|
174
|
+
children(): Array<LoroTreeNode<T>>;
|
|
178
175
|
}
|
|
179
176
|
}
|
|
180
177
|
|
package/dist/loro.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loro.js","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport {\n Container,\n Delta,\n LoroText,\n LoroTree,\n LoroTreeNode,\n OpId,\n Value,\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 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) strings\n * (e.g., keys of a map container) and TreeID (the node of a tree container),\n * indicating the absolute position of the event's source within a loro document.\n */\nexport type Path = (number | string | TreeID)[];\n\n/**\n * A batch of events that created by a single `import`/`transaction`/`checkout`.\n *\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 LoroEventBatch {\n local: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n origin?: string;\n /**\n * The container ID of the current event receiver.\n * It's undefined if the subscriber is on the root document.\n */\n currentTarget?: ContainerID;\n events: LoroEvent[];\n}\n\n/**\n * The concrete event of Loro.\n */\nexport interface LoroEvent {\n /**\n * The container ID of the event's target.\n */\n target: ContainerID;\n diff: Diff;\n /**\n * 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 */\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<(Value | Container)[]>[];\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 | Container | undefined>;\n};\n\nexport type TreeDiffItem =\n | { target: TreeID; action: \"create\"; parent: TreeID | undefined }\n | { target: TreeID; action: \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID | undefined };\n\nexport type TreeDiff = {\n type: \"tree\";\n diff: TreeDiffItem[];\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEventBatch): 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\n/** Whether the value is a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * isContainer(map); // true\n * isContainer(list); // true\n * isContainer(text); // true\n * isContainer(123); // false\n * isContainer(\"123\"); // false\n * isContainer({}); // false\n */\nexport function isContainer(value: any): value is Container {\n if (typeof value !== \"object\" || value == null) {\n return false;\n }\n\n const p = Object.getPrototypeOf(value);\n if (p == null || typeof p !== \"object\" || typeof p[\"kind\"] !== \"function\") {\n return false;\n }\n\n return CONTAINER_TYPES.includes(value.kind());\n}\n\n/** Get the type of a value that may be a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * getType(map); // \"Map\"\n * getType(list); // \"List\"\n * getType(text); // \"Text\"\n * getType(123); // \"Json\"\n * getType(\"123\"); // \"Json\"\n * getType({}); // \"Json\"\n * ```\n */\nexport function getType<T>(\n value: T,\n): T extends LoroText\n ? \"Text\"\n : T extends LoroMap\n ? \"Map\"\n : T extends LoroTree\n ? \"Tree\"\n : T extends LoroList\n ? \"List\"\n : \"Json\" {\n if (isContainer(value)) {\n return value.kind();\n }\n\n return \"Json\" as any;\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): 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 getOrCreateContainer(key: string, container_type: \"Map\"): LoroMap;\n getOrCreateContainer(key: string, container_type: \"List\"): LoroList;\n getOrCreateContainer(key: string, container_type: \"Text\"): LoroText;\n getOrCreateContainer(key: string, container_type: \"Tree\"): LoroTree;\n getOrCreateContainer(key: string, container_type: string): never;\n\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): 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 interface LoroTree {\n createNode(parent: TreeID | undefined): LoroTreeNode;\n move(target: TreeID, parent: TreeID | undefined): void;\n delete(target: TreeID): void;\n has(target: TreeID): boolean;\n getNodeByID(target: TreeID): LoroTreeNode;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroTreeNode {\n readonly data: LoroMap;\n createNode(): LoroTreeNode;\n setAsRoot(): void;\n moveTo(parent: LoroTreeNode): void;\n parent(): LoroTreeNode | undefined;\n children(): Array<LoroTreeNode>;\n }\n}\n"],"names":["Loro","LoroList","LoroMap"],"mappings":";;;;AAgBAA,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;AAkFA,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;AAoBO,SAAS,YAAY,KAAgC,EAAA;AAC1D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,KAAA,IAAS,IAAM,EAAA;AAC9C,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,CAAA,GAAI,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AACrC,EAAI,IAAA,CAAA,IAAK,QAAQ,OAAO,CAAA,KAAM,YAAY,OAAO,CAAA,CAAE,MAAM,CAAA,KAAM,UAAY,EAAA;AACzE,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,eAAgB,CAAA,QAAA,CAAS,KAAM,CAAA,IAAA,EAAM,CAAA,CAAA;AAC9C,CAAA;AAmBO,SAAS,QACd,KASS,EAAA;AACT,EAAI,IAAA,WAAA,CAAY,KAAK,CAAG,EAAA;AACtB,IAAA,OAAO,MAAM,IAAK,EAAA,CAAA;AAAA,GACpB;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"loro.js","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport {\n Container,\n ContainerID,\n Delta,\n Loro,\n LoroList,\n LoroMap,\n LoroText,\n LoroTree,\n LoroTreeNode,\n OpId,\n TreeID,\n Value,\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 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) strings\n * (e.g., keys of a map container) and TreeID (the node of a tree container),\n * indicating the absolute position of the event's source within a loro document.\n */\nexport type Path = (number | string | TreeID)[];\n\n/**\n * A batch of events that created by a single `import`/`transaction`/`checkout`.\n *\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 LoroEventBatch {\n local: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n origin?: string;\n /**\n * The container ID of the current event receiver.\n * It's undefined if the subscriber is on the root document.\n */\n currentTarget?: ContainerID;\n events: LoroEvent[];\n}\n\n/**\n * The concrete event of Loro.\n */\nexport interface LoroEvent {\n /**\n * The container ID of the event's target.\n */\n target: ContainerID;\n diff: Diff;\n /**\n * 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 */\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<(Value | Container)[]>[];\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 | Container | undefined>;\n};\n\nexport type TreeDiffItem =\n | { target: TreeID; action: \"create\"; parent: TreeID | undefined }\n | { target: TreeID; action: \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID | undefined };\n\nexport type TreeDiff = {\n type: \"tree\";\n diff: TreeDiffItem[];\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEventBatch): 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\n/** Whether the value is a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * isContainer(map); // true\n * isContainer(list); // true\n * isContainer(text); // true\n * isContainer(123); // false\n * isContainer(\"123\"); // false\n * isContainer({}); // false\n */\nexport function isContainer(value: any): value is Container {\n if (typeof value !== \"object\" || value == null) {\n return false;\n }\n\n const p = Object.getPrototypeOf(value);\n if (p == null || typeof p !== \"object\" || typeof p[\"kind\"] !== \"function\") {\n return false;\n }\n\n return CONTAINER_TYPES.includes(value.kind());\n}\n\n/** Get the type of a value that may be a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * getType(map); // \"Map\"\n * getType(list); // \"List\"\n * getType(text); // \"Text\"\n * getType(123); // \"Json\"\n * getType(\"123\"); // \"Json\"\n * getType({}); // \"Json\"\n * ```\n */\nexport function getType<T>(\n value: T,\n): T extends LoroText ? \"Text\"\n : T extends LoroMap<any> ? \"Map\"\n : T extends LoroTree<any> ? \"Tree\"\n : T extends LoroList<any> ? \"List\"\n : \"Json\" {\n if (isContainer(value)) {\n return value.kind() as unknown as any;\n }\n\n return \"Json\" as any;\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 getMap(key: string | ContainerID): LoroMap<T[string]>;\n getList(key: string | ContainerID): LoroList<T[string]>;\n getTree(key: string | ContainerID): LoroTree<T[string]>;\n getText(key: string | ContainerID): LoroText;\n }\n\n interface LoroList<\n T extends any[] = any[],\n > {\n new (): LoroList<T>;\n insertContainer<C extends Container>(\n pos: number,\n child: C,\n ): C;\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): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n getAttached(): undefined | LoroList<T>;\n }\n\n interface LoroMap<\n T extends Record<string, any> = Record<string, any>,\n > {\n new (): LoroMap<T>;\n getOrCreateContainer<C extends Container>(\n key: string,\n child: C,\n ): C;\n setContainer<C extends Container>(\n key: string,\n child: C,\n ): C;\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): 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 new (): 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 interface LoroTree<\n T extends Record<string, any> = Record<string, any>,\n > {\n new (): LoroTree<T>;\n createNode(parent: TreeID | undefined): LoroTreeNode<T>;\n move(target: TreeID, parent: TreeID | undefined): void;\n delete(target: TreeID): void;\n has(target: TreeID): boolean;\n getNodeByID(target: TreeID): LoroTreeNode;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroTreeNode<\n T extends Record<string, any> = Record<string, any>,\n > {\n readonly data: LoroMap<T>;\n createNode(): LoroTreeNode<T>;\n setAsRoot(): void;\n moveTo(parent: LoroTreeNode<T>): void;\n parent(): LoroTreeNode | undefined;\n children(): Array<LoroTreeNode<T>>;\n }\n}\n"],"names":["Loro","LoroList","LoroMap"],"mappings":";;;;AAgBAA,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;AAkFA,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;AAoBO,SAAS,YAAY,KAAgC,EAAA;AAC1D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,KAAA,IAAS,IAAM,EAAA;AAC9C,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,CAAA,GAAI,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AACrC,EAAI,IAAA,CAAA,IAAK,QAAQ,OAAO,CAAA,KAAM,YAAY,OAAO,CAAA,CAAE,MAAM,CAAA,KAAM,UAAY,EAAA;AACzE,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,eAAgB,CAAA,QAAA,CAAS,KAAM,CAAA,IAAA,EAAM,CAAA,CAAA;AAC9C,CAAA;AAmBO,SAAS,QACd,KAKS,EAAA;AACT,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.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loro.mjs","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport {\n Container,\n
|
|
1
|
+
{"version":3,"file":"loro.mjs","sources":["../src/index.ts"],"sourcesContent":["export * from \"loro-wasm\";\nimport {\n Container,\n ContainerID,\n Delta,\n Loro,\n LoroList,\n LoroMap,\n LoroText,\n LoroTree,\n LoroTreeNode,\n OpId,\n TreeID,\n Value,\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 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) strings\n * (e.g., keys of a map container) and TreeID (the node of a tree container),\n * indicating the absolute position of the event's source within a loro document.\n */\nexport type Path = (number | string | TreeID)[];\n\n/**\n * A batch of events that created by a single `import`/`transaction`/`checkout`.\n *\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 LoroEventBatch {\n local: boolean;\n /**\n * If true, this event was triggered by a checkout.\n */\n fromCheckout: boolean;\n origin?: string;\n /**\n * The container ID of the current event receiver.\n * It's undefined if the subscriber is on the root document.\n */\n currentTarget?: ContainerID;\n events: LoroEvent[];\n}\n\n/**\n * The concrete event of Loro.\n */\nexport interface LoroEvent {\n /**\n * The container ID of the event's target.\n */\n target: ContainerID;\n diff: Diff;\n /**\n * 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 */\n path: Path;\n}\n\nexport type ListDiff = {\n type: \"list\";\n diff: Delta<(Value | Container)[]>[];\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 | Container | undefined>;\n};\n\nexport type TreeDiffItem =\n | { target: TreeID; action: \"create\"; parent: TreeID | undefined }\n | { target: TreeID; action: \"delete\" }\n | { target: TreeID; action: \"move\"; parent: TreeID | undefined };\n\nexport type TreeDiff = {\n type: \"tree\";\n diff: TreeDiffItem[];\n};\n\nexport type Diff = ListDiff | TextDiff | MapDiff | TreeDiff;\n\ninterface Listener {\n (event: LoroEventBatch): 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\n/** Whether the value is a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * isContainer(map); // true\n * isContainer(list); // true\n * isContainer(text); // true\n * isContainer(123); // false\n * isContainer(\"123\"); // false\n * isContainer({}); // false\n */\nexport function isContainer(value: any): value is Container {\n if (typeof value !== \"object\" || value == null) {\n return false;\n }\n\n const p = Object.getPrototypeOf(value);\n if (p == null || typeof p !== \"object\" || typeof p[\"kind\"] !== \"function\") {\n return false;\n }\n\n return CONTAINER_TYPES.includes(value.kind());\n}\n\n/** Get the type of a value that may be a container.\n *\n * # Example\n *\n * ```ts\n * const doc = new Loro();\n * const map = doc.getMap(\"map\");\n * const list = doc.getList(\"list\");\n * const text = doc.getText(\"text\");\n * getType(map); // \"Map\"\n * getType(list); // \"List\"\n * getType(text); // \"Text\"\n * getType(123); // \"Json\"\n * getType(\"123\"); // \"Json\"\n * getType({}); // \"Json\"\n * ```\n */\nexport function getType<T>(\n value: T,\n): T extends LoroText ? \"Text\"\n : T extends LoroMap<any> ? \"Map\"\n : T extends LoroTree<any> ? \"Tree\"\n : T extends LoroList<any> ? \"List\"\n : \"Json\" {\n if (isContainer(value)) {\n return value.kind() as unknown as any;\n }\n\n return \"Json\" as any;\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 getMap(key: string | ContainerID): LoroMap<T[string]>;\n getList(key: string | ContainerID): LoroList<T[string]>;\n getTree(key: string | ContainerID): LoroTree<T[string]>;\n getText(key: string | ContainerID): LoroText;\n }\n\n interface LoroList<\n T extends any[] = any[],\n > {\n new (): LoroList<T>;\n insertContainer<C extends Container>(\n pos: number,\n child: C,\n ): C;\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): void;\n delete(pos: number, len: number): void;\n subscribe(txn: Loro, listener: Listener): number;\n getAttached(): undefined | LoroList<T>;\n }\n\n interface LoroMap<\n T extends Record<string, any> = Record<string, any>,\n > {\n new (): LoroMap<T>;\n getOrCreateContainer<C extends Container>(\n key: string,\n child: C,\n ): C;\n setContainer<C extends Container>(\n key: string,\n child: C,\n ): C;\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): 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 new (): 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 interface LoroTree<\n T extends Record<string, any> = Record<string, any>,\n > {\n new (): LoroTree<T>;\n createNode(parent: TreeID | undefined): LoroTreeNode<T>;\n move(target: TreeID, parent: TreeID | undefined): void;\n delete(target: TreeID): void;\n has(target: TreeID): boolean;\n getNodeByID(target: TreeID): LoroTreeNode;\n subscribe(txn: Loro, listener: Listener): number;\n }\n\n interface LoroTreeNode<\n T extends Record<string, any> = Record<string, any>,\n > {\n readonly data: LoroMap<T>;\n createNode(): LoroTreeNode<T>;\n setAsRoot(): void;\n moveTo(parent: LoroTreeNode<T>): void;\n parent(): LoroTreeNode | undefined;\n children(): Array<LoroTreeNode<T>>;\n }\n}\n"],"names":[],"mappings":";;;;AAgBA,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;AAkFA,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;AAoBO,SAAS,YAAY,KAAgC,EAAA;AAC1D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAY,IAAA,KAAA,IAAS,IAAM,EAAA;AAC9C,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAM,MAAA,CAAA,GAAI,MAAO,CAAA,cAAA,CAAe,KAAK,CAAA,CAAA;AACrC,EAAI,IAAA,CAAA,IAAK,QAAQ,OAAO,CAAA,KAAM,YAAY,OAAO,CAAA,CAAE,MAAM,CAAA,KAAM,UAAY,EAAA;AACzE,IAAO,OAAA,KAAA,CAAA;AAAA,GACT;AAEA,EAAA,OAAO,eAAgB,CAAA,QAAA,CAAS,KAAM,CAAA,IAAA,EAAM,CAAA,CAAA;AAC9C,CAAA;AAmBO,SAAS,QACd,KAKS,EAAA;AACT,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.
|
|
3
|
+
"version": "0.13.1",
|
|
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.
|
|
20
|
+
"loro-wasm": "0.13.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
@@ -32,12 +32,12 @@
|
|
|
32
32
|
"typescript": "^5.0.2",
|
|
33
33
|
"vite": "^4.2.1",
|
|
34
34
|
"vite-plugin-wasm": "^3.2.2",
|
|
35
|
-
"vitest": "^1.0
|
|
35
|
+
"vitest": "^1.4.0"
|
|
36
36
|
},
|
|
37
37
|
"scripts": {
|
|
38
38
|
"build": "rollup -c",
|
|
39
39
|
"watch": "rollup -c -w",
|
|
40
|
-
"test": "vitest run",
|
|
40
|
+
"test": "vitest run --typecheck",
|
|
41
41
|
"prepublish": "pnpm run build"
|
|
42
42
|
}
|
|
43
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export * from "loro-wasm";
|
|
2
2
|
import {
|
|
3
3
|
Container,
|
|
4
|
+
ContainerID,
|
|
4
5
|
Delta,
|
|
6
|
+
Loro,
|
|
7
|
+
LoroList,
|
|
8
|
+
LoroMap,
|
|
5
9
|
LoroText,
|
|
6
10
|
LoroTree,
|
|
7
11
|
LoroTreeNode,
|
|
8
12
|
OpId,
|
|
9
|
-
Value,
|
|
10
|
-
ContainerID,
|
|
11
|
-
Loro,
|
|
12
|
-
LoroList,
|
|
13
|
-
LoroMap,
|
|
14
13
|
TreeID,
|
|
14
|
+
Value,
|
|
15
15
|
} from "loro-wasm";
|
|
16
16
|
|
|
17
17
|
Loro.prototype.getTypedMap = function (...args) {
|
|
@@ -179,17 +179,13 @@ export function isContainer(value: any): value is Container {
|
|
|
179
179
|
*/
|
|
180
180
|
export function getType<T>(
|
|
181
181
|
value: T,
|
|
182
|
-
): T extends LoroText
|
|
183
|
-
? "
|
|
184
|
-
: T extends
|
|
185
|
-
? "
|
|
186
|
-
: T extends LoroTree
|
|
187
|
-
? "Tree"
|
|
188
|
-
: T extends LoroList
|
|
189
|
-
? "List"
|
|
182
|
+
): T extends LoroText ? "Text"
|
|
183
|
+
: T extends LoroMap<any> ? "Map"
|
|
184
|
+
: T extends LoroTree<any> ? "Tree"
|
|
185
|
+
: T extends LoroList<any> ? "List"
|
|
190
186
|
: "Json" {
|
|
191
187
|
if (isContainer(value)) {
|
|
192
|
-
return value.kind();
|
|
188
|
+
return value.kind() as unknown as any;
|
|
193
189
|
}
|
|
194
190
|
|
|
195
191
|
return "Json" as any;
|
|
@@ -207,36 +203,41 @@ declare module "loro-wasm" {
|
|
|
207
203
|
getTypedList<Key extends keyof T & string>(
|
|
208
204
|
name: Key,
|
|
209
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]>;
|
|
209
|
+
getText(key: string | ContainerID): LoroText;
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
interface LoroList<
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
insertContainer
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
interface LoroList<
|
|
213
|
+
T extends any[] = any[],
|
|
214
|
+
> {
|
|
215
|
+
new (): LoroList<T>;
|
|
216
|
+
insertContainer<C extends Container>(
|
|
217
|
+
pos: number,
|
|
218
|
+
child: C,
|
|
219
|
+
): C;
|
|
219
220
|
get(index: number): undefined | Value | Container;
|
|
220
221
|
getTyped<Key extends keyof T & number>(loro: Loro, index: Key): T[Key];
|
|
221
222
|
insertTyped<Key extends keyof T & number>(pos: Key, value: T[Key]): void;
|
|
222
223
|
insert(pos: number, value: Value): void;
|
|
223
224
|
delete(pos: number, len: number): void;
|
|
224
225
|
subscribe(txn: Loro, listener: Listener): number;
|
|
226
|
+
getAttached(): undefined | LoroList<T>;
|
|
225
227
|
}
|
|
226
228
|
|
|
227
|
-
interface LoroMap<
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
getOrCreateContainer
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
setContainer
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
229
|
+
interface LoroMap<
|
|
230
|
+
T extends Record<string, any> = Record<string, any>,
|
|
231
|
+
> {
|
|
232
|
+
new (): LoroMap<T>;
|
|
233
|
+
getOrCreateContainer<C extends Container>(
|
|
234
|
+
key: string,
|
|
235
|
+
child: C,
|
|
236
|
+
): C;
|
|
237
|
+
setContainer<C extends Container>(
|
|
238
|
+
key: string,
|
|
239
|
+
child: C,
|
|
240
|
+
): C;
|
|
240
241
|
get(key: string): undefined | Value | Container;
|
|
241
242
|
getTyped<Key extends keyof T & string>(txn: Loro, key: Key): T[Key];
|
|
242
243
|
set(key: string, value: Value): void;
|
|
@@ -246,13 +247,17 @@ declare module "loro-wasm" {
|
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
interface LoroText {
|
|
250
|
+
new (): LoroText;
|
|
249
251
|
insert(pos: number, text: string): void;
|
|
250
252
|
delete(pos: number, len: number): void;
|
|
251
253
|
subscribe(txn: Loro, listener: Listener): number;
|
|
252
254
|
}
|
|
253
255
|
|
|
254
|
-
interface LoroTree
|
|
255
|
-
|
|
256
|
+
interface LoroTree<
|
|
257
|
+
T extends Record<string, any> = Record<string, any>,
|
|
258
|
+
> {
|
|
259
|
+
new (): LoroTree<T>;
|
|
260
|
+
createNode(parent: TreeID | undefined): LoroTreeNode<T>;
|
|
256
261
|
move(target: TreeID, parent: TreeID | undefined): void;
|
|
257
262
|
delete(target: TreeID): void;
|
|
258
263
|
has(target: TreeID): boolean;
|
|
@@ -260,12 +265,14 @@ declare module "loro-wasm" {
|
|
|
260
265
|
subscribe(txn: Loro, listener: Listener): number;
|
|
261
266
|
}
|
|
262
267
|
|
|
263
|
-
interface LoroTreeNode
|
|
264
|
-
|
|
265
|
-
|
|
268
|
+
interface LoroTreeNode<
|
|
269
|
+
T extends Record<string, any> = Record<string, any>,
|
|
270
|
+
> {
|
|
271
|
+
readonly data: LoroMap<T>;
|
|
272
|
+
createNode(): LoroTreeNode<T>;
|
|
266
273
|
setAsRoot(): void;
|
|
267
|
-
moveTo(parent: LoroTreeNode): void;
|
|
274
|
+
moveTo(parent: LoroTreeNode<T>): void;
|
|
268
275
|
parent(): LoroTreeNode | undefined;
|
|
269
|
-
children(): Array<LoroTreeNode
|
|
276
|
+
children(): Array<LoroTreeNode<T>>;
|
|
270
277
|
}
|
|
271
278
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
4
|
-
|
|
5
4
|
/* Projects */
|
|
6
5
|
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
|
7
6
|
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
|
@@ -9,7 +8,6 @@
|
|
|
9
8
|
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
|
10
9
|
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
|
11
10
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
12
|
-
|
|
13
11
|
/* Language and Environment */
|
|
14
12
|
"target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
15
13
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
@@ -23,7 +21,6 @@
|
|
|
23
21
|
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
|
24
22
|
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
|
25
23
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
26
|
-
|
|
27
24
|
/* Modules */
|
|
28
25
|
"module": "commonjs" /* Specify what module code is generated. */,
|
|
29
26
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
@@ -42,12 +39,10 @@
|
|
|
42
39
|
// "resolveJsonModule": true, /* Enable importing .json files. */
|
|
43
40
|
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
|
44
41
|
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
|
45
|
-
|
|
46
42
|
/* JavaScript Support */
|
|
47
43
|
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
|
48
44
|
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
|
49
45
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
50
|
-
|
|
51
46
|
/* Emit */
|
|
52
47
|
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
|
53
48
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
@@ -55,7 +50,7 @@
|
|
|
55
50
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
|
56
51
|
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
|
57
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. */
|
|
58
|
-
|
|
53
|
+
"outDir": "./dist", /* Specify an output folder for all emitted files. */
|
|
59
54
|
// "removeComments": true, /* Disable emitting comments. */
|
|
60
55
|
// "noEmit": true, /* Disable emitting files from a compilation. */
|
|
61
56
|
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
|
@@ -72,7 +67,6 @@
|
|
|
72
67
|
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
|
73
68
|
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
|
74
69
|
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
|
75
|
-
|
|
76
70
|
/* Interop Constraints */
|
|
77
71
|
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
|
78
72
|
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
|
@@ -80,7 +74,6 @@
|
|
|
80
74
|
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
|
|
81
75
|
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
|
82
76
|
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
|
|
83
|
-
|
|
84
77
|
/* Type Checking */
|
|
85
78
|
"strict": true /* Enable all strict type-checking options. */,
|
|
86
79
|
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
|
@@ -101,7 +94,6 @@
|
|
|
101
94
|
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
|
102
95
|
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
|
103
96
|
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
|
104
|
-
|
|
105
97
|
/* Completeness */
|
|
106
98
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
107
99
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|