reptree 0.4.0 → 0.5.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.d.cts CHANGED
@@ -1,5 +1,3 @@
1
- import * as Y from 'yjs';
2
-
3
1
  interface OpId {
4
2
  readonly counter: number;
5
3
  readonly peerId: string;
@@ -26,18 +24,8 @@ type TreeVertexId = string;
26
24
  /**
27
25
  * Serializable CRDT data for operations
28
26
  */
29
- interface CRDTType {
30
- type: string;
31
- value: Uint8Array;
32
- }
33
- /**
34
- * Property type for state - includes Y.Doc for runtime usage
35
- */
36
- type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined | Y.Doc;
37
- /**
38
- * Property type for operations - includes CRDTType instead of Y.Doc
39
- */
40
- type VertexPropertyTypeInOperation = string | number | boolean | string[] | number[] | boolean[] | undefined | CRDTType;
27
+ /** Property type for state */
28
+ type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined;
41
29
  type TreeVertexProperty = {
42
30
  readonly key: string;
43
31
  readonly value: VertexPropertyType;
@@ -79,17 +67,15 @@ interface SetVertexProperty {
79
67
  id: OpId;
80
68
  targetId: string;
81
69
  key: string;
82
- value: VertexPropertyTypeInOperation;
70
+ value: VertexPropertyType;
83
71
  transient: boolean;
84
72
  }
85
73
  type VertexOperation = MoveVertex | SetVertexProperty;
86
74
  declare function isMoveVertexOp(op: VertexOperation): op is MoveVertex;
87
75
  declare function isAnyPropertyOp(op: VertexOperation): op is SetVertexProperty;
88
- declare function isLWWPropertyOp(op: VertexOperation): op is SetVertexProperty;
89
- declare function isModifyPropertyOp(op: VertexOperation): op is SetVertexProperty;
90
76
  declare function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex;
91
- declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyTypeInOperation): SetVertexProperty;
92
- declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyTypeInOperation): SetVertexProperty;
77
+ declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
78
+ declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
93
79
 
