reptree 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -20,21 +20,21 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ Node: () => Node,
24
+ NodeState: () => NodeState,
23
25
  RepTree: () => RepTree,
24
26
  StateVector: () => StateVector,
25
27
  TreeState: () => TreeState,
26
- Vertex: () => Vertex,
27
- VertexState: () => VertexState,
28
- bindVertex: () => bindVertex,
28
+ bindNode: () => bindNode,
29
29
  compareOpId: () => compareOpId,
30
30
  createOpId: () => createOpId,
31
31
  equalsOpId: () => equalsOpId,
32
32
  isAnyPropertyOp: () => isAnyPropertyOp,
33
- isMoveVertexOp: () => isMoveVertexOp,
33
+ isMoveNodeOp: () => isMoveNodeOp,
34
34
  isOpIdGreaterThan: () => isOpIdGreaterThan,
35
- newMoveVertexOp: () => newMoveVertexOp,
36
- newSetTransientVertexPropertyOp: () => newSetTransientVertexPropertyOp,
37
- newSetVertexPropertyOp: () => newSetVertexPropertyOp,
35
+ newMoveNodeOp: () => newMoveNodeOp,
36
+ newSetNodePropertyOp: () => newSetNodePropertyOp,
37
+ newSetTransientNodePropertyOp: () => newSetTransientNodePropertyOp,
38
38
  opIdToString: () => opIdToString,
39
39
  tryParseOpIdStr: () => tryParseOpIdStr,
40
40
  uuid: () => uuid
@@ -89,24 +89,24 @@ function opIdToString(opId) {
89
89
  }
90
90
 
91
91
  // src/operations.ts
