reptree 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- OpId: () => OpId,
34
33
  RepTree: () => RepTree,
35
34
  StateVector: () => StateVector,
36
35
  TreeState: () => TreeState,
@@ -48,54 +47,51 @@ __export(index_exports, {
48
47
  module.exports = __toCommonJS(index_exports);
49
48
 
50
49
  // src/OpId.ts
51
- var OpId = class _OpId {
52
- constructor(counter, peerId) {
53
- this.counter = counter;
54
- this.peerId = peerId;
55
- }
56
- static compare(opIdA, opIdB) {
57
- if (!(opIdA instanceof _OpId)) {
58
- const parsedA = _OpId.tryParseStr(opIdA);
59
- if (!parsedA) throw new Error(`Invalid OpId string: ${opIdA}`);
60
- opIdA = parsedA;
61
- }
62
- if (!(opIdB instanceof _OpId)) {
63
- const parsedB = _OpId.tryParseStr(opIdB);
64
- if (!parsedB) throw new Error(`Invalid OpId string: ${opIdB}`);
65
- opIdB = parsedB;
66
- }
67
- const counterA = opIdA.counter;
68
- const counterB = opIdB.counter;
69
- if (counterA > counterB) {
70
- return 1;
71
- } else if (counterA < counterB) {
72
- return -1;
73
- } else {
74
- return opIdA.peerId.localeCompare(opIdB.peerId);
75
- }
76
- }
77
- static equals(opIdA, opIdB) {
78
- if (opIdA === opIdB) {
79
- return true;
80
- } else if (!opIdA || !opIdB) {
81
- return false;
82
- }
83
- return _OpId.compare(opIdA, opIdB) === 0;
84
- }
85
- static tryParseStr(opIdStr) {
86
- const parts = opIdStr.split("@");
87
- if (parts.length !== 2) {
88
- throw new Error(`Invalid OpId string: ${opIdStr}`);
89
- }
90
- return new _OpId(parseInt(parts[0], 10), parts[1]);
50
+ function createOpId(counter, peerId) {
51
+ return { counter, peerId };
52
+ }
53
+ function compareOpId(opIdA, opIdB) {
54
+ if (typeof opIdA === "string") {
55
+ const parsedA = tryParseOpIdStr(opIdA);
56
+ if (!parsedA) throw new Error(`Invalid OpId string: ${opIdA}`);
57
+ opIdA = parsedA;
58
+ }
59
+ if (typeof opIdB === "string") {
60
+ const parsedB = tryParseOpIdStr(opIdB);
61
+ if (!parsedB) throw new Error(`Invalid OpId string: ${opIdB}`);
62
+ opIdB = parsedB;
63
+ }
64
+ const counterA = opIdA.counter;
65
+ const counterB = opIdB.counter;
66
+ if (counterA > counterB) {
67
+ return 1;
68
+ } else if (counterA < counterB) {
69
+ return -1;
70
+ } else {
71
+ return opIdA.peerId.localeCompare(opIdB.peerId);
91
72
  }
92
- isGreaterThan(opId) {
93
- return _OpId.compare(this, opId) === 1;
73
+ }
74
+ function equalsOpId(opIdA, opIdB) {
75
+ if (opIdA === opIdB) {
76
+ return true;
77
+ } else if (!opIdA || !opIdB) {
78
+ return false;
94
79
  }
95
- toString() {
96
- return `${this.counter}@${this.peerId}`;
80
+ return compareOpId(opIdA, opIdB) === 0;
81
+ }
82
+ function tryParseOpIdStr(opIdStr) {
83
+ const parts = opIdStr.split("@");
84
+ if (parts.length !== 2) {
85
+ throw new Error(`Invalid OpId string: ${opIdStr}`);
97
86
  }
98
- };
87
+ return createOpId(parseInt(parts[0], 10), parts[1]);
88
+ }
89
+ function isOpIdGreaterThan(opIdA, opIdB) {
90
+ return compareOpId(opIdA, opIdB) === 1;
91
+ }
92
+ function opIdToString(opId) {
93
+ return `${opId.counter}@${opId.peerId}`;
94
+ }
99
95
 
100
96
  // src/operations.ts
101
97
  function isMoveVertexOp(op) {
@@ -111,13 +107,13 @@ function isModifyPropertyOp(op) {
111
107
  return "key" in op && "value" in op && typeof op.value === "object" && op.value !== null && "type" in op.value;
112
108
  }
113
109
  function newMoveVertexOp(clock, peerId, targetId, parentId) {
114
- return { id: new OpId(clock, peerId), targetId, parentId };
110
+ return { id: createOpId(clock, peerId), targetId, parentId };
115
111
  }
116
112
  function newSetVertexPropertyOp(clock, peerId, targetId, key, value) {
117
- return { id: new OpId(clock, peerId), targetId, key, value, transient: false };
113
+ return { id: createOpId(clock, peerId), targetId, key, value, transient: false };
118
114
  }
119
115
  function newSetTransientVertexPropertyOp(clock, peerId, targetId, key, value) {
120
- return { id: new OpId(clock, peerId), targetId, key, value, transient: true };
116
+ return { id: createOpId(clock, peerId), targetId, key, value, transient: true };
121
117
  }
122
118
 
123
119
  // src/VertexState.ts
@@ -949,7 +945,7 @@ var _RepTree = class _RepTree {
949
945
  }
950
946
  applyOps(ops) {
951
947
  for (const op of ops) {
952
- if (this.knownOps.has(op.id.toString())) {
948
+ if (this.knownOps.has(opIdToString(op.id))) {
953
949
  continue;
954
950
  }
955
951
  this.applyOperation(op);
@@ -957,16 +953,16 @@ var _RepTree = class _RepTree {
957
953
  }
958
954
  /** Applies operations in an optimized way, sorting move ops by OpId to avoid undo-do-redo cycles */
959
955
  applyOpsOptimizedForLotsOfMoves(ops) {
960
- const newMoveOps = ops.filter((op) => isMoveVertexOp(op) && !this.knownOps.has(op.id.toString()));
956
+ const newMoveOps = ops.filter((op) => isMoveVertexOp(op) && !this.knownOps.has(opIdToString(op.id)));
961
957
  if (newMoveOps.length > 0) {
962
958
  const allMoveOps = [...this.moveOps, ...newMoveOps];
963
- allMoveOps.sort((a, b) => OpId.compare(a.id, b.id));
959
+ allMoveOps.sort((a, b) => compareOpId(a.id, b.id));
964
960
  for (let i = 0, len = allMoveOps.length; i < len; i++) {
965
961
  const op = allMoveOps[i];
966
962
  this.applyMove(op);
967
963
  }
968
964
  }
969
- const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(op.id.toString()));
965
+ const propertyOps = ops.filter((op) => isAnyPropertyOp(op) && !this.knownOps.has(opIdToString(op.id)));
970
966
  for (let i = 0, len = propertyOps.length; i < len; i++) {
971
967
  const op = propertyOps[i];
972
968
  this.applyProperty(op);
@@ -988,7 +984,7 @@ var _RepTree = class _RepTree {
988
984
  return false;
989
985
  }
990
986
  for (let i = 0; i < movesA.length; i++) {
991
- if (!OpId.equals(movesA[i].id, movesB[i].id)) {
987
+ if (!equalsOpId(movesA[i].id, movesB[i].id)) {
992
988
  return false;
993
989
  }
994
990
  }
@@ -1133,7 +1129,7 @@ var _RepTree = class _RepTree {
1133
1129
  }
1134
1130
  this.updateLamportClock(op);
1135
1131
  const lastOp = this.moveOps.length > 0 ? this.moveOps[this.moveOps.length - 1] : null;
1136
- if (lastOp === null || op.id.isGreaterThan(lastOp.id)) {
1132
+ if (lastOp === null || isOpIdGreaterThan(op.id, lastOp.id)) {
1137
1133
  this.moveOps.push(op);
1138
1134
  this.reportOpAsApplied(op);
1139
1135
  this.tryToMove(op);
@@ -1142,7 +1138,7 @@ var _RepTree = class _RepTree {
1142
1138
  for (let i = this.moveOps.length - 1; i >= 0; i--) {
1143
1139
  const moveOp = this.moveOps[i];
1144
1140
  targetIndex = i;
1145
- if (op.id.isGreaterThan(moveOp.id)) {
1141
+ if (isOpIdGreaterThan(op.id, moveOp.id)) {
1146
1142
  break;
1147
1143
  } else {
1148
1144
  this.undoMove(moveOp);
@@ -1222,21 +1218,20 @@ var _RepTree = class _RepTree {
1222
1218
  }
1223
1219
  applyLLWProperty(op, targetVertex) {
1224
1220
  const prevTransientOpId = this.transientPropertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1225
- const prevProp = targetVertex.getProperty(op.key);
1226
1221
  const prevOpId = this.propertiesAndTheirOpIds.get(`${op.key}@${op.targetId}`);
1227
1222
  if (!op.transient) {
1228
1223
  this.setPropertyOps.push(op);
1229
- if (!prevProp || !prevOpId || op.id.isGreaterThan(prevOpId)) {
1224
+ if (!prevOpId || isOpIdGreaterThan(op.id, prevOpId)) {
1230
1225
  this.setLLWPropertyAndItsOpId(op);
1231
1226
  } else {
1232
- this.knownOps.add(op.id.toString());
1227
+ this.knownOps.add(opIdToString(op.id));
1233
1228
  }
1234
- if (prevTransientOpId && op.id.isGreaterThan(prevTransientOpId)) {
1229
+ if (prevTransientOpId && isOpIdGreaterThan(op.id, prevTransientOpId)) {
1235
1230
  this.transientPropertiesAndTheirOpIds.delete(`${op.key}@${op.targetId}`);
1236
1231
  targetVertex.removeTransientProperty(op.key);
1237
1232
  }
1238
1233
  } else {
1239
- if (!prevTransientOpId || op.id.isGreaterThan(prevTransientOpId)) {
1234
+ if (!prevTransientOpId || isOpIdGreaterThan(op.id, prevTransientOpId)) {
1240
1235
  this.setTransientPropertyAndItsOpId(op);
1241
1236
  }
1242
1237
  }
@@ -1271,7 +1266,7 @@ var _RepTree = class _RepTree {
1271
1266
  }
1272
1267
  }
1273
1268
  reportOpAsApplied(op) {
1274
- this.knownOps.add(op.id.toString());
1269
+ this.knownOps.add(opIdToString(op.id));
1275
1270
  if (this._stateVectorEnabled) {
1276
1271
  this.stateVector.updateFromOp(op);
1277
1272
  }
@@ -1298,7 +1293,7 @@ var _RepTree = class _RepTree {
1298
1293
  undoMove(op) {
1299
1294
  const targetVertex = this.state.getVertex(op.targetId);
1300
1295
  if (!targetVertex) {
1301
- console.error(`An attempt to undo move operation ${op.id.toString()} failed because the target vertex ${op.targetId} not found`);
1296
+ console.error(`An attempt to undo move operation ${opIdToString(op.id)} failed because the target vertex ${op.targetId} not found`);
1302
1297
  return;
1303
1298
  }
1304
1299
  const prevParentId = this.parentIdBeforeMove.get(op.id);
@@ -1341,7 +1336,7 @@ var _RepTree = class _RepTree {
1341
1336
  }
1342
1337
  }
1343
1338
  }
1344
- missingOps.sort((a, b) => OpId.compare(a.id, b.id));
1339
+ missingOps.sort((a, b) => compareOpId(a.id, b.id));
1345
1340
  return missingOps;
1346
1341
  }
1347
1342
  /**
@@ -1369,7 +1364,6 @@ _RepTree.NULL_VERTEX_ID = "0";
1369
1364
  var RepTree = _RepTree;
1370
1365
  // Annotate the CommonJS export names for ESM import in node:
1371
1366
  0 && (module.exports = {
1372
- OpId,
1373
1367
  RepTree,
1374
1368
  StateVector,
1375
1369
  TreeState,