94
80
  type FieldSchemaLike = {
95
81
  safeParse?: (input: unknown) => {
@@ -242,7 +228,6 @@ declare class RepTree {
242
228
  private setPropertyOps;
243
229
  private propertiesAndTheirOpIds;
244
230
  private transientPropertiesAndTheirOpIds;
245
- private yjsObservers;
246
231
  private localOps;
247
232
  private pendingMovesWithMissingParent;
248
233
  private pendingPropertiesWithMissingVertex;
@@ -273,12 +258,23 @@ declare class RepTree {
273
258
  * Can be used to get all operations that were generated from this peer and need to be sent to other peers.
274
259
  */
275
260
  popLocalOps(): VertexOperation[];
261
+ /**
262
+ * This is the first vertex that will contain all other vertices.
263
+ * If you plan to replicate a tree then don't use this method and instead merge
264
+ * in the ops from another tree (that will also contain the root vertex).
265
+ * @returns The root vertex
266
+ */
276
267
  createRoot(): Vertex;
277
268
  newVertex(parentId: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
278
269
  newNamedVertex(parentId: string, name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
279
270
  moveVertex(vertexId: string, parentId: string): void;
280
271
  deleteVertex(vertexId: string): void;
281
272
  setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
273
+ /**
274
+ * Promotes all transient (temporary) properties to persistent properties.
275
+ * @param vertexId - The ID of the vertex to commit transients for.
276
+ * @returns
277
+ */
282
278
  commitTransients(vertexId: string): void;
283
279
  setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
284
280
  setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
@@ -307,10 +303,8 @@ declare class RepTree {
307
303
  private applyMove;
308
304
  private setLLWPropertyAndItsOpId;
309
305
  private setTransientPropertyAndItsOpId;
310
- private setupYjsObserver;
311
306
  private applyProperty;
312
307
  private applyLLWProperty;
313
- private applyModifyProperty;
314
308
  private applyOperation;
315
309
  private reportOpAsApplied;
316
310
  private tryToMove;
@@ -428,4 +422,4 @@ declare class StateVector {
428
422
 
429
423
  declare function uuid(): string;
430
424
 
431
- export { type AliasRule, type BindOptions, type BindedVertex, type CRDTType, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, type VertexPropertyTypeInOperation, VertexState, bindVertex, defaultAliases, isAnyPropertyOp, isLWWPropertyOp, isModifyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
425
+ export { type AliasRule, type BindOptions, type BindedVertex, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, bindVertex, defaultAliases, isAnyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- import * as Y from 'yjs';
2
-
3
1
  interface OpId {
4
2
  readonly counter: number;
5
3
  readonly peerId: string;
@@ -26,18 +24,8 @@ type TreeVertexId = string;
26
24
  /**
27
25
  * Serializable CRDT data for operations
28
26
  */
29
- interface CRDTType {
30
- type: string;
31
- value: Uint8Array;
32
- }
33
- /**
34
- * Property type for state - includes Y.Doc for runtime usage
35
- */
36
- type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined | Y.Doc;
37
- /**
38
- * Property type for operations - includes CRDTType instead of Y.Doc
39
- */
40
- type VertexPropertyTypeInOperation = string | number | boolean | string[] | number[] | boolean[] | undefined | CRDTType;
27
+ /** Property type for state */
28
+ type VertexPropertyType = string | number | boolean | string[] | number[] | boolean[] | undefined;
41
29
  type TreeVertexProperty = {
42
30
  readonly key: string;
43
31
  readonly value: VertexPropertyType;
@@ -79,17 +67,15 @@ interface SetVertexProperty {
79
67
  id: OpId;
80
68
  targetId: string;
81
69
  key: string;
82
- value: VertexPropertyTypeInOperation;
70
+ value: VertexPropertyType;
83
71
  transient: boolean;
84
72
  }
85
73
  type VertexOperation = MoveVertex | SetVertexProperty;
86
74
  declare function isMoveVertexOp(op: VertexOperation): op is MoveVertex;
87
75
  declare function isAnyPropertyOp(op: VertexOperation): op is SetVertexProperty;
88
- declare function isLWWPropertyOp(op: VertexOperation): op is SetVertexProperty;
89
- declare function isModifyPropertyOp(op: VertexOperation): op is SetVertexProperty;
90
76
  declare function newMoveVertexOp(clock: number, peerId: string, targetId: string, parentId: string | null): MoveVertex;
91
- declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyTypeInOperation): SetVertexProperty;
92
- declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyTypeInOperation): SetVertexProperty;
77
+ declare function newSetVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
78
+ declare function newSetTransientVertexPropertyOp(clock: number, peerId: string, targetId: string, key: string, value: VertexPropertyType): SetVertexProperty;
93
79
 
94
80
  type FieldSchemaLike = {
95
81
  safeParse?: (input: unknown) => {
@@ -242,7 +228,6 @@ declare class RepTree {
242
228
  private setPropertyOps;
243
229
  private propertiesAndTheirOpIds;
244
230
  private transientPropertiesAndTheirOpIds;
245
- private yjsObservers;
246
231
  private localOps;
247
232
  private pendingMovesWithMissingParent;
248
233
  private pendingPropertiesWithMissingVertex;
@@ -273,12 +258,23 @@ declare class RepTree {
273
258
  * Can be used to get all operations that were generated from this peer and need to be sent to other peers.
274
259
  */
275
260
  popLocalOps(): VertexOperation[];
261
+ /**
262
+ * This is the first vertex that will contain all other vertices.
263
+ * If you plan to replicate a tree then don't use this method and instead merge
264
+ * in the ops from another tree (that will also contain the root vertex).
265
+ * @returns The root vertex
266
+ */
276
267
  createRoot(): Vertex;
277
268
  newVertex(parentId: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
278
269
  newNamedVertex(parentId: string, name: string, props?: Record<string, VertexPropertyType> | object | null): Vertex;
279
270
  moveVertex(vertexId: string, parentId: string): void;
280
271
  deleteVertex(vertexId: string): void;
281
272
  setTransientVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
273
+ /**
274
+ * Promotes all transient (temporary) properties to persistent properties.
275
+ * @param vertexId - The ID of the vertex to commit transients for.
276
+ * @returns
277
+ */
282
278
  commitTransients(vertexId: string): void;
283
279
  setVertexProperty(vertexId: string, key: string, value: VertexPropertyType): void;
284
280
  setVertexProperties(vertexId: string, props: Record<string, VertexPropertyType> | object): void;
@@ -307,10 +303,8 @@ declare class RepTree {
307
303
  private applyMove;
308
304
  private setLLWPropertyAndItsOpId;
309
305
  private setTransientPropertyAndItsOpId;
310
- private setupYjsObserver;
311
306
  private applyProperty;
312
307
  private applyLLWProperty;
313
- private applyModifyProperty;
314
308
  private applyOperation;
315
309
  private reportOpAsApplied;
316
310
  private tryToMove;
@@ -428,4 +422,4 @@ declare class StateVector {
428
422
 
429
423
  declare function uuid(): string;
430
424
 
431
- export { type AliasRule, type BindOptions, type BindedVertex, type CRDTType, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, type VertexPropertyTypeInOperation, VertexState, bindVertex, defaultAliases, isAnyPropertyOp, isLWWPropertyOp, isModifyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
425
+ export { type AliasRule, type BindOptions, type BindedVertex, type MoveVertex, type OpId, type OpIdRange, RepTree, type SchemaLike, type SetVertexProperty, StateVector, TreeState, type TreeVertexId, type TreeVertexProperty, Vertex, type VertexChangeEvent, type VertexChildrenChangeEvent, type VertexMoveEvent, type VertexOperation, type VertexPropertyChangeEvent, type VertexPropertyType, VertexState, bindVertex, defaultAliases, isAnyPropertyOp, isMoveVertexOp, newMoveVertexOp, newSetTransientVertexPropertyOp, newSetVertexPropertyOp, uuid };
package/dist/index.js CHANGED
@@ -52,12 +52,6 @@ function isMoveVertexOp(op) {
52
52
  function isAnyPropertyOp(op) {
53
53
  return "key" in op;
54
54
  }
55
- function isLWWPropertyOp(op) {
56
- return "key" in op && "value" in op && (!op.value || typeof op.value !== "object" || !("type" in op.value));
57
- }
58
- function isModifyPropertyOp(op) {
59
- return "key" in op && "value" in op && typeof op.value === "object" && op.value !== null && "type" in op.value;
60
- }
61
55
  function newMoveVertexOp(clock, peerId, targetId, parentId) {
62
56
  return { id: createOpId(clock, peerId), targetId, parentId };
63
57
  }
@@ -500,7 +494,6 @@ function bindVertex(tree, id, schemaOrOptions) {
500
494
  }
501
495
 
502
496
  // src/Vertex.ts
503
- import * as Y from "yjs";
504
497
  var Vertex = class _Vertex {
505
498
  constructor(tree, state) {
506
499
  this.tree = tree;
@@ -674,10 +667,8 @@ var Vertex = class _Vertex {
674
667
  continue;
675
668
  }
676
669
  } else if (typeof value === "object" && value !== null) {
677
- if (!(value instanceof Y.Doc)) {
678
- skipped.push(rawKey);
679
- continue;
680
- }
670
+ skipped.push(rawKey);
671
+ continue;
681
672
  } else if (!isPrimitive(value)) {
682
673
  skipped.push(rawKey);
683
674
  continue;
@@ -877,7 +868,6 @@ var StateVector = class _StateVector {
877
868
  };
878
869
 
879
870
  // src/RepTree.ts
880
- import * as Y2 from "yjs";
881
871
  var _RepTree = class _RepTree {
882
872
  /**
883
873
  * @param peerId - The peer ID of the current client. Should be unique across all peers.
@@ -889,7 +879,7 @@ var _RepTree = class _RepTree {
889
879
  this.setPropertyOps = [];
890
880
  this.propertiesAndTheirOpIds = /* @__PURE__ */ new Map();
891
881
  this.transientPropertiesAndTheirOpIds = /* @__PURE__ */ new Map();
892
- this.yjsObservers = /* @__PURE__ */ new Map();
882
+ // Observers for non-structural properties are not used
893
883
  this.localOps = [];
894
884
  this.pendingMovesWithMissingParent = /* @__PURE__ */ new Map();
895
885
  this.pendingPropertiesWithMissingVertex = /* @__PURE__ */ new Map();
@@ -991,6 +981,12 @@ var _RepTree = class _RepTree {
991
981
  this.localOps = [];
992
982
  return ops;
993
983
  }
984
+ /**
985
+ * This is the first vertex that will contain all other vertices.
986
+ * 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
989
+ */
994
990
  createRoot() {
995
991
  if (this.rootVertexId) {
996
992
  throw new Error("Root vertex already exists");
@@ -1038,21 +1034,15 @@ var _RepTree = class _RepTree {
1038
1034
  }
1039
1035
  setTransientVertexProperty(vertexId, key, value) {
1040
1036
  this.lamportClock++;
1041
- let opValue;
1042
- if (value instanceof Y2.Doc) {
1043
- const state = Y2.encodeStateAsUpdate(value);
1044
- opValue = {
1045
- type: "yjs",
1046
- value: state
1047
- };
1048
- this.setupYjsObserver(value, vertexId, key);
1049
- } else {
1050
- opValue = value;
1051
- }
1052
- const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, opValue);
1037
+ const op = newSetTransientVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1053
1038
  this.localOps.push(op);
1054
1039
  this.applyProperty(op);
1055
1040
  }
1041
+ /**
1042
+ * Promotes all transient (temporary) properties to persistent properties.
1043
+ * @param vertexId - The ID of the vertex to commit transients for.
1044
+ * @returns
1045
+ */
1056
1046
  commitTransients(vertexId) {
1057
1047
  const vertex = this.state.getVertex(vertexId);
1058
1048
  if (!vertex) {
@@ -1069,18 +1059,7 @@ var _RepTree = class _RepTree {
1069
1059
  }
1070
1060
  setVertexProperty(vertexId, key, value) {
1071
1061
  this.lamportClock++;
1072
- let opValue;
1073
- if (value instanceof Y2.Doc) {
1074
- const state = Y2.encodeStateAsUpdate(value);
1075
- opValue = {
1076
- type: "yjs",
1077
- value: state
1078
- };
1079
- this.setupYjsObserver(value, vertexId, key);
1080
- } else {
1081
- opValue = value;
1082
- }
1083
- const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, opValue);
1062
+ const op = newSetVertexPropertyOp(this.lamportClock, this.peerId, vertexId, key, value);
1084
1063
  this.localOps.push(op);
1085
1064
  this.applyProperty(op);
1086
1065
  }
@@ -1243,13 +1222,7 @@ var _RepTree = class _RepTree {
1243
1222
  if (!propB) {
1244
1223
  return false;
1245
1224
  }
1246
- if (propA.value instanceof Y2.Doc && propB.value instanceof Y2.Doc) {
1247
- const snapshotA = Y2.snapshot(propA.value);
1248
- const snapshotB = Y2.snapshot(propB.value);
1249
- if (!Y2.equalSnapshots(snapshotA, snapshotB)) {
1250
- return false;
1251
- }
1252
- } else if (propA.value !== propB.value) {
1225
+ if (propA.value !== propB.value) {
1253
1226
  return false;
1254
1227
  }
1255
1228
  }
@@ -1346,40 +1319,6 @@ var _RepTree = class _RepTree {
1346
1319
  this.state.setTransientProperty(op.targetId, op.key, op.value);
1347
1320
  this.reportOpAsApplied(op);
1348
1321
  }
1349
- setupYjsObserver(doc, vertexId, key) {
1350
- const propertyKey = `${key}@${vertexId}`;
1351
- if (this.yjsObservers.has(propertyKey)) {
1352
- const existingDoc = this.getVertexProperty(vertexId, key);
1353
- if (existingDoc instanceof Y2.Doc) {
1354
- existingDoc.off("update", this.yjsObservers.get(propertyKey));
1355
- }
1356
- this.yjsObservers.delete(propertyKey);
1357
- }
1358
- const ydocObserver = (update, origin, doc2, transaction) => {
1359
- if (!transaction.local) {
1360
- return;
1361
- }
1362
- const crdtValue = {
1363
- type: "yjs",
1364
- value: update
1365
- };
1366
- this.lamportClock++;
1367
- const op = newSetVertexPropertyOp(
1368
- this.lamportClock,
1369
- this.peerId,
1370
- vertexId,
1371
- key,
1372
- crdtValue
1373
- );
1374
- this.localOps.push(op);
1375
- this.applyProperty(op);
1376
- if (this._stateVectorEnabled) {
1377
- this.stateVector.updateFromOp(op);
1378
- }
1379
- };
1380
- doc.on("update", ydocObserver);
1381
- this.yjsObservers.set(propertyKey, ydocObserver);
1382
- }
1383
1322
  applyProperty(op) {
1384
1323
  const targetVertex = this.state.getVertex(op.targetId);
1385
1324
  if (!targetVertex) {
@@ -1393,11 +1332,7 @@ var _RepTree = class _RepTree {
1393
1332
  return;
1394
1333
  }
1395
1334
  this.updateLamportClock(op);
1396
- if (isModifyPropertyOp(op)) {
1397
- this.applyModifyProperty(op, targetVertex);
1398
- } else {
1399
- this.applyLLWProperty(op, targetVertex);
1400
- }
1335
+ this.applyLLWProperty(op, targetVertex);
1401
1336
  }
1402
1337
  applyLLWProperty(op, targetVertex) {
1403
1338
  const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
@@ -1419,28 +1354,7 @@ var _RepTree = class _RepTree {
1419
1354
  }
1420
1355
  }
1421
1356
  }
1422
- applyModifyProperty(op, targetVertex) {
1423
- if (op.transient) {
1424
- console.warn("Not implemented: transient non LWW property");
1425
- return;
1426
- }
1427
- this.setPropertyOps.push(op);
1428
- const crdtValue = op.value;
1429
- if (crdtValue.type !== "yjs") {
1430
- throw new Error("Unknown CRDT type");
1431
- }
1432
- const ydoc = targetVertex.getProperty(op.key);
1433
- if (ydoc instanceof Y2.Doc) {
1434
- Y2.applyUpdate(ydoc, crdtValue.value);
1435
- } else {
1436
- const newDoc = new Y2.Doc();
1437
- this.setupYjsObserver(newDoc, op.targetId, op.key);
1438
- this.state.setProperty(op.targetId, op.key, newDoc);
1439
- Y2.applyUpdate(newDoc, crdtValue.value);
1440
- }
1441
- this.propertiesAndTheirOpIds.set(`${op.key}@${op.targetId}`, op.id);
1442
- this.reportOpAsApplied(op);
1443
- }
1357
+ // Non-LWW modify-property flow removed
1444
1358
  applyOperation(op) {
1445
1359
  if (isMoveVertexOp(op)) {
1446
1360
  this.applyMove(op);
@@ -1565,8 +1479,6 @@ export {
1565
1479
  bindVertex,
1566
1480
  defaultAliases,
1567
1481
  isAnyPropertyOp,
1568
- isLWWPropertyOp,
1569
- isModifyPropertyOp,
1570
1482
  isMoveVertexOp,
1571
1483
  newMoveVertexOp,
1572
1484
  newSetTransientVertexPropertyOp,