@fluidframework/merge-tree 2.11.0 → 2.13.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/CHANGELOG.md +45 -0
- package/api-report/merge-tree.legacy.alpha.api.md +50 -19
- package/dist/MergeTreeTextHelper.d.ts.map +1 -1
- package/dist/MergeTreeTextHelper.js +0 -2
- package/dist/MergeTreeTextHelper.js.map +1 -1
- package/dist/attributionPolicy.d.ts.map +1 -1
- package/dist/attributionPolicy.js +6 -15
- package/dist/attributionPolicy.js.map +1 -1
- package/dist/client.d.ts +3 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +39 -28
- package/dist/client.js.map +1 -1
- package/dist/endOfTreeSegment.d.ts +5 -4
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +2 -1
- package/dist/localReference.d.ts +1 -0
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +1 -0
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +8 -7
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +202 -211
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodeWalk.d.ts +5 -5
- package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
- package/dist/mergeTreeNodeWalk.js +3 -2
- package/dist/mergeTreeNodeWalk.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +181 -159
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +121 -109
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/mergeTreeTracking.d.ts.map +1 -1
- package/dist/mergeTreeTracking.js +0 -2
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +33 -27
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +10 -9
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +11 -4
- package/dist/perspective.js.map +1 -1
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js +4 -1
- package/dist/referencePositions.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +13 -11
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts +4 -4
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +0 -6
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentInfos.d.ts +257 -0
- package/dist/segmentInfos.d.ts.map +1 -0
- package/dist/segmentInfos.js +166 -0
- package/dist/segmentInfos.js.map +1 -0
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +38 -44
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +9 -12
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +2 -2
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +5 -3
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +4 -4
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +5 -8
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/test/beastTest.spec.d.ts +0 -2
- package/dist/test/beastTest.spec.d.ts.map +1 -1
- package/dist/test/beastTest.spec.js +1 -5
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +15 -12
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.d.ts.map +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +3 -2
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +6 -6
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/dirname.cjs +0 -1
- package/dist/test/dirname.cjs.map +1 -1
- package/dist/test/index.d.ts +1 -1
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -4
- package/dist/test/index.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +3 -0
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +2 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/mergeTree.walk.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +2 -3
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/propertyManager.spec.js.map +1 -1
- package/dist/test/reconnectHelper.d.ts +2 -1
- package/dist/test/reconnectHelper.d.ts.map +1 -1
- package/dist/test/reconnectHelper.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/revertibleFarm.spec.js.map +1 -1
- package/dist/test/segmentGroupCollection.spec.js +15 -3
- package/dist/test/segmentGroupCollection.spec.js.map +1 -1
- package/dist/test/snapshot.utils.d.ts +2 -2
- package/dist/test/snapshot.utils.d.ts.map +1 -1
- package/dist/test/snapshot.utils.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +4 -3
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +8 -6
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +29 -27
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +6 -4
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testUtils.d.ts +2 -2
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +32 -8
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts +2 -2
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +12 -6
- package/dist/test/text.js.map +1 -1
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.d.ts.map +1 -1
- package/dist/test/wordUnitTests.spec.js +4 -2
- package/dist/test/wordUnitTests.spec.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +8 -7
- package/dist/zamboni.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts.map +1 -1
- package/lib/MergeTreeTextHelper.js +0 -2
- package/lib/MergeTreeTextHelper.js.map +1 -1
- package/lib/attributionPolicy.d.ts.map +1 -1
- package/lib/attributionPolicy.js +6 -15
- package/lib/attributionPolicy.js.map +1 -1
- package/lib/client.d.ts +3 -4
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +40 -29
- package/lib/client.js.map +1 -1
- package/lib/endOfTreeSegment.d.ts +5 -4
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +2 -1
- package/lib/localReference.d.ts +1 -0
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +1 -0
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +8 -7
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +192 -201
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodeWalk.d.ts +5 -5
- package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
- package/lib/mergeTreeNodeWalk.js +3 -2
- package/lib/mergeTreeNodeWalk.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +181 -159
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +115 -105
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/mergeTreeTracking.d.ts.map +1 -1
- package/lib/mergeTreeTracking.js +0 -2
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +30 -24
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +10 -9
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +11 -4
- package/lib/perspective.js.map +1 -1
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js +4 -1
- package/lib/referencePositions.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +11 -9
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts +4 -4
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +0 -6
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentInfos.d.ts +257 -0
- package/lib/segmentInfos.d.ts.map +1 -0
- package/lib/segmentInfos.js +145 -0
- package/lib/segmentInfos.js.map +1 -0
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +38 -44
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +9 -12
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +2 -2
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +5 -3
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +4 -4
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +5 -8
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/test/beastTest.spec.d.ts +0 -2
- package/lib/test/beastTest.spec.d.ts.map +1 -1
- package/lib/test/beastTest.spec.js +0 -3
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +15 -12
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.d.ts.map +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +3 -2
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +1 -1
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +1 -1
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/dirname.cjs +0 -1
- package/lib/test/dirname.cjs.map +1 -1
- package/lib/test/index.d.ts +1 -1
- package/lib/test/index.d.ts.map +1 -1
- package/lib/test/index.js +1 -1
- package/lib/test/index.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +3 -0
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.insertingWalk.spec.js +2 -2
- package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +2 -0
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/mergeTree.walk.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +1 -2
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/propertyManager.spec.js.map +1 -1
- package/lib/test/reconnectHelper.d.ts +2 -1
- package/lib/test/reconnectHelper.d.ts.map +1 -1
- package/lib/test/reconnectHelper.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/revertibleFarm.spec.js.map +1 -1
- package/lib/test/segmentGroupCollection.spec.js +15 -3
- package/lib/test/segmentGroupCollection.spec.js.map +1 -1
- package/lib/test/snapshot.utils.d.ts +2 -2
- package/lib/test/snapshot.utils.d.ts.map +1 -1
- package/lib/test/snapshot.utils.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +4 -3
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +8 -6
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +30 -28
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +5 -3
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testUtils.d.ts +2 -2
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +9 -8
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts +2 -2
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +12 -6
- package/lib/test/text.js.map +1 -1
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.d.ts.map +1 -1
- package/lib/test/wordUnitTests.spec.js +4 -2
- package/lib/test/wordUnitTests.spec.js.map +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +7 -6
- package/lib/zamboni.js.map +1 -1
- package/package.json +18 -18
- package/src/MergeTreeTextHelper.ts +2 -4
- package/src/attributionPolicy.ts +5 -11
- package/src/client.ts +55 -44
- package/src/endOfTreeSegment.ts +7 -4
- package/src/index.ts +5 -6
- package/src/localReference.ts +1 -0
- package/src/mergeTree.ts +253 -271
- package/src/mergeTreeNodeWalk.ts +9 -8
- package/src/mergeTreeNodes.ts +300 -305
- package/src/mergeTreeTracking.ts +0 -3
- package/src/partialLengths.ts +44 -25
- package/src/perspective.ts +36 -13
- package/src/referencePositions.ts +4 -1
- package/src/revertibles.ts +20 -16
- package/src/segmentGroupCollection.ts +7 -18
- package/src/segmentInfos.ts +377 -0
- package/src/snapshotLoader.ts +60 -57
- package/src/snapshotV1.ts +14 -16
- package/src/snapshotlegacy.ts +12 -17
- package/src/sortedSegmentSet.ts +12 -15
- package/src/zamboni.ts +10 -12
package/dist/mergeTree.js
CHANGED
|
@@ -22,40 +22,26 @@ const partialLengths_js_1 = require("./partialLengths.js");
|
|
|
22
22
|
const perspective_js_1 = require("./perspective.js");
|
|
23
23
|
const properties_js_1 = require("./properties.js");
|
|
24
24
|
const referencePositions_js_1 = require("./referencePositions.js");
|
|
25
|
-
// eslint-disable-next-line import/no-deprecated
|
|
26
25
|
const segmentGroupCollection_js_1 = require("./segmentGroupCollection.js");
|
|
27
|
-
|
|
26
|
+
const segmentInfos_js_1 = require("./segmentInfos.js");
|
|
28
27
|
const segmentPropertiesManager_js_1 = require("./segmentPropertiesManager.js");
|
|
29
28
|
const sequencePlace_js_1 = require("./sequencePlace.js");
|
|
30
29
|
const sortedSegmentSet_js_1 = require("./sortedSegmentSet.js");
|
|
31
30
|
const zamboni_js_1 = require("./zamboni.js");
|
|
32
|
-
function markSegmentMoved(seg, moveInfo) {
|
|
33
|
-
seg.moveDst = moveInfo.moveDst;
|
|
34
|
-
seg.movedClientIds = [...moveInfo.movedClientIds];
|
|
35
|
-
seg.movedSeqs = [moveInfo.movedSeq];
|
|
36
|
-
seg.movedSeq = moveInfo.movedSeq;
|
|
37
|
-
seg.localMovedSeq = moveInfo.localMovedSeq;
|
|
38
|
-
seg.wasMovedOnInsert = moveInfo.wasMovedOnInsert;
|
|
39
|
-
}
|
|
40
|
-
function isMoved(segment) {
|
|
41
|
-
return (0, mergeTreeNodes_js_1.toMoveInfo)(segment) !== undefined;
|
|
42
|
-
}
|
|
43
|
-
function isRemoved(segment) {
|
|
44
|
-
return (0, mergeTreeNodes_js_1.toRemovalInfo)(segment) !== undefined;
|
|
45
|
-
}
|
|
46
31
|
function isRemovedAndAcked(segment) {
|
|
47
|
-
const removalInfo = (0,
|
|
32
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
48
33
|
return removalInfo !== undefined && removalInfo.removedSeq !== constants_js_1.UnassignedSequenceNumber;
|
|
49
34
|
}
|
|
35
|
+
// eslint-disable-next-line import/no-deprecated
|
|
50
36
|
function isMovedAndAcked(segment) {
|
|
51
|
-
const moveInfo = (0,
|
|
37
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
52
38
|
return moveInfo !== undefined && moveInfo.movedSeq !== constants_js_1.UnassignedSequenceNumber;
|
|
53
39
|
}
|
|
54
40
|
function isRemovedAndAckedOrMovedAndAcked(segment) {
|
|
55
41
|
return isRemovedAndAcked(segment) || isMovedAndAcked(segment);
|
|
56
42
|
}
|
|
57
43
|
function isRemovedOrMoved(segment) {
|
|
58
|
-
return isRemoved(segment) || isMoved(segment);
|
|
44
|
+
return (0, segmentInfos_js_1.isRemoved)(segment) || (0, segmentInfos_js_1.isMoved)(segment);
|
|
59
45
|
}
|
|
60
46
|
function nodeTotalLength(mergeTree, node) {
|
|
61
47
|
if (!node.isLeaf()) {
|
|
@@ -85,27 +71,25 @@ function ackSegment(segment, segmentGroup, opArgs) {
|
|
|
85
71
|
return true;
|
|
86
72
|
}
|
|
87
73
|
case ops_js_1.MergeTreeDeltaType.REMOVE: {
|
|
88
|
-
|
|
89
|
-
(0, internal_1.assert)(removalInfo !== undefined, 0x046 /* "On remove ack, missing removal info!" */);
|
|
74
|
+
(0, segmentInfos_js_1.assertRemoved)(segment);
|
|
90
75
|
segment.localRemovedSeq = undefined;
|
|
91
|
-
if (
|
|
92
|
-
|
|
76
|
+
if (segment.removedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
77
|
+
segment.removedSeq = sequenceNumber;
|
|
93
78
|
return true;
|
|
94
79
|
}
|
|
95
80
|
return false;
|
|
96
81
|
}
|
|
97
82
|
case ops_js_1.MergeTreeDeltaType.OBLITERATE:
|
|
98
83
|
case ops_js_1.MergeTreeDeltaType.OBLITERATE_SIDED: {
|
|
99
|
-
|
|
100
|
-
(0, internal_1.assert)(moveInfo !== undefined, 0x86e /* On obliterate ack, missing move info! */);
|
|
84
|
+
(0, segmentInfos_js_1.assertMoved)(segment);
|
|
101
85
|
const obliterateInfo = segmentGroup.obliterateInfo;
|
|
102
86
|
(0, internal_1.assert)(obliterateInfo !== undefined, 0xa40 /* must have obliterate info */);
|
|
103
87
|
segment.localMovedSeq = obliterateInfo.localSeq = undefined;
|
|
104
|
-
const seqIdx =
|
|
88
|
+
const seqIdx = segment.movedSeqs.indexOf(constants_js_1.UnassignedSequenceNumber);
|
|
105
89
|
(0, internal_1.assert)(seqIdx !== -1, 0x86f /* expected movedSeqs to contain unacked seq */);
|
|
106
|
-
|
|
107
|
-
if (
|
|
108
|
-
|
|
90
|
+
segment.movedSeqs[seqIdx] = sequenceNumber;
|
|
91
|
+
if (segment.movedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
92
|
+
segment.movedSeq = sequenceNumber;
|
|
109
93
|
return true;
|
|
110
94
|
}
|
|
111
95
|
return false;
|
|
@@ -144,7 +128,6 @@ exports.findRootMergeBlock = findRootMergeBlock;
|
|
|
144
128
|
* entries for all segments visited during excursion.
|
|
145
129
|
* This can reduce the number of times the tree needs to be scanned if a range containing many
|
|
146
130
|
* SlideOnRemove references is removed.
|
|
147
|
-
* @internal
|
|
148
131
|
*/
|
|
149
132
|
function getSlideToSegment(segment, slidingPreference = localReference_js_1.SlidingPreference.FORWARD, cache, useNewSlidingBehavior = false) {
|
|
150
133
|
if (!segment ||
|
|
@@ -164,7 +147,8 @@ function getSlideToSegment(segment, slidingPreference = localReference_js_1.Slid
|
|
|
164
147
|
return false;
|
|
165
148
|
}
|
|
166
149
|
if (cache !== undefined &&
|
|
167
|
-
(seg
|
|
150
|
+
((0, segmentInfos_js_1.toRemovalInfo)(seg)?.removedSeq === (0, segmentInfos_js_1.toRemovalInfo)(segment)?.removedSeq ||
|
|
151
|
+
(0, segmentInfos_js_1.toMoveInfo)(seg)?.movedSeq === (0, segmentInfos_js_1.toMoveInfo)(segment)?.movedSeq)) {
|
|
168
152
|
cache.set(seg, result);
|
|
169
153
|
}
|
|
170
154
|
return true;
|
|
@@ -211,7 +195,7 @@ function getSlideToSegment(segment, slidingPreference = localReference_js_1.Slid
|
|
|
211
195
|
* @internal
|
|
212
196
|
*/
|
|
213
197
|
function getSlideToSegoff(segoff, slidingPreference = localReference_js_1.SlidingPreference.FORWARD, useNewSlidingBehavior = false) {
|
|
214
|
-
if (segoff.segment
|
|
198
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(segoff.segment)) {
|
|
215
199
|
return segoff;
|
|
216
200
|
}
|
|
217
201
|
const [segment, _] = getSlideToSegment(segoff.segment, slidingPreference, undefined, useNewSlidingBehavior);
|
|
@@ -239,7 +223,6 @@ class Obliterates {
|
|
|
239
223
|
* See https://github.com/microsoft/FluidFramework/blob/main/packages/dds/merge-tree/docs/Obliterate.md#remote-perspective
|
|
240
224
|
* for additional context
|
|
241
225
|
*/
|
|
242
|
-
// eslint-disable-next-line import/no-deprecated
|
|
243
226
|
this.seqOrdered = new index_js_1.DoublyLinkedList();
|
|
244
227
|
/**
|
|
245
228
|
* This contains a sorted lists of all obliterate starts
|
|
@@ -257,7 +240,6 @@ class Obliterates {
|
|
|
257
240
|
this.mergeTree.removeLocalReferencePosition(ob.data.end);
|
|
258
241
|
}
|
|
259
242
|
}
|
|
260
|
-
// eslint-disable-next-line import/no-deprecated
|
|
261
243
|
addOrUpdate(obliterateInfo) {
|
|
262
244
|
const { seq, start } = obliterateInfo;
|
|
263
245
|
if (seq !== constants_js_1.UnassignedSequenceNumber) {
|
|
@@ -268,14 +250,14 @@ class Obliterates {
|
|
|
268
250
|
empty() {
|
|
269
251
|
return this.startOrdered.size === 0;
|
|
270
252
|
}
|
|
271
|
-
// eslint-disable-next-line import/no-deprecated
|
|
272
253
|
findOverlapping(seg) {
|
|
273
|
-
// eslint-disable-next-line import/no-deprecated
|
|
274
254
|
const overlapping = [];
|
|
275
255
|
for (const start of this.startOrdered.items) {
|
|
276
|
-
|
|
256
|
+
const startSeg = start.getSegment();
|
|
257
|
+
if ((0, segmentInfos_js_1.isMergeNodeInfo)(startSeg) && startSeg.ordinal <= seg.ordinal) {
|
|
277
258
|
const ob = start.properties?.obliterate;
|
|
278
|
-
|
|
259
|
+
const endSeg = ob.end.getSegment();
|
|
260
|
+
if ((0, segmentInfos_js_1.isMergeNodeInfo)(endSeg) && endSeg.ordinal >= seg.ordinal) {
|
|
279
261
|
overlapping.push(ob);
|
|
280
262
|
}
|
|
281
263
|
}
|
|
@@ -293,9 +275,7 @@ class Obliterates {
|
|
|
293
275
|
class MergeTree {
|
|
294
276
|
constructor(options) {
|
|
295
277
|
this.options = options;
|
|
296
|
-
// eslint-disable-next-line import/no-deprecated
|
|
297
278
|
this.collabWindow = new mergeTreeNodes_js_1.CollaborationWindow();
|
|
298
|
-
// eslint-disable-next-line import/no-deprecated
|
|
299
279
|
this.pendingSegments = new index_js_1.DoublyLinkedList();
|
|
300
280
|
this.segmentsToScour = new internal_1.Heap(LRUSegmentComparer);
|
|
301
281
|
/**
|
|
@@ -313,6 +293,7 @@ class MergeTree {
|
|
|
313
293
|
return {};
|
|
314
294
|
}
|
|
315
295
|
const next = segment.splitAt(pos);
|
|
296
|
+
(0, mergeTreeNodes_js_1.assertSegmentLeaf)(next);
|
|
316
297
|
if (segment?.segmentGroups) {
|
|
317
298
|
next.segmentGroups ?? (next.segmentGroups = new segmentGroupCollection_js_1.SegmentGroupCollection(next));
|
|
318
299
|
segment.segmentGroups.copyTo(next.segmentGroups);
|
|
@@ -356,8 +337,8 @@ class MergeTree {
|
|
|
356
337
|
* numbers corresponding to un-acked operations give valid results.
|
|
357
338
|
*/
|
|
358
339
|
localNetLength(segment, refSeq, localSeq) {
|
|
359
|
-
const removalInfo = (0,
|
|
360
|
-
const moveInfo = (0,
|
|
340
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
341
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
361
342
|
if (localSeq === undefined) {
|
|
362
343
|
if (removalInfo !== undefined || moveInfo !== undefined) {
|
|
363
344
|
if ((!!removalInfo && !(0, mergeTreeNodes_js_1.seqLTE)(removalInfo.removedSeq, this.collabWindow.minSeq)) ||
|
|
@@ -375,7 +356,9 @@ class MergeTree {
|
|
|
375
356
|
}
|
|
376
357
|
(0, internal_1.assert)(refSeq !== undefined, 0x398 /* localSeq provided for local length without refSeq */);
|
|
377
358
|
(0, internal_1.assert)(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
|
|
378
|
-
const { seq
|
|
359
|
+
const { seq } = segment;
|
|
360
|
+
const { removedSeq, localRemovedSeq } = removalInfo ?? {};
|
|
361
|
+
const { movedSeq, localMovedSeq } = moveInfo ?? {};
|
|
379
362
|
if (seq === constants_js_1.UnassignedSequenceNumber) {
|
|
380
363
|
(0, internal_1.assert)(segment.localSeq !== undefined, 0x39a /* unacked segment with undefined localSeq */);
|
|
381
364
|
// inserted locally, still un-acked
|
|
@@ -411,7 +394,7 @@ class MergeTree {
|
|
|
411
394
|
}
|
|
412
395
|
addNode(block, node) {
|
|
413
396
|
const index = block.childCount++;
|
|
414
|
-
|
|
397
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, node, index, false);
|
|
415
398
|
return index;
|
|
416
399
|
}
|
|
417
400
|
reloadFromSegments(segments) {
|
|
@@ -505,12 +488,12 @@ class MergeTree {
|
|
|
505
488
|
(0, internal_1.assert)(localSeq === undefined || clientId === this.collabWindow.clientId, 0x39b /* localSeq provided for non-local client */);
|
|
506
489
|
let segment;
|
|
507
490
|
let offset;
|
|
508
|
-
const leaf = (leafSeg,
|
|
491
|
+
const leaf = (leafSeg, _, start) => {
|
|
509
492
|
segment = leafSeg;
|
|
510
493
|
offset = start;
|
|
511
494
|
return false;
|
|
512
495
|
};
|
|
513
|
-
this.nodeMap(refSeq, clientId, leaf, undefined,
|
|
496
|
+
this.nodeMap(refSeq, clientId, leaf, undefined, pos, pos + 1, localSeq);
|
|
514
497
|
return { segment, offset };
|
|
515
498
|
}
|
|
516
499
|
/**
|
|
@@ -535,7 +518,9 @@ class MergeTree {
|
|
|
535
518
|
*/
|
|
536
519
|
slideAckedRemovedSegmentReferences(segments) {
|
|
537
520
|
// References are slid in groups to preserve their order.
|
|
521
|
+
// eslint-disable-next-line import/no-deprecated
|
|
538
522
|
let currentForwardSlideGroup = [];
|
|
523
|
+
// eslint-disable-next-line import/no-deprecated
|
|
539
524
|
let currentBackwardSlideGroup = [];
|
|
540
525
|
let currentForwardMaybeEndpoint;
|
|
541
526
|
let currentForwardSlideDestination;
|
|
@@ -543,7 +528,9 @@ class MergeTree {
|
|
|
543
528
|
let currentBackwardMaybeEndpoint;
|
|
544
529
|
let currentBackwardSlideDestination;
|
|
545
530
|
let currentBackwardSlideIsForward;
|
|
546
|
-
const slideGroup = (currentSlideDestination, currentSlideIsForward,
|
|
531
|
+
const slideGroup = (currentSlideDestination, currentSlideIsForward,
|
|
532
|
+
// eslint-disable-next-line import/no-deprecated
|
|
533
|
+
currentSlideGroup, pred, maybeEndpoint) => {
|
|
547
534
|
if (currentSlideIsForward === undefined) {
|
|
548
535
|
return;
|
|
549
536
|
}
|
|
@@ -551,6 +538,7 @@ class MergeTree {
|
|
|
551
538
|
const endpointRefsToAdd = currentSlideGroup.map((collection) => (0, localReference_js_1.filterLocalReferencePositions)(collection, (ref) => pred(ref) && !!ref.canSlideToEndpoint));
|
|
552
539
|
if (maybeEndpoint) {
|
|
553
540
|
const endpoint = maybeEndpoint === "start" ? this.startOfTree : this.endOfTree;
|
|
541
|
+
// eslint-disable-next-line import/no-deprecated
|
|
554
542
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(endpoint);
|
|
555
543
|
if (currentSlideIsForward) {
|
|
556
544
|
localRefs.addBeforeTombstones(...endpointRefsToAdd);
|
|
@@ -571,6 +559,7 @@ class MergeTree {
|
|
|
571
559
|
}
|
|
572
560
|
}
|
|
573
561
|
else {
|
|
562
|
+
// eslint-disable-next-line import/no-deprecated
|
|
574
563
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(currentSlideDestination);
|
|
575
564
|
if (currentSlideIsForward) {
|
|
576
565
|
localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
|
|
@@ -580,7 +569,9 @@ class MergeTree {
|
|
|
580
569
|
}
|
|
581
570
|
}
|
|
582
571
|
};
|
|
583
|
-
const trySlideSegment = (segment, currentSlideDestination, currentSlideIsForward,
|
|
572
|
+
const trySlideSegment = (segment, currentSlideDestination, currentSlideIsForward,
|
|
573
|
+
// eslint-disable-next-line import/no-deprecated
|
|
574
|
+
currentSlideGroup, pred, slidingPreference, currentMaybeEndpoint, reassign) => {
|
|
584
575
|
// avoid sliding logic if this segment doesn't have any references
|
|
585
576
|
// with the given sliding preference
|
|
586
577
|
if (!segment.localRefs || !(0, localReference_js_1.anyLocalReferencePosition)(segment.localRefs, pred)) {
|
|
@@ -637,7 +628,6 @@ class MergeTree {
|
|
|
637
628
|
if (this.localPartialsComputed) {
|
|
638
629
|
return;
|
|
639
630
|
}
|
|
640
|
-
// eslint-disable-next-line import/no-deprecated
|
|
641
631
|
const rebaseCollabWindow = new mergeTreeNodes_js_1.CollaborationWindow();
|
|
642
632
|
rebaseCollabWindow.loadFrom(this.collabWindow);
|
|
643
633
|
if (refSeq < this.collabWindow.minSeq) {
|
|
@@ -667,8 +657,8 @@ class MergeTree {
|
|
|
667
657
|
// Sequence number within window
|
|
668
658
|
if (node.isLeaf()) {
|
|
669
659
|
const segment = node;
|
|
670
|
-
const removalInfo = (0,
|
|
671
|
-
const moveInfo = (0,
|
|
660
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
661
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
672
662
|
if (removalInfo !== undefined) {
|
|
673
663
|
if ((0, mergeTreeNodes_js_1.seqLTE)(removalInfo.removedSeq, this.collabWindow.minSeq)) {
|
|
674
664
|
return undefined;
|
|
@@ -721,24 +711,26 @@ class MergeTree {
|
|
|
721
711
|
*/
|
|
722
712
|
referencePositionToLocalPosition(refPos, refSeq = Number.MAX_SAFE_INTEGER, clientId = this.collabWindow.clientId, localSeq = this.collabWindow.localSeq) {
|
|
723
713
|
const seg = refPos.getSegment();
|
|
724
|
-
if (
|
|
714
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(seg)) {
|
|
725
715
|
// We have no idea where this reference is, because it refers to a segment which is not in the tree.
|
|
726
716
|
return referencePositions_js_1.DetachedReferencePosition;
|
|
727
717
|
}
|
|
728
718
|
if (refPos.isLeaf()) {
|
|
729
|
-
return this.getPosition(
|
|
719
|
+
return this.getPosition(seg, refSeq, clientId, localSeq);
|
|
730
720
|
}
|
|
731
721
|
if ((0, referencePositions_js_1.refTypeIncludesFlag)(refPos, ops_js_1.ReferenceType.Transient) || seg.localRefs?.has(refPos)) {
|
|
732
722
|
if (seg !== this.startOfTree &&
|
|
733
723
|
seg !== this.endOfTree &&
|
|
734
724
|
!(0, perspective_js_1.isSegmentPresent)(seg, { refSeq, localSeq })) {
|
|
735
725
|
const forward = refPos.slidingPreference === localReference_js_1.SlidingPreference.FORWARD;
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
726
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(seg);
|
|
727
|
+
const removeInfo = (0, segmentInfos_js_1.toRemovalInfo)(seg);
|
|
728
|
+
const slideSeq = moveInfo !== undefined && moveInfo.movedSeq !== constants_js_1.UnassignedSequenceNumber
|
|
729
|
+
? moveInfo.movedSeq
|
|
730
|
+
: removeInfo !== undefined && removeInfo.removedSeq !== constants_js_1.UnassignedSequenceNumber
|
|
731
|
+
? removeInfo.removedSeq
|
|
740
732
|
: refSeq;
|
|
741
|
-
const slideLocalSeq =
|
|
733
|
+
const slideLocalSeq = moveInfo?.localMovedSeq ?? removeInfo?.localRemovedSeq;
|
|
742
734
|
const perspective = new perspective_js_1.PerspectiveImpl(this, {
|
|
743
735
|
refSeq: slideSeq,
|
|
744
736
|
localSeq: slideLocalSeq,
|
|
@@ -766,11 +758,10 @@ class MergeTree {
|
|
|
766
758
|
searchForMarker(startPos, clientId, markerLabel, forwards = true) {
|
|
767
759
|
let foundMarker;
|
|
768
760
|
const { segment } = this.getContainingSegment(startPos, constants_js_1.UniversalSequenceNumber, clientId);
|
|
769
|
-
|
|
770
|
-
if (segWithParent?.parent === undefined) {
|
|
761
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(segment)) {
|
|
771
762
|
return undefined;
|
|
772
763
|
}
|
|
773
|
-
(0, mergeTreeNodeWalk_js_1.depthFirstNodeWalk)(
|
|
764
|
+
(0, mergeTreeNodeWalk_js_1.depthFirstNodeWalk)(segment.parent, segment, (node) => {
|
|
774
765
|
if (node.isLeaf()) {
|
|
775
766
|
if (mergeTreeNodes_js_1.Marker.is(node) && (0, referencePositions_js_1.refHasTileLabel)(node, markerLabel)) {
|
|
776
767
|
foundMarker = node;
|
|
@@ -792,8 +783,8 @@ class MergeTree {
|
|
|
792
783
|
updateRoot(splitNode) {
|
|
793
784
|
if (splitNode !== undefined) {
|
|
794
785
|
const newRoot = this.makeBlock(2);
|
|
795
|
-
|
|
796
|
-
|
|
786
|
+
(0, mergeTreeNodes_js_1.assignChild)(newRoot, this.root, 0, false);
|
|
787
|
+
(0, mergeTreeNodes_js_1.assignChild)(newRoot, splitNode, 1, false);
|
|
797
788
|
this.root = newRoot;
|
|
798
789
|
this.nodeUpdateOrdinals(this.root);
|
|
799
790
|
this.nodeUpdateLengthNewStructure(this.root);
|
|
@@ -849,9 +840,7 @@ class MergeTree {
|
|
|
849
840
|
(0, zamboni_js_1.zamboniSegments)(this);
|
|
850
841
|
}
|
|
851
842
|
}
|
|
852
|
-
addToPendingList(segment,
|
|
853
|
-
// eslint-disable-next-line import/no-deprecated
|
|
854
|
-
segmentGroup, localSeq, previousProps) {
|
|
843
|
+
addToPendingList(segment, segmentGroup, localSeq, previousProps) {
|
|
855
844
|
let _segmentGroup = segmentGroup;
|
|
856
845
|
if (_segmentGroup === undefined) {
|
|
857
846
|
_segmentGroup = {
|
|
@@ -871,7 +860,6 @@ class MergeTree {
|
|
|
871
860
|
if (previousProps) {
|
|
872
861
|
_segmentGroup.previousProps.push(previousProps);
|
|
873
862
|
}
|
|
874
|
-
// eslint-disable-next-line import/no-deprecated
|
|
875
863
|
const segmentGroups = (segment.segmentGroups ?? (segment.segmentGroups = new segmentGroupCollection_js_1.SegmentGroupCollection(segment)));
|
|
876
864
|
segmentGroups.enqueue(_segmentGroup);
|
|
877
865
|
return _segmentGroup;
|
|
@@ -880,8 +868,8 @@ class MergeTree {
|
|
|
880
868
|
getMarkerFromId(id) {
|
|
881
869
|
const marker = this.idToMarker.get(id);
|
|
882
870
|
return marker === undefined ||
|
|
883
|
-
isRemoved(marker) ||
|
|
884
|
-
(isMoved(marker) && marker.moveDst === undefined)
|
|
871
|
+
(0, segmentInfos_js_1.isRemoved)(marker) ||
|
|
872
|
+
((0, segmentInfos_js_1.isMoved)(marker) && marker.moveDst === undefined)
|
|
885
873
|
? undefined
|
|
886
874
|
: marker;
|
|
887
875
|
}
|
|
@@ -898,7 +886,7 @@ class MergeTree {
|
|
|
898
886
|
if (relativePos.id) {
|
|
899
887
|
marker = this.getMarkerFromId(relativePos.id);
|
|
900
888
|
}
|
|
901
|
-
if (marker) {
|
|
889
|
+
if ((0, mergeTreeNodes_js_1.isSegmentLeaf)(marker)) {
|
|
902
890
|
pos = this.getPosition(marker, refseq, clientId);
|
|
903
891
|
if (relativePos.before) {
|
|
904
892
|
if (relativePos.offset !== undefined) {
|
|
@@ -921,7 +909,7 @@ class MergeTree {
|
|
|
921
909
|
// opArgs == undefined => loading snapshot or test code
|
|
922
910
|
if (opArgs !== undefined) {
|
|
923
911
|
const deltaSegments = segments
|
|
924
|
-
.filter((segment) => !(0,
|
|
912
|
+
.filter((segment) => !(0, segmentInfos_js_1.toMoveInfo)(segment))
|
|
925
913
|
.map((segment) => ({ segment }));
|
|
926
914
|
if (deltaSegments.length > 0) {
|
|
927
915
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
@@ -956,7 +944,7 @@ class MergeTree {
|
|
|
956
944
|
}
|
|
957
945
|
const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
|
|
958
946
|
const { currentSeq, clientId } = this.collabWindow;
|
|
959
|
-
if (segmentInfo?.segment) {
|
|
947
|
+
if ((0, mergeTreeNodes_js_1.isSegmentLeaf)(segmentInfo?.segment)) {
|
|
960
948
|
const segmentPosition = this.getPosition(segmentInfo.segment, currentSeq, clientId);
|
|
961
949
|
return segmentPosition + segmentInfo.offset;
|
|
962
950
|
}
|
|
@@ -977,7 +965,6 @@ class MergeTree {
|
|
|
977
965
|
});
|
|
978
966
|
return siblingExists;
|
|
979
967
|
};
|
|
980
|
-
// eslint-disable-next-line import/no-deprecated
|
|
981
968
|
let segmentGroup;
|
|
982
969
|
const saveIfLocal = (locSegment) => {
|
|
983
970
|
// Save segment so we can assign sequence number when acked by server
|
|
@@ -1007,92 +994,95 @@ class MergeTree {
|
|
|
1007
994
|
}
|
|
1008
995
|
return segmentChanges;
|
|
1009
996
|
};
|
|
997
|
+
const insertInfo = {
|
|
998
|
+
clientId,
|
|
999
|
+
seq,
|
|
1000
|
+
localSeq,
|
|
1001
|
+
};
|
|
1010
1002
|
// TODO: build tree from segs and insert all at once
|
|
1011
1003
|
let insertPos = pos;
|
|
1012
|
-
for (const newSegment of newSegments
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1019
|
-
if (markerId) {
|
|
1020
|
-
this.idToMarker.set(markerId, newSegment);
|
|
1021
|
-
}
|
|
1004
|
+
for (const newSegment of newSegments
|
|
1005
|
+
.filter((s) => s.cachedLength > 0)
|
|
1006
|
+
.map((s) => (0, segmentInfos_js_1.overwriteInfo)(s, insertInfo))) {
|
|
1007
|
+
if (mergeTreeNodes_js_1.Marker.is(newSegment)) {
|
|
1008
|
+
const markerId = newSegment.getId();
|
|
1009
|
+
if (markerId) {
|
|
1010
|
+
this.idToMarker.set(markerId, newSegment);
|
|
1022
1011
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1012
|
+
}
|
|
1013
|
+
const splitNode = this.insertingWalk(this.root, insertPos, refSeq, clientId, seq, {
|
|
1014
|
+
leaf: onLeaf,
|
|
1015
|
+
candidateSegment: newSegment,
|
|
1016
|
+
continuePredicate: continueFrom,
|
|
1017
|
+
});
|
|
1018
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(newSegment)) {
|
|
1019
|
+
// Indicates an attempt to insert past the end of the merge-tree's content.
|
|
1020
|
+
const errorConstructor = localSeq === undefined ? internal_2.DataProcessingError : internal_2.UsageError;
|
|
1021
|
+
throw new errorConstructor("MergeTree insert failed", {
|
|
1022
|
+
currentSeq: this.collabWindow.currentSeq,
|
|
1023
|
+
minSeq: this.collabWindow.minSeq,
|
|
1024
|
+
segSeq: insertInfo.seq,
|
|
1027
1025
|
});
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq
|
|
1056
|
-
: ob.seq;
|
|
1057
|
-
if (normalizedObSeq > refSeq) {
|
|
1058
|
-
if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
|
|
1059
|
-
normalizedOldestSeq = normalizedObSeq;
|
|
1060
|
-
oldest = ob;
|
|
1061
|
-
movedClientIds.unshift(ob.clientId);
|
|
1062
|
-
movedSeqs.unshift(ob.seq);
|
|
1063
|
-
}
|
|
1064
|
-
else {
|
|
1065
|
-
movedClientIds.push(ob.clientId);
|
|
1066
|
-
movedSeqs.push(ob.seq);
|
|
1067
|
-
}
|
|
1068
|
-
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1069
|
-
normalizedNewestSeq = normalizedObSeq;
|
|
1070
|
-
newest = ob;
|
|
1071
|
-
}
|
|
1026
|
+
}
|
|
1027
|
+
this.updateRoot(splitNode);
|
|
1028
|
+
insertPos += newSegment.cachedLength;
|
|
1029
|
+
if (!this.options?.mergeTreeEnableObliterate || this.obliterates.empty()) {
|
|
1030
|
+
saveIfLocal(newSegment);
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1033
|
+
let oldest;
|
|
1034
|
+
let normalizedOldestSeq = 0;
|
|
1035
|
+
let newest;
|
|
1036
|
+
let normalizedNewestSeq = 0;
|
|
1037
|
+
const movedClientIds = [];
|
|
1038
|
+
const movedSeqs = [];
|
|
1039
|
+
for (const ob of this.obliterates.findOverlapping(newSegment)) {
|
|
1040
|
+
// compute a normalized seq that takes into account local seqs
|
|
1041
|
+
// but is still comparable to remote seqs to keep the checks below easy
|
|
1042
|
+
// REMOTE SEQUENCE NUMBERS LOCAL SEQUENCE NUMBERS
|
|
1043
|
+
// [0, 1, 2, 3, ..., 100, ..., 1000, ..., (MAX - MaxLocalSeq), L1, L2, L3, L4, ..., L100, ..., L1000, ...(MAX)]
|
|
1044
|
+
const normalizedObSeq = ob.seq === constants_js_1.UnassignedSequenceNumber
|
|
1045
|
+
? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq
|
|
1046
|
+
: ob.seq;
|
|
1047
|
+
if (normalizedObSeq > refSeq) {
|
|
1048
|
+
if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
|
|
1049
|
+
normalizedOldestSeq = normalizedObSeq;
|
|
1050
|
+
oldest = ob;
|
|
1051
|
+
movedClientIds.unshift(ob.clientId);
|
|
1052
|
+
movedSeqs.unshift(ob.seq);
|
|
1072
1053
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
movedClientIds,
|
|
1077
|
-
movedSeq: oldest.seq,
|
|
1078
|
-
movedSeqs,
|
|
1079
|
-
localMovedSeq: oldest.localSeq,
|
|
1080
|
-
wasMovedOnInsert: oldest.seq !== constants_js_1.UnassignedSequenceNumber,
|
|
1081
|
-
};
|
|
1082
|
-
markSegmentMoved(newSegment, moveInfo);
|
|
1083
|
-
if (moveInfo.localMovedSeq !== undefined) {
|
|
1084
|
-
(0, internal_1.assert)(oldest.segmentGroup !== undefined, 0x86c /* expected segment group to exist */);
|
|
1085
|
-
this.addToPendingList(newSegment, oldest.segmentGroup);
|
|
1054
|
+
else {
|
|
1055
|
+
movedClientIds.push(ob.clientId);
|
|
1056
|
+
movedSeqs.push(ob.seq);
|
|
1086
1057
|
}
|
|
1087
|
-
if (
|
|
1088
|
-
|
|
1058
|
+
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1059
|
+
normalizedNewestSeq = normalizedObSeq;
|
|
1060
|
+
newest = ob;
|
|
1089
1061
|
}
|
|
1090
1062
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1063
|
+
}
|
|
1064
|
+
if (oldest && newest?.clientId !== clientId) {
|
|
1065
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1066
|
+
const moveInfo = {
|
|
1067
|
+
movedClientIds,
|
|
1068
|
+
movedSeq: oldest.seq,
|
|
1069
|
+
movedSeqs,
|
|
1070
|
+
localMovedSeq: oldest.localSeq,
|
|
1071
|
+
wasMovedOnInsert: oldest.seq !== constants_js_1.UnassignedSequenceNumber,
|
|
1072
|
+
};
|
|
1073
|
+
(0, segmentInfos_js_1.overwriteInfo)(newSegment, moveInfo);
|
|
1074
|
+
if (moveInfo.localMovedSeq !== undefined) {
|
|
1075
|
+
(0, internal_1.assert)(oldest.segmentGroup !== undefined, 0x86c /* expected segment group to exist */);
|
|
1076
|
+
this.addToPendingList(newSegment, oldest.segmentGroup);
|
|
1093
1077
|
}
|
|
1094
|
-
|
|
1078
|
+
if (newSegment.parent) {
|
|
1079
|
+
this.blockUpdatePathLengths(newSegment.parent, seq, clientId);
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
else if (oldest && newest?.clientId === clientId) {
|
|
1083
|
+
newSegment.prevObliterateByInserter = newest;
|
|
1095
1084
|
}
|
|
1085
|
+
saveIfLocal(newSegment);
|
|
1096
1086
|
}
|
|
1097
1087
|
}
|
|
1098
1088
|
ensureIntervalBoundary(pos, refSeq, clientId) {
|
|
@@ -1113,10 +1103,8 @@ class MergeTree {
|
|
|
1113
1103
|
const newSeq = seq === constants_js_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
|
|
1114
1104
|
const segSeq = node.seq === constants_js_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER - 1 : (node.seq ?? 0);
|
|
1115
1105
|
return (newSeq > segSeq ||
|
|
1116
|
-
(node.movedSeq !==
|
|
1117
|
-
|
|
1118
|
-
node.movedSeq > seq) ||
|
|
1119
|
-
(node.removedSeq !== undefined &&
|
|
1106
|
+
((0, segmentInfos_js_1.isMoved)(node) && node.movedSeq !== constants_js_1.UnassignedSequenceNumber && node.movedSeq > seq) ||
|
|
1107
|
+
((0, segmentInfos_js_1.isRemoved)(node) &&
|
|
1120
1108
|
node.removedSeq !== constants_js_1.UnassignedSequenceNumber &&
|
|
1121
1109
|
node.removedSeq > seq));
|
|
1122
1110
|
}
|
|
@@ -1148,7 +1136,7 @@ class MergeTree {
|
|
|
1148
1136
|
const segment = child;
|
|
1149
1137
|
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1150
1138
|
if (segmentChanges.replaceCurrent) {
|
|
1151
|
-
|
|
1139
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, segmentChanges.replaceCurrent, childIndex, false);
|
|
1152
1140
|
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1153
1141
|
}
|
|
1154
1142
|
if (segmentChanges.next) {
|
|
@@ -1199,7 +1187,7 @@ class MergeTree {
|
|
|
1199
1187
|
block.children[i] = block.children[i - 1];
|
|
1200
1188
|
block.children[i].index = i;
|
|
1201
1189
|
}
|
|
1202
|
-
|
|
1190
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, newNode, childIndex, false);
|
|
1203
1191
|
block.childCount++;
|
|
1204
1192
|
block.setOrdinal(newNode, childIndex);
|
|
1205
1193
|
if (block.childCount < mergeTreeNodes_js_1.MaxNodesInBlock) {
|
|
@@ -1228,7 +1216,7 @@ class MergeTree {
|
|
|
1228
1216
|
// Update ordinals to reflect lowered child count
|
|
1229
1217
|
this.nodeUpdateOrdinals(node);
|
|
1230
1218
|
for (let i = 0; i < halfCount; i++) {
|
|
1231
|
-
|
|
1219
|
+
(0, mergeTreeNodes_js_1.assignChild)(newNode, node.children[halfCount + i], i, false);
|
|
1232
1220
|
node.children[halfCount + i] = undefined;
|
|
1233
1221
|
}
|
|
1234
1222
|
this.nodeUpdateLengthNewStructure(node);
|
|
@@ -1255,9 +1243,7 @@ class MergeTree {
|
|
|
1255
1243
|
* @param opArgs - The op args for the annotate op. this is passed to the merge tree callback if there is one
|
|
1256
1244
|
* @param rollback - Whether this is for a local rollback and what kind
|
|
1257
1245
|
*/
|
|
1258
|
-
annotateRange(start, end, propsOrAdjust, refSeq, clientId, seq, opArgs,
|
|
1259
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1260
|
-
rollback = segmentPropertiesManager_js_1.PropertiesRollback.None) {
|
|
1246
|
+
annotateRange(start, end, propsOrAdjust, refSeq, clientId, seq, opArgs, rollback = segmentPropertiesManager_js_1.PropertiesRollback.None) {
|
|
1261
1247
|
if (propsOrAdjust.adjust !== undefined) {
|
|
1262
1248
|
errorIfOptionNotTrue(this.options, "mergeTreeEnableAnnotateAdjust");
|
|
1263
1249
|
}
|
|
@@ -1265,7 +1251,6 @@ class MergeTree {
|
|
|
1265
1251
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1266
1252
|
const deltaSegments = [];
|
|
1267
1253
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1268
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1269
1254
|
let segmentGroup;
|
|
1270
1255
|
const opObj = propsOrAdjust.props ?? propsOrAdjust.adjust;
|
|
1271
1256
|
const annotateSegment = (segment) => {
|
|
@@ -1289,7 +1274,7 @@ class MergeTree {
|
|
|
1289
1274
|
}
|
|
1290
1275
|
return true;
|
|
1291
1276
|
};
|
|
1292
|
-
this.nodeMap(refSeq, clientId, annotateSegment, undefined,
|
|
1277
|
+
this.nodeMap(refSeq, clientId, annotateSegment, undefined, start, end);
|
|
1293
1278
|
// OpArgs == undefined => test code
|
|
1294
1279
|
if (deltaSegments.length > 0) {
|
|
1295
1280
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
@@ -1310,9 +1295,9 @@ class MergeTree {
|
|
|
1310
1295
|
this.ensureIntervalBoundary(endPos, refSeq, clientId);
|
|
1311
1296
|
let _overwrite = false;
|
|
1312
1297
|
const localOverlapWithRefs = [];
|
|
1298
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1313
1299
|
const movedSegments = [];
|
|
1314
1300
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1315
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1316
1301
|
const obliterate = {
|
|
1317
1302
|
clientId,
|
|
1318
1303
|
end: (0, localReference_js_1.createDetachedLocalReferencePosition)(undefined),
|
|
@@ -1324,7 +1309,7 @@ class MergeTree {
|
|
|
1324
1309
|
};
|
|
1325
1310
|
const { segment: startSeg } = this.getContainingSegment(start.pos, refSeq, clientId);
|
|
1326
1311
|
const { segment: endSeg } = this.getContainingSegment(end.pos, refSeq, clientId);
|
|
1327
|
-
(0, internal_1.assert)(startSeg
|
|
1312
|
+
(0, internal_1.assert)((0, mergeTreeNodes_js_1.isSegmentLeaf)(startSeg) && (0, mergeTreeNodes_js_1.isSegmentLeaf)(endSeg), 0xa3f /* segments cannot be undefined */);
|
|
1328
1313
|
obliterate.start = this.createLocalReferencePosition(startSeg, start.side === sequencePlace_js_1.Side.Before ? 0 : Math.max(startSeg.cachedLength - 1, 0), ops_js_1.ReferenceType.StayOnRemove, {
|
|
1329
1314
|
obliterate,
|
|
1330
1315
|
});
|
|
@@ -1345,7 +1330,7 @@ class MergeTree {
|
|
|
1345
1330
|
this.pendingSegments.push(obliterate.segmentGroup);
|
|
1346
1331
|
}
|
|
1347
1332
|
this.obliterates.addOrUpdate(obliterate);
|
|
1348
|
-
const markMoved = (segment, pos
|
|
1333
|
+
const markMoved = (segment, pos) => {
|
|
1349
1334
|
if ((start.side === sequencePlace_js_1.Side.After && startPos === pos + segment.cachedLength) || // exclusive start segment
|
|
1350
1335
|
(end.side === sequencePlace_js_1.Side.Before &&
|
|
1351
1336
|
endPos === pos &&
|
|
@@ -1355,30 +1340,34 @@ class MergeTree {
|
|
|
1355
1340
|
// These segments are outside of the obliteration range though, so return true to keep walking.
|
|
1356
1341
|
return true;
|
|
1357
1342
|
}
|
|
1358
|
-
const existingMoveInfo = (0,
|
|
1343
|
+
const existingMoveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
1359
1344
|
if (segment.prevObliterateByInserter?.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1360
1345
|
// We chose to not obliterate this segment because we are aware of an unacked local obliteration.
|
|
1361
1346
|
// The local obliterate has not been sequenced yet, so it is still the newest obliterate we are aware of.
|
|
1362
1347
|
// Other clients will also choose not to obliterate this segment because the most recent obliteration has the same clientId
|
|
1363
1348
|
return true;
|
|
1364
1349
|
}
|
|
1365
|
-
|
|
1350
|
+
const wasMovedOnInsert = clientId !== segment.clientId &&
|
|
1366
1351
|
segment.seq !== undefined &&
|
|
1367
1352
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
1368
|
-
(refSeq < segment.seq || segment.seq === constants_js_1.UnassignedSequenceNumber)
|
|
1369
|
-
segment.wasMovedOnInsert = true;
|
|
1370
|
-
}
|
|
1353
|
+
(refSeq < segment.seq || segment.seq === constants_js_1.UnassignedSequenceNumber);
|
|
1371
1354
|
if (existingMoveInfo === undefined) {
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1355
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1356
|
+
const movedSeg = (0, segmentInfos_js_1.overwriteInfo)(segment, {
|
|
1357
|
+
movedClientIds: [clientId],
|
|
1358
|
+
movedSeq: seq,
|
|
1359
|
+
localMovedSeq: localSeq,
|
|
1360
|
+
movedSeqs: [seq],
|
|
1361
|
+
wasMovedOnInsert,
|
|
1362
|
+
});
|
|
1363
|
+
if (!(0, segmentInfos_js_1.toRemovalInfo)(movedSeg)) {
|
|
1364
|
+
movedSegments.push(movedSeg);
|
|
1378
1365
|
}
|
|
1379
1366
|
}
|
|
1380
1367
|
else {
|
|
1381
1368
|
_overwrite = true;
|
|
1369
|
+
// never move wasMovedOnInsert from true to false
|
|
1370
|
+
existingMoveInfo.wasMovedOnInsert || (existingMoveInfo.wasMovedOnInsert = wasMovedOnInsert);
|
|
1382
1371
|
if (existingMoveInfo.movedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
1383
1372
|
// we moved this locally, but someone else moved it first
|
|
1384
1373
|
// so put them at the head of the list
|
|
@@ -1397,6 +1386,7 @@ class MergeTree {
|
|
|
1397
1386
|
existingMoveInfo.movedSeqs.push(seq);
|
|
1398
1387
|
}
|
|
1399
1388
|
}
|
|
1389
|
+
(0, segmentInfos_js_1.assertMoved)(segment);
|
|
1400
1390
|
// Save segment so can assign moved sequence number when acked by server
|
|
1401
1391
|
if (this.collabWindow.collaborating) {
|
|
1402
1392
|
if (segment.movedSeq === constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1411,7 +1401,7 @@ class MergeTree {
|
|
|
1411
1401
|
}
|
|
1412
1402
|
return true;
|
|
1413
1403
|
};
|
|
1414
|
-
const afterMarkMoved = (node
|
|
1404
|
+
const afterMarkMoved = (node) => {
|
|
1415
1405
|
if (_overwrite) {
|
|
1416
1406
|
this.nodeUpdateLengthNewStructure(node);
|
|
1417
1407
|
}
|
|
@@ -1420,21 +1410,21 @@ class MergeTree {
|
|
|
1420
1410
|
}
|
|
1421
1411
|
return true;
|
|
1422
1412
|
};
|
|
1423
|
-
this.nodeMap(refSeq, clientId, markMoved,
|
|
1413
|
+
this.nodeMap(refSeq, clientId, markMoved, afterMarkMoved, start.pos, end.pos + 1, // include the segment containing the end reference
|
|
1424
1414
|
undefined, seq === constants_js_1.UnassignedSequenceNumber ? undefined : seq);
|
|
1425
1415
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
1426
1416
|
// opArgs == undefined => test code
|
|
1427
1417
|
if (start.pos !== end.pos || start.side !== end.side) {
|
|
1428
1418
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1429
1419
|
operation: ops_js_1.MergeTreeDeltaType.OBLITERATE,
|
|
1430
|
-
deltaSegments: movedSegments,
|
|
1420
|
+
deltaSegments: movedSegments.map((segment) => ({ segment })),
|
|
1431
1421
|
});
|
|
1432
1422
|
}
|
|
1433
1423
|
// these events are newly removed
|
|
1434
1424
|
// so we slide after eventing in case the consumer wants to make reference
|
|
1435
1425
|
// changes at remove time, like add a ref to track undo redo.
|
|
1436
1426
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1437
|
-
this.slideAckedRemovedSegmentReferences(movedSegments
|
|
1427
|
+
this.slideAckedRemovedSegmentReferences(movedSegments);
|
|
1438
1428
|
}
|
|
1439
1429
|
if (this.collabWindow.collaborating &&
|
|
1440
1430
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1457,19 +1447,22 @@ class MergeTree {
|
|
|
1457
1447
|
let _overwrite = false;
|
|
1458
1448
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1459
1449
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1460
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1461
1450
|
let segmentGroup;
|
|
1451
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1462
1452
|
const removedSegments = [];
|
|
1463
1453
|
const localOverlapWithRefs = [];
|
|
1464
1454
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1465
1455
|
const markRemoved = (segment, pos, _start, _end) => {
|
|
1466
|
-
const existingRemovalInfo = (0,
|
|
1456
|
+
const existingRemovalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
1467
1457
|
if (existingRemovalInfo === undefined) {
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1458
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1459
|
+
const removed = (0, segmentInfos_js_1.overwriteInfo)(segment, {
|
|
1460
|
+
removedClientIds: [clientId],
|
|
1461
|
+
removedSeq: seq,
|
|
1462
|
+
localRemovedSeq: localSeq,
|
|
1463
|
+
});
|
|
1464
|
+
if (!(0, segmentInfos_js_1.toMoveInfo)(removed)) {
|
|
1465
|
+
removedSegments.push(removed);
|
|
1473
1466
|
}
|
|
1474
1467
|
}
|
|
1475
1468
|
else {
|
|
@@ -1490,6 +1483,7 @@ class MergeTree {
|
|
|
1490
1483
|
existingRemovalInfo.removedClientIds.push(clientId);
|
|
1491
1484
|
}
|
|
1492
1485
|
}
|
|
1486
|
+
(0, segmentInfos_js_1.assertRemoved)(segment);
|
|
1493
1487
|
// Save segment so we can assign removed sequence number when acked by server
|
|
1494
1488
|
if (this.collabWindow.collaborating) {
|
|
1495
1489
|
if (segment.removedSeq === constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1504,7 +1498,7 @@ class MergeTree {
|
|
|
1504
1498
|
}
|
|
1505
1499
|
return true;
|
|
1506
1500
|
};
|
|
1507
|
-
const afterMarkRemoved = (node
|
|
1501
|
+
const afterMarkRemoved = (node) => {
|
|
1508
1502
|
if (_overwrite) {
|
|
1509
1503
|
this.nodeUpdateLengthNewStructure(node);
|
|
1510
1504
|
}
|
|
@@ -1513,7 +1507,7 @@ class MergeTree {
|
|
|
1513
1507
|
}
|
|
1514
1508
|
return true;
|
|
1515
1509
|
};
|
|
1516
|
-
this.nodeMap(refSeq, clientId, markRemoved,
|
|
1510
|
+
this.nodeMap(refSeq, clientId, markRemoved, afterMarkRemoved, start, end);
|
|
1517
1511
|
// these segments are already viewed as being removed locally and are not event-ed
|
|
1518
1512
|
// so can slide non-StayOnRemove refs immediately
|
|
1519
1513
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
@@ -1521,14 +1515,14 @@ class MergeTree {
|
|
|
1521
1515
|
if (removedSegments.length > 0) {
|
|
1522
1516
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1523
1517
|
operation: ops_js_1.MergeTreeDeltaType.REMOVE,
|
|
1524
|
-
deltaSegments: removedSegments,
|
|
1518
|
+
deltaSegments: removedSegments.map((segment) => ({ segment })),
|
|
1525
1519
|
});
|
|
1526
1520
|
}
|
|
1527
1521
|
// these events are newly removed
|
|
1528
1522
|
// so we slide after eventing in case the consumer wants to make reference
|
|
1529
1523
|
// changes at remove time, like add a ref to track undo redo.
|
|
1530
1524
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1531
|
-
this.slideAckedRemovedSegmentReferences(removedSegments
|
|
1525
|
+
this.slideAckedRemovedSegmentReferences(removedSegments);
|
|
1532
1526
|
}
|
|
1533
1527
|
if (this.collabWindow.collaborating &&
|
|
1534
1528
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1539,24 +1533,21 @@ class MergeTree {
|
|
|
1539
1533
|
/**
|
|
1540
1534
|
* Revert an unacked local op
|
|
1541
1535
|
*/
|
|
1542
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1543
1536
|
rollback(op, localOpMetadata) {
|
|
1544
1537
|
if (op.type === ops_js_1.MergeTreeDeltaType.REMOVE) {
|
|
1545
|
-
const pendingSegmentGroup = this.pendingSegments.pop
|
|
1538
|
+
const pendingSegmentGroup = this.pendingSegments.pop()?.data;
|
|
1546
1539
|
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
|
|
1547
1540
|
throw new Error("Rollback op doesn't match last edit");
|
|
1548
1541
|
}
|
|
1549
1542
|
// Disabling because a for of loop causes the type of segment to be ISegmentLeaf, which does not have parent information stored
|
|
1550
1543
|
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1551
1544
|
pendingSegmentGroup.segments.forEach((segment) => {
|
|
1552
|
-
const segmentSegmentGroup = segment?.segmentGroups?.pop
|
|
1545
|
+
const segmentSegmentGroup = segment?.segmentGroups?.pop();
|
|
1553
1546
|
(0, internal_1.assert)(segmentSegmentGroup === pendingSegmentGroup, 0x3ee /* Unexpected segmentGroup in segment */);
|
|
1554
|
-
(0, internal_1.assert)(segment.removedClientIds
|
|
1555
|
-
|
|
1556
|
-
segment
|
|
1557
|
-
|
|
1558
|
-
segment.localRemovedSeq = undefined;
|
|
1559
|
-
for (let updateNode = segment.parent; updateNode !== undefined; updateNode = updateNode.parent) {
|
|
1547
|
+
(0, internal_1.assert)((0, segmentInfos_js_1.isRemoved)(segment) && segment.removedClientIds[0] === this.collabWindow.clientId, 0x39d /* Rollback segment removedClientId does not match local client */);
|
|
1548
|
+
let updateNode = segment.parent;
|
|
1549
|
+
(0, segmentInfos_js_1.removeRemovalInfo)(segment);
|
|
1550
|
+
for (updateNode; updateNode !== undefined; updateNode = updateNode.parent) {
|
|
1560
1551
|
this.blockUpdateLength(updateNode, constants_js_1.UnassignedSequenceNumber, this.collabWindow.clientId);
|
|
1561
1552
|
}
|
|
1562
1553
|
// Note: optional chaining short-circuits:
|
|
@@ -1569,7 +1560,7 @@ class MergeTree {
|
|
|
1569
1560
|
}
|
|
1570
1561
|
else if (op.type === ops_js_1.MergeTreeDeltaType.INSERT ||
|
|
1571
1562
|
op.type === ops_js_1.MergeTreeDeltaType.ANNOTATE) {
|
|
1572
|
-
const pendingSegmentGroup = this.pendingSegments.pop
|
|
1563
|
+
const pendingSegmentGroup = this.pendingSegments.pop()?.data;
|
|
1573
1564
|
if (pendingSegmentGroup === undefined ||
|
|
1574
1565
|
pendingSegmentGroup !== localOpMetadata ||
|
|
1575
1566
|
(op.type === ops_js_1.MergeTreeDeltaType.ANNOTATE && !pendingSegmentGroup.previousProps)) {
|
|
@@ -1577,7 +1568,7 @@ class MergeTree {
|
|
|
1577
1568
|
}
|
|
1578
1569
|
let i = 0;
|
|
1579
1570
|
for (const segment of pendingSegmentGroup.segments) {
|
|
1580
|
-
const segmentSegmentGroup = segment?.segmentGroups?.pop
|
|
1571
|
+
const segmentSegmentGroup = segment?.segmentGroups?.pop();
|
|
1581
1572
|
(0, internal_1.assert)(segmentSegmentGroup === pendingSegmentGroup, 0x3ef /* Unexpected segmentGroup in segment */);
|
|
1582
1573
|
const start = this.findRollbackPosition(segment);
|
|
1583
1574
|
if (op.type === ops_js_1.MergeTreeDeltaType.INSERT) {
|
|
@@ -1609,7 +1600,7 @@ class MergeTree {
|
|
|
1609
1600
|
return false;
|
|
1610
1601
|
}
|
|
1611
1602
|
// If not removed, increase position
|
|
1612
|
-
if (
|
|
1603
|
+
if (!(0, segmentInfos_js_1.isRemoved)(seg)) {
|
|
1613
1604
|
segmentPosition += seg.cachedLength;
|
|
1614
1605
|
}
|
|
1615
1606
|
return true;
|
|
@@ -1643,8 +1634,10 @@ class MergeTree {
|
|
|
1643
1634
|
segment = this.endOfTree;
|
|
1644
1635
|
}
|
|
1645
1636
|
else {
|
|
1637
|
+
(0, mergeTreeNodes_js_1.assertSegmentLeaf)(_segment);
|
|
1646
1638
|
segment = _segment;
|
|
1647
1639
|
}
|
|
1640
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1648
1641
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(segment);
|
|
1649
1642
|
const segRef = localRefs.createLocalRef(offset, refType, properties, slidingPreference, canSlideToEndpoint);
|
|
1650
1643
|
return segRef;
|
|
@@ -1672,7 +1665,7 @@ class MergeTree {
|
|
|
1672
1665
|
affectedSegments.remove(segmentToSlide);
|
|
1673
1666
|
affectedSegments.insertAfter(lastLocalSegment, segmentToSlide.data);
|
|
1674
1667
|
}
|
|
1675
|
-
else if (isRemoved(segmentToSlide.data)) {
|
|
1668
|
+
else if ((0, segmentInfos_js_1.isRemoved)(segmentToSlide.data)) {
|
|
1676
1669
|
(0, internal_1.assert)(segmentToSlide.data.localRemovedSeq !== undefined, 0x54d /* Removed segment that hasnt had its removal acked should be locally removed */);
|
|
1677
1670
|
// Slide each locally removed item past all segments that have localSeq > lremoveItem.localSeq
|
|
1678
1671
|
// but not past remotely removed segments;
|
|
@@ -1706,7 +1699,7 @@ class MergeTree {
|
|
|
1706
1699
|
for (let i = 0; i < newOrder.length; i++) {
|
|
1707
1700
|
const seg = newOrder[i];
|
|
1708
1701
|
const { parent, index, ordinal } = currentOrder[i];
|
|
1709
|
-
|
|
1702
|
+
(0, mergeTreeNodes_js_1.assignChild)(parent, seg, index, false);
|
|
1710
1703
|
seg.ordinal = ordinal;
|
|
1711
1704
|
}
|
|
1712
1705
|
for (const [segment, groups] of perSegmentTrackingGroups.entries()) {
|
|
@@ -1766,7 +1759,7 @@ class MergeTree {
|
|
|
1766
1759
|
}
|
|
1767
1760
|
};
|
|
1768
1761
|
(0, mergeTreeNodeWalk_js_1.walkAllChildSegments)(this.root, (seg) => {
|
|
1769
|
-
if (isRemoved(seg) || seg.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1762
|
+
if ((0, segmentInfos_js_1.isRemoved)(seg) || seg.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1770
1763
|
if (isRemovedAndAcked(seg)) {
|
|
1771
1764
|
rangeContainsRemoteRemovedSegs = true;
|
|
1772
1765
|
}
|
|
@@ -1873,7 +1866,7 @@ class MergeTree {
|
|
|
1873
1866
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1874
1867
|
}
|
|
1875
1868
|
}
|
|
1876
|
-
this.nodeMap(refSeq, clientId, handler, accum, undefined, start, end, undefined, visibilitySeq);
|
|
1869
|
+
this.nodeMap(refSeq, clientId, (seg, pos, _start, _end) => handler(seg, pos, refSeq, clientId, _start, _end, accum), undefined, start, end, undefined, visibilitySeq);
|
|
1877
1870
|
}
|
|
1878
1871
|
/**
|
|
1879
1872
|
* Map over all visible segments in a given range
|
|
@@ -1898,7 +1891,7 @@ class MergeTree {
|
|
|
1898
1891
|
* but it will not count as a segment within the range. That is, it will be
|
|
1899
1892
|
* ignored for the purposes of tracking when traversal should end.
|
|
1900
1893
|
*/
|
|
1901
|
-
nodeMap(refSeq, clientId, leaf,
|
|
1894
|
+
nodeMap(refSeq, clientId, leaf, post, start = 0, end, localSeq, visibilitySeq = refSeq) {
|
|
1902
1895
|
const endPos = end ?? this.nodeLength(this.root, refSeq, clientId, localSeq) ?? 0;
|
|
1903
1896
|
if (endPos === start) {
|
|
1904
1897
|
return;
|
|
@@ -1925,14 +1918,12 @@ class MergeTree {
|
|
|
1925
1918
|
return mergeTreeNodeWalk_js_1.NodeAction.Skip;
|
|
1926
1919
|
}
|
|
1927
1920
|
if (node.isLeaf()) {
|
|
1928
|
-
if (leaf(node, pos,
|
|
1921
|
+
if (leaf(node, pos, start - pos, endPos - pos) === false) {
|
|
1929
1922
|
return mergeTreeNodeWalk_js_1.NodeAction.Exit;
|
|
1930
1923
|
}
|
|
1931
1924
|
pos = nextPos;
|
|
1932
1925
|
}
|
|
1933
|
-
}, undefined, post
|
|
1934
|
-
? undefined
|
|
1935
|
-
: (block) => post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum));
|
|
1926
|
+
}, undefined, post);
|
|
1936
1927
|
}
|
|
1937
1928
|
}
|
|
1938
1929
|
exports.MergeTree = MergeTree;
|