@dxos/merkle-search-tree 0.8.3 → 0.8.4-main.f9ba587
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/dist/lib/browser/index.mjs +6 -6
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/node-esm/index.mjs +6 -6
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/dist/lib/node/index.cjs +0 -994
- package/dist/lib/node/index.cjs.map +0 -7
- package/dist/lib/node/meta.json +0 -1
package/dist/lib/node/index.cjs
DELETED
|
@@ -1,994 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
var node_exports = {};
|
|
20
|
-
__export(node_exports, {
|
|
21
|
-
Forest: () => Forest,
|
|
22
|
-
LWWTree: () => LWWTree,
|
|
23
|
-
MirrorMultiMap: () => MirrorMultiMap,
|
|
24
|
-
TreeMut: () => TreeMut,
|
|
25
|
-
createValue: () => createValue,
|
|
26
|
-
digestEquals: () => digestEquals,
|
|
27
|
-
formatDigest: () => formatDigest,
|
|
28
|
-
getLevel: () => getLevel,
|
|
29
|
-
getLevelHex: () => getLevelHex,
|
|
30
|
-
initLWWTreeSyncState: () => initLWWTreeSyncState,
|
|
31
|
-
makeItem: () => makeItem,
|
|
32
|
-
randomKey: () => randomKey,
|
|
33
|
-
randomSample: () => randomSample
|
|
34
|
-
});
|
|
35
|
-
module.exports = __toCommonJS(node_exports);
|
|
36
|
-
var import_util = require("@dxos/util");
|
|
37
|
-
var import_invariant = require("@dxos/invariant");
|
|
38
|
-
var import_util2 = require("@dxos/util");
|
|
39
|
-
var import_util3 = require("@dxos/util");
|
|
40
|
-
var makeItem = async (key, value) => {
|
|
41
|
-
const keyBytes = textEncoder.encode(key);
|
|
42
|
-
const data = new Uint8Array(keyBytes.length + value.length);
|
|
43
|
-
data.set(keyBytes, 0);
|
|
44
|
-
data.set(value, keyBytes.length);
|
|
45
|
-
const digest = await crypto.subtle.digest({
|
|
46
|
-
name: "SHA-256"
|
|
47
|
-
}, data);
|
|
48
|
-
return {
|
|
49
|
-
key,
|
|
50
|
-
value,
|
|
51
|
-
digest: new Uint8Array(digest)
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
var getLevel = (digest) => {
|
|
55
|
-
let level = 0;
|
|
56
|
-
for (let i = 0; i < digest.length; i++) {
|
|
57
|
-
const byte = digest[i];
|
|
58
|
-
if (byte >> 4 === 0) {
|
|
59
|
-
level++;
|
|
60
|
-
} else {
|
|
61
|
-
break;
|
|
62
|
-
}
|
|
63
|
-
if ((byte & 15) === 0) {
|
|
64
|
-
level++;
|
|
65
|
-
} else {
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return level;
|
|
70
|
-
};
|
|
71
|
-
var formatDigest = (digest) => {
|
|
72
|
-
return (0, import_util.arrayToHex)(digest.buffer);
|
|
73
|
-
};
|
|
74
|
-
var getLevelHex = (digest) => {
|
|
75
|
-
let level = 0;
|
|
76
|
-
for (let i = 0; i < digest.length; i++) {
|
|
77
|
-
if (digest[i] === "0") {
|
|
78
|
-
level++;
|
|
79
|
-
} else {
|
|
80
|
-
break;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return level;
|
|
84
|
-
};
|
|
85
|
-
var digestEquals = (a, b) => {
|
|
86
|
-
if (a.length !== b.length) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
for (let i = 0; i < a.length; i++) {
|
|
90
|
-
if (a[i] !== b[i]) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
};
|
|
96
|
-
var textEncoder = new TextEncoder();
|
|
97
|
-
var __dxlog_file = "/home/runner/work/dxos/dxos/packages/common/merkle-search-tree/src/forest.ts";
|
|
98
|
-
var Forest = class {
|
|
99
|
-
constructor() {
|
|
100
|
-
this.#nodes = /* @__PURE__ */ new Map();
|
|
101
|
-
this.itemHashOps = 0;
|
|
102
|
-
this.nodeHashOps = 0;
|
|
103
|
-
this.#emptyNodeCache = void 0;
|
|
104
|
-
}
|
|
105
|
-
#nodes;
|
|
106
|
-
async createTree(pairs) {
|
|
107
|
-
const items = await Promise.all([
|
|
108
|
-
...pairs
|
|
109
|
-
].map(([key, value]) => makeItem2(key, value)));
|
|
110
|
-
this.itemHashOps += items.length;
|
|
111
|
-
items.sort((a, b) => a.key < b.key ? -1 : 1);
|
|
112
|
-
for (let i = 0; i < items.length; i++) {
|
|
113
|
-
if (i + 1 < items.length && items[i].key === items[i + 1].key) {
|
|
114
|
-
throw new Error("Duplicate key");
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
if (items.length === 0) {
|
|
118
|
-
return this.#makeNode(0, [], []);
|
|
119
|
-
}
|
|
120
|
-
const buildLevel = async (level, from, to) => {
|
|
121
|
-
(0, import_invariant.invariant)(level >= 0, void 0, {
|
|
122
|
-
F: __dxlog_file,
|
|
123
|
-
L: 37,
|
|
124
|
-
S: this,
|
|
125
|
-
A: [
|
|
126
|
-
"level >= 0",
|
|
127
|
-
""
|
|
128
|
-
]
|
|
129
|
-
});
|
|
130
|
-
if (level === 0) {
|
|
131
|
-
return this.#makeNode(0, items.slice(from, to), []);
|
|
132
|
-
}
|
|
133
|
-
let rangeBegin = from;
|
|
134
|
-
const childItems = [];
|
|
135
|
-
const childNodes = [];
|
|
136
|
-
for (let i = from; i < to; i++) {
|
|
137
|
-
if (items[i].level > level) {
|
|
138
|
-
throw new Error("BUG - Node level is higher then expected");
|
|
139
|
-
}
|
|
140
|
-
if (items[i].level === level) {
|
|
141
|
-
const node = await buildLevel(level - 1, rangeBegin, i);
|
|
142
|
-
childNodes.push(node);
|
|
143
|
-
childItems.push(items[i]);
|
|
144
|
-
rangeBegin = i + 1;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
childNodes.push(await buildLevel(level - 1, rangeBegin, to));
|
|
148
|
-
return this.#makeNode(level, childItems, childNodes);
|
|
149
|
-
};
|
|
150
|
-
const maxLevel = Math.max(...items.map((item) => item.level));
|
|
151
|
-
const root = await buildLevel(maxLevel, 0, items.length);
|
|
152
|
-
return root;
|
|
153
|
-
}
|
|
154
|
-
async get(root, key) {
|
|
155
|
-
const keyLevel = await getKeyLevel(key);
|
|
156
|
-
let node = this.#nodes.get(root);
|
|
157
|
-
if (node !== void 0 && node.level < keyLevel) {
|
|
158
|
-
return {
|
|
159
|
-
kind: "missing"
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
while (node !== void 0) {
|
|
163
|
-
if (node.level === keyLevel) {
|
|
164
|
-
for (let i = 0; i < node.items.length; i++) {
|
|
165
|
-
if (node.items[i].key === key) {
|
|
166
|
-
return {
|
|
167
|
-
kind: "present",
|
|
168
|
-
value: node.items[i].value
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
return {
|
|
173
|
-
kind: "missing"
|
|
174
|
-
};
|
|
175
|
-
} else {
|
|
176
|
-
let found = false;
|
|
177
|
-
for (let i = 0; i < node.items.length; i++) {
|
|
178
|
-
if (node.items[i].key > key) {
|
|
179
|
-
node = this.#nodes.get(node.children[i]);
|
|
180
|
-
found = true;
|
|
181
|
-
break;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
if (!found) {
|
|
185
|
-
(0, import_invariant.invariant)(node.level > 0, void 0, {
|
|
186
|
-
F: __dxlog_file,
|
|
187
|
-
L: 96,
|
|
188
|
-
S: this,
|
|
189
|
-
A: [
|
|
190
|
-
"node!.level > 0",
|
|
191
|
-
""
|
|
192
|
-
]
|
|
193
|
-
});
|
|
194
|
-
node = this.#nodes.get(node.children[node.items.length]);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return {
|
|
199
|
-
kind: "not-available"
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
async merge(digest1, digest2, mergeFn) {
|
|
203
|
-
if (digest1 === digest2) {
|
|
204
|
-
return digest1;
|
|
205
|
-
}
|
|
206
|
-
const node1 = this.#requireNode(digest1);
|
|
207
|
-
const node2 = this.#requireNode(digest2);
|
|
208
|
-
if (node2.level < node1.level) {
|
|
209
|
-
return await this.merge(digest1, await this.#makeNode(node2.level + 1, [], [
|
|
210
|
-
digest2
|
|
211
|
-
]), mergeFn);
|
|
212
|
-
} else if (node1.level < node2.level) {
|
|
213
|
-
return await this.merge(await this.#makeNode(node1.level + 1, [], [
|
|
214
|
-
digest1
|
|
215
|
-
]), digest2, mergeFn);
|
|
216
|
-
}
|
|
217
|
-
(0, import_invariant.invariant)(node1.level === node2.level, void 0, {
|
|
218
|
-
F: __dxlog_file,
|
|
219
|
-
L: 119,
|
|
220
|
-
S: this,
|
|
221
|
-
A: [
|
|
222
|
-
"node1.level === node2.level",
|
|
223
|
-
""
|
|
224
|
-
]
|
|
225
|
-
});
|
|
226
|
-
const resultItems = [];
|
|
227
|
-
const resultChildren = [];
|
|
228
|
-
let carry1 = null;
|
|
229
|
-
let carry2 = null;
|
|
230
|
-
for (let i1 = 0, i2 = 0; i1 < node1.items.length || i2 < node2.items.length; void 0) {
|
|
231
|
-
(0, import_invariant.invariant)(i1 <= node1.items.length, void 0, {
|
|
232
|
-
F: __dxlog_file,
|
|
233
|
-
L: 132,
|
|
234
|
-
S: this,
|
|
235
|
-
A: [
|
|
236
|
-
"i1 <= node1.items.length",
|
|
237
|
-
""
|
|
238
|
-
]
|
|
239
|
-
});
|
|
240
|
-
(0, import_invariant.invariant)(i2 <= node2.items.length, void 0, {
|
|
241
|
-
F: __dxlog_file,
|
|
242
|
-
L: 133,
|
|
243
|
-
S: this,
|
|
244
|
-
A: [
|
|
245
|
-
"i2 <= node2.items.length",
|
|
246
|
-
""
|
|
247
|
-
]
|
|
248
|
-
});
|
|
249
|
-
const key1 = i1 < node1.items.length ? node1.items[i1].key : null;
|
|
250
|
-
const key2 = i2 < node2.items.length ? node2.items[i2].key : null;
|
|
251
|
-
(0, import_invariant.invariant)(key1 !== null || key2 !== null, void 0, {
|
|
252
|
-
F: __dxlog_file,
|
|
253
|
-
L: 137,
|
|
254
|
-
S: this,
|
|
255
|
-
A: [
|
|
256
|
-
"key1 !== null || key2 !== null",
|
|
257
|
-
""
|
|
258
|
-
]
|
|
259
|
-
});
|
|
260
|
-
const child1 = carry1 !== null ? carry1 : node1.children[i1];
|
|
261
|
-
const child2 = carry2 !== null ? carry2 : node2.children[i2];
|
|
262
|
-
if (node1.level > 0) {
|
|
263
|
-
(0, import_invariant.invariant)(validDigest(child1), void 0, {
|
|
264
|
-
F: __dxlog_file,
|
|
265
|
-
L: 142,
|
|
266
|
-
S: this,
|
|
267
|
-
A: [
|
|
268
|
-
"validDigest(child1)",
|
|
269
|
-
""
|
|
270
|
-
]
|
|
271
|
-
});
|
|
272
|
-
(0, import_invariant.invariant)(validDigest(child2), void 0, {
|
|
273
|
-
F: __dxlog_file,
|
|
274
|
-
L: 143,
|
|
275
|
-
S: this,
|
|
276
|
-
A: [
|
|
277
|
-
"validDigest(child2)",
|
|
278
|
-
""
|
|
279
|
-
]
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
if (key1 === key2) {
|
|
283
|
-
if (node1.level > 0) {
|
|
284
|
-
resultChildren.push(await this.merge(child1, child2, mergeFn));
|
|
285
|
-
}
|
|
286
|
-
resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], node2.items[i2]));
|
|
287
|
-
carry1 = null;
|
|
288
|
-
carry2 = null;
|
|
289
|
-
i1++;
|
|
290
|
-
i2++;
|
|
291
|
-
} else if (key2 !== null && (key1 === null || key1 > key2)) {
|
|
292
|
-
(0, import_invariant.invariant)(key2 !== null, void 0, {
|
|
293
|
-
F: __dxlog_file,
|
|
294
|
-
L: 157,
|
|
295
|
-
S: this,
|
|
296
|
-
A: [
|
|
297
|
-
"key2 !== null",
|
|
298
|
-
""
|
|
299
|
-
]
|
|
300
|
-
});
|
|
301
|
-
resultItems.push(await this.#mergeItem(mergeFn, null, node2.items[i2]));
|
|
302
|
-
if (node1.level > 0) {
|
|
303
|
-
const [left, right] = await this.#splitAtKey(child1, key2);
|
|
304
|
-
resultChildren.push(await this.merge(left, child2, mergeFn));
|
|
305
|
-
carry1 = right;
|
|
306
|
-
carry2 = null;
|
|
307
|
-
}
|
|
308
|
-
i2++;
|
|
309
|
-
} else {
|
|
310
|
-
(0, import_invariant.invariant)(key1 !== null, void 0, {
|
|
311
|
-
F: __dxlog_file,
|
|
312
|
-
L: 170,
|
|
313
|
-
S: this,
|
|
314
|
-
A: [
|
|
315
|
-
"key1 !== null",
|
|
316
|
-
""
|
|
317
|
-
]
|
|
318
|
-
});
|
|
319
|
-
resultItems.push(await this.#mergeItem(mergeFn, node1.items[i1], null));
|
|
320
|
-
if (node1.level > 0) {
|
|
321
|
-
const [left, right] = await this.#splitAtKey(child2, key1);
|
|
322
|
-
resultChildren.push(await this.merge(child1, left, mergeFn));
|
|
323
|
-
carry1 = null;
|
|
324
|
-
carry2 = right;
|
|
325
|
-
}
|
|
326
|
-
i1++;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
if (node1.level > 0) {
|
|
330
|
-
const child1 = carry1 !== null ? carry1 : node1.children[node1.items.length];
|
|
331
|
-
const child2 = carry2 !== null ? carry2 : node2.children[node2.items.length];
|
|
332
|
-
resultChildren.push(await this.merge(child1, child2, mergeFn));
|
|
333
|
-
}
|
|
334
|
-
return await this.#makeNode(node1.level, resultItems, resultChildren);
|
|
335
|
-
}
|
|
336
|
-
async setBatch(root, pairs) {
|
|
337
|
-
const newTree = await this.createTree(pairs);
|
|
338
|
-
return await this.merge(root, newTree, async (key, value1, value2) => value2 !== null ? value2 : value1);
|
|
339
|
-
}
|
|
340
|
-
async set(root, key, value) {
|
|
341
|
-
return this.setBatch(root, [
|
|
342
|
-
[
|
|
343
|
-
key,
|
|
344
|
-
value
|
|
345
|
-
]
|
|
346
|
-
]);
|
|
347
|
-
}
|
|
348
|
-
*missingNodes(digest) {
|
|
349
|
-
const node = this.#nodes.get(digest);
|
|
350
|
-
if (!node) {
|
|
351
|
-
yield digest;
|
|
352
|
-
} else {
|
|
353
|
-
for (const child of node.children) {
|
|
354
|
-
yield* this.missingNodes(child);
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
async insertNodes(nodes) {
|
|
359
|
-
const result = [];
|
|
360
|
-
for (const node of nodes) {
|
|
361
|
-
const items = await Promise.all(node.items.map((item) => makeItem2(item.key, item.value)));
|
|
362
|
-
const { digest } = await makeNode(node.level, items, node.children);
|
|
363
|
-
(0, import_invariant.invariant)(digest === node.digest, void 0, {
|
|
364
|
-
F: __dxlog_file,
|
|
365
|
-
L: 218,
|
|
366
|
-
S: this,
|
|
367
|
-
A: [
|
|
368
|
-
"digest === node.digest",
|
|
369
|
-
""
|
|
370
|
-
]
|
|
371
|
-
});
|
|
372
|
-
this.#nodes.set(node.digest, {
|
|
373
|
-
level: node.level,
|
|
374
|
-
digest: node.digest,
|
|
375
|
-
items,
|
|
376
|
-
children: node.children
|
|
377
|
-
});
|
|
378
|
-
result.push(node.digest);
|
|
379
|
-
}
|
|
380
|
-
return result;
|
|
381
|
-
}
|
|
382
|
-
async getNodes(digests) {
|
|
383
|
-
const result = [];
|
|
384
|
-
for (const digest of digests) {
|
|
385
|
-
const node = this.#nodes.get(digest);
|
|
386
|
-
if (!node) {
|
|
387
|
-
continue;
|
|
388
|
-
}
|
|
389
|
-
result.push({
|
|
390
|
-
level: node.level,
|
|
391
|
-
digest: node.digest,
|
|
392
|
-
items: node.items.map((item) => ({
|
|
393
|
-
key: item.key,
|
|
394
|
-
value: item.value
|
|
395
|
-
})),
|
|
396
|
-
children: node.children
|
|
397
|
-
});
|
|
398
|
-
}
|
|
399
|
-
return result;
|
|
400
|
-
}
|
|
401
|
-
treeMut(root) {
|
|
402
|
-
return new TreeMut(this, root);
|
|
403
|
-
}
|
|
404
|
-
formatToString(digest, { pad = 0 } = {}) {
|
|
405
|
-
const padStr = " ".repeat(pad);
|
|
406
|
-
const node = this.#nodes.get(digest);
|
|
407
|
-
if (!node) {
|
|
408
|
-
return `${padStr} o (${digest.slice(0, 8)}) NOT AVAILABLE`;
|
|
409
|
-
}
|
|
410
|
-
let string = `${padStr} o (${digest.slice(0, 8)}) level=${node.level} size=${node.items.length}
|
|
411
|
-
`;
|
|
412
|
-
for (let i = 0; i < node.items.length; i++) {
|
|
413
|
-
if (node.level > 0) {
|
|
414
|
-
string += this.formatToString(node.children[i], {
|
|
415
|
-
pad: pad + 1
|
|
416
|
-
});
|
|
417
|
-
}
|
|
418
|
-
string += `${padStr} - [${node.items[i].itemDigest.slice(0, 8)}] level=${node.items[i].level} ${node.items[i].key.slice(0, 10)} -> ${(0, import_util2.arrayToHex)(node.items[i].value.slice(0, 10).buffer)}
|
|
419
|
-
`;
|
|
420
|
-
}
|
|
421
|
-
if (node.level > 0) {
|
|
422
|
-
string += this.formatToString(node.children[node.items.length], {
|
|
423
|
-
pad: pad + 1
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
return string;
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Items iterator ordered by key.
|
|
430
|
-
*/
|
|
431
|
-
*items(digest) {
|
|
432
|
-
const node = this.#requireNode(digest);
|
|
433
|
-
for (let i = 0; i < node.items.length; i++) {
|
|
434
|
-
if (node.level > 0) {
|
|
435
|
-
yield* this.items(node.children[i]);
|
|
436
|
-
}
|
|
437
|
-
yield node.items[i];
|
|
438
|
-
}
|
|
439
|
-
if (node.level > 0) {
|
|
440
|
-
yield* this.items(node.children[node.items.length]);
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
#requireNode(digest) {
|
|
444
|
-
(0, import_invariant.invariant)(validDigest(digest), void 0, {
|
|
445
|
-
F: __dxlog_file,
|
|
446
|
-
L: 295,
|
|
447
|
-
S: this,
|
|
448
|
-
A: [
|
|
449
|
-
"validDigest(digest)",
|
|
450
|
-
""
|
|
451
|
-
]
|
|
452
|
-
});
|
|
453
|
-
const node = this.#nodes.get(digest);
|
|
454
|
-
if (!node) {
|
|
455
|
-
throw new Error(`Node not available: ${digest}`);
|
|
456
|
-
}
|
|
457
|
-
return node;
|
|
458
|
-
}
|
|
459
|
-
async #mergeItem(mergeFn, item1, item2) {
|
|
460
|
-
(0, import_invariant.invariant)(item1 !== null || item2 !== null, void 0, {
|
|
461
|
-
F: __dxlog_file,
|
|
462
|
-
L: 304,
|
|
463
|
-
S: this,
|
|
464
|
-
A: [
|
|
465
|
-
"item1 !== null || item2 !== null",
|
|
466
|
-
""
|
|
467
|
-
]
|
|
468
|
-
});
|
|
469
|
-
const key = item1?.key ?? item2?.key;
|
|
470
|
-
if (item1 !== null && item2 !== null && (0, import_util2.arraysEqual)(item1.value, item2.value)) {
|
|
471
|
-
return item1;
|
|
472
|
-
} else {
|
|
473
|
-
const mergeResult = await mergeFn(key, item1?.value ?? null, item2?.value ?? null);
|
|
474
|
-
if (item1 !== null && (0, import_util2.arraysEqual)(item1.value, mergeResult)) {
|
|
475
|
-
return item1;
|
|
476
|
-
} else if (item2 !== null && (0, import_util2.arraysEqual)(item2.value, mergeResult)) {
|
|
477
|
-
return item2;
|
|
478
|
-
} else {
|
|
479
|
-
this.itemHashOps++;
|
|
480
|
-
return await makeItem2(key, mergeResult);
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
#emptyNodeCache;
|
|
485
|
-
async #makeNode(level, items, children) {
|
|
486
|
-
(0, import_invariant.invariant)(level > 0 ? items.length + 1 === children.length : children.length === 0, void 0, {
|
|
487
|
-
F: __dxlog_file,
|
|
488
|
-
L: 328,
|
|
489
|
-
S: this,
|
|
490
|
-
A: [
|
|
491
|
-
"level > 0 ? items.length + 1 === children.length : children.length === 0",
|
|
492
|
-
""
|
|
493
|
-
]
|
|
494
|
-
});
|
|
495
|
-
let node;
|
|
496
|
-
if (level === 0 && items.length === 0) {
|
|
497
|
-
node = await (this.#emptyNodeCache ??= makeNode(0, [], []));
|
|
498
|
-
} else {
|
|
499
|
-
node = await makeNode(level, items, children);
|
|
500
|
-
this.nodeHashOps++;
|
|
501
|
-
}
|
|
502
|
-
if (!this.#nodes.has(node.digest)) {
|
|
503
|
-
this.#nodes.set(node.digest, node);
|
|
504
|
-
}
|
|
505
|
-
return node.digest;
|
|
506
|
-
}
|
|
507
|
-
async #splitAtKey(digest, key) {
|
|
508
|
-
const node = this.#requireNode(digest);
|
|
509
|
-
let splitIndex = node.items.length;
|
|
510
|
-
for (let i = 0; i < node.items.length; i++) {
|
|
511
|
-
if (node.items[i].key === key) {
|
|
512
|
-
return [
|
|
513
|
-
await this.#makeNode(node.level, node.items.slice(0, i), node.children.slice(0, i + 1)),
|
|
514
|
-
await this.#makeNode(node.level, node.items.slice(i + 1), node.children.slice(i + 2))
|
|
515
|
-
];
|
|
516
|
-
}
|
|
517
|
-
if (node.items[i].key > key) {
|
|
518
|
-
splitIndex = i;
|
|
519
|
-
break;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (node.level === 0) {
|
|
523
|
-
if (splitIndex === 0) {
|
|
524
|
-
return [
|
|
525
|
-
await this.#makeNode(0, [], []),
|
|
526
|
-
digest
|
|
527
|
-
];
|
|
528
|
-
} else if (splitIndex === node.items.length) {
|
|
529
|
-
return [
|
|
530
|
-
digest,
|
|
531
|
-
await this.#makeNode(0, [], [])
|
|
532
|
-
];
|
|
533
|
-
}
|
|
534
|
-
return [
|
|
535
|
-
await this.#makeNode(node.level, node.items.slice(0, splitIndex), []),
|
|
536
|
-
await this.#makeNode(node.level, node.items.slice(splitIndex), [])
|
|
537
|
-
];
|
|
538
|
-
} else {
|
|
539
|
-
const [left, right] = await this.#splitAtKey(node.children[splitIndex], key);
|
|
540
|
-
return [
|
|
541
|
-
await this.#makeNode(node.level, node.items.slice(0, splitIndex), [
|
|
542
|
-
...node.children.slice(0, splitIndex),
|
|
543
|
-
left
|
|
544
|
-
]),
|
|
545
|
-
await this.#makeNode(node.level, node.items.slice(splitIndex), [
|
|
546
|
-
right,
|
|
547
|
-
...node.children.slice(splitIndex + 1)
|
|
548
|
-
])
|
|
549
|
-
];
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
};
|
|
553
|
-
var TreeMut = class {
|
|
554
|
-
#forest;
|
|
555
|
-
#root;
|
|
556
|
-
constructor(forest, root) {
|
|
557
|
-
this.#forest = forest;
|
|
558
|
-
this.#root = root;
|
|
559
|
-
}
|
|
560
|
-
get root() {
|
|
561
|
-
return this.#root;
|
|
562
|
-
}
|
|
563
|
-
async get(key) {
|
|
564
|
-
return this.#forest.get(this.#root, key);
|
|
565
|
-
}
|
|
566
|
-
async setBatch(pairs) {
|
|
567
|
-
this.#root = await this.#forest.setBatch(this.#root, pairs);
|
|
568
|
-
}
|
|
569
|
-
async set(key, value) {
|
|
570
|
-
this.#root = await this.#forest.set(this.#root, key, value);
|
|
571
|
-
}
|
|
572
|
-
items() {
|
|
573
|
-
return this.#forest.items(this.root);
|
|
574
|
-
}
|
|
575
|
-
};
|
|
576
|
-
var makeNode = async (level, items, children) => {
|
|
577
|
-
(0, import_invariant.invariant)(level > 0 ? items.length + 1 === children.length : children.length === 0, void 0, {
|
|
578
|
-
F: __dxlog_file,
|
|
579
|
-
L: 479,
|
|
580
|
-
S: void 0,
|
|
581
|
-
A: [
|
|
582
|
-
"level > 0 ? items.length + 1 === children.length : children.length === 0",
|
|
583
|
-
""
|
|
584
|
-
]
|
|
585
|
-
});
|
|
586
|
-
const nodeInputData = textEncoder2.encode(items.map((item) => item.itemDigest).join("") + children.join(""));
|
|
587
|
-
const digest = await crypto.subtle.digest({
|
|
588
|
-
name: "SHA-256"
|
|
589
|
-
}, nodeInputData);
|
|
590
|
-
return {
|
|
591
|
-
level,
|
|
592
|
-
digest: formatDigest(new Uint8Array(digest)),
|
|
593
|
-
items,
|
|
594
|
-
children
|
|
595
|
-
};
|
|
596
|
-
};
|
|
597
|
-
var makeItem2 = async (key, value) => {
|
|
598
|
-
(0, import_invariant.invariant)(typeof key === "string", void 0, {
|
|
599
|
-
F: __dxlog_file,
|
|
600
|
-
L: 501,
|
|
601
|
-
S: void 0,
|
|
602
|
-
A: [
|
|
603
|
-
"typeof key === 'string'",
|
|
604
|
-
""
|
|
605
|
-
]
|
|
606
|
-
});
|
|
607
|
-
(0, import_invariant.invariant)(value !== null, void 0, {
|
|
608
|
-
F: __dxlog_file,
|
|
609
|
-
L: 502,
|
|
610
|
-
S: void 0,
|
|
611
|
-
A: [
|
|
612
|
-
"value !== null",
|
|
613
|
-
""
|
|
614
|
-
]
|
|
615
|
-
});
|
|
616
|
-
const keyBytes = textEncoder2.encode(key);
|
|
617
|
-
const keyDigest = await crypto.subtle.digest({
|
|
618
|
-
name: "SHA-256"
|
|
619
|
-
}, keyBytes);
|
|
620
|
-
const keyDigestHex = formatDigest(new Uint8Array(keyDigest));
|
|
621
|
-
const data = new Uint8Array(keyBytes.length + value.length);
|
|
622
|
-
data.set(keyBytes, 0);
|
|
623
|
-
data.set(value, keyBytes.length);
|
|
624
|
-
const itemDigest = await crypto.subtle.digest({
|
|
625
|
-
name: "SHA-256"
|
|
626
|
-
}, data);
|
|
627
|
-
return {
|
|
628
|
-
level: getLevelHex(keyDigestHex),
|
|
629
|
-
key,
|
|
630
|
-
value,
|
|
631
|
-
keyDigest: keyDigestHex,
|
|
632
|
-
itemDigest: formatDigest(new Uint8Array(itemDigest))
|
|
633
|
-
};
|
|
634
|
-
};
|
|
635
|
-
var getKeyLevel = async (key) => {
|
|
636
|
-
const keyBytes = textEncoder2.encode(key);
|
|
637
|
-
const keyDigest = await crypto.subtle.digest({
|
|
638
|
-
name: "SHA-256"
|
|
639
|
-
}, keyBytes);
|
|
640
|
-
const keyDigestHex = formatDigest(new Uint8Array(keyDigest));
|
|
641
|
-
return getLevelHex(keyDigestHex);
|
|
642
|
-
};
|
|
643
|
-
var textEncoder2 = new TextEncoder();
|
|
644
|
-
var validDigest = (digest) => typeof digest === "string" && digest.length > 0;
|
|
645
|
-
var LWWTree = class _LWWTree {
|
|
646
|
-
static async new(params) {
|
|
647
|
-
const tree = new _LWWTree(params);
|
|
648
|
-
tree.#currentRoot = await tree.#forest.createTree([]);
|
|
649
|
-
return tree;
|
|
650
|
-
}
|
|
651
|
-
#actor;
|
|
652
|
-
#forest = new Forest();
|
|
653
|
-
#currentRoot;
|
|
654
|
-
get currentRoot() {
|
|
655
|
-
return this.#currentRoot;
|
|
656
|
-
}
|
|
657
|
-
constructor(params) {
|
|
658
|
-
this.#actor = params.actor;
|
|
659
|
-
}
|
|
660
|
-
async get(key) {
|
|
661
|
-
const data = await this.#getData(key);
|
|
662
|
-
return data?.value;
|
|
663
|
-
}
|
|
664
|
-
async setBatch(pairs) {
|
|
665
|
-
const prevDataBatch = await Promise.all(pairs.map(([key]) => this.#getData(key)));
|
|
666
|
-
const updates = pairs.map(([key, value], i) => {
|
|
667
|
-
const prevData = prevDataBatch[i];
|
|
668
|
-
const newClock = !prevData ? [
|
|
669
|
-
this.#actor,
|
|
670
|
-
0
|
|
671
|
-
] : [
|
|
672
|
-
this.#actor,
|
|
673
|
-
prevData.clock[1] + 1
|
|
674
|
-
];
|
|
675
|
-
const data = this.#encode({
|
|
676
|
-
clock: newClock,
|
|
677
|
-
value
|
|
678
|
-
});
|
|
679
|
-
return [
|
|
680
|
-
key,
|
|
681
|
-
data
|
|
682
|
-
];
|
|
683
|
-
});
|
|
684
|
-
this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);
|
|
685
|
-
}
|
|
686
|
-
async set(key, value) {
|
|
687
|
-
await this.setBatch([
|
|
688
|
-
[
|
|
689
|
-
key,
|
|
690
|
-
value
|
|
691
|
-
]
|
|
692
|
-
]);
|
|
693
|
-
}
|
|
694
|
-
async receiveSyncMessage(state, message) {
|
|
695
|
-
await this.#forest.insertNodes(message.nodes);
|
|
696
|
-
const remoteRoot = message.root ?? state.remoteRoot;
|
|
697
|
-
if (remoteRoot !== null) {
|
|
698
|
-
const missing = [
|
|
699
|
-
...await this.#forest.missingNodes(remoteRoot)
|
|
700
|
-
];
|
|
701
|
-
if (missing.length === 0) {
|
|
702
|
-
this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));
|
|
703
|
-
} else if (state.remoteRoot !== null && state.remoteRoot !== remoteRoot) {
|
|
704
|
-
const missingFromPrevRoot = [
|
|
705
|
-
...await this.#forest.missingNodes(state.remoteRoot)
|
|
706
|
-
];
|
|
707
|
-
if (missingFromPrevRoot.length === 0) {
|
|
708
|
-
await this.#forest.merge(state.remoteRoot, this.#currentRoot, this.#merge.bind(this));
|
|
709
|
-
const missing2 = [
|
|
710
|
-
...await this.#forest.missingNodes(remoteRoot)
|
|
711
|
-
];
|
|
712
|
-
if (missing2.length === 0) {
|
|
713
|
-
this.#currentRoot = await this.#forest.merge(remoteRoot, this.#currentRoot, this.#merge.bind(this));
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
return {
|
|
719
|
-
remoteRoot,
|
|
720
|
-
remoteWant: message.want,
|
|
721
|
-
needsAck: message.nodes.length > 0
|
|
722
|
-
};
|
|
723
|
-
}
|
|
724
|
-
async generateSyncMessage(state) {
|
|
725
|
-
if (state.remoteRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {
|
|
726
|
-
return [
|
|
727
|
-
state,
|
|
728
|
-
null
|
|
729
|
-
];
|
|
730
|
-
}
|
|
731
|
-
const nodes = await this.#forest.getNodes(state.remoteWant);
|
|
732
|
-
const want = state.remoteRoot === null ? [] : [
|
|
733
|
-
...await this.#forest.missingNodes(state.remoteRoot)
|
|
734
|
-
];
|
|
735
|
-
return [
|
|
736
|
-
{
|
|
737
|
-
remoteRoot: state.remoteRoot,
|
|
738
|
-
remoteWant: state.remoteWant,
|
|
739
|
-
needsAck: false
|
|
740
|
-
},
|
|
741
|
-
{
|
|
742
|
-
root: this.#currentRoot,
|
|
743
|
-
want,
|
|
744
|
-
nodes
|
|
745
|
-
}
|
|
746
|
-
];
|
|
747
|
-
}
|
|
748
|
-
async #getData(key) {
|
|
749
|
-
const res = await this.#forest.get(this.#currentRoot, key);
|
|
750
|
-
switch (res.kind) {
|
|
751
|
-
case "present": {
|
|
752
|
-
return this.#decode(res.value);
|
|
753
|
-
}
|
|
754
|
-
case "missing":
|
|
755
|
-
return void 0;
|
|
756
|
-
case "not-available":
|
|
757
|
-
throw new Error("Key not available");
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
async #merge(key, left, right) {
|
|
761
|
-
if (!left) {
|
|
762
|
-
return right;
|
|
763
|
-
}
|
|
764
|
-
if (!right) {
|
|
765
|
-
return left;
|
|
766
|
-
}
|
|
767
|
-
const leftData = this.#decode(left);
|
|
768
|
-
const rightData = this.#decode(right);
|
|
769
|
-
const cmp = leftData.clock[1] === rightData.clock[1] ? leftData.clock[0].localeCompare(rightData.clock[0]) : leftData.clock[1] - rightData.clock[1];
|
|
770
|
-
if (cmp >= 0) {
|
|
771
|
-
return left;
|
|
772
|
-
} else {
|
|
773
|
-
return right;
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
#decode(value) {
|
|
777
|
-
return JSON.parse(textDecoder.decode(value));
|
|
778
|
-
}
|
|
779
|
-
#encode(data) {
|
|
780
|
-
const { clock, value } = data;
|
|
781
|
-
return textEncoder3.encode(JSON.stringify({
|
|
782
|
-
clock,
|
|
783
|
-
value
|
|
784
|
-
}));
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
var initLWWTreeSyncState = () => ({
|
|
788
|
-
remoteRoot: null,
|
|
789
|
-
remoteWant: [],
|
|
790
|
-
needsAck: false
|
|
791
|
-
});
|
|
792
|
-
var textDecoder = new TextDecoder();
|
|
793
|
-
var textEncoder3 = new TextEncoder();
|
|
794
|
-
var MirrorMultiMap = class _MirrorMultiMap {
|
|
795
|
-
static async new(params) {
|
|
796
|
-
const tree = new _MirrorMultiMap(params);
|
|
797
|
-
tree.#currentRoot = await tree.#forest.createTree([]);
|
|
798
|
-
return tree;
|
|
799
|
-
}
|
|
800
|
-
#forest = new Forest();
|
|
801
|
-
#actor;
|
|
802
|
-
#currentRoot;
|
|
803
|
-
#remoteStates = /* @__PURE__ */ new Map();
|
|
804
|
-
constructor(params) {
|
|
805
|
-
this.#actor = params.actor;
|
|
806
|
-
}
|
|
807
|
-
get localActorId() {
|
|
808
|
-
return this.#actor;
|
|
809
|
-
}
|
|
810
|
-
get currentRoot() {
|
|
811
|
-
return this.#currentRoot;
|
|
812
|
-
}
|
|
813
|
-
get forest() {
|
|
814
|
-
return this.#forest;
|
|
815
|
-
}
|
|
816
|
-
async getLocal(key) {
|
|
817
|
-
const entry = await this.#forest.get(this.#currentRoot, key);
|
|
818
|
-
switch (entry?.kind) {
|
|
819
|
-
case "present":
|
|
820
|
-
return this.#decode(entry.value);
|
|
821
|
-
case "missing":
|
|
822
|
-
return void 0;
|
|
823
|
-
case "not-available":
|
|
824
|
-
throw new Error("Unexpected local entry not available");
|
|
825
|
-
}
|
|
826
|
-
}
|
|
827
|
-
async setLocalBatch(pairs) {
|
|
828
|
-
const updates = pairs.map(([key, value]) => [
|
|
829
|
-
key,
|
|
830
|
-
this.#encode(value)
|
|
831
|
-
]);
|
|
832
|
-
this.#currentRoot = await this.#forest.setBatch(this.#currentRoot, updates);
|
|
833
|
-
}
|
|
834
|
-
async getFor(actorId, key) {
|
|
835
|
-
const state = this.#remoteStates.get(actorId);
|
|
836
|
-
if (!state) {
|
|
837
|
-
throw new Error(`Unknown actorId: ${actorId}`);
|
|
838
|
-
}
|
|
839
|
-
if (!state.remoteRoot) {
|
|
840
|
-
return void 0;
|
|
841
|
-
}
|
|
842
|
-
const entry = await this.#forest.get(state.remoteRoot, key);
|
|
843
|
-
switch (entry?.kind) {
|
|
844
|
-
case "present":
|
|
845
|
-
return this.#decode(entry.value);
|
|
846
|
-
case "missing":
|
|
847
|
-
return void 0;
|
|
848
|
-
case "not-available":
|
|
849
|
-
throw new Error("Unexpected remote entry not available");
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
async setForBatch(actorId, pairs) {
|
|
853
|
-
const remoteState = this.#remoteStates.get(actorId) ?? initSyncState();
|
|
854
|
-
const updates = pairs.map(([key, value]) => [
|
|
855
|
-
key,
|
|
856
|
-
this.#encode(value)
|
|
857
|
-
]);
|
|
858
|
-
const prevRoot = remoteState.remoteRoot ?? await this.#forest.createTree([]);
|
|
859
|
-
const nextRoot = await this.#forest.setBatch(prevRoot, updates);
|
|
860
|
-
this.#remoteStates.set(actorId, {
|
|
861
|
-
remoteRoot: nextRoot,
|
|
862
|
-
myRoot: null,
|
|
863
|
-
remoteWant: remoteState.remoteWant,
|
|
864
|
-
needsAck: remoteState.needsAck
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
async getAll(key) {
|
|
868
|
-
const result = /* @__PURE__ */ new Map();
|
|
869
|
-
result.set(this.#actor, await this.getLocal(key));
|
|
870
|
-
for (const [actorId, _state] of this.#remoteStates) {
|
|
871
|
-
result.set(actorId, await this.getFor(actorId, key));
|
|
872
|
-
}
|
|
873
|
-
return result;
|
|
874
|
-
}
|
|
875
|
-
async getDifferent() {
|
|
876
|
-
const resultByKey = /* @__PURE__ */ new Map();
|
|
877
|
-
const actors = /* @__PURE__ */ new Set([
|
|
878
|
-
this.#actor,
|
|
879
|
-
...this.#remoteStates.keys()
|
|
880
|
-
]);
|
|
881
|
-
for (const actor of actors) {
|
|
882
|
-
let root;
|
|
883
|
-
if (actor === this.#actor) {
|
|
884
|
-
root = this.#currentRoot;
|
|
885
|
-
} else {
|
|
886
|
-
root = this.#remoteStates.get(actor)?.remoteRoot;
|
|
887
|
-
}
|
|
888
|
-
if (!root) {
|
|
889
|
-
continue;
|
|
890
|
-
}
|
|
891
|
-
for (const item of this.#forest.items(root)) {
|
|
892
|
-
let subMap = resultByKey.get(item.key);
|
|
893
|
-
if (!subMap) {
|
|
894
|
-
subMap = /* @__PURE__ */ new Map();
|
|
895
|
-
resultByKey.set(item.key, subMap);
|
|
896
|
-
}
|
|
897
|
-
subMap.set(actor, item.value);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
const result = /* @__PURE__ */ new Map();
|
|
901
|
-
for (const [key, subMap] of resultByKey) {
|
|
902
|
-
const first = subMap.values().next().value;
|
|
903
|
-
let allEqual = subMap.size === actors.size;
|
|
904
|
-
if (allEqual) {
|
|
905
|
-
for (const value of subMap.values()) {
|
|
906
|
-
if (!(0, import_util3.arraysEqual)(first, value)) {
|
|
907
|
-
allEqual = false;
|
|
908
|
-
break;
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
if (!allEqual) {
|
|
913
|
-
const resultSubMap = /* @__PURE__ */ new Map();
|
|
914
|
-
for (const [actorId, value] of subMap) {
|
|
915
|
-
resultSubMap.set(actorId, this.#decode(value));
|
|
916
|
-
}
|
|
917
|
-
result.set(key, resultSubMap);
|
|
918
|
-
}
|
|
919
|
-
}
|
|
920
|
-
return result;
|
|
921
|
-
}
|
|
922
|
-
clearActorState(actorId) {
|
|
923
|
-
this.#remoteStates.delete(actorId);
|
|
924
|
-
}
|
|
925
|
-
async receiveSyncMessage(actorId, message) {
|
|
926
|
-
await this.#forest.insertNodes(message.nodes);
|
|
927
|
-
const state = this.#remoteStates.get(actorId) ?? initSyncState();
|
|
928
|
-
const remoteRoot = message.root ?? state.remoteRoot;
|
|
929
|
-
const newState = {
|
|
930
|
-
remoteRoot,
|
|
931
|
-
myRoot: message.remoteRoot ?? state.myRoot,
|
|
932
|
-
remoteWant: message.want,
|
|
933
|
-
needsAck: message.nodes.length > 0
|
|
934
|
-
};
|
|
935
|
-
this.#remoteStates.set(actorId, newState);
|
|
936
|
-
}
|
|
937
|
-
async generateSyncMessage(actorId) {
|
|
938
|
-
const state = this.#remoteStates.get(actorId) ?? initSyncState();
|
|
939
|
-
if (state.myRoot === this.#currentRoot && state.remoteWant.length === 0 && !state.needsAck) {
|
|
940
|
-
return null;
|
|
941
|
-
}
|
|
942
|
-
const nodes = await this.#forest.getNodes(state.remoteWant);
|
|
943
|
-
const want = state.remoteRoot === null ? [] : [
|
|
944
|
-
...await this.#forest.missingNodes(state.remoteRoot)
|
|
945
|
-
];
|
|
946
|
-
this.#remoteStates.set(actorId, {
|
|
947
|
-
remoteRoot: state.remoteRoot,
|
|
948
|
-
myRoot: state.myRoot,
|
|
949
|
-
remoteWant: state.remoteWant,
|
|
950
|
-
needsAck: false
|
|
951
|
-
});
|
|
952
|
-
return {
|
|
953
|
-
root: this.#currentRoot,
|
|
954
|
-
remoteRoot: state.remoteRoot,
|
|
955
|
-
want,
|
|
956
|
-
nodes
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
#decode(value) {
|
|
960
|
-
return JSON.parse(textDecoder2.decode(value));
|
|
961
|
-
}
|
|
962
|
-
#encode(data) {
|
|
963
|
-
return textEncoder4.encode(JSON.stringify(data));
|
|
964
|
-
}
|
|
965
|
-
};
|
|
966
|
-
var initSyncState = () => ({
|
|
967
|
-
remoteRoot: null,
|
|
968
|
-
myRoot: null,
|
|
969
|
-
remoteWant: [],
|
|
970
|
-
needsAck: false
|
|
971
|
-
});
|
|
972
|
-
var textDecoder2 = new TextDecoder();
|
|
973
|
-
var textEncoder4 = new TextEncoder();
|
|
974
|
-
var createValue = (source) => new Uint8Array(textEncoder5.encode(source));
|
|
975
|
-
var textEncoder5 = new TextEncoder();
|
|
976
|
-
var randomKey = () => crypto.randomUUID();
|
|
977
|
-
var randomSample = (data, count) => data.toSorted(() => Math.random() - 0.5).slice(0, count);
|
|
978
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
979
|
-
0 && (module.exports = {
|
|
980
|
-
Forest,
|
|
981
|
-
LWWTree,
|
|
982
|
-
MirrorMultiMap,
|
|
983
|
-
TreeMut,
|
|
984
|
-
createValue,
|
|
985
|
-
digestEquals,
|
|
986
|
-
formatDigest,
|
|
987
|
-
getLevel,
|
|
988
|
-
getLevelHex,
|
|
989
|
-
initLWWTreeSyncState,
|
|
990
|
-
makeItem,
|
|
991
|
-
randomKey,
|
|
992
|
-
randomSample
|
|
993
|
-
});
|
|
994
|
-
//# sourceMappingURL=index.cjs.map
|