reptree 0.8.2 → 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 _Vertex {
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 _Vertex {
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,56 +547,48 @@ var Vertex = class _Vertex {
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
- if (props && typeof props === "object" && "children" in props) {
544
- throw new Error("Passing children inside props is not supported at the moment");
545
- }
546
- const normalized = _Vertex.normalizePropsForCreation(props);
547
- return this.tree.newVertex(this.id, normalized);
552
+ return this.tree.newNode(this.id, props);
548
553
  }
549
- /** Creates a new named child vertex of this vertex. */
554
+ /** Creates a new named child node of this node. */
550
555
  newNamedChild(name, props) {
551
- if (props && typeof props === "object" && "children" in props) {
552
- throw new Error("Passing children inside props is not supported at the moment");
553
- }
554
- const normalized = _Vertex.normalizePropsForCreation(props);
555
- return this.tree.newNamedVertex(this.id, name, normalized);
556
+ return this.tree.newNamedNode(this.id, name, props);
556
557
  }
557
- /** Sets a property on this vertex. */
558
+ /** Sets a property on this node. */
558
559
  setProperty(key, value) {
559
560
  const existingValue = this.getProperty(key, false);
560
561
  if (existingValue === value) {
561
562
  return;
562
563
  }
563
- this.tree.setVertexProperty(this.id, key, value);
564
+ this.tree.setNodeProperty(this.id, key, value);
564
565
  }
565
- /** 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. */
566
567
  setTransientProperty(key, value) {
567
568
  const existingValue = this.getProperty(key);
568
569
  if (existingValue === value) {
569
570
  return;
570
571
  }
571
- this.tree.setTransientVertexProperty(this.id, key, value);
572
+ this.tree.setTransientNodeProperty(this.id, key, value);
572
573
  }
573
574
  /** Promotes all transient (temporary) properties to persistent properties. */
574
575
  commitTransients() {
575
576
  this.tree.commitTransients(this.id);
576
577
  }
577
- /** Sets multiple properties on this vertex. */
578
+ /** Sets multiple properties on this node. */
578
579
  setProperties(props) {
579
580
  for (const [key, value] of Object.entries(props)) {
580
581
  this.setProperty(key, value);
581
582
  }
582
583
  }
583
- /** Returns the value of a property on this vertex. */
584
+ /** Returns the value of a property on this node. */
584
585
  getProperty(key, includingTransient = true) {
585
- return this.tree.getVertexProperty(this.id, key, includingTransient);
586
+ return this.tree.getNodeProperty(this.id, key, includingTransient);
586
587
  }
587
- /** Returns all properties on this vertex. */
588
+ /** Returns all properties on this node. */
588
589
  getProperties() {
589
590
  const props = {};
590
- this.tree.getVertexProperties(this.id).forEach((p) => {
591
+ this.tree.getNodeProperties(this.id).forEach((p) => {
591
592
  props[p.key] = p.value;
592
593
  });
593
594
  return props;
@@ -595,21 +596,21 @@ var Vertex = class _Vertex {
595
596
  findAllChildrenWithProperty(key, value) {
596
597
  return this.children.filter((c) => c.getProperty(key) === value);
597
598
  }
598
- findFirstChildVertexWithProperty(key, value) {
599
+ findFirstChildNodeWithProperty(key, value) {
599
600
  return this.children.find((c) => c.getProperty(key) === value);
600
601
  }
601
602
  findFirstTypedChildWithProperty(key, value) {
602
- return this.findFirstChildVertexWithProperty(key, value)?.getAsTypedObject();
603
+ return this.findFirstChildNodeWithProperty(key, value)?.getAsTypedObject();
603
604
  }
604
605
  findAllTypedChildrenWithProperty(key, value) {
605
606
  return this.findAllChildrenWithProperty(key, value).map((c) => c.getAsTypedObject());
606
607
  }
607
- /** Observes changes to this vertex. */
608
+ /** Observes changes to this node. */
608
609
  observe(listener) {
609
610
  const unobserve = this.tree.observe(this.id, listener);
610
611
  return () => unobserve();
611
612
  }
612
- /** Observes changes to the children of this vertex. */
613
+ /** Observes changes to the children of this node. */
613
614
  observeChildren(listener) {
614
615
  const unobserve = this.tree.observe(this.id, (events) => {
615
616
  if (events.some((e) => e.type === "children")) {
@@ -624,66 +625,14 @@ var Vertex = class _Vertex {
624
625
  });
625
626
  }
626
627
  delete() {
627
- this.tree.deleteVertex(this.id);
628
+ this.tree.deleteNode(this.id);
628
629
  }
629
630
  moveTo(parent) {
630
- this.tree.moveVertex(this.id, parent.id);
631
+ this.tree.moveNode(this.id, parent.id);
631
632
  }
632
- /** 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. */
633
634
  bind(schemaOrOptions) {
634
- return bindVertex(this.tree, this.id, schemaOrOptions);
635
- }
636
- /**
637
- * Normalizes an input props object for vertex creation:
638
- * - Filters unsupported field types with a console warning
639
- * - When a name param is provided to newNamedChild, ignores conflicting name in props
640
- */
641
- static normalizePropsForCreation(props) {
642
- if (!props) return null;
643
- const input = props;
644
- const out = {};
645
- const skipped = [];
646
- const isJsonValue2 = (v) => {
647
- if (v === null) return true;
648
- const t = typeof v;
649
- if (t === "string" || t === "number" || t === "boolean") return true;
650
- if (Array.isArray(v)) return v.every(isJsonValue2);
651
- if (t === "object") {
652
- const proto = Object.getPrototypeOf(v);
653
- if (proto !== Object.prototype && proto !== null) return false;
654
- for (const val of Object.values(v)) {
655
- if (!isJsonValue2(val)) return false;
656
- }
657
- return true;
658
- }
659
- return false;
660
- };
661
- for (const [rawKey, rawValue] of Object.entries(input)) {
662
- if (rawValue === void 0) {
663
- continue;
664
- }
665
- if (rawKey === "children") continue;
666
- let key = rawKey;
667
- let value = rawValue;
668
- if (key === "_c") {
669
- if (value instanceof Date) {
670
- value = value.toISOString();
671
- } else if (typeof value === "string") {
672
- } else {
673
- skipped.push(rawKey);
674
- continue;
675
- }
676
- }
677
- if (!isJsonValue2(value)) {
678
- skipped.push(rawKey);
679
- continue;
680
- }
681
- out[key] = value;
682
- }
683
- if (skipped.length > 0) {
684
- throw new Error(`Unsupported property types for keys: ${skipped.join(", ")}`);
685
- }
686
- return Object.keys(out).length > 0 ? out : null;
635
+ return bindNode(this.tree, this.id, schemaOrOptions);
687
636
  }
688
637
  };
689
638
 
@@ -734,7 +683,7 @@ var StateVector = class _StateVector {
734
683
  /**
735
684
  * Updates the state vector with a newly applied operation.
736
685
  * Assumes ranges are sorted and non-overlapping.
737
- *
686
+ *
738
687
  * @param peerId The peer ID of the operation
739
688
  * @param counter The counter value of the operation
740
689
  */
@@ -795,7 +744,7 @@ var StateVector = class _StateVector {
795
744
  }
796
745
  /**
797
746
  * Updates the state vector with a newly applied operation.
798
- *
747
+ *
799
748
  * @param op The operation that was just applied
800
749
  */
801
750
  updateFromOp(op) {
@@ -811,7 +760,7 @@ var StateVector = class _StateVector {
811
760
  /**
812
761
  * Calculates which operation ranges we have that the other state vector is missing
813
762
  * by comparing state vectors.
814
- *
763
+ *
815
764
  * @param other The other state vector to compare against
816
765
  * @returns Array of operation ID ranges that we have but they don't
817
766
  */
@@ -835,7 +784,7 @@ var StateVector = class _StateVector {
835
784
  }
836
785
  /**
837
786
  * Checks if the state vector contains the given operation ID
838
- *
787
+ *
839
788
  * @param opId The operation ID to check
840
789
  * @returns true if the operation is in the state vector, false otherwise
841
790
  */
@@ -931,50 +880,54 @@ function isJsonValue(v) {
931
880
  var _RepTree = class _RepTree {
932
881
  /**
933
882
  * @param peerId - The peer ID of the current client. Should be unique across all peers.
934
- * @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
935
884
  */
936
885
  constructor(peerId, ops) {
937
- this.lamportClock = 0;
886
+ this.moveClock = 0;
887
+ this.propClock = 0;
938
888
  this.moveOps = [];
939
- this.setPropertyOps = [];
940
- this.propertiesAndTheirOpIds = /* @__PURE__ */ new Map();
889
+ this.propertyOpsByKey = /* @__PURE__ */ new Map();
941
890
  this.transientPropertiesAndTheirOpIds = /* @__PURE__ */ new Map();
942
891
  this.localOps = [];
943
892
  this.pendingMovesWithMissingParent = /* @__PURE__ */ new Map();
944
- this.pendingPropertiesWithMissingVertex = /* @__PURE__ */ new Map();
893
+ this.pendingPropertiesWithMissingNode = /* @__PURE__ */ new Map();
945
894
  this.knownOps = /* @__PURE__ */ new Set();
946
895
  this.parentIdBeforeMove = /* @__PURE__ */ new Map();
947
896
  this.opAppliedCallbacks = [];
948
897
  this._stateVectorEnabled = true;
949
898
  this.peerId = peerId;
950
899
  this.state = new TreeState();
951
- this.stateVector = new StateVector();
900
+ this.moveStateVector = new StateVector();
901
+ this.propStateVector = new StateVector();
952
902
  if (ops && ops.length > 0) {
953
903
  this.applyOps(ops);
954
904
  const root = this.root;
955
905
  if (!root) {
956
- 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");
957
907
  }
958
908
  } else {
959
- this.ensureNullVertex();
909
+ this.ensureNullNode();
960
910
  }
961
911
  }
912
+ dispose() {
913
+ this.state.dispose();
914
+ }
962
915
  get root() {
963
- if (!this.rootVertexId) {
964
- const vertices = this.state.getAllVertices();
965
- for (const vertex of vertices) {
966
- if (vertex.parentId === null && vertex.id !== _RepTree.NULL_VERTEX_ID) {
967
- this.rootVertexId = vertex.id;
968
- 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);
969
922
  }
970
923
  }
971
924
  return void 0;
972
925
  }
973
- const rootVertex = this.state.getVertex(this.rootVertexId);
974
- if (!rootVertex) {
975
- 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");
976
929
  }
977
- return new Vertex(this, rootVertex);
930
+ return new Node(this, rootNode);
978
931
  }
979
932
  replicate(newPeerId) {
980
933
  return new _RepTree(newPeerId, this.getAllOps());
@@ -983,54 +936,54 @@ var _RepTree = class _RepTree {
983
936
  return this.moveOps;
984
937
  }
985
938
  getAllOps() {
986
- return [...this.moveOps, ...this.setPropertyOps];
939
+ return [...this.moveOps, ...this.getPropertyOps()];
987
940
  }
988
- getVertex(vertexId) {
989
- const vertex = this.state.getVertex(vertexId);
990
- 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;
991
944
  }
992
- getAllVertices() {
993
- return this.state.getAllVertices().map((v) => new Vertex(this, v));
945
+ getAllNodes() {
946
+ return this.state.getAllNodes().map((v) => new Node(this, v));
994
947
  }
995
- getParent(vertexId) {
996
- const parentId = this.state.getVertex(vertexId)?.parentId;
997
- const parent = parentId ? this.state.getVertex(parentId) : void 0;
998
- 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;
999
952
  }
1000
- getChildren(vertexId) {
1001
- 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));
1002
955
  }
1003
- getChildrenIds(vertexId) {
1004
- return this.state.getChildrenIds(vertexId);
956
+ getChildrenIds(nodeId) {
957
+ return this.state.getChildrenIds(nodeId);
1005
958
  }
1006
- /** Returns the ancestors of the given vertex. The first element is the root vertex. */
1007
- getAncestors(vertexId) {
959
+ /** Returns the ancestors of the given node. The first element is the root node. */
960
+ getAncestors(nodeId) {
1008
961
  const ancestors = [];
1009
- let currentVertex = this.state.getVertex(vertexId);
1010
- while (currentVertex && currentVertex.parentId) {
1011
- const parentVertex = this.state.getVertex(currentVertex.parentId);
1012
- if (parentVertex) {
1013
- ancestors.push(new Vertex(this, parentVertex));
1014
- 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;
1015
968
  } else {
1016
969
  break;
1017
970
  }
1018
971
  }
1019
972
  return ancestors;
1020
973
  }
1021
- getVertexProperty(vertexId, key, includingTransient = true) {
1022
- const vertex = this.state.getVertex(vertexId);
1023
- if (!vertex) {
974
+ getNodeProperty(nodeId, key, includingTransient = true) {
975
+ const node = this.state.getNode(nodeId);
976
+ if (!node) {
1024
977
  return void 0;
1025
978
  }
1026
- return vertex.getProperty(key, includingTransient);
979
+ return node.getProperty(key, includingTransient);
1027
980
  }
1028
- getVertexProperties(vertexId) {
1029
- const vertex = this.state.getVertex(vertexId);
1030
- if (!vertex) {
981
+ getNodeProperties(nodeId) {
982
+ const node = this.state.getNode(nodeId);
983
+ if (!node) {
1031
984
  return [];
1032
985
  }
1033
- return vertex.getAllProperties();
986
+ return node.getAllProperties();
1034
987
  }
1035
988
  /**
1036
989
  * Returns all local operations and clears the local operations list.
@@ -1042,158 +995,144 @@ var _RepTree = class _RepTree {
1042
995
  return ops;
1043
996
  }
1044
997
  /**
1045
- * This is the first vertex that will contain all other vertices.
998
+ * This is the first node that will contain all other nodes.
1046
999
  * If you plan to replicate a tree then don't use this method and instead merge
1047
- * in the ops from another tree (that will also contain the root vertex).
1048
- * @returns The root vertex
1000
+ * in the ops from another tree (that will also contain the root node).
1001
+ * @returns The root node
1049
1002
  */
1050
1003
  createRoot() {
1051
- if (this.rootVertexId) {
1052
- throw new Error("Root vertex already exists");
1004
+ if (this.rootNodeId) {
1005
+ throw new Error("Root node already exists");
1053
1006
  }
1054
- this.rootVertexId = this.newVertexInternalWithUUID(null);
1055
- const rootVertex = this.state.getVertex(this.rootVertexId);
1056
- if (!rootVertex) {
1057
- 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");
1058
1011
  }
1059
- return new Vertex(this, rootVertex);
1012
+ return new Node(this, rootNode);
1060
1013
  }
1061
- newVertex(parentId, props = null) {
1014
+ newNode(parentId, props = null) {
1062
1015
  const typedProps = props;
1063
- const vertexId = this.newVertexInternalWithUUID(parentId);
1016
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1064
1017
  if (typedProps) {
1065
- this.setVertexProperties(vertexId, typedProps);
1018
+ this.setNodeProperties(nodeId, typedProps);
1066
1019
  }
1067
- const vertex = this.state.getVertex(vertexId);
1068
- if (!vertex) {
1069
- 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");
1070
1023
  }
1071
- return new Vertex(this, vertex);
1024
+ return new Node(this, node);
1072
1025
  }
1073
- newNamedVertex(parentId, name, props = null) {
1026
+ newNamedNode(parentId, name, props = null) {
1074
1027
  const typedProps = props;
1075
- const vertexId = this.newVertexInternalWithUUID(parentId);
1028
+ const nodeId = this.newNodeInternalWithUUID(parentId);
1076
1029
  if (typedProps) {
1077
- this.setVertexProperties(vertexId, typedProps);
1030
+ this.setNodeProperties(nodeId, typedProps);
1078
1031
  }
1079
- this.setVertexProperty(vertexId, "name", name);
1080
- const vertex = this.state.getVertex(vertexId);
1081
- if (!vertex) {
1082
- 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");
1083
1036
  }
1084
- return new Vertex(this, vertex);
1037
+ return new Node(this, node);
1085
1038
  }
1086
- moveVertex(vertexId, parentId) {
1087
- this.lamportClock++;
1088
- 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);
1089
1042
  this.localOps.push(op);
1090
1043
  this.applyMove(op);
1091
1044
  }
1092
- deleteVertex(vertexId) {
1093
- this.moveVertex(vertexId, _RepTree.NULL_VERTEX_ID);
1045
+ deleteNode(nodeId) {
1046
+ this.moveNode(nodeId, _RepTree.NULL_NODE_ID);
1094
1047
  }
1095
- setTransientVertexProperty(vertexId, key, value) {
1048
+ setTransientNodeProperty(nodeId, key, value) {
1096
1049
  if (!isJsonValue(value)) {
1097
1050
  throw new Error(`Unsupported transient property value for key "${key}"`);
1098
1051
  }
1099
- this.lamportClock++;
1100
- const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1052
+ this.propClock++;
1053
+ const op = newSetTransientNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1101
1054
  this.localOps.push(op);
1102
1055
  this.applyProperty(op);
1103
1056
  }
1104
1057
  /**
1105
1058
  * Promotes all transient (temporary) properties to persistent properties.
1106
- * @param vertexId - The ID of the vertex to commit transients for.
1107
- * @returns
1059
+ * @param nodeId - The ID of the node to commit transients for.
1060
+ * @returns
1108
1061
  */
1109
- commitTransients(vertexId) {
1110
- const vertex = this.state.getVertex(vertexId);
1111
- if (!vertex) {
1062
+ commitTransients(nodeId) {
1063
+ const node = this.state.getNode(nodeId);
1064
+ if (!node) {
1112
1065
  return;
1113
1066
  }
1114
- const transientProps = vertex.getTransientProperties();
1067
+ const transientProps = node.getTransientProperties();
1115
1068
  for (const prop of transientProps) {
1116
- this.setVertexProperty(vertexId, prop.key, prop.value);
1069
+ this.setNodeProperty(nodeId, prop.key, prop.value);
1117
1070
  }
1118
1071
  for (const prop of transientProps) {
1119
- this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${vertexId}`);
1120
- }
1121
- vertex.clearAllTransientProperties();
1122
- }
1123
- setVertexProperty(vertexId, key, value) {
1124
- const isJsonValue2 = (v) => {
1125
- if (v === void 0) return true;
1126
- if (v === null) return true;
1127
- const t = typeof v;
1128
- if (t === "string" || t === "number" || t === "boolean") return true;
1129
- if (t === "bigint" || t === "function" || t === "symbol") return false;
1130
- if (Array.isArray(v)) return v.every(isJsonValue2);
1131
- if (t === "object") {
1132
- if (v instanceof Date) return false;
1133
- if (v instanceof Map || v instanceof Set || v instanceof RegExp) return false;
1134
- if (ArrayBuffer.isView(v)) return false;
1135
- const proto = Object.getPrototypeOf(v);
1136
- if (proto !== Object.prototype && proto !== null) return false;
1137
- for (const val of Object.values(v)) {
1138
- if (!isJsonValue2(val)) return false;
1139
- }
1140
- return true;
1141
- }
1142
- return false;
1143
- };
1144
- if (!isJsonValue2(value)) {
1072
+ this.transientPropertiesAndTheirOpIds.delete(`${prop.key}@${nodeId}`);
1073
+ }
1074
+ node.clearAllTransientProperties();
1075
+ }
1076
+ setNodeProperty(nodeId, key, value) {
1077
+ if (!isJsonValue(value)) {
1145
1078
  throw new Error(`Unsupported property value for key "${key}"`);
1146
1079
  }
1147
- this.lamportClock++;
1148
- const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1080
+ this.propClock++;
1081
+ const op = newSetNodePropertyOp(this.propClock, this.peerId, nodeId, key, value);
1149
1082
  this.localOps.push(op);
1150
1083
  this.applyProperty(op);
1151
1084
  }
1152
- setVertexProperties(vertexId, props) {
1085
+ setNodeProperties(nodeId, props) {
1153
1086
  const typedProps = props;
1154
1087
  for (const [key, value] of Object.entries(typedProps)) {
1155
- this.setVertexProperty(vertexId, key, value);
1088
+ this.setNodeProperty(nodeId, key, value);
1156
1089
  }
1157
1090
  }
1158
- getVertexByPath(path) {
1091
+ getNodeByPath(path) {
1159
1092
  path = path.replace(/^\/+/, "");
1160
1093
  path = path.replace(/\/+$/, "");
1161
- const pathParts = path.split("/");
1162
- if (!this.rootVertexId) {
1094
+ const root = this.root;
1095
+ if (!root) {
1163
1096
  return void 0;
1164
1097
  }
1165
- const root = this.state.getVertex(this.rootVertexId);
1166
- if (!root) {
1167
- throw new Error("The root vertex is not found");
1098
+ if (path === "") {
1099
+ return root;
1168
1100
  }
1169
- const vertex = this.getVertexByPathArray(new Vertex(this, root), pathParts);
1170
- return vertex;
1101
+ return this.getNodeByPathArray(root, path.split("/"));
1171
1102
  }
1172
- getVertexByPathArray(vertex, path) {
1103
+ getNodeByPathArray(node, path) {
1173
1104
  if (path.length === 0) {
1174
- return vertex ?? void 0;
1105
+ return node ?? void 0;
1175
1106
  }
1176
1107
  const targetName = path[0];
1177
- const children = this.getChildren(vertex.id);
1108
+ const children = this.getChildren(node.id);
1178
1109
  for (const child of children) {
1179
1110
  if (child.getProperty("name") === targetName) {
1180
- return this.getVertexByPathArray(child, path.slice(1));
1111
+ return this.getNodeByPathArray(child, path.slice(1));
1181
1112
  }
1182
1113
  }
1183
1114
  return void 0;
1184
1115
  }
1185
1116
  printTree() {
1186
- if (!this.rootVertexId) {
1117
+ if (!this.rootNodeId) {
1187
1118
  return "";
1188
1119
  }
1189
- return this.state.printTree(this.rootVertexId);
1120
+ return this.state.printTree(this.rootNodeId);
1190
1121
  }
1191
1122
  merge(ops) {
1192
1123
  this.applyOps(ops);
1193
1124
  }
1194
1125
  applyOps(ops) {
1195
- for (const op of ops) {
1196
- 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))) {
1197
1136
  continue;
1198
1137
  }
1199
1138
  this.applyOperation(op);
@@ -1201,7 +1140,7 @@ var _RepTree = class _RepTree {
1201
1140
  }
1202
1141
  /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
1203
1142
  applyOpsOptimizedForLotsOfMoves(ops) {
1204
- 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)));
1205
1144
  if (newMoveOps.length > 0) {
1206
1145
  const allMoveOps = [...this.moveOps, ...newMoveOps];
1207
1146
  allMoveOps.sort((a, b) => compareOpId(a.id, b.id));
@@ -1210,7 +1149,7 @@ var _RepTree = class _RepTree {
1210
1149
  this.applyMove(op);
1211
1150
  }
1212
1151
  }
1213
- 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)));
1214
1153
  for (let i = 0, len = propertyOps.length; i < len; i++) {
1215
1154
  const op = propertyOps[i];
1216
1155
  this.applyProperty(op);
@@ -1220,10 +1159,10 @@ var _RepTree = class _RepTree {
1220
1159
  if (this.root?.id !== other.root?.id) {
1221
1160
  return false;
1222
1161
  }
1223
- if (!this.rootVertexId) {
1162
+ if (!this.rootNodeId) {
1224
1163
  return true;
1225
1164
  }
1226
- return _RepTree.compareVertices(this.rootVertexId, this, other);
1165
+ return _RepTree.compareNodes(this.rootNodeId, this, other);
1227
1166
  }
1228
1167
  compareMoveOps(other) {
1229
1168
  const movesA = this.moveOps;
@@ -1241,65 +1180,65 @@ var _RepTree = class _RepTree {
1241
1180
  /** Checks if the given `ancestorId` is an ancestor of `childId` in the tree */
1242
1181
  isAncestor(childId, ancestorId) {
1243
1182
  let targetId = childId;
1244
- let vertex;
1245
- const visitedVertices = /* @__PURE__ */ new Set();
1246
- while (vertex = this.state.getVertex(targetId)) {
1247
- if (vertex.parentId === ancestorId) return true;
1248
- if (!vertex.parentId) return false;
1249
- 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)) {
1250
1189
  console.error(`isAncestor: cycle detected in the tree structure.`);
1251
1190
  return false;
1252
1191
  }
1253
- visitedVertices.add(targetId);
1254
- targetId = vertex.parentId;
1192
+ visitedNodes.add(targetId);
1193
+ targetId = node.parentId;
1255
1194
  }
1256
1195
  return false;
1257
1196
  }
1258
- observeVertex(vertexId, callback) {
1259
- const vertex = this.getVertex(vertexId);
1260
- if (vertex) {
1261
- callback(vertex);
1197
+ observeNode(nodeId, callback) {
1198
+ const node = this.getNode(nodeId);
1199
+ if (node) {
1200
+ callback(node);
1262
1201
  }
1263
- const unsubscribe = this.observe(vertexId, (_) => {
1264
- const vertex2 = this.getVertex(vertexId);
1265
- if (vertex2) {
1266
- callback(vertex2);
1202
+ const unsubscribe = this.observe(nodeId, (_) => {
1203
+ const node2 = this.getNode(nodeId);
1204
+ if (node2) {
1205
+ callback(node2);
1267
1206
  }
1268
1207
  });
1269
1208
  return () => {
1270
1209
  unsubscribe();
1271
1210
  };
1272
1211
  }
1273
- observeVertexMove(callback) {
1212
+ observeNodeMove(callback) {
1274
1213
  const listener = (events) => {
1275
1214
  const moveEvent = events.find((e) => e.type === "move");
1276
1215
  if (moveEvent) {
1277
- const vertex = this.getVertex(moveEvent.vertexId);
1278
- if (vertex) {
1279
- callback(vertex, moveEvent.oldParentId === void 0);
1216
+ const node = this.getNode(moveEvent.nodeId);
1217
+ if (node) {
1218
+ callback(node, moveEvent.oldParentId === void 0);
1280
1219
  }
1281
1220
  }
1282
1221
  };
1283
1222
  this.state.addGlobalChangeCallback(listener);
1284
1223
  return () => this.state.removeGlobalChangeCallback(listener);
1285
1224
  }
1286
- observe(vertexId, callback) {
1287
- this.state.addChangeCallback(vertexId, callback);
1288
- return () => this.state.removeChangeCallback(vertexId, callback);
1225
+ observe(nodeId, callback) {
1226
+ this.state.addChangeCallback(nodeId, callback);
1227
+ return () => this.state.removeChangeCallback(nodeId, callback);
1289
1228
  }
1290
1229
  observeOpApplied(callback) {
1291
1230
  this.opAppliedCallbacks.push(callback);
1292
1231
  return () => this.opAppliedCallbacks = this.opAppliedCallbacks.filter((l) => l !== callback);
1293
1232
  }
1294
- static compareVertices(vertexId, treeA, treeB) {
1295
- const childrenA = treeA.state.getChildrenIds(vertexId);
1296
- 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);
1297
1236
  if (childrenA.length !== childrenB.length) {
1298
1237
  return false;
1299
1238
  }
1300
- if (vertexId !== null) {
1301
- const propertiesA = treeA.getVertexProperties(vertexId);
1302
- const propertiesB = treeB.getVertexProperties(vertexId);
1239
+ if (nodeId !== null) {
1240
+ const propertiesA = treeA.getNodeProperties(nodeId);
1241
+ const propertiesB = treeB.getNodeProperties(nodeId);
1303
1242
  if (propertiesA.length !== propertiesB.length) {
1304
1243
  return false;
1305
1244
  }
@@ -1313,39 +1252,44 @@ var _RepTree = class _RepTree {
1313
1252
  if (!childrenB.includes(childId)) {
1314
1253
  return false;
1315
1254
  }
1316
- if (!_RepTree.compareVertices(childId, treeA, treeB)) {
1255
+ if (!_RepTree.compareNodes(childId, treeA, treeB)) {
1317
1256
  return false;
1318
1257
  }
1319
1258
  }
1320
1259
  return true;
1321
1260
  }
1322
- newVertexInternal(vertexId, parentId) {
1323
- this.lamportClock++;
1324
- 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);
1325
1264
  this.localOps.push(op);
1326
1265
  this.applyMove(op);
1327
- this.setVertexProperty(vertexId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1328
- return vertexId;
1266
+ this.setNodeProperty(nodeId, "_c", (/* @__PURE__ */ new Date()).toISOString());
1267
+ return nodeId;
1329
1268
  }
1330
- newVertexInternalWithUUID(parentId) {
1331
- const vertexId = uuid();
1332
- return this.newVertexInternal(vertexId, parentId);
1269
+ newNodeInternalWithUUID(parentId) {
1270
+ const nodeId = uuid();
1271
+ return this.newNodeInternal(nodeId, parentId);
1333
1272
  }
1334
- ensureNullVertex() {
1335
- const vertexId = _RepTree.NULL_VERTEX_ID;
1336
- if (this.state.getVertex(vertexId)) {
1273
+ ensureNullNode() {
1274
+ const nodeId = _RepTree.NULL_NODE_ID;
1275
+ if (this.state.getNode(nodeId)) {
1337
1276
  return;
1338
1277
  }
1339
- this.newVertexInternal(vertexId, null);
1278
+ this.newNodeInternal(nodeId, null);
1340
1279
  }
1341
1280
  /** Updates the lamport clock with the counter value of the operation */
1342
- updateLamportClock(operation) {
1343
- if (operation.id.counter > this.lamportClock) {
1344
- 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;
1345
1289
  }
1346
1290
  }
1347
1291
  applyPendingMovesForParent(parentId) {
1348
- if (!this.state.getVertex(parentId)) {
1292
+ if (!this.state.getNode(parentId)) {
1349
1293
  return;
1350
1294
  }
1351
1295
  const pendingMoves = this.pendingMovesWithMissingParent.get(parentId);
@@ -1358,14 +1302,15 @@ var _RepTree = class _RepTree {
1358
1302
  }
1359
1303
  }
1360
1304
  applyMove(op) {
1361
- if (op.parentId !== null && !this.state.getVertex(op.parentId)) {
1305
+ if (op.parentId !== null && !this.state.getNode(op.parentId)) {
1362
1306
  if (!this.pendingMovesWithMissingParent.has(op.parentId)) {
1363
1307
  this.pendingMovesWithMissingParent.set(op.parentId, []);
1364
1308
  }
1365
1309
  this.pendingMovesWithMissingParent.get(op.parentId).push(op);
1310
+ this.markOpSeen(op, true);
1366
1311
  return;
1367
1312
  }
1368
- this.updateLamportClock(op);
1313
+ this.updateMoveClock(op);
1369
1314
  const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;
1370
1315
  if (lastOp === null || isOpIdGreaterThan(op.id, lastOp.id)) {
1371
1316
  this.moveOps.push(op);
@@ -1392,130 +1337,138 @@ var _RepTree = class _RepTree {
1392
1337
  this.applyPendingMovesForParent(op.targetId);
1393
1338
  }
1394
1339
  setLLWPropertyAndItsOpId(op) {
1395
- this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1340
+ this.propertyOpsByKey.set(`${op.key}@${op.targetId}`, op);
1396
1341
  this.state.setProperty(op.targetId, op.key, op.value);
1397
- this.reportOpAsApplied(op);
1342
+ this.reportOpAsApplied(op, false);
1343
+ this.refreshPropStateVector();
1398
1344
  }
1399
1345
  setTransientPropertyAndItsOpId(op) {
1400
1346
  this.transientPropertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1401
1347
  this.state.setTransientProperty(op.targetId, op.key, op.value);
1402
- this.reportOpAsApplied(op);
1348
+ this.reportOpAsApplied(op, false);
1403
1349
  }
1404
1350
  applyProperty(op) {
1405
- const targetVertex = this.state.getVertex(op.targetId);
1406
- if (!targetVertex) {
1351
+ const targetNode = this.state.getNode(op.targetId);
1352
+ if (!targetNode) {
1407
1353
  if (op.transient) {
1408
1354
  return;
1409
1355
  }
1410
- if (!this.pendingPropertiesWithMissingVertex.has(op.targetId)) {
1411
- this.pendingPropertiesWithMissingVertex.set(op.targetId, []);
1356
+ if (!this.pendingPropertiesWithMissingNode.has(op.targetId)) {
1357
+ this.pendingPropertiesWithMissingNode.set(op.targetId, []);
1412
1358
  }
1413
- this.pendingPropertiesWithMissingVertex.get(op.targetId).push(op);
1359
+ this.pendingPropertiesWithMissingNode.get(op.targetId).push(op);
1360
+ this.markOpSeen(op, false);
1414
1361
  return;
1415
1362
  }
1416
- this.updateLamportClock(op);
1417
- this.applyLLWProperty(op, targetVertex);
1363
+ this.updatePropClock(op);
1364
+ this.applyLLWProperty(op, targetNode);
1418
1365
  }
1419
- applyLLWProperty(op, targetVertex) {
1366
+ applyLLWProperty(op, targetNode) {
1420
1367
  const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1421
- const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1368
+ const prevOpId = this.propertyOpsByKey.get(`${op.key}@${op.targetId}`)?.id;
1422
1369
  if (!op.transient) {
1423
- this.setPropertyOps.push(op);
1424
1370
  if (!prevOpId || isOpIdGreaterThan(op.id, prevOpId)) {
1425
1371
  this.setLLWPropertyAndItsOpId(op);
1426
1372
  } else {
1427
- this.knownOps.add(opIdToString(op.id));
1373
+ this.markOpSeen(op, false);
1428
1374
  }
1429
1375
  if (prevTransientOpId && isOpIdGreaterThan(op.id, prevTransientOpId)) {
1430
1376
  this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);
1431
- targetVertex.removeTransientProperty(op.key);
1377
+ targetNode.removeTransientProperty(op.key);
1432
1378
  }
1433
1379
  } else {
1434
1380
  if (!prevTransientOpId || isOpIdGreaterThan(op.id, prevTransientOpId)) {
1435
1381
  this.setTransientPropertyAndItsOpId(op);
1382
+ } else {
1383
+ this.markOpSeen(op, false);
1436
1384
  }
1437
1385
  }
1438
1386
  }
1439
1387
  applyOperation(op) {
1440
- if (isMoveVertexOp(op)) {
1388
+ if (isMoveNodeOp(op)) {
1441
1389
  this.applyMove(op);
1442
1390
  } else if (isAnyPropertyOp(op)) {
1443
1391
  this.applyProperty(op);
1444
1392
  }
1445
1393
  }
1446
- reportOpAsApplied(op) {
1447
- this.knownOps.add(opIdToString(op.id));
1448
- if (this._stateVectorEnabled) {
1449
- 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
+ }
1450
1402
  }
1403
+ }
1404
+ reportOpAsApplied(op, includeInStateVector = true) {
1405
+ this.markOpSeen(op, includeInStateVector);
1451
1406
  for (const callback of this.opAppliedCallbacks) {
1452
1407
  callback(op);
1453
1408
  }
1454
1409
  }
1455
1410
  tryToMove(op) {
1456
- let targetVertex = this.state.getVertex(op.targetId);
1457
- if (targetVertex) {
1458
- 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);
1459
1414
  }
1460
1415
  if (op.targetId === op.parentId) return;
1461
1416
  if (op.parentId && this.isAncestor(op.parentId, op.targetId)) return;
1462
- this.state.moveVertex(op.targetId, op.parentId);
1463
- if (!targetVertex) {
1464
- const pendingProperties = this.pendingPropertiesWithMissingVertex.get(op.targetId) || [];
1465
- 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);
1466
1421
  for (const prop of pendingProperties) {
1467
1422
  this.applyProperty(prop);
1468
1423
  }
1469
1424
  }
1470
1425
  }
1471
1426
  undoMove(op) {
1472
- const targetVertex = this.state.getVertex(op.targetId);
1473
- if (!targetVertex) {
1474
- 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`);
1475
1430
  return;
1476
1431
  }
1477
1432
  const prevParentId = this.parentIdBeforeMove.get(op.id);
1478
1433
  if (prevParentId === void 0) {
1479
1434
  return;
1480
1435
  }
1481
- this.state.moveVertex(op.targetId, prevParentId);
1436
+ this.state.moveNode(op.targetId, prevParentId);
1482
1437
  }
1483
- // --- Range-Based State Vector Methods ---
1438
+ // --- Range-Based State Vector Methods ---
1484
1439
  /**
1485
- * Returns the current state vector.
1486
- * 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.
1487
1442
  */
1488
- getStateVector() {
1443
+ getStateVectors() {
1489
1444
  if (!this._stateVectorEnabled) {
1490
1445
  return null;
1491
1446
  }
1492
- return this.stateVector.getState();
1447
+ return {
1448
+ move: this.moveStateVector.getState(),
1449
+ prop: this.propStateVector.getState()
1450
+ };
1493
1451
  }
1494
1452
  /**
1495
- * Determines which operations are needed to synchronize
1453
+ * Determines which operations are needed to synchronize
1496
1454
  * with the provided state vector.
1497
- *
1498
- * @param theirStateVector The state vector from another peer
1499
- * @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.
1500
1458
  */
1501
- getMissingOps(theirStateVector) {
1459
+ getMissingOps(theirStateVectors) {
1502
1460
  if (!this._stateVectorEnabled) {
1503
- return [...this.moveOps, ...this.setPropertyOps];
1504
- }
1505
- const otherStateVector = new StateVector(theirStateVector);
1506
- const missingRanges = this.stateVector.diff(otherStateVector);
1507
- const missingOps = [];
1508
- const allOps = [...this.moveOps, ...this.setPropertyOps];
1509
- for (const op of allOps) {
1510
- for (const range of missingRanges) {
1511
- if (op.id.peerId === range.peerId && op.id.counter >= range.start && op.id.counter <= range.end) {
1512
- missingOps.push(op);
1513
- break;
1514
- }
1515
- }
1516
- }
1517
- missingOps.sort((a, b) => compareOpId(a.id, b.id));
1518
- 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];
1519
1472
  }
1520
1473
  /**
1521
1474
  * Gets or sets whether state vector tracking is enabled
@@ -1531,42 +1484,69 @@ var _RepTree = class _RepTree {
1531
1484
  if (value === this._stateVectorEnabled) return;
1532
1485
  if (value) {
1533
1486
  this._stateVectorEnabled = true;
1534
- this.stateVector = StateVector.fromOperations([...this.moveOps, ...this.setPropertyOps]);
1487
+ this.moveStateVector = StateVector.fromOperations(this.moveOps);
1488
+ this.propStateVector = StateVector.fromOperations(this.getPropertyOps());
1535
1489
  } else {
1536
1490
  this._stateVectorEnabled = false;
1537
- this.stateVector = new StateVector();
1491
+ this.moveStateVector = new StateVector();
1492
+ this.propStateVector = new StateVector();
1538
1493
  }
1539
1494
  }
1540
1495
  /**
1541
- * 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)
1542
1497
  */
1543
- parseVertex(vertexId, schema) {
1544
- const propsArray = this.getVertexProperties(vertexId);
1498
+ parseNode(nodeId, schema) {
1499
+ const propsArray = this.getNodeProperties(nodeId);
1545
1500
  const propsObject = {};
1546
1501
  for (const { key, value } of propsArray) {
1547
1502
  propsObject[key] = value;
1548
1503
  }
1549
1504
  return schema.parse(propsObject);
1550
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
+ }
1551
1531
  };
1552
- _RepTree.NULL_VERTEX_ID = "0";
1532
+ _RepTree.NULL_NODE_ID = "0";
1553
1533
  var RepTree = _RepTree;
1554
1534
  export {
1535
+ Node,
1536
+ NodeState,
1555
1537
  RepTree,
1556
1538
  StateVector,
1557
1539
  TreeState,
1558
- Vertex,
1559
- VertexState,
1560
- bindVertex,
1540
+ bindNode,
1561
1541
  compareOpId,
1562
1542
  createOpId,
1563
1543
  equalsOpId,
1564
1544
  isAnyPropertyOp,
1565
- isMoveVertexOp,
1545
+ isMoveNodeOp,
1566
1546
  isOpIdGreaterThan,
1567
- newMoveVertexOp,
1568
- newSetTransientVertexPropertyOp,
1569
- newSetVertexPropertyOp,
1547
+ newMoveNodeOp,
1548
+ newSetNodePropertyOp,
1549
+ newSetTransientNodePropertyOp,
1570
1550
  opIdToString,
1571
1551
  tryParseOpIdStr,
1572
1552
  uuid