meridian-sdk 1.2.0 → 1.2.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 +8 -0
- package/README.md +1 -0
- package/dist/client.d.ts +29 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +43 -1
- package/dist/client.js.map +1 -1
- package/dist/crdt/tree.d.ts +83 -0
- package/dist/crdt/tree.d.ts.map +1 -0
- package/dist/crdt/tree.js +179 -0
- package/dist/crdt/tree.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/sync/delta.d.ts +11 -0
- package/dist/sync/delta.d.ts.map +1 -1
- package/dist/sync/delta.js +4 -0
- package/dist/sync/delta.js.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +49 -1
- package/src/crdt/tree.ts +203 -0
- package/src/index.ts +3 -0
- package/src/sync/delta.ts +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# meridian-sdk
|
|
2
2
|
|
|
3
|
+
## 1.2.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3086c3d: feat(crdt): add TreeCRDT for hierarchical collaborative editing
|
|
8
|
+
|
|
9
|
+
Implements a convergent hierarchical tree CRDT based on Kleppmann et al. (2021). Supports addNode, moveNode, updateNode, and deleteNode operations with cycle detection, LWW value updates, and tombstone deletes. The `client.tree(id)` factory and `useTree()` React hook are now available.
|
|
10
|
+
|
|
3
11
|
## 1.2.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -96,6 +96,7 @@ await Effect.runPromise(
|
|
|
96
96
|
| `client.crdtmap(id)` | `CRDTMapHandle` | — |
|
|
97
97
|
| `client.awareness(key, schema?)` | `AwarenessHandle<T>` | Optional |
|
|
98
98
|
| `client.rga(id)` | `RGAHandle` | — |
|
|
99
|
+
| `client.tree(id)` | `TreeHandle` | — |
|
|
99
100
|
|
|
100
101
|
Without a schema, `T = unknown`. With a schema, incoming deltas are validated at runtime via `Schema.decodeUnknownSync`.
|
|
101
102
|
|
package/dist/client.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
10
10
|
import { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
11
11
|
import { AwarenessHandle } from "./crdt/awareness.js";
|
|
12
12
|
import { RGAHandle } from "./crdt/rga.js";
|
|
13
|
+
import { TreeHandle } from "./crdt/tree.js";
|
|
14
|
+
import type { TreeNodeValue } from "./sync/delta.js";
|
|
13
15
|
import type { TokenClaims } from "./schema.js";
|
|
14
16
|
import type { TokenParseError, TokenExpiredError } from "./errors.js";
|
|
15
17
|
export interface GCounterSnapshotEntry {
|
|
@@ -56,7 +58,12 @@ export interface RGASnapshotEntry {
|
|
|
56
58
|
crdtId: string;
|
|
57
59
|
text: string;
|
|
58
60
|
}
|
|
59
|
-
export
|
|
61
|
+
export interface TreeSnapshotEntry {
|
|
62
|
+
type: "tree";
|
|
63
|
+
crdtId: string;
|
|
64
|
+
roots: TreeNodeValue[];
|
|
65
|
+
}
|
|
66
|
+
export type CRDTSnapshotEntry = GCounterSnapshotEntry | PNCounterSnapshotEntry | ORSetSnapshotEntry | LwwRegisterSnapshotEntry | PresenceSnapshotEntry | CRDTMapSnapshotEntry | RGASnapshotEntry | TreeSnapshotEntry;
|
|
60
67
|
export interface DeltaEvent {
|
|
61
68
|
crdtId: string;
|
|
62
69
|
type: CRDTSnapshotEntry["type"];
|
|
@@ -115,6 +122,7 @@ export declare class MeridianClient {
|
|
|
115
122
|
private readonly cmHandles;
|
|
116
123
|
private readonly awHandles;
|
|
117
124
|
private readonly rgaHandles;
|
|
125
|
+
private readonly treeHandles;
|
|
118
126
|
private readonly anyListeners;
|
|
119
127
|
private readonly deltaListeners;
|
|
120
128
|
private readonly handleUnsubs;
|
|
@@ -265,6 +273,26 @@ export declare class MeridianClient {
|
|
|
265
273
|
* ```
|
|
266
274
|
*/
|
|
267
275
|
rga(crdtId: string): RGAHandle;
|
|
276
|
+
/**
|
|
277
|
+
* Returns a handle for a TreeCRDT — a convergent hierarchical tree.
|
|
278
|
+
*
|
|
279
|
+
* Use this for outlines, document trees, mind maps, or any nested structure
|
|
280
|
+
* that needs concurrent editing. Concurrent moves use Kleppmann (2021)
|
|
281
|
+
* move semantics: cycle-creating moves are discarded, all replicas converge.
|
|
282
|
+
*
|
|
283
|
+
* Handles are cached by `crdtId`; the same handle is returned for repeated calls.
|
|
284
|
+
*
|
|
285
|
+
* @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```ts
|
|
289
|
+
* const tree = client.tree('doc:outline');
|
|
290
|
+
* const rootId = tree.addNode(null, 'a0', 'Introduction');
|
|
291
|
+
* const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
|
|
292
|
+
* tree.onChange(t => console.log(t.roots));
|
|
293
|
+
* ```
|
|
294
|
+
*/
|
|
295
|
+
tree(crdtId: string): TreeHandle;
|
|
268
296
|
/**
|
|
269
297
|
* Returns a handle for an ephemeral awareness channel.
|
|
270
298
|
*
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAExD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -9,7 +9,8 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
9
9
|
import { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
10
10
|
import { AwarenessHandle } from "./crdt/awareness.js";
|
|
11
11
|
import { RGAHandle } from "./crdt/rga.js";
|
|
12
|
-
import {
|
|
12
|
+
import { TreeHandle } from "./crdt/tree.js";
|
|
13
|
+
import { decodeGCounterDelta, decodePNCounterDelta, decodeORSetDelta, decodeLwwDelta, decodePresenceDelta, decodeCRDTMapDelta, decodeRGADelta, decodeTreeDelta, } from "./sync/delta.js";
|
|
13
14
|
import { parseAndValidateToken } from "./auth/token.js";
|
|
14
15
|
/**
|
|
15
16
|
* The main entry point for the Meridian real-time CRDT SDK.
|
|
@@ -52,6 +53,7 @@ export class MeridianClient {
|
|
|
52
53
|
cmHandles = new Map();
|
|
53
54
|
awHandles = new Map();
|
|
54
55
|
rgaHandles = new Map();
|
|
56
|
+
treeHandles = new Map();
|
|
55
57
|
anyListeners = new Set();
|
|
56
58
|
deltaListeners = new Set();
|
|
57
59
|
handleUnsubs = [];
|
|
@@ -290,6 +292,35 @@ export class MeridianClient {
|
|
|
290
292
|
}
|
|
291
293
|
return handle;
|
|
292
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Returns a handle for a TreeCRDT — a convergent hierarchical tree.
|
|
297
|
+
*
|
|
298
|
+
* Use this for outlines, document trees, mind maps, or any nested structure
|
|
299
|
+
* that needs concurrent editing. Concurrent moves use Kleppmann (2021)
|
|
300
|
+
* move semantics: cycle-creating moves are discarded, all replicas converge.
|
|
301
|
+
*
|
|
302
|
+
* Handles are cached by `crdtId`; the same handle is returned for repeated calls.
|
|
303
|
+
*
|
|
304
|
+
* @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* const tree = client.tree('doc:outline');
|
|
309
|
+
* const rootId = tree.addNode(null, 'a0', 'Introduction');
|
|
310
|
+
* const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
|
|
311
|
+
* tree.onChange(t => console.log(t.roots));
|
|
312
|
+
* ```
|
|
313
|
+
*/
|
|
314
|
+
tree(crdtId) {
|
|
315
|
+
let handle = this.treeHandles.get(crdtId);
|
|
316
|
+
if (!handle) {
|
|
317
|
+
handle = new TreeHandle({ crdtId, clientId: this.clientId, transport: this.transport });
|
|
318
|
+
this.treeHandles.set(crdtId, handle);
|
|
319
|
+
this.transport.subscribe(crdtId);
|
|
320
|
+
this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
|
|
321
|
+
}
|
|
322
|
+
return handle;
|
|
323
|
+
}
|
|
293
324
|
/**
|
|
294
325
|
* Returns a handle for an ephemeral awareness channel.
|
|
295
326
|
*
|
|
@@ -378,6 +409,8 @@ export class MeridianClient {
|
|
|
378
409
|
crdts.push({ type: "crdtmap", crdtId, value: h.value() });
|
|
379
410
|
for (const [crdtId, h] of this.rgaHandles)
|
|
380
411
|
crdts.push({ type: "rga", crdtId, text: h.value() });
|
|
412
|
+
for (const [crdtId, h] of this.treeHandles)
|
|
413
|
+
crdts.push({ type: "tree", crdtId, roots: h.value().roots });
|
|
381
414
|
return {
|
|
382
415
|
namespace: this.namespace,
|
|
383
416
|
clientId: this.clientId,
|
|
@@ -479,6 +512,15 @@ export class MeridianClient {
|
|
|
479
512
|
}
|
|
480
513
|
catch { /* stale */ }
|
|
481
514
|
this.notifyDelta(crdt_id, "rga");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const treeHandle = this.treeHandles.get(crdt_id);
|
|
518
|
+
if (treeHandle) {
|
|
519
|
+
try {
|
|
520
|
+
treeHandle.applyDelta(decodeTreeDelta(delta_bytes));
|
|
521
|
+
}
|
|
522
|
+
catch { /* stale */ }
|
|
523
|
+
this.notifyDelta(crdt_id, "tree");
|
|
482
524
|
}
|
|
483
525
|
}
|
|
484
526
|
notifyDelta(crdtId, type) {
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAe,MAAM,QAAQ,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,eAAe,GAChB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AA+ExD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,cAAc;IAChB,SAAS,CAAS;IAClB,QAAQ,CAAS;IACjB,MAAM,CAAc;IAEZ,SAAS,CAAc;IAC/B,IAAI,CAAa;IAE1B,4GAA4G;IAC3F,SAAS,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC/C,SAAS,GAAG,IAAI,GAAG,EAAgC,CAAC;IACpD,SAAS,GAAG,IAAI,GAAG,EAAsC,CAAC;IAC1D,SAAS,GAAG,IAAI,GAAG,EAAmC,CAAC;IACvD,SAAS,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC7C,SAAS,GAAG,IAAI,GAAG,EAAoC,CAAC;IACxD,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAE5C,YAAY,GAAG,IAAI,GAAG,EAAc,CAAC;IACrC,cAAc,GAAG,IAAI,GAAG,EAA+B,CAAC;IACxD,YAAY,GAAsB,EAAE,CAAC;IAEtD,YAAoB,MAA4B,EAAE,MAAmB;QACnE,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;QAEjC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG;aACxB,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC;aAChC,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;QAEvE,MAAM,KAAK,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,kBAAkB,MAAM,CAAC,SAAS,UAAU,CAAC;QAC/F,IAAI,CAAC,SAAS,GAAG,IAAI,WAAW,CAAC;YAC/B,GAAG,EAAE,KAAK;YACV,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACnD,CAAC,CAAC;QAEH,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;YACjC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAC3B,CAAC;QAED,wEAAwE;QACxE,+EAA+E;QAC/E,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,MAAM,CAAC,MAAM,CACX,MAA4B;QAE5B,OAAO,qBAAqB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAC7C,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,MAAc;QACrB,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,cAAc,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAChH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,SAAS,CAAC,MAAc;QACtB,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,eAAe,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACjH,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,KAAK,CAAI,MAAc,EAAE,MAAyB;QAChD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAA+B,CAAC;QACtE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YAChG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,WAAW,CAAI,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,WAAW,CAAI,IAAI,CAAC,CAAC;YACrF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAA8B,CAAC,CAAC;YAC3D,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAI,MAAc,EAAE,MAAyB;QACtD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAqC,CAAC;QAC5E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YAChG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAI,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAI,IAAI,CAAC,CAAC;YACjG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAoC,CAAC,CAAC;YACjE,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,QAAQ,CAAI,MAAc,EAAE,MAAyB;QACnD,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAkC,CAAC;QACzE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YAChG,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,cAAc,CAAI,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,cAAc,CAAI,IAAI,CAAC,CAAC;YAC3F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAiC,CAAC,CAAC;YAC9D,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,MAAc;QACpB,IAAI,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,aAAa,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAC/G,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACnC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,GAAG,CAAC,MAAc;QAChB,IAAI,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACvF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACpC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,IAAI,CAAC,MAAc;QACjB,IAAI,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YACxF,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACrC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,SAAS,CAAc,GAAW,EAAE,MAAyB;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,QAAQ;YAAE,OAAO,QAA8B,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAI,GAAG,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAClF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAkC,CAAC,CAAC;QAC5D,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gBAAgB,CAAC,SAAS,GAAG,KAAK;QAChC,OAAO,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,uEAAuE;IACvE,IAAI,cAAc;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;IACvC,CAAC;IAED,mFAAmF;IACnF,eAAe;QACb,OAAO,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,CAAC;IAC1C,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,QAAkC;QAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,QAAoB;QAC9B,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;;OAIG;IACH,OAAO,CAAC,QAAqC;QAC3C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,GAAG,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAED;;;OAGG;IACH,QAAQ;QACN,MAAM,KAAK,GAAwB,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjF,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9D,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAe,EAAE,CAAC,CAAC;QAC7E,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAChF,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAgE,EAAE,CAAC,CAAC;QAC7H,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS;YACtC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5D,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,UAAU;YACvC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACvD,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW;YACxC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY;YACpC,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc;YAC7C,KAAK;SACN,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,KAAK;QACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY;YAAE,KAAK,EAAE,CAAC;QAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAED,mHAAmH;IACnH,MAAM;QACJ,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;IAC1B,CAAC;IAEO,eAAe;QACrB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,YAAY;YAAE,EAAE,EAAE,CAAC;IAC3C,CAAC;IAEO,eAAe,CAAC,GAAc;QACpC,IAAI,oBAAoB,IAAI,GAAG,EAAE,CAAC;YAChC,MAAM,EAAE,SAAS,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC,kBAAkB,CAAC;YACxD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACzD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC;YAAE,OAAO;QAC9B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;QAE3C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACpF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACrF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACjF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACpF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBAAC,QAAQ,CAAC,UAAU,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YACnF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC;gBAAC,SAAS,CAAC,UAAU,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YAChF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QACD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC;gBAAC,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;YAClF,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,MAAc,EAAE,IAA+B;QACjE,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QAC3C,MAAM,KAAK,GAAe,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAC3D,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,cAAc;YAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Stream } from "effect";
|
|
2
|
+
import type { WsTransport } from "../transport/websocket.js";
|
|
3
|
+
import type { TreeDelta, TreeNodeValue } from "../sync/delta.js";
|
|
4
|
+
/**
|
|
5
|
+
* Low-level handle for a TreeCRDT — a convergent hierarchical tree.
|
|
6
|
+
*
|
|
7
|
+
* Obtained via `MeridianClient.tree()`. Supports add, move, update, and delete
|
|
8
|
+
* operations on tree nodes. Concurrent moves use Kleppmann et al. (2021)
|
|
9
|
+
* move semantics — cycles are prevented, all replicas converge.
|
|
10
|
+
*
|
|
11
|
+
* Node IDs are returned by `addNode()` as opaque strings of the form
|
|
12
|
+
* "wall_ms:logical:node_id" matching the Rust HLC serialization.
|
|
13
|
+
*/
|
|
14
|
+
export declare class TreeHandle {
|
|
15
|
+
private roots;
|
|
16
|
+
private readonly crdtId;
|
|
17
|
+
private readonly clientId;
|
|
18
|
+
private readonly transport;
|
|
19
|
+
private readonly listeners;
|
|
20
|
+
private opCounter;
|
|
21
|
+
constructor(opts: {
|
|
22
|
+
crdtId: string;
|
|
23
|
+
clientId: number;
|
|
24
|
+
transport: WsTransport;
|
|
25
|
+
});
|
|
26
|
+
/** Returns the current tree value. */
|
|
27
|
+
value(): {
|
|
28
|
+
roots: TreeNodeValue[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Registers a listener called whenever the tree changes.
|
|
32
|
+
*
|
|
33
|
+
* @returns An unsubscribe function.
|
|
34
|
+
*/
|
|
35
|
+
onChange(listener: (value: {
|
|
36
|
+
roots: TreeNodeValue[];
|
|
37
|
+
}) => void): () => void;
|
|
38
|
+
/** Returns an Effect Stream that emits the tree on every change. */
|
|
39
|
+
stream(): Stream.Stream<{
|
|
40
|
+
roots: TreeNodeValue[];
|
|
41
|
+
}, never, never>;
|
|
42
|
+
/**
|
|
43
|
+
* Adds a new node to the tree.
|
|
44
|
+
*
|
|
45
|
+
* @param parentId - ID of the parent node, or null for a root-level node.
|
|
46
|
+
* @param position - Fractional index string for sibling ordering (e.g. "a0", "b0").
|
|
47
|
+
* @param value - String content of the node.
|
|
48
|
+
* @param ttlMs - Optional TTL.
|
|
49
|
+
* @returns The new node's ID as a string.
|
|
50
|
+
*/
|
|
51
|
+
addNode(parentId: string | null, position: string, value: string, ttlMs?: number): string;
|
|
52
|
+
/**
|
|
53
|
+
* Moves a node to a new parent and/or position.
|
|
54
|
+
*
|
|
55
|
+
* @param nodeId - ID of the node to move.
|
|
56
|
+
* @param newParentId - New parent node ID, or null for root level.
|
|
57
|
+
* @param newPosition - New fractional index position.
|
|
58
|
+
* @param ttlMs - Optional TTL.
|
|
59
|
+
*/
|
|
60
|
+
moveNode(nodeId: string, newParentId: string | null, newPosition: string, ttlMs?: number): void;
|
|
61
|
+
/**
|
|
62
|
+
* Updates the value of an existing node (LWW — last write wins).
|
|
63
|
+
*
|
|
64
|
+
* @param nodeId - ID of the node to update.
|
|
65
|
+
* @param value - New string value.
|
|
66
|
+
* @param ttlMs - Optional TTL.
|
|
67
|
+
*/
|
|
68
|
+
updateNode(nodeId: string, value: string, ttlMs?: number): void;
|
|
69
|
+
/**
|
|
70
|
+
* Tombstone-deletes a node. Children are preserved in the tree structure
|
|
71
|
+
* but become invisible until the node is undeleted via a concurrent move.
|
|
72
|
+
*
|
|
73
|
+
* @param nodeId - ID of the node to delete.
|
|
74
|
+
* @param ttlMs - Optional TTL.
|
|
75
|
+
*/
|
|
76
|
+
deleteNode(nodeId: string, ttlMs?: number): void;
|
|
77
|
+
/** Apply a delta received from the server. Replaces local state with authoritative tree. */
|
|
78
|
+
applyDelta(delta: TreeDelta): void;
|
|
79
|
+
private emit;
|
|
80
|
+
/** Parse an HLC string "wall_ms:logical:node_id" back to a Rust-compatible object. */
|
|
81
|
+
private parseHlc;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/crdt/tree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;;;;;;;;GASG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0D;IACpF,OAAO,CAAC,SAAS,CAAK;gBAEV,IAAI,EAAE;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,WAAW,CAAC;KACxB;IAMD,sCAAsC;IACtC,KAAK,IAAI;QAAE,KAAK,EAAE,aAAa,EAAE,CAAA;KAAE;IAInC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,aAAa,EAAE,CAAA;KAAE,KAAK,IAAI,GAAG,MAAM,IAAI;IAK3E,oEAAoE;IACpE,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;QAAE,KAAK,EAAE,aAAa,EAAE,CAAA;KAAE,EAAE,KAAK,EAAE,KAAK,CAAC;IAOjE;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IA4BzF;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAyB/F;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAwB/D;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAkBhD,4FAA4F;IAC5F,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAKlC,OAAO,CAAC,IAAI;IAKZ,sFAAsF;IACtF,OAAO,CAAC,QAAQ;CAQjB"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { Chunk, Effect, Stream } from "effect";
|
|
2
|
+
import { encode } from "../codec.js";
|
|
3
|
+
/**
|
|
4
|
+
* Low-level handle for a TreeCRDT — a convergent hierarchical tree.
|
|
5
|
+
*
|
|
6
|
+
* Obtained via `MeridianClient.tree()`. Supports add, move, update, and delete
|
|
7
|
+
* operations on tree nodes. Concurrent moves use Kleppmann et al. (2021)
|
|
8
|
+
* move semantics — cycles are prevented, all replicas converge.
|
|
9
|
+
*
|
|
10
|
+
* Node IDs are returned by `addNode()` as opaque strings of the form
|
|
11
|
+
* "wall_ms:logical:node_id" matching the Rust HLC serialization.
|
|
12
|
+
*/
|
|
13
|
+
export class TreeHandle {
|
|
14
|
+
roots = [];
|
|
15
|
+
crdtId;
|
|
16
|
+
clientId;
|
|
17
|
+
transport;
|
|
18
|
+
listeners = new Set();
|
|
19
|
+
opCounter = 0;
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
this.crdtId = opts.crdtId;
|
|
22
|
+
this.clientId = opts.clientId;
|
|
23
|
+
this.transport = opts.transport;
|
|
24
|
+
}
|
|
25
|
+
/** Returns the current tree value. */
|
|
26
|
+
value() {
|
|
27
|
+
return { roots: this.roots };
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Registers a listener called whenever the tree changes.
|
|
31
|
+
*
|
|
32
|
+
* @returns An unsubscribe function.
|
|
33
|
+
*/
|
|
34
|
+
onChange(listener) {
|
|
35
|
+
this.listeners.add(listener);
|
|
36
|
+
return () => { this.listeners.delete(listener); };
|
|
37
|
+
}
|
|
38
|
+
/** Returns an Effect Stream that emits the tree on every change. */
|
|
39
|
+
stream() {
|
|
40
|
+
return Stream.async((emit) => {
|
|
41
|
+
const unsub = this.onChange((value) => { void emit(Effect.succeed(Chunk.of(value))); });
|
|
42
|
+
return Effect.sync(unsub);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Adds a new node to the tree.
|
|
47
|
+
*
|
|
48
|
+
* @param parentId - ID of the parent node, or null for a root-level node.
|
|
49
|
+
* @param position - Fractional index string for sibling ordering (e.g. "a0", "b0").
|
|
50
|
+
* @param value - String content of the node.
|
|
51
|
+
* @param ttlMs - Optional TTL.
|
|
52
|
+
* @returns The new node's ID as a string.
|
|
53
|
+
*/
|
|
54
|
+
addNode(parentId, position, value, ttlMs) {
|
|
55
|
+
const wallMs = Date.now();
|
|
56
|
+
const logical = this.opCounter++;
|
|
57
|
+
const id = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
58
|
+
const idStr = `${wallMs}:${logical}:${this.clientId}`;
|
|
59
|
+
const op = encode({
|
|
60
|
+
Tree: {
|
|
61
|
+
AddNode: {
|
|
62
|
+
id,
|
|
63
|
+
parent_id: parentId !== null ? this.parseHlc(parentId) : null,
|
|
64
|
+
position,
|
|
65
|
+
value,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
this.transport.send({
|
|
70
|
+
Op: {
|
|
71
|
+
crdt_id: this.crdtId,
|
|
72
|
+
op_bytes: op,
|
|
73
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
return idStr;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Moves a node to a new parent and/or position.
|
|
80
|
+
*
|
|
81
|
+
* @param nodeId - ID of the node to move.
|
|
82
|
+
* @param newParentId - New parent node ID, or null for root level.
|
|
83
|
+
* @param newPosition - New fractional index position.
|
|
84
|
+
* @param ttlMs - Optional TTL.
|
|
85
|
+
*/
|
|
86
|
+
moveNode(nodeId, newParentId, newPosition, ttlMs) {
|
|
87
|
+
const wallMs = Date.now();
|
|
88
|
+
const logical = this.opCounter++;
|
|
89
|
+
const opId = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
90
|
+
const op = encode({
|
|
91
|
+
Tree: {
|
|
92
|
+
MoveNode: {
|
|
93
|
+
op_id: opId,
|
|
94
|
+
node_id: this.parseHlc(nodeId),
|
|
95
|
+
new_parent_id: newParentId !== null ? this.parseHlc(newParentId) : null,
|
|
96
|
+
new_position: newPosition,
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
this.transport.send({
|
|
101
|
+
Op: {
|
|
102
|
+
crdt_id: this.crdtId,
|
|
103
|
+
op_bytes: op,
|
|
104
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Updates the value of an existing node (LWW — last write wins).
|
|
110
|
+
*
|
|
111
|
+
* @param nodeId - ID of the node to update.
|
|
112
|
+
* @param value - New string value.
|
|
113
|
+
* @param ttlMs - Optional TTL.
|
|
114
|
+
*/
|
|
115
|
+
updateNode(nodeId, value, ttlMs) {
|
|
116
|
+
const wallMs = Date.now();
|
|
117
|
+
const logical = this.opCounter++;
|
|
118
|
+
const updatedAt = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
119
|
+
const op = encode({
|
|
120
|
+
Tree: {
|
|
121
|
+
UpdateNode: {
|
|
122
|
+
id: this.parseHlc(nodeId),
|
|
123
|
+
value,
|
|
124
|
+
updated_at: updatedAt,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
this.transport.send({
|
|
129
|
+
Op: {
|
|
130
|
+
crdt_id: this.crdtId,
|
|
131
|
+
op_bytes: op,
|
|
132
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Tombstone-deletes a node. Children are preserved in the tree structure
|
|
138
|
+
* but become invisible until the node is undeleted via a concurrent move.
|
|
139
|
+
*
|
|
140
|
+
* @param nodeId - ID of the node to delete.
|
|
141
|
+
* @param ttlMs - Optional TTL.
|
|
142
|
+
*/
|
|
143
|
+
deleteNode(nodeId, ttlMs) {
|
|
144
|
+
const op = encode({
|
|
145
|
+
Tree: {
|
|
146
|
+
DeleteNode: {
|
|
147
|
+
id: this.parseHlc(nodeId),
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
this.transport.send({
|
|
152
|
+
Op: {
|
|
153
|
+
crdt_id: this.crdtId,
|
|
154
|
+
op_bytes: op,
|
|
155
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/** Apply a delta received from the server. Replaces local state with authoritative tree. */
|
|
160
|
+
applyDelta(delta) {
|
|
161
|
+
this.roots = delta.roots;
|
|
162
|
+
this.emit();
|
|
163
|
+
}
|
|
164
|
+
emit() {
|
|
165
|
+
const v = { roots: this.roots };
|
|
166
|
+
for (const listener of this.listeners)
|
|
167
|
+
listener(v);
|
|
168
|
+
}
|
|
169
|
+
/** Parse an HLC string "wall_ms:logical:node_id" back to a Rust-compatible object. */
|
|
170
|
+
parseHlc(id) {
|
|
171
|
+
const parts = id.split(":");
|
|
172
|
+
return {
|
|
173
|
+
wall_ms: Number(parts[0]),
|
|
174
|
+
logical: Number(parts[1]),
|
|
175
|
+
node_id: Number(parts[2]),
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/crdt/tree.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { MeridianClient } from "./client.js";
|
|
2
|
-
export type { MeridianClientConfig, ClientSnapshot, DeltaEvent, CRDTSnapshotEntry, GCounterSnapshotEntry, PNCounterSnapshotEntry, ORSetSnapshotEntry, LwwRegisterSnapshotEntry, PresenceSnapshotEntry, CRDTMapSnapshotEntry, RGASnapshotEntry, } from "./client.js";
|
|
2
|
+
export type { MeridianClientConfig, ClientSnapshot, DeltaEvent, CRDTSnapshotEntry, GCounterSnapshotEntry, PNCounterSnapshotEntry, ORSetSnapshotEntry, LwwRegisterSnapshotEntry, PresenceSnapshotEntry, CRDTMapSnapshotEntry, RGASnapshotEntry, TreeSnapshotEntry, } from "./client.js";
|
|
3
3
|
export { GCounterHandle } from "./crdt/gcounter.js";
|
|
4
4
|
export { PNCounterHandle } from "./crdt/pncounter.js";
|
|
5
5
|
export { ORSetHandle } from "./crdt/orset.js";
|
|
@@ -11,6 +11,8 @@ export type { CrdtMapValue } from "./crdt/crdtmap.js";
|
|
|
11
11
|
export { AwarenessHandle } from "./crdt/awareness.js";
|
|
12
12
|
export type { AwarenessEntry } from "./crdt/awareness.js";
|
|
13
13
|
export { RGAHandle } from "./crdt/rga.js";
|
|
14
|
+
export { TreeHandle } from "./crdt/tree.js";
|
|
15
|
+
export type { TreeNodeValue, TreeDelta } from "./sync/delta.js";
|
|
14
16
|
export { HttpClient } from "./transport/http.js";
|
|
15
17
|
export type { HttpClientConfig, HistoryEntry, HistoryResponse } from "./transport/http.js";
|
|
16
18
|
export { WsTransport } from "./transport/websocket.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,oBAAoB,EACpB,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAG3E,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlG,OAAO,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAGrB,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,aAAa,EACb,cAAc,EACd,UAAU,EACV,QAAQ,EACR,aAAa,EACb,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGzD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,IAAI,EACJ,YAAY,EACZ,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG3D,OAAO,EACL,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,7 @@ export { PresenceHandle } from "./crdt/presence.js";
|
|
|
9
9
|
export { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
10
10
|
export { AwarenessHandle } from "./crdt/awareness.js";
|
|
11
11
|
export { RGAHandle } from "./crdt/rga.js";
|
|
12
|
+
export { TreeHandle } from "./crdt/tree.js";
|
|
12
13
|
// Transport
|
|
13
14
|
export { HttpClient } from "./transport/http.js";
|
|
14
15
|
export { WsTransport } from "./transport/websocket.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AAErB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qBAAqB;AAErB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAgB7C,eAAe;AACf,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,YAAY;AACZ,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGvD,OAAO;AACP,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElG,iEAAiE;AACjE,OAAO,EACL,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,YAAY,EACZ,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,qEAAqE;AACrE,OAAO,EACL,WAAW,EACX,WAAW,EACX,WAAW,EACX,SAAS,EACT,SAAS,EACT,aAAa,EACb,cAAc,EACd,UAAU,EACV,QAAQ,EACR,aAAa,EACb,eAAe,EACf,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,sCAAsC;AACtC,OAAO,EACL,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAOrB,sCAAsC;AACtC,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3D,qCAAqC;AACrC,OAAO,EACL,MAAM,EACN,MAAM,EACN,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/sync/delta.d.ts
CHANGED
|
@@ -42,6 +42,15 @@ export interface RGADelta {
|
|
|
42
42
|
text: string;
|
|
43
43
|
}
|
|
44
44
|
export declare const decodeRGADelta: (bytes: Uint8Array) => RGADelta;
|
|
45
|
+
export interface TreeNodeValue {
|
|
46
|
+
id: string;
|
|
47
|
+
value: string;
|
|
48
|
+
children: TreeNodeValue[];
|
|
49
|
+
}
|
|
50
|
+
export interface TreeDelta {
|
|
51
|
+
roots: TreeNodeValue[];
|
|
52
|
+
}
|
|
53
|
+
export declare const decodeTreeDelta: (bytes: Uint8Array) => TreeDelta;
|
|
45
54
|
export type CrdtValueDelta = {
|
|
46
55
|
GCounter: GCounterDelta;
|
|
47
56
|
} | {
|
|
@@ -54,6 +63,8 @@ export type CrdtValueDelta = {
|
|
|
54
63
|
Presence: PresenceDelta;
|
|
55
64
|
} | {
|
|
56
65
|
RGA: RGADelta;
|
|
66
|
+
} | {
|
|
67
|
+
Tree: TreeDelta;
|
|
57
68
|
};
|
|
58
69
|
export interface CRDTMapDelta {
|
|
59
70
|
deltas: Record<string, CrdtValueDelta>;
|
package/dist/sync/delta.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../src/sync/delta.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,UAAU,KAAG,aAGvD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,oBAAoB,GAAI,OAAO,UAAU,KAAG,cASxD,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,KAAG,UAUpD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,QAGlD,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,UAAU,KAAG,aAGvD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,QAGlD,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC3B;IAAE,SAAS,EAAE,cAAc,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,GACrB;IAAE,WAAW,EAAE,QAAQ,CAAA;CAAE,GACzB;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC3B;IAAE,GAAG,EAAE,QAAQ,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"delta.d.ts","sourceRoot":"","sources":["../../src/sync/delta.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,UAAU,KAAG,aAGvD,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;IAC1B,GAAG,EAAE,aAAa,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,oBAAoB,GAAI,OAAO,UAAU,KAAG,cASxD,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,gBAAgB,GAAI,OAAO,UAAU,KAAG,UAUpD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACxB;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,QAGlD,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IAC7E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC,CAAC;CACpD;AAED,eAAO,MAAM,mBAAmB,GAAI,OAAO,UAAU,KAAG,aAGvD,CAAC;AAEF,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,cAAc,GAAI,OAAO,UAAU,KAAG,QAGlD,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,aAAa,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,GAAI,OAAO,UAAU,KAAG,SAGnD,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC3B;IAAE,SAAS,EAAE,cAAc,CAAA;CAAE,GAC7B;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,GACrB;IAAE,WAAW,EAAE,QAAQ,CAAA;CAAE,GACzB;IAAE,QAAQ,EAAE,aAAa,CAAA;CAAE,GAC3B;IAAE,GAAG,EAAE,QAAQ,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACxC;AAED,eAAO,MAAM,kBAAkB,GAAI,OAAO,UAAU,KAAG,YAGtD,CAAC"}
|
package/dist/sync/delta.js
CHANGED
|
@@ -28,6 +28,10 @@ export const decodeRGADelta = (bytes) => {
|
|
|
28
28
|
const raw = decode(bytes);
|
|
29
29
|
return { text: raw.text ?? "" };
|
|
30
30
|
};
|
|
31
|
+
export const decodeTreeDelta = (bytes) => {
|
|
32
|
+
const raw = decode(bytes);
|
|
33
|
+
return { roots: raw.roots ?? [] };
|
|
34
|
+
};
|
|
31
35
|
export const decodeCRDTMapDelta = (bytes) => {
|
|
32
36
|
const raw = decode(bytes);
|
|
33
37
|
return { deltas: (raw.deltas ?? {}) };
|
package/dist/sync/delta.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../src/sync/delta.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAM1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAA0C,CAAC;IACnE,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;AAC1C,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAiB,EAAkB,EAAE;IACxE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAGvB,CAAC;IACF,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;QAC1D,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;KAC3D,CAAC;AACJ,CAAC,CAAC;AAOF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAiB,EAAc,EAAE;IAChE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAGvB,CAAC;IACF,MAAM,OAAO,GAAG,CAAC,KAAc,EAAc,EAAE,CAC7C,KAAK,YAAY,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,KAAiB,CAAC,CAAC;IAC1E,MAAM,SAAS,GAAG,CAAC,GAA+B,EAAE,EAAE,CACpD,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/F,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;AACxE,CAAC,CAAC;AAYF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAiB,EAAY,EAAE;IAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAgC,CAAC;IACzD,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;AACtC,CAAC,CAAC;AAYF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACtE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAA4D,CAAC;IACrF,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;AACxC,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAiB,EAAY,EAAE;IAC5D,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAsB,CAAC;IAC/C,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC;AAClC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"delta.js","sourceRoot":"","sources":["../../src/sync/delta.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/client.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { PresenceHandle } from "./crdt/presence.js";
|
|
|
11
11
|
import { CRDTMapHandle } from "./crdt/crdtmap.js";
|
|
12
12
|
import { AwarenessHandle } from "./crdt/awareness.js";
|
|
13
13
|
import { RGAHandle } from "./crdt/rga.js";
|
|
14
|
+
import { TreeHandle } from "./crdt/tree.js";
|
|
14
15
|
import {
|
|
15
16
|
decodeGCounterDelta,
|
|
16
17
|
decodePNCounterDelta,
|
|
@@ -19,7 +20,9 @@ import {
|
|
|
19
20
|
decodePresenceDelta,
|
|
20
21
|
decodeCRDTMapDelta,
|
|
21
22
|
decodeRGADelta,
|
|
23
|
+
decodeTreeDelta,
|
|
22
24
|
} from "./sync/delta.js";
|
|
25
|
+
import type { TreeNodeValue } from "./sync/delta.js";
|
|
23
26
|
import { parseAndValidateToken } from "./auth/token.js";
|
|
24
27
|
import type { ServerMsg, TokenClaims } from "./schema.js";
|
|
25
28
|
import type { TokenParseError, TokenExpiredError } from "./errors.js";
|
|
@@ -63,6 +66,11 @@ export interface RGASnapshotEntry {
|
|
|
63
66
|
crdtId: string;
|
|
64
67
|
text: string;
|
|
65
68
|
}
|
|
69
|
+
export interface TreeSnapshotEntry {
|
|
70
|
+
type: "tree";
|
|
71
|
+
crdtId: string;
|
|
72
|
+
roots: TreeNodeValue[];
|
|
73
|
+
}
|
|
66
74
|
export type CRDTSnapshotEntry =
|
|
67
75
|
| GCounterSnapshotEntry
|
|
68
76
|
| PNCounterSnapshotEntry
|
|
@@ -70,7 +78,8 @@ export type CRDTSnapshotEntry =
|
|
|
70
78
|
| LwwRegisterSnapshotEntry
|
|
71
79
|
| PresenceSnapshotEntry
|
|
72
80
|
| CRDTMapSnapshotEntry
|
|
73
|
-
| RGASnapshotEntry
|
|
81
|
+
| RGASnapshotEntry
|
|
82
|
+
| TreeSnapshotEntry;
|
|
74
83
|
|
|
75
84
|
export interface DeltaEvent {
|
|
76
85
|
crdtId: string;
|
|
@@ -136,6 +145,7 @@ export class MeridianClient {
|
|
|
136
145
|
private readonly cmHandles = new Map<string, CRDTMapHandle>();
|
|
137
146
|
private readonly awHandles = new Map<string, AwarenessHandle<unknown>>();
|
|
138
147
|
private readonly rgaHandles = new Map<string, RGAHandle>();
|
|
148
|
+
private readonly treeHandles = new Map<string, TreeHandle>();
|
|
139
149
|
|
|
140
150
|
private readonly anyListeners = new Set<() => void>();
|
|
141
151
|
private readonly deltaListeners = new Set<(event: DeltaEvent) => void>();
|
|
@@ -393,6 +403,36 @@ export class MeridianClient {
|
|
|
393
403
|
return handle;
|
|
394
404
|
}
|
|
395
405
|
|
|
406
|
+
/**
|
|
407
|
+
* Returns a handle for a TreeCRDT — a convergent hierarchical tree.
|
|
408
|
+
*
|
|
409
|
+
* Use this for outlines, document trees, mind maps, or any nested structure
|
|
410
|
+
* that needs concurrent editing. Concurrent moves use Kleppmann (2021)
|
|
411
|
+
* move semantics: cycle-creating moves are discarded, all replicas converge.
|
|
412
|
+
*
|
|
413
|
+
* Handles are cached by `crdtId`; the same handle is returned for repeated calls.
|
|
414
|
+
*
|
|
415
|
+
* @param crdtId - Logical CRDT identifier (e.g. `"tree:outline"`).
|
|
416
|
+
*
|
|
417
|
+
* @example
|
|
418
|
+
* ```ts
|
|
419
|
+
* const tree = client.tree('doc:outline');
|
|
420
|
+
* const rootId = tree.addNode(null, 'a0', 'Introduction');
|
|
421
|
+
* const childId = tree.addNode(rootId, 'a0', 'Chapter 1');
|
|
422
|
+
* tree.onChange(t => console.log(t.roots));
|
|
423
|
+
* ```
|
|
424
|
+
*/
|
|
425
|
+
tree(crdtId: string): TreeHandle {
|
|
426
|
+
let handle = this.treeHandles.get(crdtId);
|
|
427
|
+
if (!handle) {
|
|
428
|
+
handle = new TreeHandle({ crdtId, clientId: this.clientId, transport: this.transport });
|
|
429
|
+
this.treeHandles.set(crdtId, handle);
|
|
430
|
+
this.transport.subscribe(crdtId);
|
|
431
|
+
this.handleUnsubs.push(handle.onChange(() => { this.notifyAnyChange(); }));
|
|
432
|
+
}
|
|
433
|
+
return handle;
|
|
434
|
+
}
|
|
435
|
+
|
|
396
436
|
/**
|
|
397
437
|
* Returns a handle for an ephemeral awareness channel.
|
|
398
438
|
*
|
|
@@ -487,6 +527,8 @@ export class MeridianClient {
|
|
|
487
527
|
crdts.push({ type: "crdtmap", crdtId, value: h.value() });
|
|
488
528
|
for (const [crdtId, h] of this.rgaHandles)
|
|
489
529
|
crdts.push({ type: "rga", crdtId, text: h.value() });
|
|
530
|
+
for (const [crdtId, h] of this.treeHandles)
|
|
531
|
+
crdts.push({ type: "tree", crdtId, roots: h.value().roots });
|
|
490
532
|
return {
|
|
491
533
|
namespace: this.namespace,
|
|
492
534
|
clientId: this.clientId,
|
|
@@ -570,6 +612,12 @@ export class MeridianClient {
|
|
|
570
612
|
if (rgaHandle) {
|
|
571
613
|
try { rgaHandle.applyDelta(decodeRGADelta(delta_bytes)); } catch { /* stale */ }
|
|
572
614
|
this.notifyDelta(crdt_id, "rga");
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const treeHandle = this.treeHandles.get(crdt_id);
|
|
618
|
+
if (treeHandle) {
|
|
619
|
+
try { treeHandle.applyDelta(decodeTreeDelta(delta_bytes)); } catch { /* stale */ }
|
|
620
|
+
this.notifyDelta(crdt_id, "tree");
|
|
573
621
|
}
|
|
574
622
|
}
|
|
575
623
|
|
package/src/crdt/tree.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { Chunk, Effect, Stream } from "effect";
|
|
2
|
+
import { encode } from "../codec.js";
|
|
3
|
+
import type { WsTransport } from "../transport/websocket.js";
|
|
4
|
+
import type { TreeDelta, TreeNodeValue } from "../sync/delta.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Low-level handle for a TreeCRDT — a convergent hierarchical tree.
|
|
8
|
+
*
|
|
9
|
+
* Obtained via `MeridianClient.tree()`. Supports add, move, update, and delete
|
|
10
|
+
* operations on tree nodes. Concurrent moves use Kleppmann et al. (2021)
|
|
11
|
+
* move semantics — cycles are prevented, all replicas converge.
|
|
12
|
+
*
|
|
13
|
+
* Node IDs are returned by `addNode()` as opaque strings of the form
|
|
14
|
+
* "wall_ms:logical:node_id" matching the Rust HLC serialization.
|
|
15
|
+
*/
|
|
16
|
+
export class TreeHandle {
|
|
17
|
+
private roots: TreeNodeValue[] = [];
|
|
18
|
+
private readonly crdtId: string;
|
|
19
|
+
private readonly clientId: number;
|
|
20
|
+
private readonly transport: WsTransport;
|
|
21
|
+
private readonly listeners = new Set<(value: { roots: TreeNodeValue[] }) => void>();
|
|
22
|
+
private opCounter = 0;
|
|
23
|
+
|
|
24
|
+
constructor(opts: {
|
|
25
|
+
crdtId: string;
|
|
26
|
+
clientId: number;
|
|
27
|
+
transport: WsTransport;
|
|
28
|
+
}) {
|
|
29
|
+
this.crdtId = opts.crdtId;
|
|
30
|
+
this.clientId = opts.clientId;
|
|
31
|
+
this.transport = opts.transport;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Returns the current tree value. */
|
|
35
|
+
value(): { roots: TreeNodeValue[] } {
|
|
36
|
+
return { roots: this.roots };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Registers a listener called whenever the tree changes.
|
|
41
|
+
*
|
|
42
|
+
* @returns An unsubscribe function.
|
|
43
|
+
*/
|
|
44
|
+
onChange(listener: (value: { roots: TreeNodeValue[] }) => void): () => void {
|
|
45
|
+
this.listeners.add(listener);
|
|
46
|
+
return () => { this.listeners.delete(listener); };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Returns an Effect Stream that emits the tree on every change. */
|
|
50
|
+
stream(): Stream.Stream<{ roots: TreeNodeValue[] }, never, never> {
|
|
51
|
+
return Stream.async<{ roots: TreeNodeValue[] }>((emit) => {
|
|
52
|
+
const unsub = this.onChange((value) => { void emit(Effect.succeed(Chunk.of(value))); });
|
|
53
|
+
return Effect.sync(unsub);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Adds a new node to the tree.
|
|
59
|
+
*
|
|
60
|
+
* @param parentId - ID of the parent node, or null for a root-level node.
|
|
61
|
+
* @param position - Fractional index string for sibling ordering (e.g. "a0", "b0").
|
|
62
|
+
* @param value - String content of the node.
|
|
63
|
+
* @param ttlMs - Optional TTL.
|
|
64
|
+
* @returns The new node's ID as a string.
|
|
65
|
+
*/
|
|
66
|
+
addNode(parentId: string | null, position: string, value: string, ttlMs?: number): string {
|
|
67
|
+
const wallMs = Date.now();
|
|
68
|
+
const logical = this.opCounter++;
|
|
69
|
+
const id = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
70
|
+
const idStr = `${wallMs}:${logical}:${this.clientId}`;
|
|
71
|
+
|
|
72
|
+
const op = encode({
|
|
73
|
+
Tree: {
|
|
74
|
+
AddNode: {
|
|
75
|
+
id,
|
|
76
|
+
parent_id: parentId !== null ? this.parseHlc(parentId) : null,
|
|
77
|
+
position,
|
|
78
|
+
value,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
this.transport.send({
|
|
84
|
+
Op: {
|
|
85
|
+
crdt_id: this.crdtId,
|
|
86
|
+
op_bytes: op,
|
|
87
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return idStr;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Moves a node to a new parent and/or position.
|
|
96
|
+
*
|
|
97
|
+
* @param nodeId - ID of the node to move.
|
|
98
|
+
* @param newParentId - New parent node ID, or null for root level.
|
|
99
|
+
* @param newPosition - New fractional index position.
|
|
100
|
+
* @param ttlMs - Optional TTL.
|
|
101
|
+
*/
|
|
102
|
+
moveNode(nodeId: string, newParentId: string | null, newPosition: string, ttlMs?: number): void {
|
|
103
|
+
const wallMs = Date.now();
|
|
104
|
+
const logical = this.opCounter++;
|
|
105
|
+
const opId = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
106
|
+
|
|
107
|
+
const op = encode({
|
|
108
|
+
Tree: {
|
|
109
|
+
MoveNode: {
|
|
110
|
+
op_id: opId,
|
|
111
|
+
node_id: this.parseHlc(nodeId),
|
|
112
|
+
new_parent_id: newParentId !== null ? this.parseHlc(newParentId) : null,
|
|
113
|
+
new_position: newPosition,
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
this.transport.send({
|
|
119
|
+
Op: {
|
|
120
|
+
crdt_id: this.crdtId,
|
|
121
|
+
op_bytes: op,
|
|
122
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Updates the value of an existing node (LWW — last write wins).
|
|
129
|
+
*
|
|
130
|
+
* @param nodeId - ID of the node to update.
|
|
131
|
+
* @param value - New string value.
|
|
132
|
+
* @param ttlMs - Optional TTL.
|
|
133
|
+
*/
|
|
134
|
+
updateNode(nodeId: string, value: string, ttlMs?: number): void {
|
|
135
|
+
const wallMs = Date.now();
|
|
136
|
+
const logical = this.opCounter++;
|
|
137
|
+
const updatedAt = { wall_ms: wallMs, logical, node_id: this.clientId };
|
|
138
|
+
|
|
139
|
+
const op = encode({
|
|
140
|
+
Tree: {
|
|
141
|
+
UpdateNode: {
|
|
142
|
+
id: this.parseHlc(nodeId),
|
|
143
|
+
value,
|
|
144
|
+
updated_at: updatedAt,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
this.transport.send({
|
|
150
|
+
Op: {
|
|
151
|
+
crdt_id: this.crdtId,
|
|
152
|
+
op_bytes: op,
|
|
153
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Tombstone-deletes a node. Children are preserved in the tree structure
|
|
160
|
+
* but become invisible until the node is undeleted via a concurrent move.
|
|
161
|
+
*
|
|
162
|
+
* @param nodeId - ID of the node to delete.
|
|
163
|
+
* @param ttlMs - Optional TTL.
|
|
164
|
+
*/
|
|
165
|
+
deleteNode(nodeId: string, ttlMs?: number): void {
|
|
166
|
+
const op = encode({
|
|
167
|
+
Tree: {
|
|
168
|
+
DeleteNode: {
|
|
169
|
+
id: this.parseHlc(nodeId),
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
this.transport.send({
|
|
175
|
+
Op: {
|
|
176
|
+
crdt_id: this.crdtId,
|
|
177
|
+
op_bytes: op,
|
|
178
|
+
...(ttlMs !== undefined && { ttl_ms: ttlMs }),
|
|
179
|
+
},
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Apply a delta received from the server. Replaces local state with authoritative tree. */
|
|
184
|
+
applyDelta(delta: TreeDelta): void {
|
|
185
|
+
this.roots = delta.roots;
|
|
186
|
+
this.emit();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private emit(): void {
|
|
190
|
+
const v = { roots: this.roots };
|
|
191
|
+
for (const listener of this.listeners) listener(v);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Parse an HLC string "wall_ms:logical:node_id" back to a Rust-compatible object. */
|
|
195
|
+
private parseHlc(id: string): { wall_ms: number; logical: number; node_id: number } {
|
|
196
|
+
const parts = id.split(":");
|
|
197
|
+
return {
|
|
198
|
+
wall_ms: Number(parts[0]),
|
|
199
|
+
logical: Number(parts[1]),
|
|
200
|
+
node_id: Number(parts[2]),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export type {
|
|
|
13
13
|
PresenceSnapshotEntry,
|
|
14
14
|
CRDTMapSnapshotEntry,
|
|
15
15
|
RGASnapshotEntry,
|
|
16
|
+
TreeSnapshotEntry,
|
|
16
17
|
} from "./client.js";
|
|
17
18
|
|
|
18
19
|
// CRDT handles
|
|
@@ -27,6 +28,8 @@ export type { CrdtMapValue } from "./crdt/crdtmap.js";
|
|
|
27
28
|
export { AwarenessHandle } from "./crdt/awareness.js";
|
|
28
29
|
export type { AwarenessEntry } from "./crdt/awareness.js";
|
|
29
30
|
export { RGAHandle } from "./crdt/rga.js";
|
|
31
|
+
export { TreeHandle } from "./crdt/tree.js";
|
|
32
|
+
export type { TreeNodeValue, TreeDelta } from "./sync/delta.js";
|
|
30
33
|
|
|
31
34
|
// Transport
|
|
32
35
|
export { HttpClient } from "./transport/http.js";
|
package/src/sync/delta.ts
CHANGED
|
@@ -81,13 +81,29 @@ export const decodeRGADelta = (bytes: Uint8Array): RGADelta => {
|
|
|
81
81
|
return { text: raw.text ?? "" };
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
export interface TreeNodeValue {
|
|
85
|
+
id: string;
|
|
86
|
+
value: string;
|
|
87
|
+
children: TreeNodeValue[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface TreeDelta {
|
|
91
|
+
roots: TreeNodeValue[];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export const decodeTreeDelta = (bytes: Uint8Array): TreeDelta => {
|
|
95
|
+
const raw = decode(bytes) as { roots?: TreeNodeValue[] };
|
|
96
|
+
return { roots: raw.roots ?? [] };
|
|
97
|
+
};
|
|
98
|
+
|
|
84
99
|
export type CrdtValueDelta =
|
|
85
100
|
| { GCounter: GCounterDelta }
|
|
86
101
|
| { PNCounter: PNCounterDelta }
|
|
87
102
|
| { ORSet: ORSetDelta }
|
|
88
103
|
| { LwwRegister: LwwDelta }
|
|
89
104
|
| { Presence: PresenceDelta }
|
|
90
|
-
| { RGA: RGADelta }
|
|
105
|
+
| { RGA: RGADelta }
|
|
106
|
+
| { Tree: TreeDelta };
|
|
91
107
|
|
|
92
108
|
export interface CRDTMapDelta {
|
|
93
109
|
deltas: Record<string, CrdtValueDelta>;
|