@fluidframework/merge-tree 2.4.0-294316 → 2.4.0-297027
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/api-report/merge-tree.legacy.alpha.api.md +26 -5
- package/dist/attributionPolicy.d.ts.map +1 -1
- package/dist/attributionPolicy.js +10 -3
- package/dist/attributionPolicy.js.map +1 -1
- package/dist/client.d.ts +14 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +97 -9
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/mergeTree.d.ts +15 -1
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +65 -19
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +6 -0
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +2 -1
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/opBuilder.d.ts +15 -1
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js +28 -1
- package/dist/opBuilder.js.map +1 -1
- package/dist/ops.d.ts +27 -1
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js +1 -0
- package/dist/ops.js.map +1 -1
- package/dist/sequencePlace.d.ts +4 -0
- package/dist/sequencePlace.d.ts.map +1 -1
- package/dist/sequencePlace.js +17 -1
- package/dist/sequencePlace.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +18 -0
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.rangeExpansion.spec.js +109 -53
- package/dist/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +2 -2
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/reconnectHelper.d.ts +8 -6
- package/dist/test/reconnectHelper.d.ts.map +1 -1
- package/dist/test/reconnectHelper.js +14 -13
- package/dist/test/reconnectHelper.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +19 -8
- package/dist/test/testClientLogger.js.map +1 -1
- package/lib/attributionPolicy.d.ts.map +1 -1
- package/lib/attributionPolicy.js +10 -3
- package/lib/attributionPolicy.js.map +1 -1
- package/lib/client.d.ts +14 -4
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +98 -10
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/mergeTree.d.ts +15 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +65 -19
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +6 -0
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +2 -1
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/opBuilder.d.ts +15 -1
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js +26 -0
- package/lib/opBuilder.js.map +1 -1
- package/lib/ops.d.ts +27 -1
- package/lib/ops.d.ts.map +1 -1
- package/lib/ops.js +1 -0
- package/lib/ops.js.map +1 -1
- package/lib/sequencePlace.d.ts +4 -0
- package/lib/sequencePlace.d.ts.map +1 -1
- package/lib/sequencePlace.js +15 -0
- package/lib/sequencePlace.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +18 -0
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.rangeExpansion.spec.js +109 -53
- package/lib/test/obliterate.rangeExpansion.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +2 -2
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/reconnectHelper.d.ts +8 -6
- package/lib/test/reconnectHelper.d.ts.map +1 -1
- package/lib/test/reconnectHelper.js +15 -14
- package/lib/test/reconnectHelper.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +19 -8
- package/lib/test/testClientLogger.js.map +1 -1
- package/package.json +29 -16
- package/src/attributionPolicy.ts +5 -0
- package/src/client.ts +136 -21
- package/src/index.ts +1 -0
- package/src/mergeTree.ts +108 -22
- package/src/mergeTreeNodes.ts +9 -1
- package/src/opBuilder.ts +32 -0
- package/src/ops.ts +23 -1
- package/src/sequencePlace.ts +16 -0
package/dist/mergeTree.js
CHANGED
|
@@ -24,6 +24,7 @@ const properties_js_1 = require("./properties.js");
|
|
|
24
24
|
const referencePositions_js_1 = require("./referencePositions.js");
|
|
25
25
|
// eslint-disable-next-line import/no-deprecated
|
|
26
26
|
const segmentPropertiesManager_js_1 = require("./segmentPropertiesManager.js");
|
|
27
|
+
const sequencePlace_js_1 = require("./sequencePlace.js");
|
|
27
28
|
const sortedSegmentSet_js_1 = require("./sortedSegmentSet.js");
|
|
28
29
|
const zamboni_js_1 = require("./zamboni.js");
|
|
29
30
|
function markSegmentMoved(seg, moveInfo) {
|
|
@@ -764,13 +765,15 @@ class MergeTree {
|
|
|
764
765
|
segment: pendingSegment,
|
|
765
766
|
});
|
|
766
767
|
});
|
|
767
|
-
if (opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE
|
|
768
|
+
if (opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE ||
|
|
769
|
+
opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE_SIDED) {
|
|
768
770
|
this.obliterates.addOrUpdate(pendingSegmentGroup.obliterateInfo);
|
|
769
771
|
}
|
|
770
772
|
// Perform slides after all segments have been acked, so that
|
|
771
773
|
// positions after slide are final
|
|
772
774
|
if (opArgs.op.type === ops_js_1.MergeTreeDeltaType.REMOVE ||
|
|
773
|
-
opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE
|
|
775
|
+
opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE ||
|
|
776
|
+
opArgs.op.type === ops_js_1.MergeTreeDeltaType.OBLITERATE_SIDED) {
|
|
774
777
|
this.slideAckedRemovedSegmentReferences(pendingSegmentGroup.segments);
|
|
775
778
|
}
|
|
776
779
|
this.mergeTreeMaintenanceCallback?.({
|
|
@@ -970,9 +973,9 @@ class MergeTree {
|
|
|
970
973
|
});
|
|
971
974
|
}
|
|
972
975
|
this.updateRoot(splitNode);
|
|
973
|
-
saveIfLocal(newSegment);
|
|
974
976
|
insertPos += newSegment.cachedLength;
|
|
975
977
|
if (!this.options?.mergeTreeEnableObliterate || this.obliterates.empty()) {
|
|
978
|
+
saveIfLocal(newSegment);
|
|
976
979
|
continue;
|
|
977
980
|
}
|
|
978
981
|
// eslint-disable-next-line import/no-deprecated
|
|
@@ -999,13 +1002,13 @@ class MergeTree {
|
|
|
999
1002
|
movedSeqs.unshift(ob.seq);
|
|
1000
1003
|
}
|
|
1001
1004
|
else {
|
|
1002
|
-
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1003
|
-
normalizedNewestSeq = normalizedObSeq;
|
|
1004
|
-
newest = ob;
|
|
1005
|
-
}
|
|
1006
1005
|
movedClientIds.push(ob.clientId);
|
|
1007
1006
|
movedSeqs.push(ob.seq);
|
|
1008
1007
|
}
|
|
1008
|
+
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1009
|
+
normalizedNewestSeq = normalizedObSeq;
|
|
1010
|
+
newest = ob;
|
|
1011
|
+
}
|
|
1009
1012
|
}
|
|
1010
1013
|
}
|
|
1011
1014
|
if (oldest && newest?.clientId !== clientId) {
|
|
@@ -1025,6 +1028,10 @@ class MergeTree {
|
|
|
1025
1028
|
this.blockUpdatePathLengths(newSegment.parent, seq, clientId);
|
|
1026
1029
|
}
|
|
1027
1030
|
}
|
|
1031
|
+
else if (oldest && newest?.clientId === clientId) {
|
|
1032
|
+
newSegment.prevObliterateByInserter = newest;
|
|
1033
|
+
}
|
|
1034
|
+
saveIfLocal(newSegment);
|
|
1028
1035
|
}
|
|
1029
1036
|
}
|
|
1030
1037
|
}
|
|
@@ -1231,10 +1238,11 @@ class MergeTree {
|
|
|
1231
1238
|
(0, zamboni_js_1.zamboniSegments)(this);
|
|
1232
1239
|
}
|
|
1233
1240
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
this.ensureIntervalBoundary(
|
|
1241
|
+
obliterateRangeSided(start, end, refSeq, clientId, seq, overwrite = false, opArgs) {
|
|
1242
|
+
const startPos = start.side === sequencePlace_js_1.Side.Before ? start.pos : start.pos + 1;
|
|
1243
|
+
const endPos = end.side === sequencePlace_js_1.Side.Before ? end.pos : end.pos + 1;
|
|
1244
|
+
this.ensureIntervalBoundary(startPos, refSeq, clientId);
|
|
1245
|
+
this.ensureIntervalBoundary(endPos, refSeq, clientId);
|
|
1238
1246
|
let _overwrite = overwrite;
|
|
1239
1247
|
const localOverlapWithRefs = [];
|
|
1240
1248
|
const movedSegments = [];
|
|
@@ -1249,18 +1257,46 @@ class MergeTree {
|
|
|
1249
1257
|
localSeq,
|
|
1250
1258
|
segmentGroup: undefined,
|
|
1251
1259
|
};
|
|
1252
|
-
const { segment: startSeg } = this.getContainingSegment(start, refSeq, clientId);
|
|
1253
|
-
const { segment: endSeg } = this.getContainingSegment(end
|
|
1260
|
+
const { segment: startSeg } = this.getContainingSegment(start.pos, refSeq, clientId);
|
|
1261
|
+
const { segment: endSeg } = this.getContainingSegment(end.pos, refSeq, clientId);
|
|
1254
1262
|
(0, internal_1.assert)(startSeg !== undefined && endSeg !== undefined, 0xa3f /* segments cannot be undefined */);
|
|
1255
|
-
obliterate.start = this.createLocalReferencePosition(startSeg, 0, ops_js_1.ReferenceType.StayOnRemove, {
|
|
1263
|
+
obliterate.start = this.createLocalReferencePosition(startSeg, start.side === sequencePlace_js_1.Side.Before ? 0 : Math.max(startSeg.cachedLength - 1, 0), ops_js_1.ReferenceType.StayOnRemove, {
|
|
1256
1264
|
obliterate,
|
|
1257
1265
|
});
|
|
1258
|
-
obliterate.end = this.createLocalReferencePosition(endSeg, endSeg.cachedLength - 1, ops_js_1.ReferenceType.StayOnRemove, {
|
|
1266
|
+
obliterate.end = this.createLocalReferencePosition(endSeg, end.side === sequencePlace_js_1.Side.Before ? 0 : Math.max(endSeg.cachedLength - 1, 0), ops_js_1.ReferenceType.StayOnRemove, {
|
|
1259
1267
|
obliterate,
|
|
1260
1268
|
});
|
|
1269
|
+
// Always create a segment group for obliterate,
|
|
1270
|
+
// even if there are no segments currently in the obliteration range.
|
|
1271
|
+
// Segments may be concurrently inserted into the obliteration range,
|
|
1272
|
+
// at which point they are added to the segment group.
|
|
1273
|
+
obliterate.segmentGroup = {
|
|
1274
|
+
segments: [],
|
|
1275
|
+
localSeq,
|
|
1276
|
+
refSeq: this.collabWindow.currentSeq,
|
|
1277
|
+
obliterateInfo: obliterate,
|
|
1278
|
+
};
|
|
1279
|
+
if (this.collabWindow.collaborating && clientId === this.collabWindow.clientId) {
|
|
1280
|
+
this.pendingSegments.push(obliterate.segmentGroup);
|
|
1281
|
+
}
|
|
1282
|
+
this.obliterates.addOrUpdate(obliterate);
|
|
1261
1283
|
const markMoved = (segment, pos, _start, _end) => {
|
|
1262
|
-
|
|
1284
|
+
if ((start.side === sequencePlace_js_1.Side.After && startPos === pos + segment.cachedLength) || // exclusive start segment
|
|
1285
|
+
(end.side === sequencePlace_js_1.Side.Before &&
|
|
1286
|
+
endPos === pos &&
|
|
1287
|
+
(0, perspective_js_1.isSegmentPresent)(segment, { refSeq, localSeq })) // exclusive end segment
|
|
1288
|
+
) {
|
|
1289
|
+
// We walk these segments because we want to also walk any concurrently inserted segments between here and the obliterated segments.
|
|
1290
|
+
// These segments are outside of the obliteration range though, so return true to keep walking.
|
|
1291
|
+
return true;
|
|
1292
|
+
}
|
|
1263
1293
|
const existingMoveInfo = (0, mergeTreeNodes_js_1.toMoveInfo)(segment);
|
|
1294
|
+
if (segment.prevObliterateByInserter?.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1295
|
+
// We chose to not obliterate this segment because we are aware of an unacked local obliteration.
|
|
1296
|
+
// The local obliterate has not been sequenced yet, so it is still the newest obliterate we are aware of.
|
|
1297
|
+
// Other clients will also choose not to obliterate this segment because the most recent obliteration has the same clientId
|
|
1298
|
+
return true;
|
|
1299
|
+
}
|
|
1264
1300
|
if (clientId !== segment.clientId &&
|
|
1265
1301
|
segment.seq !== undefined &&
|
|
1266
1302
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1301,7 +1337,6 @@ class MergeTree {
|
|
|
1301
1337
|
if (segment.movedSeq === constants_js_1.UnassignedSequenceNumber &&
|
|
1302
1338
|
clientId === this.collabWindow.clientId) {
|
|
1303
1339
|
obliterate.segmentGroup = this.addToPendingList(segment, obliterate.segmentGroup, localSeq);
|
|
1304
|
-
(_a = obliterate.segmentGroup).obliterateInfo ?? (_a.obliterateInfo = obliterate);
|
|
1305
1340
|
}
|
|
1306
1341
|
else {
|
|
1307
1342
|
if (MergeTree.options.zamboniSegments) {
|
|
@@ -1320,8 +1355,8 @@ class MergeTree {
|
|
|
1320
1355
|
}
|
|
1321
1356
|
return true;
|
|
1322
1357
|
};
|
|
1323
|
-
this.nodeMap(refSeq, clientId, markMoved, undefined, afterMarkMoved, start, end
|
|
1324
|
-
|
|
1358
|
+
this.nodeMap(refSeq, clientId, markMoved, undefined, afterMarkMoved, start.pos, end.pos + 1, // include the segment containing the end reference
|
|
1359
|
+
undefined, seq === constants_js_1.UnassignedSequenceNumber ? undefined : seq);
|
|
1325
1360
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
1326
1361
|
// opArgs == undefined => test code
|
|
1327
1362
|
if (movedSegments.length > 0) {
|
|
@@ -1342,6 +1377,17 @@ class MergeTree {
|
|
|
1342
1377
|
(0, zamboni_js_1.zamboniSegments)(this);
|
|
1343
1378
|
}
|
|
1344
1379
|
}
|
|
1380
|
+
obliterateRange(start, end, refSeq, clientId, seq, overwrite = false, opArgs) {
|
|
1381
|
+
errorIfOptionNotTrue(this.options, "mergeTreeEnableObliterate");
|
|
1382
|
+
if (this.options?.mergeTreeEnableSidedObliterate) {
|
|
1383
|
+
(0, internal_1.assert)(typeof start === "object" && typeof end === "object", "Start and end must be of type InteriorSequencePlace if mergeTreeEnableSidedObliterate is enabled.");
|
|
1384
|
+
this.obliterateRangeSided(start, end, refSeq, clientId, seq, overwrite, opArgs);
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
(0, internal_1.assert)(typeof start === "number" && typeof end === "number", "Start and end must be numbers if mergeTreeEnableSidedObliterate is not enabled.");
|
|
1388
|
+
this.obliterateRangeSided({ pos: start, side: sequencePlace_js_1.Side.Before }, { pos: end - 1, side: sequencePlace_js_1.Side.After }, refSeq, clientId, seq, overwrite, opArgs);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1345
1391
|
markRangeRemoved(start, end, refSeq, clientId, seq, overwrite = false, opArgs) {
|
|
1346
1392
|
let _overwrite = overwrite;
|
|
1347
1393
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|