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.js CHANGED
@@ -46,24 +46,24 @@ function opIdToString(opId) {
46
46
  }
47
47
 
48
48
  // src/operations.ts
49
- function isMoveVertexOp(op) {
49
+ function isMoveNodeOp(op) {
50
50
  return "parentId" in op;
51
51
  }
52
52
  function isAnyPropertyOp(op) {
53
53
  return "key" in op;
54
54
  }
55
- function newMoveVertexOp(clock, peerId, targetId, parentId) {
55
+ function newMoveNodeOp(clock, peerId, targetId, parentId) {
56
56
  return { id: createOpId(clock, peerId), targetId, parentId };
57
57
  }
58
- function newSetVertexPropertyOp(clock, peerId, targetId, key, value) {
58
+ function newSetNodePropertyOp(clock, peerId, targetId, key, value) {
59
59
  return { id: createOpId(clock, peerId), targetId, key, value, transient: false };
60
60
  }
61
- function newSetTransientVertexPropertyOp(clock, peerId, targetId, key, value) {
61
+ function newSetTransientNodePropertyOp(clock, peerId, targetId, key, value) {
62
62
  return { id: createOpId(clock, peerId), targetId, key, value, transient: true };
63
63
  }
64
64
 
65
- // src/VertexState.ts
66
- var VertexState = class {
65
+ // src/NodeState.ts
66
+ var NodeState = class {
67
67
  constructor(id, parentId) {
68
68
  this.id = id;
69
69
  this.parentId = parentId;
@@ -140,21 +140,31 @@ var VertexState = class {
140
140
  };
141
141
 
142
142
  // src/TreeState.ts
143
- var TreeState = class {
143
+ var _TreeState = class _TreeState {
144
144
  constructor() {
145
145
  this.changeCallbacks = /* @__PURE__ */ new Map();
146
146
  this.globalChangeCallbacks = /* @__PURE__ */ new Set();
147
147
  this.batchedEvents = /* @__PURE__ */ new Map();
148
- this.vertices = /* @__PURE__ */ new Map();
149
- this.batchTickInterval = setInterval(() => {
150
- this.processBatchedEvents();
151
- }, 33.3);
148
+ this.nodes = /* @__PURE__ */ new Map();
152
149
  }
153
150
  dispose() {
154
- clearInterval(this.batchTickInterval);
151
+ if (this.batchTickTimeout) {
152
+ clearTimeout(this.batchTickTimeout);
153
+ this.batchTickTimeout = void 0;
154
+ }
155
+ this.batchedEvents.clear();
156
+ }
157
+ scheduleBatchProcessing() {
158
+ if (this.batchTickTimeout) {
159
+ return;
160
+ }
161
+ this.batchTickTimeout = setTimeout(() => {
162
+ this.batchTickTimeout = void 0;
163
+ this.processBatchedEvents();
164
+ }, _TreeState.BATCH_DELAY_MS);
155
165
  }
156
166
  processBatchedEvents() {
157
- for (const [vertexId, events] of this.batchedEvents) {
167
+ for (const [nodeId, events] of this.batchedEvents) {
158
168
  let lastMoveEvent = null;
159
169
  let lastChildrenEvent = null;
160
170
  const propertyEventsByKey = /* @__PURE__ */ new Map();
@@ -175,24 +185,21 @@ var TreeState = class {
175
185
  ...propertyEventsByKey.values()
176
186
  ];
177
187
  this.globalChangeCallbacks.forEach((listener) => listener(filteredEvents));
178
- this.changeCallbacks.get(vertexId)?.forEach((listener) => listener(filteredEvents));
188
+ this.changeCallbacks.get(nodeId)?.forEach((listener) => listener(filteredEvents));
179
189
  }
180
190
  this.batchedEvents.clear();
181
191
  }
182
- getAllVertices() {
183
- return Array.from(this.vertices.values());
192
+ getAllNodes() {
193
+ return Array.from(this.nodes.values());
184
194
  }
185
- getVertex(id) {
186
- return this.vertices.get(id);
195
+ getNode(id) {
196
+ return this.nodes.get(id);
187
197
  }
188
- getChildrenIds(vertexId) {
189
- return this.getVertex(vertexId)?.children ?? [];
198
+ getChildrenIds(nodeId) {
199
+ return this.getNode(nodeId)?.children ?? [];
190
200
  }
191
- getChildren(vertexId) {
192
- return this.getChildrenIds(vertexId).map((id) => {
193
- const vertex = this.vertices.get(id);
194
- return vertex ? vertex : void 0;
195
- }).filter((vertex) => vertex !== void 0).sort((a, b) => {
201
+ getChildren(nodeId) {
202
+ return this.getChildrenIds(nodeId).map((id) => this.nodes.get(id)).filter((node) => node !== void 0).sort((a, b) => {
196
203
  const aDate = a.getProperty("_c");
197
204
  const bDate = b.getProperty("_c");
198
205
  if (!aDate) return -1;
@@ -200,100 +207,99 @@ var TreeState = class {
200
207
  return new Date(aDate).getTime() - new Date(bDate).getTime();
201
208
  });
202
209
  }
203
- moveVertex(vertexId, newParentId) {
204
- let vertex = this.getVertex(vertexId);
205
- const prevParentId = vertex ? vertex.parentId : void 0;
206
- if (!vertex) {
207
- vertex = new VertexState(vertexId, newParentId);
208
- this.vertices.set(vertexId, vertex);
210
+ moveNode(nodeId, newParentId) {
211
+ let node = this.getNode(nodeId);
212
+ const prevParentId = node ? node.parentId : void 0;
213
+ if (!node) {
214
+ node = new NodeState(nodeId, newParentId);
215
+ this.nodes.set(nodeId, node);
209
216
  }
210
217
  if (prevParentId === newParentId) {
211
- return vertex;
218
+ return node;
212
219
  }
213
- vertex.parentId = newParentId;
220
+ node.parentId = newParentId;
214
221
  let childrenInNewParent = null;
215
222
  let childrenInOldParent = null;
216
223
  if (prevParentId) {
217
- const oldParentVertex = this.getVertex(prevParentId);
218
- if (oldParentVertex) {
219
- oldParentVertex.children = oldParentVertex.children.filter((child) => child !== vertexId);
220
- childrenInOldParent = oldParentVertex.children;
224
+ const oldParentNode = this.getNode(prevParentId);
225
+ if (oldParentNode) {
226
+ oldParentNode.children = oldParentNode.children.filter((child) => child !== nodeId);
227
+ childrenInOldParent = oldParentNode.children;
221
228
  } else {
222
- console.error(`Old parent vertex not found for ${prevParentId}`);
229
+ console.error(`Old parent node not found for ${prevParentId}`);
223
230
  }
224
231
  }
225
232
  if (newParentId !== null) {
226
- const newParentVertex = this.vertices.get(newParentId);
227
- if (newParentVertex) {
228
- newParentVertex.children.push(vertexId);
229
- childrenInNewParent = newParentVertex.children;
233
+ const newParentNode = this.nodes.get(newParentId);
234
+ if (newParentNode) {
235
+ newParentNode.children.push(nodeId);
236
+ childrenInNewParent = newParentNode.children;
230
237
  } else {
231
- console.error(`New parent vertex not found for ${newParentId}`);
238
+ console.error(`New parent node not found for ${newParentId}`);
232
239
  }
233
240
  }
234
241
  this.notifyChange({
235
242
  type: "move",
236
- vertexId,
243
+ nodeId,
237
244
  oldParentId: prevParentId,
238
245
  newParentId
239
246
  });
240
247
  if (childrenInNewParent !== null && newParentId !== null) {
241
248
  this.notifyChange({
242
249
  type: "children",
243
- vertexId: newParentId,
244
- children: childrenInNewParent.map((id) => this.vertices.get(id))
250
+ nodeId: newParentId,
251
+ children: childrenInNewParent.map((id) => this.nodes.get(id))
245
252
  });
246
253
  }
247
254
  if (childrenInOldParent !== null && prevParentId) {
248
255
  this.notifyChange({
249
256
  type: "children",
250
- vertexId: prevParentId,
251
- children: childrenInOldParent.map((id) => this.vertices.get(id))
257
+ nodeId: prevParentId,
258
+ children: childrenInOldParent.map((id) => this.nodes.get(id))
252
259
  });
253
260
  }
254
- return vertex;
261
+ return node;
255
262
  }
256
- setProperty(vertexId, key, value) {
257
- const vertex = this.getVertex(vertexId);
258
- if (!vertex) {
259
- throw new Error(`Vertex ${vertexId} not found`);
263
+ setProperty(nodeId, key, value) {
264
+ const node = this.getNode(nodeId);
265
+ if (!node) {
266
+ throw new Error(`Node ${nodeId} not found`);
260
267
  }
261
- vertex.setProperty(key, value);
268
+ node.setProperty(key, value);
262
269
  this.notifyChange({
263
270
  type: "property",
264
- vertexId,
271
+ nodeId,
265
272
  key,
266
273
  value
267
274
  });
268
- if (vertex.parentId !== null) {
275
+ if (node.parentId !== null) {
269
276
  this.notifyChange({
270
277
  type: "children",
271
- vertexId: vertex.parentId,
272
- children: [vertex]
273
- // @TODO: shoulld I set all children or rename this property?
278
+ nodeId: node.parentId,
279
+ children: this.getChildren(node.parentId)
274
280
  });
275
281
  }
276
282
  }
277
- setTransientProperty(vertexId, key, value) {
278
- const vertex = this.getVertex(vertexId);
279
- if (vertex) {
280
- vertex.setTransientProperty(key, value);
283
+ setTransientProperty(nodeId, key, value) {
284
+ const node = this.getNode(nodeId);
285
+ if (node) {
286
+ node.setTransientProperty(key, value);
281
287
  }
282
288
  this.notifyChange({
283
289
  type: "property",
284
- vertexId,
290
+ nodeId,
285
291
  key,
286
292
  value
287
293
  });
288
294
  }
289
- addChangeCallback(vertexId, listener) {
290
- if (!this.changeCallbacks.has(vertexId)) {
291
- this.changeCallbacks.set(vertexId, /* @__PURE__ */ new Set());
295
+ addChangeCallback(nodeId, listener) {
296
+ if (!this.changeCallbacks.has(nodeId)) {
297
+ this.changeCallbacks.set(nodeId, /* @__PURE__ */ new Set());
292
298
  }
293
- this.changeCallbacks.get(vertexId).add(listener);
299
+ this.changeCallbacks.get(nodeId).add(listener);
294
300
  }
295
- removeChangeCallback(vertexId, listener) {
296
- this.changeCallbacks.get(vertexId)?.delete(listener);
301
+ removeChangeCallback(nodeId, listener) {
302
+ this.changeCallbacks.get(nodeId)?.delete(listener);
297
303
  }
298
304
  addGlobalChangeCallback(listener) {
299
305
  this.globalChangeCallbacks.add(listener);
@@ -302,23 +308,24 @@ var TreeState = class {
302
308
  this.globalChangeCallbacks.delete(listener);
303
309
  }
304
310
  notifyChange(event) {
305
- let events = this.batchedEvents.get(event.vertexId);
311
+ let events = this.batchedEvents.get(event.nodeId);
306
312
  if (!events) {
307
313
  events = [];
308
- this.batchedEvents.set(event.vertexId, events);
314
+ this.batchedEvents.set(event.nodeId, events);
309
315
  }
310
316
  events.push(event);
317
+ this.scheduleBatchProcessing();
311
318
  }
312
- printTree(vertexId, indent = "", isLast = true) {
319
+ printTree(nodeId, indent = "", isLast = true) {
313
320
  const prefix = indent + (isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ");
314
- let result = prefix + vertexId + "\n";
315
- let vertexName = null;
316
- if (vertexId !== null) {
317
- const vertex = this.getVertex(vertexId);
318
- if (vertex) {
319
- for (const prop of vertex.getAllProperties()) {
321
+ let result = prefix + nodeId + "\n";
322
+ let nodeName = null;
323
+ if (nodeId !== null) {
324
+ const node = this.getNode(nodeId);
325
+ if (node) {
326
+ for (const prop of node.getAllProperties()) {
320
327
  if (prop.key === "name") {
321
- vertexName = prop.value;
328
+ nodeName = prop.value;
322
329
  }
323
330
  const propPrefix = indent + (isLast ? " " : "\u2502 ") + "\u2022 ";
324
331
  result += `${propPrefix}${prop.key}: ${JSON.stringify(prop.value)}
@@ -326,12 +333,12 @@ var TreeState = class {
326
333
  }
327
334
  }
328
335
  }
329
- const children = this.getChildrenIds(vertexId);
336
+ const children = this.getChildrenIds(nodeId);
330
337
  const sortedChildren = [...children].sort((a, b) => {
331
- const vertexA = this.getVertex(a);
332
- const vertexB = this.getVertex(b);
333
- const nameA = vertexA?.getProperty("name");
334
- const nameB = vertexB?.getProperty("name");
338
+ const nodeA = this.getNode(a);
339
+ const nodeB = this.getNode(b);
340
+ const nameA = nodeA?.getProperty("name");
341
+ const nameB = nodeB?.getProperty("name");
335
342
  if (nameA && nameB) {
336
343
  return nameA.localeCompare(nameB);
337
344
  }
@@ -347,6 +354,8 @@ var TreeState = class {
347
354
  return result;
348
355
  }
349
356
  };
357
+ _TreeState.BATCH_DELAY_MS = 33.3;
358
+ var TreeState = _TreeState;
350
359
 
351
360
  // src/utils/uuid.ts
352
361
  var removeDashes = (guid) => guid.replace(/-/g, "");
@@ -355,28 +364,28 @@ function uuid() {
355
364
  }
356
365
 
357
366
  // src/reactive.ts
358
- function bindVertex(tree, id, schemaOrOptions) {
367
+ function bindNode(tree, id, schemaOrOptions) {
359
368
  const isOptions = typeof schemaOrOptions === "object" && schemaOrOptions !== null && (Object.prototype.hasOwnProperty.call(schemaOrOptions, "includeInternalKeys") || Object.prototype.hasOwnProperty.call(schemaOrOptions, "schema"));
360
369
  const options = isOptions ? schemaOrOptions : { schema: schemaOrOptions };
361
370
  const schema = options.schema;
362
371
  const obj = {};
363
372
  Object.defineProperties(obj, {
364
- $vertex: { get: () => tree.getVertex(id), enumerable: false, configurable: true },
373
+ $node: { get: () => tree.getNode(id), enumerable: false, configurable: true },
365
374
  $id: { get: () => id, enumerable: false, configurable: true },
366
- $parentId: { get: () => tree.getVertex(id)?.parentId ?? null, enumerable: false, configurable: true },
367
- $parent: { get: () => tree.getVertex(id)?.parent, enumerable: false, configurable: true },
375
+ $parentId: { get: () => tree.getNode(id)?.parentId ?? null, enumerable: false, configurable: true },
376
+ $parent: { get: () => tree.getNode(id)?.parent, enumerable: false, configurable: true },
368
377
  $children: { get: () => tree.getChildren(id), enumerable: false, configurable: true },
369
378
  $childrenIds: { get: () => tree.getChildrenIds(id), enumerable: false, configurable: true },
370
379
  $moveTo: {
371
380
  value: (parent) => {
372
381
  const parentId = typeof parent === "object" && parent !== null ? parent.id || parent.$id : parent;
373
- tree.moveVertex(id, parentId);
382
+ tree.moveNode(id, parentId);
374
383
  },
375
384
  enumerable: false,
376
385
  configurable: true,
377
386
  writable: false
378
387
  },
379
- $delete: { value: () => tree.deleteVertex(id), enumerable: false, configurable: true, writable: false },
388
+ $delete: { value: () => tree.deleteNode(id), enumerable: false, configurable: true, writable: false },
380
389
  $observe: { value: (listener) => tree.observe(id, listener), enumerable: false, configurable: true, writable: false },
381
390
  $observeChildren: {
382
391
  value: (listener) => tree.observe(id, (events) => {
@@ -388,20 +397,20 @@ function bindVertex(tree, id, schemaOrOptions) {
388
397
  configurable: true,
389
398
  writable: false
390
399
  },
391
- $newChild: { value: (props) => tree.getVertex(id).newChild(props), enumerable: false, configurable: true, writable: false },
392
- $newNamedChild: { value: (name, props) => tree.getVertex(id).newNamedChild(name, props), enumerable: false, configurable: true, writable: false },
400
+ $newChild: { value: (props) => tree.getNode(id).newChild(props), enumerable: false, configurable: true, writable: false },
401
+ $newNamedChild: { value: (name, props) => tree.getNode(id).newNamedChild(name, props), enumerable: false, configurable: true, writable: false },
393
402
  $useTransients: {
394
403
  value: function(fn) {
395
404
  const transientProxy = new Proxy({}, {
396
405
  set(_, prop, value) {
397
406
  if (typeof prop === "string") {
398
- tree.setTransientVertexProperty(id, prop, value);
407
+ tree.setTransientNodeProperty(id, prop, value);
399
408
  }
400
409
  return true;
401
410
  },
402
411
  get(_, prop) {
403
412
  if (typeof prop !== "string") return void 0;
404
- const rawValue = tree.getVertexProperty(id, prop, true);
413
+ const rawValue = tree.getNodeProperty(id, prop, true);
405
414
  return rawValue;
406
415
  }
407
416
  });
@@ -432,7 +441,7 @@ function bindVertex(tree, id, schemaOrOptions) {
432
441
  if (prop in target) {
433
442
  return Reflect.get(target, prop, receiver);
434
443
  }
435
- const rawValue = tree.getVertexProperty(id, prop, true);
444
+ const rawValue = tree.getNodeProperty(id, prop, true);
436
445
  return rawValue;
437
446
  },
438
447
  set(target, prop, value) {
@@ -447,46 +456,46 @@ function bindVertex(tree, id, schemaOrOptions) {
447
456
  value = res.data;
448
457
  }
449
458
  }
450
- tree.setVertexProperty(id, prop, value);
459
+ tree.setNodeProperty(id, prop, value);
451
460
  return true;
452
461
  },
453
462
  deleteProperty(_target, prop) {
454
463
  if (typeof prop !== "string") {
455
464
  return true;
456
465
  }
457
- tree.setVertexProperty(id, prop, void 0);
466
+ tree.setNodeProperty(id, prop, void 0);
458
467
  return true;
459
468
  }
460
469
  });
461
470
  return proxy;
462
471
  }
463
472
 
464
- // src/Vertex.ts
465
- var Vertex = class {
473
+ // src/Node.ts
474
+ var Node = class {
466
475
  constructor(tree, state) {
467
476
  this.state = state;
468
477
  this._tree = tree;
469
478
  }
470
- /** Returns the tree this vertex belongs to. */
479
+ /** Returns the tree this node belongs to. */
471
480
  get tree() {
472
481
  return this._tree;
473
482
  }
474
483
  set tree(value) {
475
484
  this._tree = value;
476
485
  }
477
- /** Returns the ID of this vertex. */
486
+ /** Returns the ID of this node. */
478
487
  get id() {
479
488
  return this.state.id;
480
489
  }
481
- /** Returns the name of this vertex. The name is stored as a property with the key 'name'. */
490
+ /** Returns the name of this node. The name is stored as a property with the key 'name'. */
482
491
  get name() {
483
492
  return this.getProperty("name");
484
493
  }
485
- /** Sets the name of this vertex. The name is stored as a property with the key 'name'. */
494
+ /** Sets the name of this node. The name is stored as a property with the key 'name'. */
486
495
  set name(name) {
487
- this.tree.setVertexProperty(this.id, "name", name);
496
+ this.tree.setNodeProperty(this.id, "name", name);
488
497
  }
489
- /** Returns the creation date of this vertex. The creation date is stored as a property with the key '_c'. */
498
+ /** Returns the creation date of this node. The creation date is stored as a property with the key '_c'. */
490
499
  get createdAt() {
491
500
  const createdAt = this.getProperty("_c");
492
501
  if (!createdAt) {
@@ -494,41 +503,41 @@ var Vertex = class {
494
503
  }
495
504
  return new Date(createdAt);
496
505
  }
497
- /** Returns the ID of the parent vertex of this vertex. */
506
+ /** Returns the ID of the parent node of this node. */
498
507
  get parentId() {
499
508
  return this.state.parentId;
500
509
  }
501
- /** Returns the parent vertex of this vertex. */
510
+ /** Returns the parent node of this node. */
502
511
  get parent() {
503
512
  if (!this.parentId) {
504
513
  return void 0;
505
514
  }
506
- return this.tree.getVertex(this.parentId);
515
+ return this.tree.getNode(this.parentId);
507
516
  }
508
- /** Returns the children vertices of this vertex. */
517
+ /** Returns the children nodes of this node. */
509
518
  get children() {
510
519
  return this.tree.getChildren(this.id);
511
520
  }
512
- /** Returns the IDs of the children vertices of this vertex. */
521
+ /** Returns the IDs of the children nodes of this node. */
513
522
  get childrenIds() {
514
523
  return this.tree.getChildrenIds(this.id);
515
524
  }
516
- /** Returns the ancestors of this vertex. The first element is the root vertex.
525
+ /** Returns the ancestors of this node. The first element is the root node.
517
526
  * E.g root -> grandparent -> parent.
518
- * Doesn't include this vertex in the array.
527
+ * Doesn't include this node in the array.
519
528
  */
520
529
  get ancestors() {
521
530
  return this.tree.getAncestors(this.id);
522
531
  }
523
- /** Returns the ID of the root vertex of the tree this vertex belongs to. */
532
+ /** Returns the ID of the root node of the tree this node belongs to. */
524
533
  get treeId() {
525
534
  return this.root.id;
526
535
  }
527
- /** Returns the root vertex of the tree this vertex belongs to. */
536
+ /** Returns the root node of the tree this node belongs to. */
528
537
  get root() {
529
538
  const root = this.tree.root;
530
539
  if (!root) {
531
- throw new Error("Root vertex of the tree is not set");
540
+ throw new Error("Root node of the tree is not set");
532
541
  }
533
542
  return root;
534
543
  }
@@ -538,48 +547,48 @@ var Vertex = class {
538
547
  getChildrenAsTypedArray() {
539
548
  return this.children.map((v) => v.getAsTypedObject());
540
549
  }
541
- /** Creates a new child vertex of this vertex. */
550
+ /** Creates a new child node of this node. */
542
551
  newChild(props) {
543
- return this.tree.newVertex(this.id, props);
552
+ return this.tree.newNode(this.id, props);
544
553
  }
545
- /** Creates a new named child vertex of this vertex. */
554
+ /** Creates a new named child node of this node. */
546
555
  newNamedChild(name, props) {
547
- return this.tree.newNamedVertex(this.id, name, props);
556
+ return this.tree.newNamedNode(this.id, name, props);
548
557
  }
549
- /** Sets a property on this vertex. */
558
+ /** Sets a property on this node. */
550
559
  setProperty(key, value) {
551
560
  const existingValue = this.getProperty(key, false);
552
561
  if (existingValue === value) {
553
562
  return;
554
563
  }
555
- this.tree.setVertexProperty(this.id, key, value);
564
+ this.tree.setNodeProperty(this.id, key, value);
556
565
  }
557
- /** Sets a transient property on this vertex. Transient properties are not persisted to the tree and are not included in the state vector. */
566
+ /** Sets a transient property on this node. Transient properties are not persisted to the tree and are not included in the state vector. */
558
567
  setTransientProperty(key, value) {
559
568
  const existingValue = this.getProperty(key);
560
569
  if (existingValue === value) {
561
570
  return;
562
571
  }
563
- this.tree.setTransientVertexProperty(this.id, key, value);
572
+ this.tree.setTransientNodeProperty(this.id, key, value);
564
573
  }
565
574
  /** Promotes all transient (temporary) properties to persistent properties. */
566
575
  commitTransients() {
567
576
  this.tree.commitTransients(this.id);
568
577
  }
569
- /** Sets multiple properties on this vertex. */
578
+ /** Sets multiple properties on this node. */
570
579
  setProperties(props) {
571
580
  for (const [key, value] of Object.entries(props)) {
572
581
  this.setProperty(key, value);
573
582
  }
574
583
  }
575
- /** Returns the value of a property on this vertex. */
584
+ /** Returns the value of a property on this node. */
576
585
  getProperty(key, includingTransient = true) {
577
- return this.tree.getVertexProperty(this.id, key, includingTransient);
586
+ return this.tree.getNodeProperty(this.id, key, includingTransient);
578
587
  }
579
- /** Returns all properties on this vertex. */
588
+ /** Returns all properties on this node. */
580
589
  getProperties() {
581
590
  const props = {};
582
- this.tree.getVertexProperties(this.id).forEach((p) => {
591
+ this.tree.getNodeProperties(this.id).forEach((p) => {
583
592
  props[p.key] = p.value;
584
593
  });
585
594
  return props;
@@ -587,21 +596,21 @@ var Vertex = class {
587
596
  findAllChildrenWithProperty(key, value) {
588
597
  return this.children.filter((c) => c.getProperty(key) === value);
589
598
  }
590
- findFirstChildVertexWithProperty(key, value) {
599
+ findFirstChildNodeWithProperty(key, value) {
591
600
  return this.children.find((c) => c.getProperty(key) === value);
592
601
  }
593
602
  findFirstTypedChildWithProperty(key, value) {
594
- return this.findFirstChildVertexWithProperty(key, value)?.getAsTypedObject();
603
+ return this.findFirstChildNodeWithProperty(key, value)?.getAsTypedObject();
595
604
  }
596
605
  findAllTypedChildrenWithProperty(key, value) {
597
606
  return this.findAllChildrenWithProperty(key, value).map((c) => c.getAsTypedObject());
598
607
  }
599
- /** Observes changes to this vertex. */
608
+ /** Observes changes to this node. */
600
609
  observe(listener) {
601
610
  const unobserve = this.tree.observe(this.id, listener);
602
611
  return () => unobserve();
603
612
  }
604
- /** Observes changes to the children of this vertex. */
613
+ /** Observes changes to the children of this node. */
605
614
  observeChildren(listener) {
606
615
  const unobserve = this.tree.observe(this.id, (events) => {
607
616
  if (events.some((e) => e.type === "children")) {
@@ -616,14 +625,14 @@ var Vertex = class {
616
625
  });
617
626
  }
618
627
  delete() {
619
- this.tree.deleteVertex(this.id);
628
+ this.tree.deleteNode(this.id);
620
629
  }
621
630
  moveTo(parent) {
622
- this.tree.moveVertex(this.id, parent.id);
631
+ this.tree.moveNode(this.id, parent.id);
623
632
  }
624
- /** Returns a live reactive object bound to this vertex. Accepts schema or options. */
633
+ /** Returns a live reactive object bound to this node. Accepts schema or options. */
625
634
  bind(schemaOrOptions) {
626
- return bindVertex(this.tree, this.id, schemaOrOptions);
635
+ return bindNode(this.tree, this.id, schemaOrOptions);
627
636
  }
628
637
  };
629
638
 
@@ -674,7 +683,7 @@ var StateVector = class _StateVector {
674
683
  /**
675
684
  * Updates the state vector with a newly applied operation.
676
685
  * Assumes ranges are sorted and non-overlapping.
677
- *
686
+ *
678
687
  * @param peerId The peer ID of the operation
679
688
  * @param counter The counter value of the operation
680
689
  */
@@ -735,7 +744,7 @@ var StateVector = class _StateVector {
735
744
  }
736
745
  /**
737
746
  * Updates the state vector with a newly applied operation.
738
- *
747
+ *
739
748
  * @param op The operation that was just applied
740
749
  */
741
750
  updateFromOp(op) {
@@ -751,7 +760,7 @@ var StateVector = class _StateVector {
751
760
  /**
752
761
  * Calculates which operation ranges we have that the other state vector is missing
753
762
  * by comparing state vectors.
754
- *
763
+ *
755
764
  * @param other The other state vector to compare against
756
765
  * @returns Array of operation ID ranges that we have but they don't
757
766
  */
@@ -775,7 +784,7 @@ var StateVector = class _StateVector {
775
784
  }
776
785
  /**
777
786
  * Checks if the state vector contains the given operation ID
778
- *
787
+ *
779
788
  * @param opId The operation ID to check
780
789
  * @returns true if the operation is in the state vector, false otherwise
781
790
  */
@@ -871,50 +880,54 @@ function isJsonValue(v) {
871
880
  var _RepTree = class _RepTree {
872
881
  /**
873
882
  * @param peerId - The peer ID of the current client. Should be unique across all peers.
874
- * @param ops - The operations to replicate an existing tree, if not provided - an empty tree will be created without a root vertex
883
+ * @param ops - The operations to replicate an existing tree, if not provided - an empty tree will be created without a root node
875
884
  */
876
885
  constructor(peerId, ops) {
877
- this.lamportClock = 0;
886
+ this.moveClock = 0;
887
+ this.propClock = 0;
878
888
  this.moveOps = [];
879
- this.setPropertyOps = [];
880
- this.propertiesAndTheirOpIds = /* @__PURE__ */ new Map();
889
+ this.propertyOpsByKey = /* @__PURE__ */ new Map();
881
890
  this.transientPropertiesAndTheirOpIds = /* @__PURE__ */ new Map();
882
891
  this.localOps = [];
883
892
  this.pendingMovesWithMissingParent = /* @__PURE__ */ new Map();
884
- this.pendingPropertiesWithMissingVertex = /* @__PURE__ */ new Map();
893
+ this.pendingPropertiesWithMissingNode = /* @__PURE__ */ new Map();
885
894
  this.knownOps = /* @__PURE__ */ new Set();
886
895
  this.parentIdBeforeMove = /* @__PURE__ */ new Map();
887
896
  this.opAppliedCallbacks = [];
888
897
  this._stateVectorEnabled = true;
889
898
  this.peerId = peerId;
890
899
  this.state = new TreeState();
891
- this.stateVector = new StateVector();
900
+ this.moveStateVector = new StateVector();
901
+ this.propStateVector = new StateVector();
892
902
  if (ops && ops.length > 0) {
893
903
  this.applyOps(ops);
894
904
  const root = this.root;
895
905
  if (!root) {
896
- throw new Error("There has to be a root vertex in the operations");
906
+ throw new Error("There has to be a root node in the operations");
897
907
  }
898
908
  } else {
899
- this.ensureNullVertex();
909
+ this.ensureNullNode();
900
910
  }
901
911
  }
912
+ dispose() {
913
+ this.state.dispose();
914
+ }
902
915
  get root() {
903
- if (!this.rootVertexId) {
904
- const vertices = this.state.getAllVertices();
905
- for (const vertex of vertices) {
906
- if (vertex.parentId === null && vertex.id !== _RepTree.NULL_VERTEX_ID) {
907
- this.rootVertexId = vertex.id;
908
- return new Vertex(this, vertex);
916
+ if (!this.rootNodeId) {
917
+ const nodes = this.state.getAllNodes();
918
+ for (const node of nodes) {
919
+ if (node.parentId === null && node.id !== _RepTree.NULL_NODE_ID) {
920
+ this.rootNodeId = node.id;
921
+ return new Node(this, node);
909
922
  }
910
923
  }
911
924
  return void 0;
912
925
  }
913
- const rootVertex = this.state.getVertex(this.rootVertexId);
914
- if (!rootVertex) {
915
- throw new Error("Root vertex not found");
926
+ const rootNode = this.state.getNode(this.rootNodeId);
927
+ if (!rootNode) {
928
+ throw new Error("Root node not found");
916
929
  }
917
- return new Vertex(this, rootVertex);
930
+ return new Node(this, rootNode);
918
931
  }
919
932
  replicate(newPeerId) {
920
933
  return new _RepTree(newPeerId, this.getAllOps());
@@ -923,54 +936,54 @@ var _RepTree = class _RepTree {
923
936
  return this.moveOps;
924
937
  }
925
938
  getAllOps() {
926
- return [...this.moveOps, ...this.setPropertyOps];
939
+ return [...this.moveOps, ...this.getPropertyOps()];
927
940
  }
928
- getVertex(vertexId) {
929
- const vertex = this.state.getVertex(vertexId);
930
- return vertex ? new Vertex(this, vertex) : void 0;
941
+ getNode(nodeId) {
942
+ const node = this.state.getNode(nodeId);
943
+ return node ? new Node(this, node) : void 0;
931
944
  }
932
- getAllVertices() {
933
- return this.state.getAllVertices().map((v) => new Vertex(this, v));
945
+ getAllNodes() {
946
+ return this.state.getAllNodes().map((v) => new Node(this, v));
934
947
  }
935
- getParent(vertexId) {
936
- const parentId = this.state.getVertex(vertexId)?.parentId;
937
- const parent = parentId ? this.state.getVertex(parentId) : void 0;
938
- return parent ? new Vertex(this, parent) : void 0;
948
+ getParent(nodeId) {
949
+ const parentId = this.state.getNode(nodeId)?.parentId;
950
+ const parent = parentId ? this.state.getNode(parentId) : void 0;
951
+ return parent ? new Node(this, parent) : void 0;
939
952
  }
940
- getChildren(vertexId) {
941
- return this.state.getChildren(vertexId).map((v) => new Vertex(this, v));
953
+ getChildren(nodeId) {
954
+ return this.state.getChildren(nodeId).map((v) => new Node(this, v));
942
955
  }
943
- getChildrenIds(vertexId) {
944
- return this.state.getChildrenIds(vertexId);
956
+ getChildrenIds(nodeId) {
957
+ return this.state.getChildrenIds(nodeId);
945
958
  }
946
- /** Returns the ancestors of the given vertex. The first element is the root vertex. */
947
- getAncestors(vertexId) {
959
+ /** Returns the ancestors of the given node. The first element is the root node. */
960
+ getAncestors(nodeId) {
948
961
  const ancestors = [];
949
- let currentVertex = this.state.getVertex(vertexId);
950
- while (currentVertex && currentVertex.parentId) {
951
- const parentVertex = this.state.getVertex(currentVertex.parentId);
952
- if (parentVertex) {
953
- ancestors.push(new Vertex(this, parentVertex));
954
- currentVertex = parentVertex;
962
+ let currentNode = this.state.getNode(nodeId);
963
+ while (currentNode && currentNode.parentId) {
964
+ const parentNode = this.state.getNode(currentNode.parentId);
965
+ if (parentNode) {
966
+ ancestors.push(new Node(this, parentNode));
967
+ currentNode = parentNode;
955
968
  } else {
956
969
  break;
957
970
  }
958
971
  }
959
972
  return ancestors;
960
973
  }
961
- getVertexProperty(vertexId, key, includingTransient = true) {
962
- const vertex = this.state.getVertex(vertexId);
963
- if (!vertex) {
974
+ getNodeProperty(nodeId, key, includingTransient = true) {
975
+ const node = this.state.getNode(nodeId);
976
+ if (!node) {
964
977
  return void 0;
965
978
  }
966
- return vertex.getProperty(key, includingTransient);
979
+ return node.getProperty(key, includingTransient);
967
980
  }
968
- getVertexProperties(vertexId) {
969
- const vertex = this.state.getVertex(vertexId);
970
- if (!vertex) {
981
+ getNodeProperties(nodeId) {
982
+ const node = this.state.getNode(nodeId);
983
+ if (!node) {
971
984
  return [];
972
985
  }
973
- return vertex.getAllProperties();
986
+ return node.getAllProperties();
974
987
  }
975
988
  /**
976
989
  * Returns all local operations and clears the local operations list.
@@ -982,158 +995,144 @@ var _RepTree = class _RepTree {
982
995
  return ops;
983
996
  }
984
997
  /**
985
- * This is the first vertex that will contain all other vertices.
998
+ * This is the first node that will contain all other nodes.
986
999
  * If you plan to replicate a tree then don't use this method and instead merge
987
- * in the ops from another tree (that will also contain the root vertex).
988
- * @returns The root vertex
1000
+ * in the ops from another tree (that will also contain the root node).
1001
+ * @returns The root node
989
1002
  */
990
1003
  createRoot() {
991
- if (this.rootVertexId) {
992
- throw new Error("Root vertex already exists");
1004
+ if (this.rootNodeId) {
1005
+ throw new Error("Root node already exists");
993
1006
  }
994
- this.rootVertexId = this.newVertexInternalWithUUID(null);
995
- const rootVertex = this.state.getVertex(this.rootVertexId);
996
- if (!rootVertex) {
997
- throw new Error("Root vertex not found");
1007
+ this.rootNodeId = this.newNodeInternalWithUUID(null);
1008
+ const rootNode = this.state.getNode(this.rootNodeId);
1009
+ if (!rootNode) {
1010
+ throw new Error("Root node not found");
998
1011
  }
999
- return new Vertex(this, rootVertex);
1012
+ return new Node(this, rootNode);
1000
1013
  }
1001
- newVertex(parentId, props = null) {
1014
+ newNode(parentId, props = null) {
1002
1015
  const typedProps = props;
1003
- const vertexId = this.newVertexInternalWithUUID(parentId);
1016
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1004
1017
  if (typedProps) {
1005
- this.setVertexProperties(vertexId, typedProps);
1018
+ this.setNodeProperties(nodeId, typedProps);
1006
1019
  }
1007
- const vertex = this.state.getVertex(vertexId);
1008
- if (!vertex) {
1009
- throw new Error("Failed to create vertex");
1020
+ const node = this.state.getNode(nodeId);
1021
+ if (!node) {
1022
+ throw new Error("Failed to create node");
1010
1023
  }
1011
- return new Vertex(this, vertex);
1024
+ return new Node(this, node);
1012
1025
  }
1013
- newNamedVertex(parentId, name, props = null) {
1026
+ newNamedNode(parentId, name, props = null) {
1014
1027
  const typedProps = props;
1015
- const vertexId = this.newVertexInternalWithUUID(parentId);
1028
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1016
1029
  if (typedProps) {
1017
- this.setVertexProperties(vertexId, typedProps);
1030
+ this.setNodeProperties(nodeId, typedProps);
1018
1031
  }
1019
- this.setVertexProperty(vertexId, "name", name);
1020
- const vertex = this.state.getVertex(vertexId);
1021
- if (!vertex) {
1022
- throw new Error("Failed to create named vertex");
1032
+ this.setNodeProperty(nodeId, "name", name);
1033
+ const node = this.state.getNode(nodeId);
1034
+ if (!node) {
1035
+ throw new Error("Failed to create named node");
1023
1036
  }
1024
- return new Vertex(this, vertex);
1037
+ return new Node(this, node);
1025
1038
  }
1026
- moveVertex(vertexId, parentId) {
1027
- this.lamportClock++;
1028
- const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);
1039
+ moveNode(nodeId, parentId) {
1040
+ this.moveClock++;
1041
+ const op = newMoveNodeOp(this.moveClock, this.peerId, nodeId, parentId);
1029
1042
  this.localOps.push(op);
1030
1043
  this.applyMove(op);
1031
1044
  }
1032
- deleteVertex(vertexId) {
1033
- this.moveVertex(vertexId, _RepTree.NULL_VERTEX_ID);
1045
+ deleteNode(nodeId) {
1046
+ this.moveNode(nodeId, _RepTree.NULL_NODE_ID);
1034
1047
  }
1035
- setTransientVertexProperty(vertexId, key, value) {
1048
+ setTransientNodeProperty(nodeId, key, value) {
1036
1049
  if (!isJsonValue(value)) {
1037
1050
  throw new Error(`Unsupported transient property value for key "${key}"`);
1038
1051
  }
1039
- this.lamportClock++;
1040
- const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1052
+ this.propClock++;
1053
+ const op = newSetTransientNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1041
1054
  this.localOps.push(op);
1042
1055
  this.applyProperty(op);
1043
1056
  }
1044
1057
  /**
1045
1058
  * Promotes all transient (temporary) properties to persistent properties.
1046
- * @param vertexId - The ID of the vertex to commit transients for.
1047
- * @returns
1059
+ * @param nodeId - The ID of the node to commit transients for.
1060
+ * @returns
1048
1061
  */
1049
- commitTransients(vertexId) {
1050
- const vertex = this.state.getVertex(vertexId);
1051
- if (!vertex) {
1062
+ commitTransients(nodeId) {
1063
+ const node = this.state.getNode(nodeId);
1064
+ if (!node) {
1052
1065
  return;
1053
1066
  }
1054
- const transientProps = vertex.getTransientProperties();
1067
+ const transientProps = node.getTransientProperties();
1055
1068
  for (const prop of transientProps) {
1056
- this.setVertexProperty(vertexId, prop.key, prop.value);
1069
+ this.setNodeProperty(nodeId, prop.key, prop.value);
1057
1070
  }
1058
1071
  for (const prop of transientProps) {
1059
- this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${vertexId}`);
1060
- }
1061
- vertex.clearAllTransientProperties();
1062
- }
1063
- setVertexProperty(vertexId, key, value) {
1064
- const isJsonValue2 = (v) => {
1065
- if (v === void 0) return true;
1066
- if (v === null) return true;
1067
- const t = typeof v;
1068
- if (t === "string" || t === "number" || t === "boolean") return true;
1069
- if (t === "bigint" || t === "function" || t === "symbol") return false;
1070
- if (Array.isArray(v)) return v.every(isJsonValue2);
1071
- if (t === "object") {
1072
- if (v instanceof Date) return false;
1073
- if (v instanceof Map || v instanceof Set || v instanceof RegExp) return false;
1074
- if (ArrayBuffer.isView(v)) return false;
1075
- const proto = Object.getPrototypeOf(v);
1076
- if (proto !== Object.prototype && proto !== null) return false;
1077
- for (const val of Object.values(v)) {
1078
- if (!isJsonValue2(val)) return false;
1079
- }
1080
- return true;
1081
- }
1082
- return false;
1083
- };
1084
- if (!isJsonValue2(value)) {
1072
+ this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${nodeId}`);
1073
+ }
1074
+ node.clearAllTransientProperties();
1075
+ }
1076
+ setNodeProperty(nodeId, key, value) {
1077
+ if (!isJsonValue(value)) {
1085
1078
  throw new Error(`Unsupported property value for key "${key}"`);
1086
1079
  }
1087
- this.lamportClock++;
1088
- const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1080
+ this.propClock++;
1081
+ const op = newSetNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1089
1082
  this.localOps.push(op);
1090
1083
  this.applyProperty(op);
1091
1084
  }
1092
- setVertexProperties(vertexId, props) {
1085
+ setNodeProperties(nodeId, props) {
1093
1086
  const typedProps = props;
1094
1087
  for (const [key, value] of Object.entries(typedProps)) {
1095
- this.setVertexProperty(vertexId, key, value);
1088
+ this.setNodeProperty(nodeId, key, value);
1096
1089
  }
1097
1090
  }
1098
- getVertexByPath(path) {
1091
+ getNodeByPath(path) {
1099
1092
  path = path.replace(/^\/+/, "");
1100
1093
  path = path.replace(/\/+$/, "");
1101
- const pathParts = path.split("/");
1102
- if (!this.rootVertexId) {
1094
+ const root = this.root;
1095
+ if (!root) {
1103
1096
  return void 0;
1104
1097
  }
1105
- const root = this.state.getVertex(this.rootVertexId);
1106
- if (!root) {
1107
- throw new Error("The root vertex is not found");
1098
+ if (path === "") {
1099
+ return root;
1108
1100
  }
1109
- const vertex = this.getVertexByPathArray(new Vertex(this, root), pathParts);
1110
- return vertex;
1101
+ return this.getNodeByPathArray(root, path.split("/"));
1111
1102
  }
1112
- getVertexByPathArray(vertex, path) {
1103
+ getNodeByPathArray(node, path) {
1113
1104
  if (path.length === 0) {
1114
- return vertex ?? void 0;
1105
+ return node ?? void 0;
1115
1106
  }
1116
1107
  const targetName = path[0];
1117
- const children = this.getChildren(vertex.id);
1108
+ const children = this.getChildren(node.id);
1118
1109
  for (const child of children) {
1119
1110
  if (child.getProperty("name") === targetName) {
1120
- return this.getVertexByPathArray(child, path.slice(1));
1111
+ return this.getNodeByPathArray(child, path.slice(1));
1121
1112
  }
1122
1113
  }
1123
1114
  return void 0;
1124
1115
  }
1125
1116
  printTree() {
1126
- if (!this.rootVertexId) {
1117
+ if (!this.rootNodeId) {
1127
1118
  return "";
1128
1119
  }
1129
- return this.state.printTree(this.rootVertexId);
1120
+ return this.state.printTree(this.rootNodeId);
1130
1121
  }
1131
1122
  merge(ops) {
1132
1123
  this.applyOps(ops);
1133
1124
  }
1134
1125
  applyOps(ops) {
1135
- for (const op of ops) {
1136
- if (this.knownOps.has(opIdToString(op.id))) {
1126
+ const moveOps = ops.filter((op) => isMoveNodeOp(op));
1127
+ const propertyOps = ops.filter((op) => isAnyPropertyOp(op));
1128
+ for (const op of moveOps) {
1129
+ if (this.knownOps.has(this.getOpKey(op))) {
1130
+ continue;
1131
+ }
1132
+ this.applyOperation(op);
1133
+ }
1134
+ for (const op of propertyOps) {
1135
+ if (this.knownOps.has(this.getOpKey(op))) {
1137
1136
  continue;
1138
1137
  }
1139
1138
  this.applyOperation(op);
@@ -1141,7 +1140,7 @@ var _RepTree = class _RepTree {
1141
1140
  }
1142
1141
  /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
1143
1142
  applyOpsOptimizedForLotsOfMoves(ops) {
1144
- const newMoveOps = ops.filter((op) => isMoveVertexOp(op) && !this.knownOps.has(opIdToString(op.id)));
1143
+ const newMoveOps = ops.filter((op) => isMoveNodeOp(op) && !this.knownOps.has(this.getOpKey(op)));
1145
1144
  if (newMoveOps.length > 0) {
1146
1145
  const allMoveOps = [...this.moveOps, ...newMoveOps];
1147
1146
  allMoveOps.sort((a, b) => compareOpId(a.id, b.id));
@@ -1150,7 +1149,7 @@ var _RepTree = class _RepTree {
1150
1149
  this.applyMove(op);
1151
1150
  }
1152
1151
  }
1153
- const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(opIdToString(op.id)));
1152
+ const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(this.getOpKey(op)));
1154
1153
  for (let i = 0, len = propertyOps.length; i < len; i++) {
1155
1154
  const op = propertyOps[i];
1156
1155
  this.applyProperty(op);
@@ -1160,10 +1159,10 @@ var _RepTree = class _RepTree {
1160
1159
  if (this.root?.id !== other.root?.id) {
1161
1160
  return false;
1162
1161
  }
1163
- if (!this.rootVertexId) {
1162
+ if (!this.rootNodeId) {
1164
1163
  return true;
1165
1164
  }
1166
- return _RepTree.compareVertices(this.rootVertexId, this, other);
1165
+ return _RepTree.compareNodes(this.rootNodeId, this, other);
1167
1166
  }
1168
1167
  compareMoveOps(other) {
1169
1168
  const movesA = this.moveOps;
@@ -1181,65 +1180,65 @@ var _RepTree = class _RepTree {
1181
1180
  /** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */
1182
1181
  isAncestor(childId, ancestorId) {
1183
1182
  let targetId = childId;
1184
- let vertex;
1185
- const visitedVertices = /* @__PURE__ */ new Set();
1186
- while (vertex = this.state.getVertex(targetId)) {
1187
- if (vertex.parentId === ancestorId) return true;
1188
- if (!vertex.parentId) return false;
1189
- if (visitedVertices.has(targetId)) {
1183
+ let node;
1184
+ const visitedNodes = /* @__PURE__ */ new Set();
1185
+ while (node = this.state.getNode(targetId)) {
1186
+ if (node.parentId === ancestorId) return true;
1187
+ if (!node.parentId) return false;
1188
+ if (visitedNodes.has(targetId)) {
1190
1189
  console.error(`isAncestor: cycle detected in the tree structure.`);
1191
1190
  return false;
1192
1191
  }
1193
- visitedVertices.add(targetId);
1194
- targetId = vertex.parentId;
1192
+ visitedNodes.add(targetId);
1193
+ targetId = node.parentId;
1195
1194
  }
1196
1195
  return false;
1197
1196
  }
1198
- observeVertex(vertexId, callback) {
1199
- const vertex = this.getVertex(vertexId);
1200
- if (vertex) {
1201
- callback(vertex);
1197
+ observeNode(nodeId, callback) {
1198
+ const node = this.getNode(nodeId);
1199
+ if (node) {
1200
+ callback(node);
1202
1201
  }
1203
- const unsubscribe = this.observe(vertexId, (_) => {
1204
- const vertex2 = this.getVertex(vertexId);
1205
- if (vertex2) {
1206
- callback(vertex2);
1202
+ const unsubscribe = this.observe(nodeId, (_) => {
1203
+ const node2 = this.getNode(nodeId);
1204
+ if (node2) {
1205
+ callback(node2);
1207
1206
  }
1208
1207
  });
1209
1208
  return () => {
1210
1209
  unsubscribe();
1211
1210
  };
1212
1211
  }
1213
- observeVertexMove(callback) {
1212
+ observeNodeMove(callback) {
1214
1213
  const listener = (events) => {
1215
1214
  const moveEvent = events.find((e) => e.type === "move");
1216
1215
  if (moveEvent) {
1217
- const vertex = this.getVertex(moveEvent.vertexId);
1218
- if (vertex) {
1219
- callback(vertex, moveEvent.oldParentId === void 0);
1216
+ const node = this.getNode(moveEvent.nodeId);
1217
+ if (node) {
1218
+ callback(node, moveEvent.oldParentId === void 0);
1220
1219
  }
1221
1220
  }
1222
1221
  };
1223
1222
  this.state.addGlobalChangeCallback(listener);
1224
1223
  return () => this.state.removeGlobalChangeCallback(listener);
1225
1224
  }
1226
- observe(vertexId, callback) {
1227
- this.state.addChangeCallback(vertexId, callback);
1228
- return () => this.state.removeChangeCallback(vertexId, callback);
1225
+ observe(nodeId, callback) {
1226
+ this.state.addChangeCallback(nodeId, callback);
1227
+ return () => this.state.removeChangeCallback(nodeId, callback);
1229
1228
  }
1230
1229
  observeOpApplied(callback) {
1231
1230
  this.opAppliedCallbacks.push(callback);
1232
1231
  return () => this.opAppliedCallbacks = this.opAppliedCallbacks.filter((l) => l !== callback);
1233
1232
  }
1234
- static compareVertices(vertexId, treeA, treeB) {
1235
- const childrenA = treeA.state.getChildrenIds(vertexId);
1236
- const childrenB = treeB.state.getChildrenIds(vertexId);
1233
+ static compareNodes(nodeId, treeA, treeB) {
1234
+ const childrenA = treeA.state.getChildrenIds(nodeId);
1235
+ const childrenB = treeB.state.getChildrenIds(nodeId);
1237
1236
  if (childrenA.length !== childrenB.length) {
1238
1237
  return false;
1239
1238
  }
1240
- if (vertexId !== null) {
1241
- const propertiesA = treeA.getVertexProperties(vertexId);
1242
- const propertiesB = treeB.getVertexProperties(vertexId);
1239
+ if (nodeId !== null) {
1240
+ const propertiesA = treeA.getNodeProperties(nodeId);
1241
+ const propertiesB = treeB.getNodeProperties(nodeId);
1243
1242
  if (propertiesA.length !== propertiesB.length) {
1244
1243
  return false;
1245
1244
  }
@@ -1253,39 +1252,44 @@ var _RepTree = class _RepTree {
1253
1252
  if (!childrenB.includes(childId)) {
1254
1253
  return false;
1255
1254
  }
1256
- if (!_RepTree.compareVertices(childId, treeA, treeB)) {
1255
+ if (!_RepTree.compareNodes(childId, treeA, treeB)) {
1257
1256
  return false;
1258
1257
  }
1259
1258
  }
1260
1259
  return true;
1261
1260
  }
1262
- newVertexInternal(vertexId, parentId) {
1263
- this.lamportClock++;
1264
- const op = newMoveVertexOp(this.lamportClock, this.peerId, vertexId, parentId);
1261
+ newNodeInternal(nodeId, parentId) {
1262
+ this.moveClock++;
1263
+ const op = newMoveNodeOp(this.moveClock, this.peerId, nodeId, parentId);
1265
1264
  this.localOps.push(op);
1266
1265
  this.applyMove(op);
1267
- this.setVertexProperty(vertexId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1268
- return vertexId;
1266
+ this.setNodeProperty(nodeId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1267
+ return nodeId;
1269
1268
  }
1270
- newVertexInternalWithUUID(parentId) {
1271
- const vertexId = uuid();
1272
- return this.newVertexInternal(vertexId, parentId);
1269
+ newNodeInternalWithUUID(parentId) {
1270
+ const nodeId = uuid();
1271
+ return this.newNodeInternal(nodeId, parentId);
1273
1272
  }
1274
- ensureNullVertex() {
1275
- const vertexId = _RepTree.NULL_VERTEX_ID;
1276
- if (this.state.getVertex(vertexId)) {
1273
+ ensureNullNode() {
1274
+ const nodeId = _RepTree.NULL_NODE_ID;
1275
+ if (this.state.getNode(nodeId)) {
1277
1276
  return;
1278
1277
  }
1279
- this.newVertexInternal(vertexId, null);
1278
+ this.newNodeInternal(nodeId, null);
1280
1279
  }
1281
1280
  /** Updates the lamport clock with the counter value of the operation */
1282
- updateLamportClock(operation) {
1283
- if (operation.id.counter > this.lamportClock) {
1284
- this.lamportClock = operation.id.counter;
1281
+ updateMoveClock(operation) {
1282
+ if (operation.id.counter > this.moveClock) {
1283
+ this.moveClock = operation.id.counter;
1284
+ }
1285
+ }
1286
+ updatePropClock(operation) {
1287
+ if (operation.id.counter > this.propClock) {
1288
+ this.propClock = operation.id.counter;
1285
1289
  }
1286
1290
  }
1287
1291
  applyPendingMovesForParent(parentId) {
1288
- if (!this.state.getVertex(parentId)) {
1292
+ if (!this.state.getNode(parentId)) {
1289
1293
  return;
1290
1294
  }
1291
1295
  const pendingMoves = this.pendingMovesWithMissingParent.get(parentId);
@@ -1298,14 +1302,15 @@ var _RepTree = class _RepTree {
1298
1302
  }
1299
1303
  }
1300
1304
  applyMove(op) {
1301
- if (op.parentId !== null && !this.state.getVertex(op.parentId)) {
1305
+ if (op.parentId !== null && !this.state.getNode(op.parentId)) {
1302
1306
  if (!this.pendingMovesWithMissingParent.has(op.parentId)) {
1303
1307
  this.pendingMovesWithMissingParent.set(op.parentId, []);
1304
1308
  }
1305
1309
  this.pendingMovesWithMissingParent.get(op.parentId).push(op);
1310
+ this.markOpSeen(op, true);
1306
1311
  return;
1307
1312
  }
1308
- this.updateLamportClock(op);
1313
+ this.updateMoveClock(op);
1309
1314
  const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;
1310
1315
  if (lastOp === null || isOpIdGreaterThan(op.id, lastOp.id)) {
1311
1316
  this.moveOps.push(op);
@@ -1332,130 +1337,138 @@ var _RepTree = class _RepTree {
1332
1337
  this.applyPendingMovesForParent(op.targetId);
1333
1338
  }
1334
1339
  setLLWPropertyAndItsOpId(op) {
1335
- this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1340
+ this.propertyOpsByKey.set(`${op.key}@${op.targetId}`, op);
1336
1341
  this.state.setProperty(op.targetId, op.key, op.value);
1337
- this.reportOpAsApplied(op);
1342
+ this.reportOpAsApplied(op, false);
1343
+ this.refreshPropStateVector();
1338
1344
  }
1339
1345
  setTransientPropertyAndItsOpId(op) {
1340
1346
  this.transientPropertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1341
1347
  this.state.setTransientProperty(op.targetId, op.key, op.value);
1342
- this.reportOpAsApplied(op);
1348
+ this.reportOpAsApplied(op, false);
1343
1349
  }
1344
1350
  applyProperty(op) {
1345
- const targetVertex = this.state.getVertex(op.targetId);
1346
- if (!targetVertex) {
1351
+ const targetNode = this.state.getNode(op.targetId);
1352
+ if (!targetNode) {
1347
1353
  if (op.transient) {
1348
1354
  return;
1349
1355
  }
1350
- if (!this.pendingPropertiesWithMissingVertex.has(op.targetId)) {
1351
- this.pendingPropertiesWithMissingVertex.set(op.targetId, []);
1356
+ if (!this.pendingPropertiesWithMissingNode.has(op.targetId)) {
1357
+ this.pendingPropertiesWithMissingNode.set(op.targetId, []);
1352
1358
  }
1353
- this.pendingPropertiesWithMissingVertex.get(op.targetId).push(op);
1359
+ this.pendingPropertiesWithMissingNode.get(op.targetId).push(op);
1360
+ this.markOpSeen(op, false);
1354
1361
  return;
1355
1362
  }
1356
- this.updateLamportClock(op);
1357
- this.applyLLWProperty(op, targetVertex);
1363
+ this.updatePropClock(op);
1364
+ this.applyLLWProperty(op, targetNode);
1358
1365
  }
1359
- applyLLWProperty(op, targetVertex) {
1366
+ applyLLWProperty(op, targetNode) {
1360
1367
  const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1361
- const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1368
+ const prevOpId = this.propertyOpsByKey.get(`${op.key}@${op.targetId}`)?.id;
1362
1369
  if (!op.transient) {
1363
- this.setPropertyOps.push(op);
1364
1370
  if (!prevOpId || isOpIdGreaterThan(op.id, prevOpId)) {
1365
1371
  this.setLLWPropertyAndItsOpId(op);
1366
1372
  } else {
1367
- this.knownOps.add(opIdToString(op.id));
1373
+ this.markOpSeen(op, false);
1368
1374
  }
1369
1375
  if (prevTransientOpId && isOpIdGreaterThan(op.id, prevTransientOpId)) {
1370
1376
  this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);
1371
- targetVertex.removeTransientProperty(op.key);
1377
+ targetNode.removeTransientProperty(op.key);
1372
1378
  }
1373
1379
  } else {
1374
1380
  if (!prevTransientOpId || isOpIdGreaterThan(op.id, prevTransientOpId)) {
1375
1381
  this.setTransientPropertyAndItsOpId(op);
1382
+ } else {
1383
+ this.markOpSeen(op, false);
1376
1384
  }
1377
1385
  }
1378
1386
  }
1379
1387
  applyOperation(op) {
1380
- if (isMoveVertexOp(op)) {
1388
+ if (isMoveNodeOp(op)) {
1381
1389
  this.applyMove(op);
1382
1390
  } else if (isAnyPropertyOp(op)) {
1383
1391
  this.applyProperty(op);
1384
1392
  }
1385
1393
  }
1386
- reportOpAsApplied(op) {
1387
- this.knownOps.add(opIdToString(op.id));
1388
- if (this._stateVectorEnabled) {
1389
- this.stateVector.updateFromOp(op);
1394
+ markOpSeen(op, includeInStateVector) {
1395
+ this.knownOps.add(this.getOpKey(op));
1396
+ if (includeInStateVector && this._stateVectorEnabled) {
1397
+ if (isMoveNodeOp(op)) {
1398
+ this.moveStateVector.updateFromOp(op);
1399
+ } else if (isAnyPropertyOp(op)) {
1400
+ this.propStateVector.updateFromOp(op);
1401
+ }
1390
1402
  }
1403
+ }
1404
+ reportOpAsApplied(op, includeInStateVector = true) {
1405
+ this.markOpSeen(op, includeInStateVector);
1391
1406
  for (const callback of this.opAppliedCallbacks) {
1392
1407
  callback(op);
1393
1408
  }
1394
1409
  }
1395
1410
  tryToMove(op) {
1396
- let targetVertex = this.state.getVertex(op.targetId);
1397
- if (targetVertex) {
1398
- this.parentIdBeforeMove.set(op.id, targetVertex.parentId);
1411
+ let targetNode = this.state.getNode(op.targetId);
1412
+ if (targetNode) {
1413
+ this.parentIdBeforeMove.set(op.id, targetNode.parentId);
1399
1414
  }
1400
1415
  if (op.targetId === op.parentId) return;
1401
1416
  if (op.parentId && this.isAncestor(op.parentId, op.targetId)) return;
1402
- this.state.moveVertex(op.targetId, op.parentId);
1403
- if (!targetVertex) {
1404
- const pendingProperties = this.pendingPropertiesWithMissingVertex.get(op.targetId) || [];
1405
- this.pendingPropertiesWithMissingVertex.delete(op.targetId);
1417
+ this.state.moveNode(op.targetId, op.parentId);
1418
+ if (!targetNode) {
1419
+ const pendingProperties = this.pendingPropertiesWithMissingNode.get(op.targetId) || [];
1420
+ this.pendingPropertiesWithMissingNode.delete(op.targetId);
1406
1421
  for (const prop of pendingProperties) {
1407
1422
  this.applyProperty(prop);
1408
1423
  }
1409
1424
  }
1410
1425
  }
1411
1426
  undoMove(op) {
1412
- const targetVertex = this.state.getVertex(op.targetId);
1413
- if (!targetVertex) {
1414
- console.error(`An attempt to undo move operation ${opIdToString(op.id)} failed because the target vertex ${op.targetId} not found`);
1427
+ const targetNode = this.state.getNode(op.targetId);
1428
+ if (!targetNode) {
1429
+ console.error(`An attempt to undo move operation ${opIdToString(op.id)} failed because the target node ${op.targetId} not found`);
1415
1430
  return;
1416
1431
  }
1417
1432
  const prevParentId = this.parentIdBeforeMove.get(op.id);
1418
1433
  if (prevParentId === void 0) {
1419
1434
  return;
1420
1435
  }
1421
- this.state.moveVertex(op.targetId, prevParentId);
1436
+ this.state.moveNode(op.targetId, prevParentId);
1422
1437
  }
1423
- // --- Range-Based State Vector Methods ---
1438
+ // --- Range-Based State Vector Methods ---
1424
1439
  /**
1425
- * Returns the current state vector.
1426
- * Returns a readonly reference to the internal state vector.
1440
+ * Returns the current state vectors for move and property streams.
1441
+ * Returns readonly references to the internal state vectors.
1427
1442
  */
1428
- getStateVector() {
1443
+ getStateVectors() {
1429
1444
  if (!this._stateVectorEnabled) {
1430
1445
  return null;
1431
1446
  }
1432
- return this.stateVector.getState();
1447
+ return {
1448
+ move: this.moveStateVector.getState(),
1449
+ prop: this.propStateVector.getState()
1450
+ };
1433
1451
  }
1434
1452
  /**
1435
- * Determines which operations are needed to synchronize
1453
+ * Determines which operations are needed to synchronize
1436
1454
  * with the provided state vector.
1437
- *
1438
- * @param theirStateVector The state vector from another peer
1439
- * @returns Operations that should be sent to the other peer, sorted by OpId.
1455
+ *
1456
+ * @param theirStateVectors The state vectors from another peer
1457
+ * @returns Operations that should be sent to the other peer, sorted by OpId within each stream.
1440
1458
  */
1441
- getMissingOps(theirStateVector) {
1459
+ getMissingOps(theirStateVectors) {
1442
1460
  if (!this._stateVectorEnabled) {
1443
- return [...this.moveOps, ...this.setPropertyOps];
1444
- }
1445
- const otherStateVector = new StateVector(theirStateVector);
1446
- const missingRanges = this.stateVector.diff(otherStateVector);
1447
- const missingOps = [];
1448
- const allOps = [...this.moveOps, ...this.setPropertyOps];
1449
- for (const op of allOps) {
1450
- for (const range of missingRanges) {
1451
- if (op.id.peerId === range.peerId && op.id.counter >= range.start && op.id.counter <= range.end) {
1452
- missingOps.push(op);
1453
- break;
1454
- }
1455
- }
1456
- }
1457
- missingOps.sort((a, b) => compareOpId(a.id, b.id));
1458
- return missingOps;
1461
+ return [...this.moveOps, ...this.getPropertyOps()];
1462
+ }
1463
+ const otherMoveStateVector = new StateVector(theirStateVectors.move);
1464
+ const otherPropStateVector = new StateVector(theirStateVectors.prop);
1465
+ const missingMoveRanges = this.moveStateVector.diff(otherMoveStateVector);
1466
+ const missingPropRanges = this.propStateVector.diff(otherPropStateVector);
1467
+ const missingMoveOps = this.filterOpsByRanges(this.moveOps, missingMoveRanges);
1468
+ const missingPropOps = this.filterOpsByRanges(this.getPropertyOps(), missingPropRanges);
1469
+ missingMoveOps.sort((a, b) => compareOpId(a.id, b.id));
1470
+ missingPropOps.sort((a, b) => compareOpId(a.id, b.id));
1471
+ return [...missingMoveOps, ...missingPropOps];
1459
1472
  }
1460
1473
  /**
1461
1474
  * Gets or sets whether state vector tracking is enabled
@@ -1471,42 +1484,69 @@ var _RepTree = class _RepTree {
1471
1484
  if (value === this._stateVectorEnabled) return;
1472
1485
  if (value) {
1473
1486
  this._stateVectorEnabled = true;
1474
- this.stateVector = StateVector.fromOperations([...this.moveOps, ...this.setPropertyOps]);
1487
+ this.moveStateVector = StateVector.fromOperations(this.moveOps);
1488
+ this.propStateVector = StateVector.fromOperations(this.getPropertyOps());
1475
1489
  } else {
1476
1490
  this._stateVectorEnabled = false;
1477
- this.stateVector = new StateVector();
1491
+ this.moveStateVector = new StateVector();
1492
+ this.propStateVector = new StateVector();
1478
1493
  }
1479
1494
  }
1480
1495
  /**
1481
- * Parses the vertex properties with a provided schema that has a `parse` method (e.g., Zod schema)
1496
+ * Parses the node properties with a provided schema that has a `parse` method (e.g., Zod schema)
1482
1497
  */
1483
- parseVertex(vertexId, schema) {
1484
- const propsArray = this.getVertexProperties(vertexId);
1498
+ parseNode(nodeId, schema) {
1499
+ const propsArray = this.getNodeProperties(nodeId);
1485
1500
  const propsObject = {};
1486
1501
  for (const { key, value } of propsArray) {
1487
1502
  propsObject[key] = value;
1488
1503
  }
1489
1504
  return schema.parse(propsObject);
1490
1505
  }
1506
+ getPropertyOps() {
1507
+ return Array.from(this.propertyOpsByKey.values());
1508
+ }
1509
+ refreshPropStateVector() {
1510
+ if (!this._stateVectorEnabled) {
1511
+ return;
1512
+ }
1513
+ this.propStateVector = StateVector.fromOperations(this.getPropertyOps());
1514
+ }
1515
+ getOpKey(op) {
1516
+ const stream = isMoveNodeOp(op) ? "move" : "prop";
1517
+ return `${stream}:${opIdToString(op.id)}`;
1518
+ }
1519
+ filterOpsByRanges(ops, ranges) {
1520
+ const missingOps = [];
1521
+ for (const op of ops) {
1522
+ for (const range of ranges) {
1523
+ if (op.id.peerId === range.peerId && op.id.counter >= range.start && op.id.counter <= range.end) {
1524
+ missingOps.push(op);
1525
+ break;
1526
+ }
1527
+ }
1528
+ }
1529
+ return missingOps;
1530
+ }
1491
1531
  };
1492
- _RepTree.NULL_VERTEX_ID = "0";
1532
+ _RepTree.NULL_NODE_ID = "0";
1493
1533
  var RepTree = _RepTree;
1494
1534
  export {
1535
+ Node,
1536
+ NodeState,
1495
1537
  RepTree,
1496
1538
  StateVector,
1497
1539
  TreeState,
1498
- Vertex,
1499
- VertexState,
1500
- bindVertex,
1540
+ bindNode,
1501
1541
  compareOpId,
1502
1542
  createOpId,
1503
1543
  equalsOpId,
1504
1544
  isAnyPropertyOp,
1505
- isMoveVertexOp,
1545
+ isMoveNodeOp,
1506
1546
  isOpIdGreaterThan,
1507
- newMoveVertexOp,
1508
- newSetTransientVertexPropertyOp,
1509
- newSetVertexPropertyOp,
1547
+ newMoveNodeOp,
1548
+ newSetNodePropertyOp,
1549
+ newSetTransientNodePropertyOp,
1510
1550
  opIdToString,
1511
1551
  tryParseOpIdStr,
1512
1552
  uuid