loro-crdt 0.14.1 → 0.14.3
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 +21 -0
- package/deno/.vscode/settings.json +3 -0
- package/deno/deno.json +5 -0
- package/deno/mod.ts +1 -0
- package/deno/test.ts +13 -0
- package/dist/loro.d.ts +40 -2
- package/dist/loro.js +83 -0
- package/dist/loro.js.map +1 -1
- package/dist/loro.mjs +84 -1
- package/dist/loro.mjs.map +1 -1
- package/package.json +2 -2
- package/src/awareness.ts +108 -0
- package/src/index.ts +11 -0
- package/tsconfig.json +6 -1
- package/vite.config.ts +7 -5
- package/dist/src/index.js +0 -106
- package/dist/tests/basic.test.js +0 -415
- package/dist/tests/checkout.test.js +0 -76
- package/dist/tests/event.test.js +0 -345
- package/dist/tests/issue.test.js +0 -59
- package/dist/tests/misc.test.js +0 -245
- package/dist/tests/richtext.test.js +0 -197
- package/dist/tests/type.test.js +0 -22
- package/dist/tests/version.test.js +0 -185
- package/dist/vite.config.js +0 -14
package/dist/src/index.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.getType = exports.isContainer = exports.Loro = exports.isContainerId = void 0;
|
|
18
|
-
__exportStar(require("loro-wasm"), exports);
|
|
19
|
-
const loro_wasm_1 = require("loro-wasm");
|
|
20
|
-
Object.defineProperty(exports, "Loro", { enumerable: true, get: function () { return loro_wasm_1.Loro; } });
|
|
21
|
-
loro_wasm_1.Loro.prototype.getTypedMap = function (...args) {
|
|
22
|
-
return this.getMap(...args);
|
|
23
|
-
};
|
|
24
|
-
loro_wasm_1.Loro.prototype.getTypedList = function (...args) {
|
|
25
|
-
return this.getList(...args);
|
|
26
|
-
};
|
|
27
|
-
loro_wasm_1.LoroList.prototype.getTyped = function (loro, index) {
|
|
28
|
-
const value = this.get(index);
|
|
29
|
-
if (typeof value === "string" && isContainerId(value)) {
|
|
30
|
-
return loro.getContainerById(value);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
return value;
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
loro_wasm_1.LoroList.prototype.insertTyped = function (...args) {
|
|
37
|
-
return this.insert(...args);
|
|
38
|
-
};
|
|
39
|
-
loro_wasm_1.LoroMap.prototype.getTyped = function (loro, key) {
|
|
40
|
-
const value = this.get(key);
|
|
41
|
-
if (typeof value === "string" && isContainerId(value)) {
|
|
42
|
-
return loro.getContainerById(value);
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
return value;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
loro_wasm_1.LoroMap.prototype.setTyped = function (...args) {
|
|
49
|
-
return this.set(...args);
|
|
50
|
-
};
|
|
51
|
-
const CONTAINER_TYPES = ["Map", "Text", "List", "Tree"];
|
|
52
|
-
function isContainerId(s) {
|
|
53
|
-
return s.startsWith("cid:");
|
|
54
|
-
}
|
|
55
|
-
exports.isContainerId = isContainerId;
|
|
56
|
-
/** Whether the value is a container.
|
|
57
|
-
*
|
|
58
|
-
* # Example
|
|
59
|
-
*
|
|
60
|
-
* ```ts
|
|
61
|
-
* const doc = new Loro();
|
|
62
|
-
* const map = doc.getMap("map");
|
|
63
|
-
* const list = doc.getList("list");
|
|
64
|
-
* const text = doc.getText("text");
|
|
65
|
-
* isContainer(map); // true
|
|
66
|
-
* isContainer(list); // true
|
|
67
|
-
* isContainer(text); // true
|
|
68
|
-
* isContainer(123); // false
|
|
69
|
-
* isContainer("123"); // false
|
|
70
|
-
* isContainer({}); // false
|
|
71
|
-
*/
|
|
72
|
-
function isContainer(value) {
|
|
73
|
-
if (typeof value !== "object" || value == null) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
const p = Object.getPrototypeOf(value);
|
|
77
|
-
if (p == null || typeof p !== "object" || typeof p["kind"] !== "function") {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
return CONTAINER_TYPES.includes(value.kind());
|
|
81
|
-
}
|
|
82
|
-
exports.isContainer = isContainer;
|
|
83
|
-
/** Get the type of a value that may be a container.
|
|
84
|
-
*
|
|
85
|
-
* # Example
|
|
86
|
-
*
|
|
87
|
-
* ```ts
|
|
88
|
-
* const doc = new Loro();
|
|
89
|
-
* const map = doc.getMap("map");
|
|
90
|
-
* const list = doc.getList("list");
|
|
91
|
-
* const text = doc.getText("text");
|
|
92
|
-
* getType(map); // "Map"
|
|
93
|
-
* getType(list); // "List"
|
|
94
|
-
* getType(text); // "Text"
|
|
95
|
-
* getType(123); // "Json"
|
|
96
|
-
* getType("123"); // "Json"
|
|
97
|
-
* getType({}); // "Json"
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
function getType(value) {
|
|
101
|
-
if (isContainer(value)) {
|
|
102
|
-
return value.kind();
|
|
103
|
-
}
|
|
104
|
-
return "Json";
|
|
105
|
-
}
|
|
106
|
-
exports.getType = getType;
|
package/dist/tests/basic.test.js
DELETED
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const src_1 = require("../src");
|
|
5
|
-
(0, vitest_1.it)("basic example", () => {
|
|
6
|
-
const doc = new src_1.Loro();
|
|
7
|
-
const list = doc.getList("list");
|
|
8
|
-
list.insert(0, "A");
|
|
9
|
-
list.insert(1, "B");
|
|
10
|
-
list.insert(2, "C");
|
|
11
|
-
const map = doc.getMap("map");
|
|
12
|
-
// map can only has string key
|
|
13
|
-
map.set("key", "value");
|
|
14
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
15
|
-
list: ["A", "B", "C"],
|
|
16
|
-
map: { key: "value" },
|
|
17
|
-
});
|
|
18
|
-
// delete 2 elements at index 0
|
|
19
|
-
list.delete(0, 2);
|
|
20
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
21
|
-
list: ["C"],
|
|
22
|
-
map: { key: "value" },
|
|
23
|
-
});
|
|
24
|
-
// Insert a text container to the list
|
|
25
|
-
const text = list.insertContainer(0, new src_1.LoroText());
|
|
26
|
-
text.insert(0, "Hello");
|
|
27
|
-
text.insert(0, "Hi! ");
|
|
28
|
-
// delete 1 element at index 0
|
|
29
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
30
|
-
list: ["Hi! Hello", "C"],
|
|
31
|
-
map: { key: "value" },
|
|
32
|
-
});
|
|
33
|
-
// Insert a list container to the map
|
|
34
|
-
const list2 = map.setContainer("test", new src_1.LoroList());
|
|
35
|
-
list2.insert(0, 1);
|
|
36
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
37
|
-
list: ["Hi! Hello", "C"],
|
|
38
|
-
map: { key: "value", test: [1] },
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
(0, vitest_1.it)("get or create on Map", () => {
|
|
42
|
-
const docA = new src_1.Loro();
|
|
43
|
-
const map = docA.getMap("map");
|
|
44
|
-
const container = map.getOrCreateContainer("list", new src_1.LoroList());
|
|
45
|
-
container.insert(0, 1);
|
|
46
|
-
container.insert(0, 2);
|
|
47
|
-
const text = map.getOrCreateContainer("text", new src_1.LoroText());
|
|
48
|
-
text.insert(0, "Hello");
|
|
49
|
-
(0, vitest_1.expect)(docA.toJson()).toStrictEqual({
|
|
50
|
-
map: { list: [2, 1], text: "Hello" },
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
(0, vitest_1.it)("basic sync example", () => {
|
|
54
|
-
const docA = new src_1.Loro();
|
|
55
|
-
const docB = new src_1.Loro();
|
|
56
|
-
const listA = docA.getList("list");
|
|
57
|
-
listA.insert(0, "A");
|
|
58
|
-
listA.insert(1, "B");
|
|
59
|
-
listA.insert(2, "C");
|
|
60
|
-
// B import the ops from A
|
|
61
|
-
docB.import(docA.exportFrom());
|
|
62
|
-
(0, vitest_1.expect)(docB.toJson()).toStrictEqual({
|
|
63
|
-
list: ["A", "B", "C"],
|
|
64
|
-
});
|
|
65
|
-
const listB = docB.getList("list");
|
|
66
|
-
// delete 1 element at index 1
|
|
67
|
-
listB.delete(1, 1);
|
|
68
|
-
// A import the ops from B
|
|
69
|
-
docA.import(docB.exportFrom(docA.version()));
|
|
70
|
-
// list at A is now ["A", "C"], with the same state as B
|
|
71
|
-
(0, vitest_1.expect)(docA.toJson()).toStrictEqual({
|
|
72
|
-
list: ["A", "C"],
|
|
73
|
-
});
|
|
74
|
-
(0, vitest_1.expect)(docA.toJson()).toStrictEqual(docB.toJson());
|
|
75
|
-
});
|
|
76
|
-
(0, vitest_1.it)("basic events", () => {
|
|
77
|
-
const doc = new src_1.Loro();
|
|
78
|
-
doc.subscribe((event) => { });
|
|
79
|
-
const list = doc.getList("list");
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.describe)("list", () => {
|
|
82
|
-
(0, vitest_1.it)("insert containers", () => {
|
|
83
|
-
const doc = new src_1.Loro();
|
|
84
|
-
const list = doc.getList("list");
|
|
85
|
-
const map = list.insertContainer(0, new src_1.LoroMap());
|
|
86
|
-
map.set("key", "value");
|
|
87
|
-
const v = list.get(0);
|
|
88
|
-
console.log(v);
|
|
89
|
-
(0, vitest_1.expect)(v instanceof src_1.LoroMap).toBeTruthy();
|
|
90
|
-
(0, vitest_1.expect)(v.toJson()).toStrictEqual({ key: "value" });
|
|
91
|
-
});
|
|
92
|
-
(0, vitest_1.it)("toArray", () => {
|
|
93
|
-
const doc = new src_1.Loro();
|
|
94
|
-
const list = doc.getList("list");
|
|
95
|
-
list.insert(0, 1);
|
|
96
|
-
list.insert(1, 2);
|
|
97
|
-
(0, vitest_1.expect)(list.toArray()).toStrictEqual([1, 2]);
|
|
98
|
-
list.insertContainer(2, new src_1.LoroText());
|
|
99
|
-
const t = list.toArray()[2];
|
|
100
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(t)).toBeTruthy();
|
|
101
|
-
(0, vitest_1.expect)((0, src_1.getType)(t)).toBe("Text");
|
|
102
|
-
(0, vitest_1.expect)((0, src_1.getType)(123)).toBe("Json");
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
(0, vitest_1.describe)("map", () => {
|
|
106
|
-
(0, vitest_1.it)("get child container", () => {
|
|
107
|
-
const doc = new src_1.Loro();
|
|
108
|
-
const map = doc.getMap("map");
|
|
109
|
-
const list = map.setContainer("key", new src_1.LoroList());
|
|
110
|
-
list.insert(0, 1);
|
|
111
|
-
(0, vitest_1.expect)(map.get("key") instanceof src_1.LoroList).toBeTruthy();
|
|
112
|
-
(0, vitest_1.expect)(map.get("key").toJson()).toStrictEqual([1]);
|
|
113
|
-
});
|
|
114
|
-
(0, vitest_1.it)("set large int", () => {
|
|
115
|
-
const doc = new src_1.Loro();
|
|
116
|
-
const map = doc.getMap("map");
|
|
117
|
-
map.set("key", 2147483699);
|
|
118
|
-
(0, vitest_1.expect)(map.get("key")).toBe(2147483699);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
(0, vitest_1.describe)("import", () => {
|
|
122
|
-
(0, vitest_1.it)("pending", () => {
|
|
123
|
-
const a = new src_1.Loro();
|
|
124
|
-
a.getText("text").insert(0, "a");
|
|
125
|
-
const b = new src_1.Loro();
|
|
126
|
-
b.import(a.exportFrom());
|
|
127
|
-
b.getText("text").insert(1, "b");
|
|
128
|
-
const c = new src_1.Loro();
|
|
129
|
-
c.import(b.exportFrom());
|
|
130
|
-
c.getText("text").insert(2, "c");
|
|
131
|
-
// c export from b's version, which cannot be imported directly to a.
|
|
132
|
-
// This operation is pending.
|
|
133
|
-
a.import(c.exportFrom(b.version()));
|
|
134
|
-
(0, vitest_1.expect)(a.getText("text").toString()).toBe("a");
|
|
135
|
-
// a import the missing ops from b. It makes the pending operation from c valid.
|
|
136
|
-
a.import(b.exportFrom(a.version()));
|
|
137
|
-
(0, vitest_1.expect)(a.getText("text").toString()).toBe("abc");
|
|
138
|
-
});
|
|
139
|
-
(0, vitest_1.it)("import by frontiers", () => {
|
|
140
|
-
const a = new src_1.Loro();
|
|
141
|
-
a.getText("text").insert(0, "a");
|
|
142
|
-
const b = new src_1.Loro();
|
|
143
|
-
b.import(a.exportFrom());
|
|
144
|
-
b.getText("text").insert(1, "b");
|
|
145
|
-
b.getList("list").insert(0, [1, 2]);
|
|
146
|
-
const updates = b.exportFrom(b.frontiersToVV(a.frontiers()));
|
|
147
|
-
a.import(updates);
|
|
148
|
-
(0, vitest_1.expect)(a.toJson()).toStrictEqual(b.toJson());
|
|
149
|
-
});
|
|
150
|
-
(0, vitest_1.it)("from snapshot", () => {
|
|
151
|
-
const a = new src_1.Loro();
|
|
152
|
-
a.getText("text").insert(0, "hello");
|
|
153
|
-
const bytes = a.exportSnapshot();
|
|
154
|
-
const b = src_1.Loro.fromSnapshot(bytes);
|
|
155
|
-
b.getText("text").insert(0, "123");
|
|
156
|
-
(0, vitest_1.expect)(b.toJson()).toStrictEqual({ text: "123hello" });
|
|
157
|
-
});
|
|
158
|
-
(0, vitest_1.it)("importBatch Error #181", () => {
|
|
159
|
-
const docA = new src_1.Loro();
|
|
160
|
-
const updateA = docA.exportSnapshot();
|
|
161
|
-
const docB = new src_1.Loro();
|
|
162
|
-
docB.importUpdateBatch([updateA]);
|
|
163
|
-
docB.getText("text").insert(0, "hello");
|
|
164
|
-
docB.commit();
|
|
165
|
-
console.log(docB.exportFrom());
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
(0, vitest_1.describe)("map", () => {
|
|
169
|
-
(0, vitest_1.it)("keys", () => {
|
|
170
|
-
const doc = new src_1.Loro();
|
|
171
|
-
const map = doc.getMap("map");
|
|
172
|
-
map.set("foo", "bar");
|
|
173
|
-
map.set("baz", "bar");
|
|
174
|
-
const entries = map.keys();
|
|
175
|
-
(0, vitest_1.expect)(entries).toStrictEqual(["foo", "baz"]);
|
|
176
|
-
});
|
|
177
|
-
(0, vitest_1.it)("values", () => {
|
|
178
|
-
const doc = new src_1.Loro();
|
|
179
|
-
const map = doc.getMap("map");
|
|
180
|
-
map.set("foo", "bar");
|
|
181
|
-
map.set("baz", "bar");
|
|
182
|
-
const entries = map.values();
|
|
183
|
-
(0, vitest_1.expect)(entries).toStrictEqual(["bar", "bar"]);
|
|
184
|
-
});
|
|
185
|
-
(0, vitest_1.it)("entries", () => {
|
|
186
|
-
const doc = new src_1.Loro();
|
|
187
|
-
const map = doc.getMap("map");
|
|
188
|
-
map.set("foo", "bar");
|
|
189
|
-
map.set("baz", "bar");
|
|
190
|
-
map.set("new", 11);
|
|
191
|
-
map.delete("new");
|
|
192
|
-
const entries = map.entries();
|
|
193
|
-
(0, vitest_1.expect)(entries).toStrictEqual([
|
|
194
|
-
["foo", "bar"],
|
|
195
|
-
["baz", "bar"],
|
|
196
|
-
]);
|
|
197
|
-
});
|
|
198
|
-
(0, vitest_1.it)("entries should return container handlers", () => {
|
|
199
|
-
const doc = new src_1.Loro();
|
|
200
|
-
const map = doc.getMap("map");
|
|
201
|
-
map.setContainer("text", new src_1.LoroText());
|
|
202
|
-
map.set("foo", "bar");
|
|
203
|
-
const entries = map.entries();
|
|
204
|
-
(0, vitest_1.expect)(entries[0][1].kind() === "Text").toBeTruthy();
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
(0, vitest_1.it)("handlers should still be usable after doc is dropped", () => {
|
|
208
|
-
const doc = new src_1.Loro();
|
|
209
|
-
const text = doc.getText("text");
|
|
210
|
-
const list = doc.getList("list");
|
|
211
|
-
const map = doc.getMap("map");
|
|
212
|
-
doc.free();
|
|
213
|
-
text.insert(0, "123");
|
|
214
|
-
(0, vitest_1.expect)(text.toString()).toBe("123");
|
|
215
|
-
list.insert(0, 1);
|
|
216
|
-
(0, vitest_1.expect)(list.toJson()).toStrictEqual([1]);
|
|
217
|
-
map.set("k", 8);
|
|
218
|
-
(0, vitest_1.expect)(map.toJson()).toStrictEqual({ k: 8 });
|
|
219
|
-
});
|
|
220
|
-
(0, vitest_1.it)("get change with given lamport", () => {
|
|
221
|
-
const doc1 = new src_1.Loro();
|
|
222
|
-
doc1.setPeerId(1);
|
|
223
|
-
const doc2 = new src_1.Loro();
|
|
224
|
-
doc2.setPeerId(2);
|
|
225
|
-
doc1.getText("text").insert(0, "01234");
|
|
226
|
-
doc2.import(doc1.exportFrom());
|
|
227
|
-
doc2.getText("text").insert(0, "56789");
|
|
228
|
-
doc1.import(doc2.exportFrom());
|
|
229
|
-
doc1.getText("text").insert(0, "01234");
|
|
230
|
-
doc1.commit();
|
|
231
|
-
{
|
|
232
|
-
const change = doc1.getChangeAtLamport("1", 1);
|
|
233
|
-
(0, vitest_1.expect)(change.lamport).toBe(0);
|
|
234
|
-
(0, vitest_1.expect)(change.peer).toBe("1");
|
|
235
|
-
(0, vitest_1.expect)(change.length).toBe(5);
|
|
236
|
-
}
|
|
237
|
-
{
|
|
238
|
-
const change = doc1.getChangeAtLamport("1", 7);
|
|
239
|
-
(0, vitest_1.expect)(change.lamport).toBe(0);
|
|
240
|
-
(0, vitest_1.expect)(change.peer).toBe("1");
|
|
241
|
-
(0, vitest_1.expect)(change.length).toBe(5);
|
|
242
|
-
}
|
|
243
|
-
{
|
|
244
|
-
const change = doc1.getChangeAtLamport("1", 10);
|
|
245
|
-
(0, vitest_1.expect)(change.lamport).toBe(10);
|
|
246
|
-
(0, vitest_1.expect)(change.peer).toBe("1");
|
|
247
|
-
(0, vitest_1.expect)(change.length).toBe(5);
|
|
248
|
-
}
|
|
249
|
-
{
|
|
250
|
-
const change = doc1.getChangeAtLamport("1", 13);
|
|
251
|
-
(0, vitest_1.expect)(change.lamport).toBe(10);
|
|
252
|
-
(0, vitest_1.expect)(change.peer).toBe("1");
|
|
253
|
-
(0, vitest_1.expect)(change.length).toBe(5);
|
|
254
|
-
}
|
|
255
|
-
{
|
|
256
|
-
const change = doc1.getChangeAtLamport("1", 20);
|
|
257
|
-
(0, vitest_1.expect)(change.lamport).toBe(10);
|
|
258
|
-
(0, vitest_1.expect)(change.peer).toBe("1");
|
|
259
|
-
(0, vitest_1.expect)(change.length).toBe(5);
|
|
260
|
-
}
|
|
261
|
-
{
|
|
262
|
-
const change = doc1.getChangeAtLamport("111", 13);
|
|
263
|
-
(0, vitest_1.expect)(change).toBeUndefined();
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
|
-
(0, vitest_1.it)("isContainer", () => {
|
|
267
|
-
(0, vitest_1.expect)((0, src_1.isContainer)("123")).toBeFalsy();
|
|
268
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(123)).toBeFalsy();
|
|
269
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(123n)).toBeFalsy();
|
|
270
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(new Map())).toBeFalsy();
|
|
271
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(new Set())).toBeFalsy();
|
|
272
|
-
(0, vitest_1.expect)((0, src_1.isContainer)({})).toBeFalsy();
|
|
273
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(undefined)).toBeFalsy();
|
|
274
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(null)).toBeFalsy();
|
|
275
|
-
const doc = new src_1.Loro();
|
|
276
|
-
const t = doc.getText("t");
|
|
277
|
-
(0, vitest_1.expect)((0, src_1.isContainer)(t)).toBeTruthy();
|
|
278
|
-
(0, vitest_1.expect)((0, src_1.getType)(t)).toBe("Text");
|
|
279
|
-
(0, vitest_1.expect)((0, src_1.getType)(123)).toBe("Json");
|
|
280
|
-
});
|
|
281
|
-
(0, vitest_1.it)("getValueType", () => {
|
|
282
|
-
// Type tests
|
|
283
|
-
const doc = new src_1.Loro();
|
|
284
|
-
const t = doc.getText("t");
|
|
285
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(t)).toEqualTypeOf();
|
|
286
|
-
(0, vitest_1.expect)((0, src_1.getType)(t)).toBe("Text");
|
|
287
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(123)).toEqualTypeOf();
|
|
288
|
-
(0, vitest_1.expect)((0, src_1.getType)(123)).toBe("Json");
|
|
289
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(undefined)).toEqualTypeOf();
|
|
290
|
-
(0, vitest_1.expect)((0, src_1.getType)(undefined)).toBe("Json");
|
|
291
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(null)).toEqualTypeOf();
|
|
292
|
-
(0, vitest_1.expect)((0, src_1.getType)(null)).toBe("Json");
|
|
293
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)({})).toEqualTypeOf();
|
|
294
|
-
(0, vitest_1.expect)((0, src_1.getType)({})).toBe("Json");
|
|
295
|
-
const map = doc.getMap("map");
|
|
296
|
-
const list = doc.getList("list");
|
|
297
|
-
const tree = doc.getTree("tree");
|
|
298
|
-
const text = doc.getText("text");
|
|
299
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(map)).toEqualTypeOf();
|
|
300
|
-
(0, vitest_1.expect)((0, src_1.getType)(map)).toBe("Map");
|
|
301
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(list)).toEqualTypeOf();
|
|
302
|
-
(0, vitest_1.expect)((0, src_1.getType)(list)).toBe("List");
|
|
303
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(tree)).toEqualTypeOf();
|
|
304
|
-
(0, vitest_1.expect)((0, src_1.getType)(tree)).toBe("Tree");
|
|
305
|
-
(0, vitest_1.expectTypeOf)((0, src_1.getType)(text)).toEqualTypeOf();
|
|
306
|
-
(0, vitest_1.expect)((0, src_1.getType)(text)).toBe("Text");
|
|
307
|
-
});
|
|
308
|
-
(0, vitest_1.it)("enable timestamp", () => {
|
|
309
|
-
const doc = new src_1.Loro();
|
|
310
|
-
doc.setPeerId(1);
|
|
311
|
-
doc.getText("123").insert(0, "123");
|
|
312
|
-
doc.commit();
|
|
313
|
-
{
|
|
314
|
-
const c = doc.getChangeAt({ peer: "1", counter: 0 });
|
|
315
|
-
(0, vitest_1.expect)(c.timestamp).toBe(0);
|
|
316
|
-
}
|
|
317
|
-
doc.setRecordTimestamp(true);
|
|
318
|
-
doc.getText("123").insert(0, "123");
|
|
319
|
-
doc.commit();
|
|
320
|
-
{
|
|
321
|
-
const c = doc.getChangeAt({ peer: "1", counter: 4 });
|
|
322
|
-
(0, vitest_1.expect)(c.timestamp).toBeCloseTo(Date.now(), -1);
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
(0, vitest_1.it)("commit with specified timestamp", () => {
|
|
326
|
-
const doc = new src_1.Loro();
|
|
327
|
-
doc.setPeerId(1);
|
|
328
|
-
doc.getText("123").insert(0, "123");
|
|
329
|
-
doc.commit(undefined, 111);
|
|
330
|
-
const c = doc.getChangeAt({ peer: "1", counter: 0 });
|
|
331
|
-
(0, vitest_1.expect)(c.timestamp).toBe(111);
|
|
332
|
-
});
|
|
333
|
-
(0, vitest_1.it)("can control the mergeable interval", () => {
|
|
334
|
-
{
|
|
335
|
-
const doc = new src_1.Loro();
|
|
336
|
-
doc.setPeerId(1);
|
|
337
|
-
doc.getText("123").insert(0, "1");
|
|
338
|
-
doc.commit(undefined, 110);
|
|
339
|
-
doc.getText("123").insert(0, "1");
|
|
340
|
-
doc.commit(undefined, 120);
|
|
341
|
-
(0, vitest_1.expect)(doc.getAllChanges().get("1")?.length).toBe(1);
|
|
342
|
-
}
|
|
343
|
-
{
|
|
344
|
-
const doc = new src_1.Loro();
|
|
345
|
-
doc.setPeerId(1);
|
|
346
|
-
doc.setChangeMergeInterval(10);
|
|
347
|
-
doc.getText("123").insert(0, "1");
|
|
348
|
-
doc.commit(undefined, 110);
|
|
349
|
-
doc.getText("123").insert(0, "1");
|
|
350
|
-
doc.commit(undefined, 120);
|
|
351
|
-
(0, vitest_1.expect)(doc.getAllChanges().get("1")?.length).toBe(2);
|
|
352
|
-
}
|
|
353
|
-
});
|
|
354
|
-
(0, vitest_1.it)("get container parent", () => {
|
|
355
|
-
const doc = new src_1.Loro();
|
|
356
|
-
const m = doc.getMap("m");
|
|
357
|
-
(0, vitest_1.expect)(m.parent()).toBeUndefined();
|
|
358
|
-
const list = m.setContainer("t", new src_1.LoroList());
|
|
359
|
-
(0, vitest_1.expect)(list.parent().id).toBe(m.id);
|
|
360
|
-
const text = list.insertContainer(0, new src_1.LoroText());
|
|
361
|
-
(0, vitest_1.expect)(text.parent().id).toBe(list.id);
|
|
362
|
-
const tree = list.insertContainer(1, new src_1.LoroTree());
|
|
363
|
-
(0, vitest_1.expect)(tree.parent().id).toBe(list.id);
|
|
364
|
-
const treeNode = tree.createNode();
|
|
365
|
-
const subtext = treeNode.data.setContainer("t", new src_1.LoroText());
|
|
366
|
-
(0, vitest_1.expect)(subtext.parent().id).toBe(treeNode.data.id);
|
|
367
|
-
});
|
|
368
|
-
(0, vitest_1.it)("prelim support", () => {
|
|
369
|
-
// Now we can create a new container directly
|
|
370
|
-
const map = new src_1.LoroMap();
|
|
371
|
-
map.set("3", 2);
|
|
372
|
-
const list = new src_1.LoroList();
|
|
373
|
-
list.insertContainer(0, map);
|
|
374
|
-
// map should still be valid
|
|
375
|
-
map.set("9", 9);
|
|
376
|
-
// the type of setContainer/insertContainer changed
|
|
377
|
-
const text = map.setContainer("text", new src_1.LoroText());
|
|
378
|
-
{
|
|
379
|
-
// Changes will be reflected in the container tree
|
|
380
|
-
text.insert(0, "Heello");
|
|
381
|
-
(0, vitest_1.expect)(list.toJson()).toStrictEqual([{ "3": 2, "9": 9, text: "Heello" }]);
|
|
382
|
-
text.delete(1, 1);
|
|
383
|
-
(0, vitest_1.expect)(list.toJson()).toStrictEqual([{ "3": 2, "9": 9, text: "Hello" }]);
|
|
384
|
-
}
|
|
385
|
-
const doc = new src_1.Loro();
|
|
386
|
-
const rootMap = doc.getMap("map");
|
|
387
|
-
rootMap.setContainer("test", map); // new way to create sub-container
|
|
388
|
-
// Use getAttached() to get the attached version of text
|
|
389
|
-
const attachedText = text.getAttached();
|
|
390
|
-
(0, vitest_1.expect)(text.isAttached()).toBeFalsy();
|
|
391
|
-
(0, vitest_1.expect)(attachedText.isAttached()).toBeTruthy();
|
|
392
|
-
text.insert(0, "Detached ");
|
|
393
|
-
attachedText.insert(0, "Attached ");
|
|
394
|
-
(0, vitest_1.expect)(text.toString()).toBe("Detached Hello");
|
|
395
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
396
|
-
map: {
|
|
397
|
-
test: {
|
|
398
|
-
"3": 2,
|
|
399
|
-
"9": 9,
|
|
400
|
-
text: "Attached Hello",
|
|
401
|
-
},
|
|
402
|
-
},
|
|
403
|
-
});
|
|
404
|
-
});
|
|
405
|
-
(0, vitest_1.it)("get elem by path", () => {
|
|
406
|
-
const doc = new src_1.Loro();
|
|
407
|
-
const map = doc.getMap("map");
|
|
408
|
-
map.set("key", 1);
|
|
409
|
-
(0, vitest_1.expect)(doc.getByPath("map/key")).toBe(1);
|
|
410
|
-
const map1 = doc.getByPath("map");
|
|
411
|
-
console.log(map1);
|
|
412
|
-
(0, vitest_1.expect)((0, src_1.getType)(map1)).toBe("Map");
|
|
413
|
-
map1.set("key1", 1);
|
|
414
|
-
(0, vitest_1.expect)(doc.getByPath("map/key1")).toBe(1);
|
|
415
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const src_1 = require("../src");
|
|
5
|
-
(0, vitest_1.describe)("Checkout", () => {
|
|
6
|
-
(0, vitest_1.it)("simple checkout", async () => {
|
|
7
|
-
const doc = new src_1.Loro();
|
|
8
|
-
doc.setPeerId(0n);
|
|
9
|
-
const text = doc.getText("text");
|
|
10
|
-
text.insert(0, "H");
|
|
11
|
-
doc.commit();
|
|
12
|
-
let triggered = false;
|
|
13
|
-
doc.subscribe((e) => {
|
|
14
|
-
(0, vitest_1.expect)(e.by).not.toBe("import");
|
|
15
|
-
(0, vitest_1.expect)(e.by === "checkout" || e.by === "local").toBeTruthy();
|
|
16
|
-
triggered = true;
|
|
17
|
-
});
|
|
18
|
-
const v = doc.frontiers();
|
|
19
|
-
text.insert(1, "i");
|
|
20
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
21
|
-
text: "Hi",
|
|
22
|
-
});
|
|
23
|
-
(0, vitest_1.expect)(doc.isDetached()).toBeFalsy();
|
|
24
|
-
doc.checkout([{ peer: "0", counter: 0 }]);
|
|
25
|
-
(0, vitest_1.expect)(doc.isDetached()).toBeTruthy();
|
|
26
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
27
|
-
text: "H",
|
|
28
|
-
});
|
|
29
|
-
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
30
|
-
(0, vitest_1.expect)(triggered).toBeTruthy();
|
|
31
|
-
});
|
|
32
|
-
(0, vitest_1.it)("Chinese char", () => {
|
|
33
|
-
const doc = new src_1.Loro();
|
|
34
|
-
const text = doc.getText("text");
|
|
35
|
-
text.insert(0, "你好世界");
|
|
36
|
-
doc.commit();
|
|
37
|
-
const v = doc.frontiers();
|
|
38
|
-
(0, vitest_1.expect)(v[0].counter).toBe(3);
|
|
39
|
-
v[0].counter -= 1;
|
|
40
|
-
doc.checkout(v);
|
|
41
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
42
|
-
text: "你好世",
|
|
43
|
-
});
|
|
44
|
-
v[0].counter -= 1;
|
|
45
|
-
doc.checkout(v);
|
|
46
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
47
|
-
text: "你好",
|
|
48
|
-
});
|
|
49
|
-
v[0].counter -= 1;
|
|
50
|
-
doc.checkout(v);
|
|
51
|
-
(0, vitest_1.expect)(doc.toJson()).toStrictEqual({
|
|
52
|
-
text: "你",
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
(0, vitest_1.it)("two clients", () => {
|
|
56
|
-
const doc = new src_1.Loro();
|
|
57
|
-
const text = doc.getText("text");
|
|
58
|
-
text.insert(0, "0");
|
|
59
|
-
doc.commit();
|
|
60
|
-
const v0 = doc.frontiers();
|
|
61
|
-
const docB = new src_1.Loro();
|
|
62
|
-
docB.import(doc.exportFrom());
|
|
63
|
-
(0, vitest_1.expect)(docB.cmpWithFrontiers(v0)).toBe(0);
|
|
64
|
-
text.insert(1, "0");
|
|
65
|
-
doc.commit();
|
|
66
|
-
(0, vitest_1.expect)(docB.cmpWithFrontiers(doc.frontiers())).toBe(-1);
|
|
67
|
-
const textB = docB.getText("text");
|
|
68
|
-
textB.insert(0, "0");
|
|
69
|
-
docB.commit();
|
|
70
|
-
(0, vitest_1.expect)(docB.cmpWithFrontiers(doc.frontiers())).toBe(-1);
|
|
71
|
-
docB.import(doc.exportFrom());
|
|
72
|
-
(0, vitest_1.expect)(docB.cmpWithFrontiers(doc.frontiers())).toBe(1);
|
|
73
|
-
doc.import(docB.exportFrom());
|
|
74
|
-
(0, vitest_1.expect)(docB.cmpWithFrontiers(doc.frontiers())).toBe(0);
|
|
75
|
-
});
|
|
76
|
-
});
|