92
- function isMoveVertexOp(op) {
92
+ function isMoveNodeOp(op) {
93
93
  return "parentId" in op;
94
94
  }
95
95
  function isAnyPropertyOp(op) {
96
96
  return "key" in op;
97
97
  }
98
- function newMoveVertexOp(clock, peerId, targetId, parentId) {
98
+ function newMoveNodeOp(clock, peerId, targetId, parentId) {
99
99
  return { id: createOpId(clock, peerId), targetId, parentId };
100
100
  }
101
- function newSetVertexPropertyOp(clock, peerId, targetId, key, value) {
101
+ function newSetNodePropertyOp(clock, peerId, targetId, key, value) {
102
102
  return { id: createOpId(clock, peerId), targetId, key, value, transient: false };
103
103
  }
104
- function newSetTransientVertexPropertyOp(clock, peerId, targetId, key, value) {
104
+ function newSetTransientNodePropertyOp(clock, peerId, targetId, key, value) {
105
105
  return { id: createOpId(clock, peerId), targetId, key, value, transient: true };
106
106
  }
107
107
 
108
- // src/VertexState.ts
109
- var VertexState = class {
108
+ // src/NodeState.ts
109
+ var NodeState = class {
110
110
  constructor(id, parentId) {
111
111
  this.id = id;
112
112
  this.parentId = parentId;
@@ -183,21 +183,31 @@ var VertexState = class {
183
183
  };
184
184
 
185
185
  // src/TreeState.ts
186
- var TreeState = class {
186
+ var _TreeState = class _TreeState {
187
187
  constructor() {
188
188
  this.changeCallbacks = /* @__PURE__ */ new Map();
189
189
  this.globalChangeCallbacks = /* @__PURE__ */ new Set();
190
190
  this.batchedEvents = /* @__PURE__ */ new Map();
191
- this.vertices = /* @__PURE__ */ new Map();
192
- this.batchTickInterval = setInterval(() => {
193
- this.processBatchedEvents();
194
- }, 33.3);
191
+ this.nodes = /* @__PURE__ */ new Map();
195
192
  }
196
193
  dispose() {
197
- clearInterval(this.batchTickInterval);
194
+ if (this.batchTickTimeout) {
195
+ clearTimeout(this.batchTickTimeout);
196
+ this.batchTickTimeout = void 0;
197
+ }
198
+ this.batchedEvents.clear();
199
+ }
200
+ scheduleBatchProcessing() {
201
+ if (this.batchTickTimeout) {
202
+ return;
203
+ }
204
+ this.batchTickTimeout = setTimeout(() => {
205
+ this.batchTickTimeout = void 0;
206
+ this.processBatchedEvents();
207
+ }, _TreeState.BATCH_DELAY_MS);
198
208
  }
199
209
  processBatchedEvents() {
200
- for (const [vertexId, events] of this.batchedEvents) {
210
+ for (const [nodeId, events] of this.batchedEvents) {
201
211
  let lastMoveEvent = null;
202
212
  let lastChildrenEvent = null;
203
213
  const propertyEventsByKey = /* @__PURE__ */ new Map();
@@ -218,24 +228,21 @@ var TreeState = class {
218
228
  ...propertyEventsByKey.values()
219
229
  ];
220
230
  this.globalChangeCallbacks.forEach((listener) => listener(filteredEvents));
221
- this.changeCallbacks.get(vertexId)?.forEach((listener) => listener(filteredEvents));
231
+ this.changeCallbacks.get(nodeId)?.forEach((listener) => listener(filteredEvents));
222
232
  }
223
233
  this.batchedEvents.clear();
224
234
  }
225
- getAllVertices() {
226
- return Array.from(this.vertices.values());
235
+ getAllNodes() {
236
+ return Array.from(this.nodes.values());
227
237
  }
228
- getVertex(id) {
229
- return this.vertices.get(id);
238
+ getNode(id) {
239
+ return this.nodes.get(id);
230
240
  }
231
- getChildrenIds(vertexId) {
232
- return this.getVertex(vertexId)?.children ?? [];
241
+ getChildrenIds(nodeId) {
242
+ return this.getNode(nodeId)?.children ?? [];
233
243
  }
234
- getChildren(vertexId) {
235
- return this.getChildrenIds(vertexId).map((id) => {
236
- const vertex = this.vertices.get(id);
237
- return vertex ? vertex : void 0;
238
- }).filter((vertex) => vertex !== void 0).sort((a, b) => {
244
+ getChildren(nodeId) {
245
+ return this.getChildrenIds(nodeId).map((id) => this.nodes.get(id)).filter((node) => node !== void 0).sort((a, b) => {
239
246
  const aDate = a.getProperty("_c");
240
247
  const bDate = b.getProperty("_c");
241
248
  if (!aDate) return -1;
@@ -243,100 +250,99 @@ var TreeState = class {
243
250
  return new Date(aDate).getTime() - new Date(bDate).getTime();
244
251
  });
245
252
  }
246
- moveVertex(vertexId, newParentId) {
247
- let vertex = this.getVertex(vertexId);
248
- const prevParentId = vertex ? vertex.parentId : void 0;
249
- if (!vertex) {
250
- vertex = new VertexState(vertexId, newParentId);
251
- this.vertices.set(vertexId, vertex);
253
+ moveNode(nodeId, newParentId) {
254
+ let node = this.getNode(nodeId);
255
+ const prevParentId = node ? node.parentId : void 0;
256
+ if (!node) {
257
+ node = new NodeState(nodeId, newParentId);
258
+ this.nodes.set(nodeId, node);
252
259
  }
253
260
  if (prevParentId === newParentId) {
254
- return vertex;
261
+ return node;
255
262
  }
256
- vertex.parentId = newParentId;
263
+ node.parentId = newParentId;
257
264
  let childrenInNewParent = null;
258
265
  let childrenInOldParent = null;
259
266
  if (prevParentId) {
260
- const oldParentVertex = this.getVertex(prevParentId);
261
- if (oldParentVertex) {
262
- oldParentVertex.children = oldParentVertex.children.filter((child) => child !== vertexId);
263
- childrenInOldParent = oldParentVertex.children;
267
+ const oldParentNode = this.getNode(prevParentId);
268
+ if (oldParentNode) {
269
+ oldParentNode.children = oldParentNode.children.filter((child) => child !== nodeId);
270
+ childrenInOldParent = oldParentNode.children;
264
271
  } else {
265
- console.error(`Old parent vertex not found for ${prevParentId}`);
272
+ console.error(`Old parent node not found for ${prevParentId}`);
266
273
  }
267
274
  }
268
275
  if (newParentId !== null) {
269
- const newParentVertex = this.vertices.get(newParentId);
270
- if (newParentVertex) {
271
- newParentVertex.children.push(vertexId);
272
- childrenInNewParent = newParentVertex.children;
276
+ const newParentNode = this.nodes.get(newParentId);
277
+ if (newParentNode) {
278
+ newParentNode.children.push(nodeId);
279
+ childrenInNewParent = newParentNode.children;
273
280
  } else {
274
- console.error(`New parent vertex not found for ${newParentId}`);
281
+ console.error(`New parent node not found for ${newParentId}`);
275
282
  }
276
283
  }
277
284
  this.notifyChange({
278
285
  type: "move",
279
- vertexId,
286
+ nodeId,
280
287
  oldParentId: prevParentId,
281
288
  newParentId
282
289
  });
283
290
  if (childrenInNewParent !== null && newParentId !== null) {
284
291
  this.notifyChange({
285
292
  type: "children",
286
- vertexId: newParentId,
287
- children: childrenInNewParent.map((id) => this.vertices.get(id))
293
+ nodeId: newParentId,
294
+ children: childrenInNewParent.map((id) => this.nodes.get(id))
288
295
  });
289
296
  }
290
297
  if (childrenInOldParent !== null && prevParentId) {
291
298
  this.notifyChange({
292
299
  type: "children",
293
- vertexId: prevParentId,
294
- children: childrenInOldParent.map((id) => this.vertices.get(id))
300
+ nodeId: prevParentId,
301
+ children: childrenInOldParent.map((id) => this.nodes.get(id))
295
302
  });
296
303
  }
297
- return vertex;
304
+ return node;
298
305
  }
299
- setProperty(vertexId, key, value) {
300
- const vertex = this.getVertex(vertexId);
301
- if (!vertex) {
302
- throw new Error(`Vertex ${vertexId} not found`);
306
+ setProperty(nodeId, key, value) {
307
+ const node = this.getNode(nodeId);
308
+ if (!node) {
309
+ throw new Error(`Node ${nodeId} not found`);
303
310
  }
304
- vertex.setProperty(key, value);
311
+ node.setProperty(key, value);
305
312
  this.notifyChange({
306
313
  type: "property",
307
- vertexId,
314
+ nodeId,
308
315
  key,
309
316
  value
310
317
  });
311
- if (vertex.parentId !== null) {
318
+ if (node.parentId !== null) {
312
319
  this.notifyChange({
313
320
  type: "children",
314
- vertexId: vertex.parentId,
315
- children: [vertex]
316
- // @TODO: shoulld I set all children or rename this property?
321
+ nodeId: node.parentId,
322
+ children: this.getChildren(node.parentId)
317
323
  });
318
324
  }
319
325
  }
320
- setTransientProperty(vertexId, key, value) {
321
- const vertex = this.getVertex(vertexId);
322
- if (vertex) {
323
- vertex.setTransientProperty(key, value);
326
+ setTransientProperty(nodeId, key, value) {
327
+ const node = this.getNode(nodeId);
328
+ if (node) {
329
+ node.setTransientProperty(key, value);
324
330
  }
325
331
  this.notifyChange({
326
332
  type: "property",
327
- vertexId,
333
+ nodeId,
328
334
  key,
329
335
  value
330
336
  });
331
337
  }
332
- addChangeCallback(vertexId, listener) {
333
- if (!this.changeCallbacks.has(vertexId)) {
334
- this.changeCallbacks.set(vertexId, /* @__PURE__ */ new Set());
338
+ addChangeCallback(nodeId, listener) {
339
+ if (!this.changeCallbacks.has(nodeId)) {
340
+ this.changeCallbacks.set(nodeId, /* @__PURE__ */ new Set());
335
341
  }
336
- this.changeCallbacks.get(vertexId).add(listener);
342
+ this.changeCallbacks.get(nodeId).add(listener);
337
343
  }
338
- removeChangeCallback(vertexId, listener) {
339
- this.changeCallbacks.get(vertexId)?.delete(listener);
344
+ removeChangeCallback(nodeId, listener) {
345
+ this.changeCallbacks.get(nodeId)?.delete(listener);
340
346
  }
341
347
  addGlobalChangeCallback(listener) {
342
348
  this.globalChangeCallbacks.add(listener);
@@ -345,23 +351,24 @@ var TreeState = class {
345
351
  this.globalChangeCallbacks.delete(listener);
346
352
  }
347
353
  notifyChange(event) {
348
- let events = this.batchedEvents.get(event.vertexId);
354
+ let events = this.batchedEvents.get(event.nodeId);
349
355
  if (!events) {
350
356
  events = [];
351
- this.batchedEvents.set(event.vertexId, events);
357
+ this.batchedEvents.set(event.nodeId, events);
352
358
  }
353
359
  events.push(event);
360
+ this.scheduleBatchProcessing();
354
361
  }
355
- printTree(vertexId, indent = "", isLast = true) {
362
+ printTree(nodeId, indent = "", isLast = true) {
356
363
  const prefix = indent + (isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ");
357
- let result = prefix + vertexId + "\n";
358
- let vertexName = null;
359
- if (vertexId !== null) {
360
- const vertex = this.getVertex(vertexId);
361
- if (vertex) {
362
- for (const prop of vertex.getAllProperties()) {
364
+ let result = prefix + nodeId + "\n";
365
+ let nodeName = null;
366
+ if (nodeId !== null) {
367
+ const node = this.getNode(nodeId);
368
+ if (node) {
369
+ for (const prop of node.getAllProperties()) {
363
370
  if (prop.key === "name") {
364
- vertexName = prop.value;
371
+ nodeName = prop.value;
365
372
  }
366
373
  const propPrefix = indent + (isLast ? " " : "\u2502 ") + "\u2022 ";
367
374
  result += `${propPrefix}${prop.key}: ${JSON.stringify(prop.value)}
@@ -369,12 +376,12 @@ var TreeState = class {
369
376
  }
370
377
  }
371
378
  }
372
- const children = this.getChildrenIds(vertexId);
379
+ const children = this.getChildrenIds(nodeId);
373
380
  const sortedChildren = [...children].sort((a, b) => {
374
- const vertexA = this.getVertex(a);
375
- const vertexB = this.getVertex(b);
376
- const nameA = vertexA?.getProperty("name");
377
- const nameB = vertexB?.getProperty("name");
381
+ const nodeA = this.getNode(a);
382
+ const nodeB = this.getNode(b);
383
+ const nameA = nodeA?.getProperty("name");
384
+ const nameB = nodeB?.getProperty("name");
378
385
  if (nameA && nameB) {
379
386
  return nameA.localeCompare(nameB);
380
387
  }
@@ -390,6 +397,8 @@ var TreeState = class {
390
397
  return result;
391
398
  }
392
399
  };
400
+ _TreeState.BATCH_DELAY_MS = 33.3;
401
+ var TreeState = _TreeState;
393
402
 
394
403
  // src/utils/uuid.ts
395
404
  var removeDashes = (guid) => guid.replace(/-/g, "");
@@ -398,28 +407,28 @@ function uuid() {
398
407
  }
399
408
 
400
409
  // src/reactive.ts
401
- function bindVertex(tree, id, schemaOrOptions) {
410
+ function bindNode(tree, id, schemaOrOptions) {
402
411
  const isOptions = typeof schemaOrOptions === "object" && schemaOrOptions !== null && (Object.prototype.hasOwnProperty.call(schemaOrOptions, "includeInternalKeys") || Object.prototype.hasOwnProperty.call(schemaOrOptions, "schema"));
403
412
  const options = isOptions ? schemaOrOptions : { schema: schemaOrOptions };
404
413
  const schema = options.schema;
405
414
  const obj = {};
406
415
  Object.defineProperties(obj, {
407
- $vertex: { get: () => tree.getVertex(id), enumerable: false, configurable: true },
416
+ $node: { get: () => tree.getNode(id), enumerable: false, configurable: true },
408
417
  $id: { get: () => id, enumerable: false, configurable: true },
409
- $parentId: { get: () => tree.getVertex(id)?.parentId ?? null, enumerable: false, configurable: true },
410
- $parent: { get: () => tree.getVertex(id)?.parent, enumerable: false, configurable: true },
418
+ $parentId: { get: () => tree.getNode(id)?.parentId ?? null, enumerable: false, configurable: true },
419
+ $parent: { get: () => tree.getNode(id)?.parent, enumerable: false, configurable: true },
411
420
  $children: { get: () => tree.getChildren(id), enumerable: false, configurable: true },
412
421
  $childrenIds: { get: () => tree.getChildrenIds(id), enumerable: false, configurable: true },
413
422
  $moveTo: {
414
423
  value: (parent) => {
415
424
  const parentId = typeof parent === "object" && parent !== null ? parent.id || parent.$id : parent;
416
- tree.moveVertex(id, parentId);
425
+ tree.moveNode(id, parentId);
417
426
  },
418
427
  enumerable: false,
419
428
  configurable: true,
420
429
  writable: false
421
430
  },
422
- $delete: { value: () => tree.deleteVertex(id), enumerable: false, configurable: true, writable: false },
431
+ $delete: { value: () => tree.deleteNode(id), enumerable: false, configurable: true, writable: false },
423
432
  $observe: { value: (listener) => tree.observe(id, listener), enumerable: false, configurable: true, writable: false },
424
433
  $observeChildren: {
425
434
  value: (listener) => tree.observe(id, (events) => {
@@ -431,20 +440,20 @@ function bindVertex(tree, id, schemaOrOptions) {
431
440
  configurable: true,
432
441
  writable: false
433
442
  },
434
- $newChild: { value: (props) => tree.getVertex(id).newChild(props), enumerable: false, configurable: true, writable: false },
435
- $newNamedChild: { value: (name, props) => tree.getVertex(id).newNamedChild(name, props), enumerable: false, configurable: true, writable: false },
443
+ $newChild: { value: (props) => tree.getNode(id).newChild(props), enumerable: false, configurable: true, writable: false },
444
+ $newNamedChild: { value: (name, props) => tree.getNode(id).newNamedChild(name, props), enumerable: false, configurable: true, writable: false },
436
445
  $useTransients: {
437
446
  value: function(fn) {
438
447
  const transientProxy = new Proxy({}, {
439
448
  set(_, prop, value) {
440
449
  if (typeof prop === "string") {
441
- tree.setTransientVertexProperty(id, prop, value);
450
+ tree.setTransientNodeProperty(id, prop, value);
442
451
  }
443
452
  return true;
444
453
  },
445
454
  get(_, prop) {
446
455
  if (typeof prop !== "string") return void 0;
447
- const rawValue = tree.getVertexProperty(id, prop, true);
456
+ const rawValue = tree.getNodeProperty(id, prop, true);
448
457
  return rawValue;
449
458
  }
450
459
  });
@@ -475,7 +484,7 @@ function bindVertex(tree, id, schemaOrOptions) {
475
484
  if (prop in target) {
476
485
  return Reflect.get(target, prop, receiver);
477
486
  }
478
- const rawValue = tree.getVertexProperty(id, prop, true);
487
+ const rawValue = tree.getNodeProperty(id, prop, true);
479
488
  return rawValue;
480
489
  },
481
490
  set(target, prop, value) {
@@ -490,46 +499,46 @@ function bindVertex(tree, id, schemaOrOptions) {
490
499
  value = res.data;
491
500
  }
492
501
  }
493
- tree.setVertexProperty(id, prop, value);
502
+ tree.setNodeProperty(id, prop, value);
494
503
  return true;
495
504
  },
496
505
  deleteProperty(_target, prop) {
497
506
  if (typeof prop !== "string") {
498
507
  return true;
499
508
  }
500
- tree.setVertexProperty(id, prop, void 0);
509
+ tree.setNodeProperty(id, prop, void 0);
501
510
  return true;
502
511
  }
503
512
  });
504
513
  return proxy;
505
514
  }
506
515
 
507
- // src/Vertex.ts
508
- var Vertex = class {
516
+ // src/Node.ts
517
+ var Node = class {
509
518
  constructor(tree, state) {
510
519
  this.state = state;
511
520
  this._tree = tree;
512
521
  }
513
- /** Returns the tree this vertex belongs to. */
522
+ /** Returns the tree this node belongs to. */
514
523
  get tree() {
515
524
  return this._tree;
516
525
  }
517
526
  set tree(value) {
518
527
  this._tree = value;
519
528
  }
520
- /** Returns the ID of this vertex. */
529
+ /** Returns the ID of this node. */
521
530
  get id() {
522
531
  return this.state.id;
523
532
  }
524
- /** Returns the name of this vertex. The name is stored as a property with the key 'name'. */
533
+ /** Returns the name of this node. The name is stored as a property with the key 'name'. */
525
534
  get name() {
526
535
  return this.getProperty("name");
527
536
  }
528
- /** Sets the name of this vertex. The name is stored as a property with the key 'name'. */
537
+ /** Sets the name of this node. The name is stored as a property with the key 'name'. */
529
538
  set name(name) {
530
- this.tree.setVertexProperty(this.id, "name", name);
539
+ this.tree.setNodeProperty(this.id, "name", name);
531
540
  }
532
- /** Returns the creation date of this vertex. The creation date is stored as a property with the key '_c'. */
541
+ /** Returns the creation date of this node. The creation date is stored as a property with the key '_c'. */
533
542
  get createdAt() {
534
543
  const createdAt = this.getProperty("_c");
535
544
  if (!createdAt) {
@@ -537,41 +546,41 @@ var Vertex = class {
537
546
  }
538
547
  return new Date(createdAt);
539
548
  }
540
- /** Returns the ID of the parent vertex of this vertex. */
549
+ /** Returns the ID of the parent node of this node. */
541
550
  get parentId() {
542
551
  return this.state.parentId;
543
552
  }
544
- /** Returns the parent vertex of this vertex. */
553
+ /** Returns the parent node of this node. */
545
554
  get parent() {
546
555
  if (!this.parentId) {
547
556
  return void 0;
548
557
  }
549
- return this.tree.getVertex(this.parentId);
558
+ return this.tree.getNode(this.parentId);
550
559
  }
551
- /** Returns the children vertices of this vertex. */
560
+ /** Returns the children nodes of this node. */
552
561
  get children() {
553
562
  return this.tree.getChildren(this.id);
554
563
  }
555
- /** Returns the IDs of the children vertices of this vertex. */
564
+ /** Returns the IDs of the children nodes of this node. */
556
565
  get childrenIds() {
557
566
  return this.tree.getChildrenIds(this.id);
558
567
  }
559
- /** Returns the ancestors of this vertex. The first element is the root vertex.
568
+ /** Returns the ancestors of this node. The first element is the root node.
560
569
  * E.g root -> grandparent -> parent.
561
- * Doesn't include this vertex in the array.
570
+ * Doesn't include this node in the array.
562
571
  */
563
572
  get ancestors() {
564
573
  return this.tree.getAncestors(this.id);
565
574
  }
566
- /** Returns the ID of the root vertex of the tree this vertex belongs to. */
575
+ /** Returns the ID of the root node of the tree this node belongs to. */
567
576
  get treeId() {
568
577
  return this.root.id;
569
578
  }
570
- /** Returns the root vertex of the tree this vertex belongs to. */
579
+ /** Returns the root node of the tree this node belongs to. */
571
580
  get root() {
572
581
  const root = this.tree.root;
573
582
  if (!root) {
574
- throw new Error("Root vertex of the tree is not set");
583
+ throw new Error("Root node of the tree is not set");
575
584
  }
576
585
  return root;
577
586
  }
@@ -581,48 +590,48 @@ var Vertex = class {
581
590
  getChildrenAsTypedArray() {
582
591
  return this.children.map((v) => v.getAsTypedObject());
583
592
  }
584
- /** Creates a new child vertex of this vertex. */
593
+ /** Creates a new child node of this node. */
585
594
  newChild(props) {
586
- return this.tree.newVertex(this.id, props);
595
+ return this.tree.newNode(this.id, props);
587
596
  }
588
- /** Creates a new named child vertex of this vertex. */
597
+ /** Creates a new named child node of this node. */
589
598
  newNamedChild(name, props) {
590
- return this.tree.newNamedVertex(this.id, name, props);
599
+ return this.tree.newNamedNode(this.id, name, props);
591
600
  }
592
- /** Sets a property on this vertex. */
601
+ /** Sets a property on this node. */
593
602
  setProperty(key, value) {
594
603
  const existingValue = this.getProperty(key, false);
595
604
  if (existingValue === value) {
596
605
  return;
597
606
  }
598
- this.tree.setVertexProperty(this.id, key, value);
607
+ this.tree.setNodeProperty(this.id, key, value);
599
608
  }
600
- /** Sets a transient property on this vertex. Transient properties are not persisted to the tree and are not included in the state vector. */
609
+ /** Sets a transient property on this node. Transient properties are not persisted to the tree and are not included in the state vector. */
601
610
  setTransientProperty(key, value) {
602
611
  const existingValue = this.getProperty(key);
603
612
  if (existingValue === value) {
604
613
  return;
605
614
  }
606
- this.tree.setTransientVertexProperty(this.id, key, value);
615
+ this.tree.setTransientNodeProperty(this.id, key, value);
607
616
  }
608
617
  /** Promotes all transient (temporary) properties to persistent properties. */
609
618
  commitTransients() {
610
619
  this.tree.commitTransients(this.id);
611
620
  }
612
- /** Sets multiple properties on this vertex. */
621
+ /** Sets multiple properties on this node. */
613
622
  setProperties(props) {
614
623
  for (const [key, value] of Object.entries(props)) {
615
624
  this.setProperty(key, value);
616
625
  }
617
626
  }
618
- /** Returns the value of a property on this vertex. */
627
+ /** Returns the value of a property on this node. */
619
628
  getProperty(key, includingTransient = true) {
620
- return this.tree.getVertexProperty(this.id, key, includingTransient);
629
+ return this.tree.getNodeProperty(this.id, key, includingTransient);
621
630
  }
622
- /** Returns all properties on this vertex. */
631
+ /** Returns all properties on this node. */
623
632
  getProperties() {
624
633
  const props = {};
625
- this.tree.getVertexProperties(this.id).forEach((p) => {
634
+ this.tree.getNodeProperties(this.id).forEach((p) => {
626
635
  props[p.key] = p.value;
627
636
  });
628
637
  return props;
@@ -630,21 +639,21 @@ var Vertex = class {
630
639
  findAllChildrenWithProperty(key, value) {
631
640
  return this.children.filter((c) => c.getProperty(key) === value);
632
641
  }
633
- findFirstChildVertexWithProperty(key, value) {
642
+ findFirstChildNodeWithProperty(key, value) {
634
643
  return this.children.find((c) => c.getProperty(key) === value);
635
644
  }
636
645
  findFirstTypedChildWithProperty(key, value) {
637
- return this.findFirstChildVertexWithProperty(key, value)?.getAsTypedObject();
646
+ return this.findFirstChildNodeWithProperty(key, value)?.getAsTypedObject();
638
647
  }
639
648
  findAllTypedChildrenWithProperty(key, value) {
640
649
  return this.findAllChildrenWithProperty(key, value).map((c) => c.getAsTypedObject());
641
650
  }
642
- /** Observes changes to this vertex. */
651
+ /** Observes changes to this node. */
643
652
  observe(listener) {
644
653
  const unobserve = this.tree.observe(this.id, listener);
645
654
  return () => unobserve();
646
655
  }
647
- /** Observes changes to the children of this vertex. */
656
+ /** Observes changes to the children of this node. */
648
657
  observeChildren(listener) {
649
658
  const unobserve = this.tree.observe(this.id, (events) => {
650
659
  if (events.some((e) => e.type === "children")) {
@@ -659,14 +668,14 @@ var Vertex = class {
659
668
  });
660
669
  }
661
670
  delete() {
662
- this.tree.deleteVertex(this.id);
671
+ this.tree.deleteNode(this.id);
663
672
  }
664
673
  moveTo(parent) {
665
- this.tree.moveVertex(this.id, parent.id);
674
+ this.tree.moveNode(this.id, parent.id);
666
675
  }
667
- /** Returns a live reactive object bound to this vertex. Accepts schema or options. */
676
+ /** Returns a live reactive object bound to this node. Accepts schema or options. */
668
677
  bind(schemaOrOptions) {
669
- return bindVertex(this.tree, this.id, schemaOrOptions);
678
+ return bindNode(this.tree, this.id, schemaOrOptions);
670
679
  }
671
680
  };
672
681
 
@@ -717,7 +726,7 @@ var StateVector = class _StateVector {
717
726
  /**
718
727
  * Updates the state vector with a newly applied operation.
719
728
  * Assumes ranges are sorted and non-overlapping.
720
- *
729
+ *
721
730
  * @param peerId The peer ID of the operation
722
731
  * @param counter The counter value of the operation
723
732
  */
@@ -778,7 +787,7 @@ var StateVector = class _StateVector {
778
787
  }
779
788
  /**
780
789
  * Updates the state vector with a newly applied operation.
781
- *
790
+ *
782
791
  * @param op The operation that was just applied
783
792
  */
784
793
  updateFromOp(op) {
@@ -794,7 +803,7 @@ var StateVector = class _StateVector {
794
803
  /**
795
804
  * Calculates which operation ranges we have that the other state vector is missing
796
805
  * by comparing state vectors.
797
- *
806
+ *
798
807
  * @param other The other state vector to compare against
799
808
  * @returns Array of operation ID ranges that we have but they don't
800
809
  */
@@ -818,7 +827,7 @@ var StateVector = class _StateVector {
818
827
  }
819
828
  /**
820
829
  * Checks if the state vector contains the given operation ID
821
- *
830
+ *
822
831
  * @param opId The operation ID to check
823
832
  * @returns true if the operation is in the state vector, false otherwise
824
833
  */
@@ -914,50 +923,54 @@ function isJsonValue(v) {
914
923
  var _RepTree = class _RepTree {
915
924
  /**
916
925
  * @param peerId - The peer ID of the current client. Should be unique across all peers.
917
- * @param ops - The operations to replicate an existing tree, if not provided - an empty tree will be created without a root vertex
926
+ * @param ops - The operations to replicate an existing tree, if not provided - an empty tree will be created without a root node
918
927
  */
919
928
  constructor(peerId, ops) {
920
- this.lamportClock = 0;
929
+ this.moveClock = 0;
930
+ this.propClock = 0;
921
931
  this.moveOps = [];
922
- this.setPropertyOps = [];
923
- this.propertiesAndTheirOpIds = /* @__PURE__ */ new Map();
932
+ this.propertyOpsByKey = /* @__PURE__ */ new Map();
924
933
  this.transientPropertiesAndTheirOpIds = /* @__PURE__ */ new Map();
925
934
  this.localOps = [];
926
935
  this.pendingMovesWithMissingParent = /* @__PURE__ */ new Map();
927
- this.pendingPropertiesWithMissingVertex = /* @__PURE__ */ new Map();
936
+ this.pendingPropertiesWithMissingNode = /* @__PURE__ */ new Map();
928
937
  this.knownOps = /* @__PURE__ */ new Set();
929
938
  this.parentIdBeforeMove = /* @__PURE__ */ new Map();
930
939
  this.opAppliedCallbacks = [];
931
940
  this._stateVectorEnabled = true;
932
941
  this.peerId = peerId;
933
942
  this.state = new TreeState();
934
- this.stateVector = new StateVector();
943
+ this.moveStateVector = new StateVector();
944
+ this.propStateVector = new StateVector();
935
945
  if (ops && ops.length > 0) {
936
946
  this.applyOps(ops);
937
947
  const root = this.root;
938
948
  if (!root) {
939
- throw new Error("There has to be a root vertex in the operations");
949
+ throw new Error("There has to be a root node in the operations");
940
950
  }
941
951
  } else {
942
- this.ensureNullVertex();
952
+ this.ensureNullNode();
943
953
  }
944
954
  }
955
+ dispose() {
956
+ this.state.dispose();
957
+ }
945
958
  get root() {
946
- if (!this.rootVertexId) {
947
- const vertices = this.state.getAllVertices();
948
- for (const vertex of vertices) {
949
- if (vertex.parentId === null && vertex.id !== _RepTree.NULL_VERTEX_ID) {
950
- this.rootVertexId = vertex.id;
951
- return new Vertex(this, vertex);
959
+ if (!this.rootNodeId) {
960
+ const nodes = this.state.getAllNodes();
961
+ for (const node of nodes) {
962
+ if (node.parentId === null && node.id !== _RepTree.NULL_NODE_ID) {
963
+ this.rootNodeId = node.id;
964
+ return new Node(this, node);
952
965
  }
953
966
  }
954
967
  return void 0;
955
968
  }
956
- const rootVertex = this.state.getVertex(this.rootVertexId);
957
- if (!rootVertex) {
958
- throw new Error("Root vertex not found");
969
+ const rootNode = this.state.getNode(this.rootNodeId);
970
+ if (!rootNode) {
971
+ throw new Error("Root node not found");
959
972
  }
960
- return new Vertex(this, rootVertex);
973
+ return new Node(this, rootNode);
961
974
  }
962
975
  replicate(newPeerId) {
963
976
  return new _RepTree(newPeerId, this.getAllOps());
@@ -966,54 +979,54 @@ var _RepTree = class _RepTree {
966
979
  return this.moveOps;
967
980
  }
968
981
  getAllOps() {
969
- return [...this.moveOps, ...this.setPropertyOps];
982
+ return [...this.moveOps, ...this.getPropertyOps()];
970
983
  }
971
- getVertex(vertexId) {
972
- const vertex = this.state.getVertex(vertexId);
973
- return vertex ? new Vertex(this, vertex) : void 0;
984
+ getNode(nodeId) {
985
+ const node = this.state.getNode(nodeId);
986
+ return node ? new Node(this, node) : void 0;
974
987
  }
975
- getAllVertices() {
976
- return this.state.getAllVertices().map((v) => new Vertex(this, v));
988
+ getAllNodes() {
989
+ return this.state.getAllNodes().map((v) => new Node(this, v));
977
990
  }
978
- getParent(vertexId) {
979
- const parentId = this.state.getVertex(vertexId)?.parentId;
980
- const parent = parentId ? this.state.getVertex(parentId) : void 0;
981
- return parent ? new Vertex(this, parent) : void 0;
991
+ getParent(nodeId) {
992
+ const parentId = this.state.getNode(nodeId)?.parentId;
993
+ const parent = parentId ? this.state.getNode(parentId) : void 0;
994
+ return parent ? new Node(this, parent) : void 0;
982
995
  }
983
- getChildren(vertexId) {
984
- return this.state.getChildren(vertexId).map((v) => new Vertex(this, v));
996
+ getChildren(nodeId) {
997
+ return this.state.getChildren(nodeId).map((v) => new Node(this, v));
985
998
  }
986
- getChildrenIds(vertexId) {
987
- return this.state.getChildrenIds(vertexId);
999
+ getChildrenIds(nodeId) {
1000
+ return this.state.getChildrenIds(nodeId);
988
1001
  }
989
- /** Returns the ancestors of the given vertex. The first element is the root vertex. */
990
- getAncestors(vertexId) {
1002
+ /** Returns the ancestors of the given node. The first element is the root node. */
1003
+ getAncestors(nodeId) {
991
1004
  const ancestors = [];
992
- let currentVertex = this.state.getVertex(vertexId);
993
- while (currentVertex && currentVertex.parentId) {
994
- const parentVertex = this.state.getVertex(currentVertex.parentId);
995
- if (parentVertex) {
996
- ancestors.push(new Vertex(this, parentVertex));
997
- currentVertex = parentVertex;
1005
+ let currentNode = this.state.getNode(nodeId);
1006
+ while (currentNode && currentNode.parentId) {
1007
+ const parentNode = this.state.getNode(currentNode.parentId);
1008
+ if (parentNode) {
1009
+ ancestors.push(new Node(this, parentNode));
1010
+ currentNode = parentNode;
998
1011
  } else {
999
1012
  break;
1000
1013
  }
1001
1014
  }
1002
1015
  return ancestors;
1003
1016
  }
1004
- getVertexProperty(vertexId, key, includingTransient = true) {
1005
- const vertex = this.state.getVertex(vertexId);
1006
- if (!vertex) {
1017
+ getNodeProperty(nodeId, key, includingTransient = true) {
1018
+ const node = this.state.getNode(nodeId);
1019
+ if (!node) {
1007
1020
  return void 0;
1008
1021
  }
1009
- return vertex.getProperty(key, includingTransient);
1022
+ return node.getProperty(key, includingTransient);
1010
1023
  }
1011
- getVertexProperties(vertexId) {
1012
- const vertex = this.state.getVertex(vertexId);
1013
- if (!vertex) {
1024
+ getNodeProperties(nodeId) {
1025
+ const node = this.state.getNode(nodeId);
1026
+ if (!node) {
1014
1027
  return [];
1015
1028
  }
1016
- return vertex.getAllProperties();
1029
+ return node.getAllProperties();
1017
1030
  }
1018
1031
  /**
1019
1032
  * Returns all local operations and clears the local operations list.
@@ -1025,158 +1038,144 @@ var _RepTree = class _RepTree {
1025
1038
  return ops;
1026
1039
  }
1027
1040
  /**
1028
- * This is the first vertex that will contain all other vertices.
1041
+ * This is the first node that will contain all other nodes.
1029
1042
  * If you plan to replicate a tree then don't use this method and instead merge
1030
- * in the ops from another tree (that will also contain the root vertex).
1031
- * @returns The root vertex
1043
+ * in the ops from another tree (that will also contain the root node).
1044
+ * @returns The root node
1032
1045
  */
1033
1046
  createRoot() {
1034
- if (this.rootVertexId) {
1035
- throw new Error("Root vertex already exists");
1047
+ if (this.rootNodeId) {
1048
+ throw new Error("Root node already exists");
1036
1049
  }
1037
- this.rootVertexId = this.newVertexInternalWithUUID(null);
1038
- const rootVertex = this.state.getVertex(this.rootVertexId);
1039
- if (!rootVertex) {
1040
- throw new Error("Root vertex not found");
1050
+ this.rootNodeId = this.newNodeInternalWithUUID(null);
1051
+ const rootNode = this.state.getNode(this.rootNodeId);
1052
+ if (!rootNode) {
1053
+ throw new Error("Root node not found");
1041
1054
  }
1042
- return new Vertex(this, rootVertex);
1055
+ return new Node(this, rootNode);
1043
1056
  }
1044
- newVertex(parentId, props = null) {
1057
+ newNode(parentId, props = null) {
1045
1058
  const typedProps = props;
1046
- const vertexId = this.newVertexInternalWithUUID(parentId);
1059
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1047
1060
  if (typedProps) {
1048
- this.setVertexProperties(vertexId, typedProps);
1061
+ this.setNodeProperties(nodeId, typedProps);
1049
1062
  }
1050
- const vertex = this.state.getVertex(vertexId);
1051
- if (!vertex) {
1052
- throw new Error("Failed to create vertex");
1063
+ const node = this.state.getNode(nodeId);
1064
+ if (!node) {
1065
+ throw new Error("Failed to create node");
1053
1066
  }
1054
- return new Vertex(this, vertex);
1067
+ return new Node(this, node);
1055
1068
  }
1056
- newNamedVertex(parentId, name, props = null) {
1069
+ newNamedNode(parentId, name, props = null) {
1057
1070
  const typedProps = props;
1058
- const vertexId = this.newVertexInternalWithUUID(parentId);
1071
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1059
1072
  if (typedProps) {
1060
- this.setVertexProperties(vertexId, typedProps);
1073
+ this.setNodeProperties(nodeId, typedProps);
1061
1074
  }
1062
- this.setVertexProperty(vertexId, "name", name);
1063
- const vertex = this.state.getVertex(vertexId);
1064
- if (!vertex) {
1065
- throw new Error("Failed to create named vertex");
1075
+ this.setNodeProperty(nodeId, "name", name);
1076
+ const node = this.state.getNode(nodeId);
1077
+ if (!node) {
1078
+ throw new Error("Failed to create named node");
1066
1079
  }
1067
- return new Vertex(this, vertex);
1080
+ return new Node(this, node);
1068
1081
  }
1069
- moveVertex(vertexId, parentId) {
1070
- this.lamportClock++;
1071
- const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);
1082
+ moveNode(nodeId, parentId) {
1083
+ this.moveClock++;
1084
+ const op = newMoveNodeOp(this.moveClock, this.peerId, nodeId, parentId);
1072
1085
  this.localOps.push(op);
1073
1086
  this.applyMove(op);
1074
1087
  }
1075
- deleteVertex(vertexId) {
1076
- this.moveVertex(vertexId, _RepTree.NULL_VERTEX_ID);
1088
+ deleteNode(nodeId) {
1089
+ this.moveNode(nodeId, _RepTree.NULL_NODE_ID);
1077
1090
  }
1078
- setTransientVertexProperty(vertexId, key, value) {
1091
+ setTransientNodeProperty(nodeId, key, value) {
1079
1092
  if (!isJsonValue(value)) {
1080
1093
  throw new Error(`Unsupported transient property value for key "${key}"`);
1081
1094
  }
1082
- this.lamportClock++;
1083
- const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1095
+ this.propClock++;
1096
+ const op = newSetTransientNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1084
1097
  this.localOps.push(op);
1085
1098
  this.applyProperty(op);
1086
1099
  }
1087
1100
  /**
1088
1101
  * Promotes all transient (temporary) properties to persistent properties.
1089
- * @param vertexId - The ID of the vertex to commit transients for.
1090
- * @returns
1102
+ * @param nodeId - The ID of the node to commit transients for.
1103
+ * @returns
1091
1104
  */
1092
- commitTransients(vertexId) {
1093
- const vertex = this.state.getVertex(vertexId);
1094
- if (!vertex) {
1105
+ commitTransients(nodeId) {
1106
+ const node = this.state.getNode(nodeId);
1107
+ if (!node) {
1095
1108
  return;
1096
1109
  }
1097
- const transientProps = vertex.getTransientProperties();
1110
+ const transientProps = node.getTransientProperties();
1098
1111
  for (const prop of transientProps) {
1099
- this.setVertexProperty(vertexId, prop.key, prop.value);
1112
+ this.setNodeProperty(nodeId, prop.key, prop.value);
1100
1113
  }
1101
1114
  for (const prop of transientProps) {
1102
- this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${vertexId}`);
1103
- }
1104
- vertex.clearAllTransientProperties();
1105
- }
1106
- setVertexProperty(vertexId, key, value) {
1107
- const isJsonValue2 = (v) => {
1108
- if (v === void 0) return true;
1109
- if (v === null) return true;
1110
- const t = typeof v;
1111
- if (t === "string" || t === "number" || t === "boolean") return true;
1112
- if (t === "bigint" || t === "function" || t === "symbol") return false;
1113
- if (Array.isArray(v)) return v.every(isJsonValue2);
1114
- if (t === "object") {
1115
- if (v instanceof Date) return false;
1116
- if (v instanceof Map || v instanceof Set || v instanceof RegExp) return false;
1117
- if (ArrayBuffer.isView(v)) return false;
1118
- const proto = Object.getPrototypeOf(v);
1119
- if (proto !== Object.prototype && proto !== null) return false;
1120
- for (const val of Object.values(v)) {
1121
- if (!isJsonValue2(val)) return false;
1122
- }
1123
- return true;
1124
- }
1125
- return false;
1126
- };
1127
- if (!isJsonValue2(value)) {
1115
+ this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${nodeId}`);
1116
+ }
1117
+ node.clearAllTransientProperties();
1118
+ }
1119
+ setNodeProperty(nodeId, key, value) {
1120
+ if (!isJsonValue(value)) {
1128
1121
  throw new Error(`Unsupported property value for key "${key}"`);
1129
1122
  }
1130
- this.lamportClock++;
1131
- const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1123
+ this.propClock++;
1124
+ const op = newSetNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1132
1125
  this.localOps.push(op);
1133
1126
  this.applyProperty(op);
1134
1127
  }
1135
- setVertexProperties(vertexId, props) {
1128
+ setNodeProperties(nodeId, props) {
1136
1129
  const typedProps = props;
1137
1130
  for (const [key, value] of Object.entries(typedProps)) {
1138
- this.setVertexProperty(vertexId, key, value);
1131
+ this.setNodeProperty(nodeId, key, value);
1139
1132
  }
1140
1133
  }
1141
- getVertexByPath(path) {
1134
+ getNodeByPath(path) {
1142
1135
  path = path.replace(/^\/+/, "");
1143
1136
  path = path.replace(/\/+$/, "");
1144
- const pathParts = path.split("/");
1145
- if (!this.rootVertexId) {
1137
+ const root = this.root;
1138
+ if (!root) {
1146
1139
  return void 0;
1147
1140
  }
1148
- const root = this.state.getVertex(this.rootVertexId);
1149
- if (!root) {
1150
- throw new Error("The root vertex is not found");
1141
+ if (path === "") {
1142
+ return root;
1151
1143
  }
1152
- const vertex = this.getVertexByPathArray(new Vertex(this, root), pathParts);
1153
- return vertex;
1144
+ return this.getNodeByPathArray(root, path.split("/"));
1154
1145
  }
1155
- getVertexByPathArray(vertex, path) {
1146
+ getNodeByPathArray(node, path) {
1156
1147
  if (path.length === 0) {
1157
- return vertex ?? void 0;
1148
+ return node ?? void 0;
1158
1149
  }
1159
1150
  const targetName = path[0];
1160
- const children = this.getChildren(vertex.id);
1151
+ const children = this.getChildren(node.id);
1161
1152
  for (const child of children) {
1162
1153
  if (child.getProperty("name") === targetName) {
1163
- return this.getVertexByPathArray(child, path.slice(1));
1154
+ return this.getNodeByPathArray(child, path.slice(1));
1164
1155
  }
1165
1156
  }
1166
1157
  return void 0;
1167
1158
  }
1168
1159
  printTree() {
1169
- if (!this.rootVertexId) {
1160
+ if (!this.rootNodeId) {
1170
1161
  return "";
1171
1162
  }
1172
- return this.state.printTree(this.rootVertexId);
1163
+ return this.state.printTree(this.rootNodeId);
1173
1164
  }
1174
1165
  merge(ops) {
1175
1166
  this.applyOps(ops);
1176
1167
  }
1177
1168
  applyOps(ops) {
1178
- for (const op of ops) {
1179
- if (this.knownOps.has(opIdToString(op.id))) {
1169
+ const moveOps = ops.filter((op) => isMoveNodeOp(op));
1170
+ const propertyOps = ops.filter((op) => isAnyPropertyOp(op));
1171
+ for (const op of moveOps) {
1172
+ if (this.knownOps.has(this.getOpKey(op))) {
1173
+ continue;
1174
+ }
1175
+ this.applyOperation(op);
1176
+ }
1177
+ for (const op of propertyOps) {
1178
+ if (this.knownOps.has(this.getOpKey(op))) {
1180
1179
  continue;
1181
1180
  }
1182
1181
  this.applyOperation(op);
@@ -1184,7 +1183,7 @@ var _RepTree = class _RepTree {
1184
1183
  }
1185
1184
  /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
1186
1185
  applyOpsOptimizedForLotsOfMoves(ops) {
1187
- const newMoveOps = ops.filter((op) => isMoveVertexOp(op) && !this.knownOps.has(opIdToString(op.id)));
1186
+ const newMoveOps = ops.filter((op) => isMoveNodeOp(op) && !this.knownOps.has(this.getOpKey(op)));
1188
1187
  if (newMoveOps.length > 0) {
1189
1188
  const allMoveOps = [...this.moveOps, ...newMoveOps];
1190
1189
  allMoveOps.sort((a, b) => compareOpId(a.id, b.id));
@@ -1193,7 +1192,7 @@ var _RepTree = class _RepTree {
1193
1192
  this.applyMove(op);
1194
1193
  }
1195
1194
  }
1196
- const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(opIdToString(op.id)));
1195
+ const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(this.getOpKey(op)));
1197
1196
  for (let i = 0, len = propertyOps.length; i < len; i++) {
1198
1197
  const op = propertyOps[i];
1199
1198
  this.applyProperty(op);
@@ -1203,10 +1202,10 @@ var _RepTree = class _RepTree {
1203
1202
  if (this.root?.id !== other.root?.id) {
1204
1203
  return false;
1205
1204
  }
1206
- if (!this.rootVertexId) {
1205
+ if (!this.rootNodeId) {
1207
1206
  return true;
1208
1207
  }
1209
- return _RepTree.compareVertices(this.rootVertexId, this, other);
1208
+ return _RepTree.compareNodes(this.rootNodeId, this, other);
1210
1209
  }
1211
1210
  compareMoveOps(other) {
1212
1211
  const movesA = this.moveOps;
@@ -1224,65 +1223,65 @@ var _RepTree = class _RepTree {
1224
1223
  /** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */
1225
1224
  isAncestor(childId, ancestorId) {
1226
1225
  let targetId = childId;
1227
- let vertex;
1228
- const visitedVertices = /* @__PURE__ */ new Set();
1229
- while (vertex = this.state.getVertex(targetId)) {
1230
- if (vertex.parentId === ancestorId) return true;
1231
- if (!vertex.parentId) return false;
1232
- if (visitedVertices.has(targetId)) {
1226
+ let node;
1227
+ const visitedNodes = /* @__PURE__ */ new Set();
1228
+ while (node = this.state.getNode(targetId)) {
1229
+ if (node.parentId === ancestorId) return true;
1230
+ if (!node.parentId) return false;
1231
+ if (visitedNodes.has(targetId)) {
1233
1232
  console.error(`isAncestor: cycle detected in the tree structure.`);
1234
1233
  return false;
1235
1234
  }
1236
- visitedVertices.add(targetId);
1237
- targetId = vertex.parentId;
1235
+ visitedNodes.add(targetId);
1236
+ targetId = node.parentId;
1238
1237
  }
1239
1238
  return false;
1240
1239
  }
1241
- observeVertex(vertexId, callback) {
1242
- const vertex = this.getVertex(vertexId);
1243
- if (vertex) {
1244
- callback(vertex);
1240
+ observeNode(nodeId, callback) {
1241
+ const node = this.getNode(nodeId);
1242
+ if (node) {
1243
+ callback(node);
1245
1244
  }
1246
- const unsubscribe = this.observe(vertexId, (_) => {
1247
- const vertex2 = this.getVertex(vertexId);
1248
- if (vertex2) {
1249
- callback(vertex2);
1245
+ const unsubscribe = this.observe(nodeId, (_) => {
1246
+ const node2 = this.getNode(nodeId);
1247
+ if (node2) {
1248
+ callback(node2);
1250
1249
  }
1251
1250
  });
1252
1251
  return () => {
1253
1252
  unsubscribe();
1254
1253
  };
1255
1254
  }
1256
- observeVertexMove(callback) {
1255
+ observeNodeMove(callback) {
1257
1256
  const listener = (events) => {
1258
1257
  const moveEvent = events.find((e) => e.type === "move");
1259
1258
  if (moveEvent) {
1260
- const vertex = this.getVertex(moveEvent.vertexId);
1261
- if (vertex) {
1262
- callback(vertex, moveEvent.oldParentId === void 0);
1259
+ const node = this.getNode(moveEvent.nodeId);
1260
+ if (node) {
1261
+ callback(node, moveEvent.oldParentId === void 0);
1263
1262
  }
1264
1263
  }
1265
1264
  };
1266
1265
  this.state.addGlobalChangeCallback(listener);
1267
1266
  return () => this.state.removeGlobalChangeCallback(listener);
1268
1267
  }
1269
- observe(vertexId, callback) {
1270
- this.state.addChangeCallback(vertexId, callback);
1271
- return () => this.state.removeChangeCallback(vertexId, callback);
1268
+ observe(nodeId, callback) {
1269
+ this.state.addChangeCallback(nodeId, callback);
1270
+ return () => this.state.removeChangeCallback(nodeId, callback);
1272
1271
  }
1273
1272
  observeOpApplied(callback) {
1274
1273
  this.opAppliedCallbacks.push(callback);
1275
1274
  return () => this.opAppliedCallbacks = this.opAppliedCallbacks.filter((l) => l !== callback);
1276
1275
  }
1277
- static compareVertices(vertexId, treeA, treeB) {
1278
- const childrenA = treeA.state.getChildrenIds(vertexId);
1279
- const childrenB = treeB.state.getChildrenIds(vertexId);
1276
+ static compareNodes(nodeId, treeA, treeB) {
1277
+ const childrenA = treeA.state.getChildrenIds(nodeId);
1278
+ const childrenB = treeB.state.getChildrenIds(nodeId);
1280
1279
  if (childrenA.length !== childrenB.length) {
1281
1280
  return false;
1282
1281
  }
1283
- if (vertexId !== null) {
1284
- const propertiesA = treeA.getVertexProperties(vertexId);
1285
- const propertiesB = treeB.getVertexProperties(vertexId);
1282
+ if (nodeId !== null) {
1283
+ const propertiesA = treeA.getNodeProperties(nodeId);
1284
+ const propertiesB = treeB.getNodeProperties(nodeId);
1286
1285
  if (propertiesA.length !== propertiesB.length) {
1287
1286
  return false;
1288
1287
  }
@@ -1296,39 +1295,44 @@ var _RepTree = class _RepTree {
1296
1295
  if (!childrenB.includes(childId)) {
1297
1296
  return false;
1298
1297
  }
1299
- if (!_RepTree.compareVertices(childId, treeA, treeB)) {
1298
+ if (!_RepTree.compareNodes(childId, treeA, treeB)) {
1300
1299
  return false;
1301
1300
  }
1302
1301
  }
1303
1302
  return true;
1304
1303
  }
1305
- newVertexInternal(vertexId, parentId) {
1306
- this.lamportClock++;
1307
- const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);
1304
+ newNodeInternal(nodeId, parentId) {
1305
+ this.moveClock++;
1306
+ const op = newMoveNodeOp(this.moveClock, this.peerId, nodeId, parentId);
1308
1307
  this.localOps.push(op);
1309
1308
  this.applyMove(op);
1310
- this.setVertexProperty(vertexId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1311
- return vertexId;
1309
+ this.setNodeProperty(nodeId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1310
+ return nodeId;
1312
1311
  }
1313
- newVertexInternalWithUUID(parentId) {
1314
- const vertexId = uuid();
1315
- return this.newVertexInternal(vertexId, parentId);
1312
+ newNodeInternalWithUUID(parentId) {
1313
+ const nodeId = uuid();
1314
+ return this.newNodeInternal(nodeId, parentId);
1316
1315
  }
1317
- ensureNullVertex() {
1318
- const vertexId = _RepTree.NULL_VERTEX_ID;
1319
- if (this.state.getVertex(vertexId)) {
1316
+ ensureNullNode() {
1317
+ const nodeId = _RepTree.NULL_NODE_ID;
1318
+ if (this.state.getNode(nodeId)) {
1320
1319
  return;
1321
1320
  }
1322
- this.newVertexInternal(vertexId, null);
1321
+ this.newNodeInternal(nodeId, null);
1323
1322
  }
1324
1323
  /** Updates the lamport clock with the counter value of the operation */
1325
- updateLamportClock(operation) {
1326
- if (operation.id.counter > this.lamportClock) {
1327
- this.lamportClock = operation.id.counter;
1324
+ updateMoveClock(operation) {
1325
+ if (operation.id.counter > this.moveClock) {
1326
+ this.moveClock = operation.id.counter;
1327
+ }
1328
+ }
1329
+ updatePropClock(operation) {
1330
+ if (operation.id.counter > this.propClock) {
1331
+ this.propClock = operation.id.counter;
1328
1332
  }
1329
1333
  }
1330
1334
  applyPendingMovesForParent(parentId) {
1331
- if (!this.state.getVertex(parentId)) {
1335
+ if (!this.state.getNode(parentId)) {
1332
1336
  return;
1333
1337
  }
1334
1338
  const pendingMoves = this.pendingMovesWithMissingParent.get(parentId);
@@ -1341,14 +1345,15 @@ var _RepTree = class _RepTree {
1341
1345
  }
1342
1346
  }
1343
1347
  applyMove(op) {
1344
- if (op.parentId !== null && !this.state.getVertex(op.parentId)) {
1348
+ if (op.parentId !== null && !this.state.getNode(op.parentId)) {
1345
1349
  if (!this.pendingMovesWithMissingParent.has(op.parentId)) {
1346
1350
  this.pendingMovesWithMissingParent.set(op.parentId, []);
1347
1351
  }
1348
1352
  this.pendingMovesWithMissingParent.get(op.parentId).push(op);
1353
+ this.markOpSeen(op, true);
1349
1354
  return;
1350
1355
  }
1351
- this.updateLamportClock(op);
1356
+ this.updateMoveClock(op);
1352
1357
  const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;
1353
1358
  if (lastOp === null || isOpIdGreaterThan(op.id, lastOp.id)) {
1354
1359
  this.moveOps.push(op);
@@ -1375,130 +1380,138 @@ var _RepTree = class _RepTree {
1375
1380
  this.applyPendingMovesForParent(op.targetId);
1376
1381
  }
1377
1382
  setLLWPropertyAndItsOpId(op) {
1378
- this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1383
+ this.propertyOpsByKey.set(`${op.key}@${op.targetId}`, op);
1379
1384
  this.state.setProperty(op.targetId, op.key, op.value);
1380
- this.reportOpAsApplied(op);
1385
+ this.reportOpAsApplied(op, false);
1386
+ this.refreshPropStateVector();
1381
1387
  }
1382
1388
  setTransientPropertyAndItsOpId(op) {
1383
1389
  this.transientPropertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1384
1390
  this.state.setTransientProperty(op.targetId, op.key, op.value);
1385
- this.reportOpAsApplied(op);
1391
+ this.reportOpAsApplied(op, false);
1386
1392
  }
1387
1393
  applyProperty(op) {
1388
- const targetVertex = this.state.getVertex(op.targetId);
1389
- if (!targetVertex) {
1394
+ const targetNode = this.state.getNode(op.targetId);
1395
+ if (!targetNode) {
1390
1396
  if (op.transient) {
1391
1397
  return;
1392
1398
  }
1393
- if (!this.pendingPropertiesWithMissingVertex.has(op.targetId)) {
1394
- this.pendingPropertiesWithMissingVertex.set(op.targetId, []);
1399
+ if (!this.pendingPropertiesWithMissingNode.has(op.targetId)) {
1400
+ this.pendingPropertiesWithMissingNode.set(op.targetId, []);
1395
1401
  }
1396
- this.pendingPropertiesWithMissingVertex.get(op.targetId).push(op);
1402
+ this.pendingPropertiesWithMissingNode.get(op.targetId).push(op);
1403
+ this.markOpSeen(op, false);
1397
1404
  return;
1398
1405
  }
1399
- this.updateLamportClock(op);
1400
- this.applyLLWProperty(op, targetVertex);
1406
+ this.updatePropClock(op);
1407
+ this.applyLLWProperty(op, targetNode);
1401
1408
  }
1402
- applyLLWProperty(op, targetVertex) {
1409
+ applyLLWProperty(op, targetNode) {
1403
1410
  const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1404
- const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1411
+ const prevOpId = this.propertyOpsByKey.get(`${op.key}@${op.targetId}`)?.id;
1405
1412
  if (!op.transient) {
1406
- this.setPropertyOps.push(op);
1407
1413
  if (!prevOpId || isOpIdGreaterThan(op.id, prevOpId)) {
1408
1414
  this.setLLWPropertyAndItsOpId(op);
1409
1415
  } else {
1410
- this.knownOps.add(opIdToString(op.id));
1416
+ this.markOpSeen(op, false);
1411
1417
  }
1412
1418
  if (prevTransientOpId && isOpIdGreaterThan(op.id, prevTransientOpId)) {
1413
1419
  this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);
1414
- targetVertex.removeTransientProperty(op.key);
1420
+ targetNode.removeTransientProperty(op.key);
1415
1421
  }
1416
1422
  } else {
1417
1423
  if (!prevTransientOpId || isOpIdGreaterThan(op.id, prevTransientOpId)) {
1418
1424
  this.setTransientPropertyAndItsOpId(op);
1425
+ } else {
1426
+ this.markOpSeen(op, false);
1419
1427
  }
1420
1428
  }
1421
1429
  }
1422
1430
  applyOperation(op) {
1423
- if (isMoveVertexOp(op)) {
1431
+ if (isMoveNodeOp(op)) {
1424
1432
  this.applyMove(op);
1425
1433
  } else if (isAnyPropertyOp(op)) {
1426
1434
  this.applyProperty(op);
1427
1435
  }
1428
1436
  }
1429
- reportOpAsApplied(op) {
1430
- this.knownOps.add(opIdToString(op.id));
1431
- if (this._stateVectorEnabled) {
1432
- this.stateVector.updateFromOp(op);
1437
+ markOpSeen(op, includeInStateVector) {
1438
+ this.knownOps.add(this.getOpKey(op));
1439
+ if (includeInStateVector && this._stateVectorEnabled) {
1440
+ if (isMoveNodeOp(op)) {
1441
+ this.moveStateVector.updateFromOp(op);
1442
+ } else if (isAnyPropertyOp(op)) {
1443
+ this.propStateVector.updateFromOp(op);
1444
+ }
1433
1445
  }
1446
+ }
1447
+ reportOpAsApplied(op, includeInStateVector = true) {
1448
+ this.markOpSeen(op, includeInStateVector);
1434
1449
  for (const callback of this.opAppliedCallbacks) {
1435
1450
  callback(op);
1436
1451
  }
1437
1452
  }
1438
1453
  tryToMove(op) {
1439
- let targetVertex = this.state.getVertex(op.targetId);
1440
- if (targetVertex) {
1441
- this.parentIdBeforeMove.set(op.id, targetVertex.parentId);
1454
+ let targetNode = this.state.getNode(op.targetId);
1455
+ if (targetNode) {
1456
+ this.parentIdBeforeMove.set(op.id, targetNode.parentId);
1442
1457
  }
1443
1458
  if (op.targetId === op.parentId) return;
1444
1459
  if (op.parentId && this.isAncestor(op.parentId, op.targetId)) return;
1445
- this.state.moveVertex(op.targetId, op.parentId);
1446
- if (!targetVertex) {
1447
- const pendingProperties = this.pendingPropertiesWithMissingVertex.get(op.targetId) || [];
1448
- this.pendingPropertiesWithMissingVertex.delete(op.targetId);
1460
+ this.state.moveNode(op.targetId, op.parentId);
1461
+ if (!targetNode) {
1462
+ const pendingProperties = this.pendingPropertiesWithMissingNode.get(op.targetId) || [];
1463
+ this.pendingPropertiesWithMissingNode.delete(op.targetId);
1449
1464
  for (const prop of pendingProperties) {
1450
1465
  this.applyProperty(prop);
1451
1466
  }
1452
1467
  }
1453
1468
  }
1454
1469
  undoMove(op) {
1455
- const targetVertex = this.state.getVertex(op.targetId);
1456
- if (!targetVertex) {
1457
- console.error(`An attempt to undo move operation ${opIdToString(op.id)} failed because the target vertex ${op.targetId} not found`);
1470
+ const targetNode = this.state.getNode(op.targetId);
1471
+ if (!targetNode) {
1472
+ console.error(`An attempt to undo move operation ${opIdToString(op.id)} failed because the target node ${op.targetId} not found`);
1458
1473
  return;
1459
1474
  }
1460
1475
  const prevParentId = this.parentIdBeforeMove.get(op.id);
1461
1476
  if (prevParentId === void 0) {
1462
1477
  return;
1463
1478
  }
1464
- this.state.moveVertex(op.targetId, prevParentId);
1479
+ this.state.moveNode(op.targetId, prevParentId);
1465
1480
  }
1466
- // --- Range-Based State Vector Methods ---
1481
+ // --- Range-Based State Vector Methods ---
1467
1482
  /**
1468
- * Returns the current state vector.
1469
- * Returns a readonly reference to the internal state vector.
1483
+ * Returns the current state vectors for move and property streams.
1484
+ * Returns readonly references to the internal state vectors.
1470
1485
  */
1471
- getStateVector() {
1486
+ getStateVectors() {
1472
1487
  if (!this._stateVectorEnabled) {
1473
1488
  return null;
1474
1489
  }
1475
- return this.stateVector.getState();
1490
+ return {
1491
+ move: this.moveStateVector.getState(),
1492
+ prop: this.propStateVector.getState()
1493
+ };
1476
1494
  }
1477
1495
  /**
1478
- * Determines which operations are needed to synchronize
1496
+ * Determines which operations are needed to synchronize
1479
1497
  * with the provided state vector.
1480
- *
1481
- * @param theirStateVector The state vector from another peer
1482
- * @returns Operations that should be sent to the other peer, sorted by OpId.
1498
+ *
1499
+ * @param theirStateVectors The state vectors from another peer
1500
+ * @returns Operations that should be sent to the other peer, sorted by OpId within each stream.
1483
1501
  */
1484
- getMissingOps(theirStateVector) {
1502
+ getMissingOps(theirStateVectors) {
1485
1503
  if (!this._stateVectorEnabled) {
1486
- return [...this.moveOps, ...this.setPropertyOps];
1487
- }
1488
- const otherStateVector = new StateVector(theirStateVector);
1489
- const missingRanges = this.stateVector.diff(otherStateVector);
1490
- const missingOps = [];
1491
- const allOps = [...this.moveOps, ...this.setPropertyOps];
1492
- for (const op of allOps) {
1493
- for (const range of missingRanges) {
1494
- if (op.id.peerId === range.peerId && op.id.counter >= range.start && op.id.counter <= range.end) {
1495
- missingOps.push(op);
1496
- break;
1497
- }
1498
- }
1499
- }
1500
- missingOps.sort((a, b) => compareOpId(a.id, b.id));
1501
- return missingOps;
1504
+ return [...this.moveOps, ...this.getPropertyOps()];
1505
+ }
1506
+ const otherMoveStateVector = new StateVector(theirStateVectors.move);
1507
+ const otherPropStateVector = new StateVector(theirStateVectors.prop);
1508
+ const missingMoveRanges = this.moveStateVector.diff(otherMoveStateVector);
1509
+ const missingPropRanges = this.propStateVector.diff(otherPropStateVector);
1510
+ const missingMoveOps = this.filterOpsByRanges(this.moveOps, missingMoveRanges);
1511
+ const missingPropOps = this.filterOpsByRanges(this.getPropertyOps(), missingPropRanges);
1512
+ missingMoveOps.sort((a, b) => compareOpId(a.id, b.id));
1513
+ missingPropOps.sort((a, b) => compareOpId(a.id, b.id));
1514
+ return [...missingMoveOps, ...missingPropOps];
1502
1515
  }
1503
1516
  /**
1504
1517
  * Gets or sets whether state vector tracking is enabled
@@ -1514,43 +1527,70 @@ var _RepTree = class _RepTree {
1514
1527
  if (value === this._stateVectorEnabled) return;
1515
1528
  if (value) {
1516
1529
  this._stateVectorEnabled = true;
1517
- this.stateVector = StateVector.fromOperations([...this.moveOps, ...this.setPropertyOps]);
1530
+ this.moveStateVector = StateVector.fromOperations(this.moveOps);
1531
+ this.propStateVector = StateVector.fromOperations(this.getPropertyOps());
1518
1532
  } else {
1519
1533
  this._stateVectorEnabled = false;
1520
- this.stateVector = new StateVector();
1534
+ this.moveStateVector = new StateVector();
1535
+ this.propStateVector = new StateVector();
1521
1536
  }
1522
1537
  }
1523
1538
  /**
1524
- * Parses the vertex properties with a provided schema that has a `parse` method (e.g., Zod schema)
1539
+ * Parses the node properties with a provided schema that has a `parse` method (e.g., Zod schema)
1525
1540
  */
1526
- parseVertex(vertexId, schema) {
1527
- const propsArray = this.getVertexProperties(vertexId);
1541
+ parseNode(nodeId, schema) {
1542
+ const propsArray = this.getNodeProperties(nodeId);
1528
1543
  const propsObject = {};
1529
1544
  for (const { key, value } of propsArray) {
1530
1545
  propsObject[key] = value;
1531
1546
  }
1532
1547
  return schema.parse(propsObject);
1533
1548
  }
1549
+ getPropertyOps() {
1550
+ return Array.from(this.propertyOpsByKey.values());
1551
+ }
1552
+ refreshPropStateVector() {
1553
+ if (!this._stateVectorEnabled) {
1554
+ return;
1555
+ }
1556
+ this.propStateVector = StateVector.fromOperations(this.getPropertyOps());
1557
+ }
1558
+ getOpKey(op) {
1559
+ const stream = isMoveNodeOp(op) ? "move" : "prop";
1560
+ return `${stream}:${opIdToString(op.id)}`;
1561
+ }
1562
+ filterOpsByRanges(ops, ranges) {
1563
+ const missingOps = [];
1564
+ for (const op of ops) {
1565
+ for (const range of ranges) {
1566
+ if (op.id.peerId === range.peerId && op.id.counter >= range.start && op.id.counter <= range.end) {
1567
+ missingOps.push(op);
1568
+ break;
1569
+ }
1570
+ }
1571
+ }
1572
+ return missingOps;
1573
+ }
1534
1574
  };
1535
- _RepTree.NULL_VERTEX_ID = "0";
1575
+ _RepTree.NULL_NODE_ID = "0";
1536
1576
  var RepTree = _RepTree;
1537
1577
  // Annotate the CommonJS export names for ESM import in node:
1538
1578
  0 && (module.exports = {
1579
+ Node,
1580
+ NodeState,
1539
1581
  RepTree,
1540
1582
  StateVector,
1541
1583
  TreeState,
1542
- Vertex,
1543
- VertexState,
1544
- bindVertex,
1584
+ bindNode,
1545
1585
  compareOpId,
1546
1586
  createOpId,
1547
1587
  equalsOpId,
1548
1588
  isAnyPropertyOp,
1549
- isMoveVertexOp,
1589
+ isMoveNodeOp,
1550
1590
  isOpIdGreaterThan,
1551
- newMoveVertexOp,
1552
- newSetTransientVertexPropertyOp,
1553
- newSetVertexPropertyOp,
1591
+ newMoveNodeOp,
1592
+ newSetNodePropertyOp,
1593
+ newSetTransientNodePropertyOp,
1554
1594
  opIdToString,
1555
1595
  tryParseOpIdStr,
1556
1596
  uuid