@fluidframework/merge-tree 2.12.0 → 2.20.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 +46 -0
- package/api-report/merge-tree.legacy.alpha.api.md +0 -108
- 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 -16
- 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 +2 -1
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +0 -4
- package/dist/localReference.d.ts +5 -7
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +1 -3
- 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 +187 -228
- package/dist/mergeTree.js.map +1 -1
- 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 +65 -325
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +96 -130
- 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/opBuilder.d.ts +0 -5
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js +0 -5
- package/dist/opBuilder.js.map +1 -1
- package/dist/package.json +2 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +29 -31
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +3 -2
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +5 -2
- 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 +10 -14
- 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 +251 -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 +36 -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.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.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 +28 -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.js +1 -1
- 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 -16
- 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 +2 -1
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.js.map +1 -1
- package/lib/index.d.ts +1 -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 +0 -4
- package/lib/localReference.d.ts +5 -7
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +1 -3
- 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 +175 -220
- package/lib/mergeTree.js.map +1 -1
- 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 +65 -325
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +92 -127
- 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/opBuilder.d.ts +0 -5
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js +0 -5
- package/lib/opBuilder.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +26 -28
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +3 -2
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +5 -2
- 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 +8 -12
- 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 +251 -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 +36 -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.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.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.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 +29 -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.js +1 -1
- 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 +77 -19
- package/src/MergeTreeTextHelper.ts +2 -4
- package/src/attributionPolicy.ts +5 -13
- package/src/client.ts +55 -44
- package/src/endOfTreeSegment.ts +3 -5
- package/src/index.ts +0 -7
- package/src/localReference.ts +6 -8
- package/src/mergeTree.ts +233 -290
- package/src/mergeTreeNodeWalk.ts +3 -2
- package/src/mergeTreeNodes.ts +160 -490
- package/src/mergeTreeTracking.ts +0 -3
- package/src/opBuilder.ts +0 -5
- package/src/partialLengths.ts +40 -29
- package/src/perspective.ts +23 -4
- package/src/referencePositions.ts +4 -1
- package/src/revertibles.ts +19 -16
- package/src/segmentGroupCollection.ts +7 -18
- package/src/segmentInfos.ts +371 -0
- package/src/snapshotLoader.ts +56 -57
- package/src/snapshotV1.ts +14 -16
- package/src/snapshotlegacy.ts +12 -17
- package/src/sortedSegmentSet.ts +6 -8
- package/src/zamboni.ts +10 -12
package/dist/mergeTree.js
CHANGED
|
@@ -22,45 +22,25 @@ 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
|
-
// eslint-disable-next-line import/no-deprecated
|
|
33
|
-
function markSegmentMoved(seg, moveInfo) {
|
|
34
|
-
seg.moveDst = moveInfo.moveDst;
|
|
35
|
-
seg.movedClientIds = [...moveInfo.movedClientIds];
|
|
36
|
-
seg.movedSeqs = [moveInfo.movedSeq];
|
|
37
|
-
seg.movedSeq = moveInfo.movedSeq;
|
|
38
|
-
seg.localMovedSeq = moveInfo.localMovedSeq;
|
|
39
|
-
seg.wasMovedOnInsert = moveInfo.wasMovedOnInsert;
|
|
40
|
-
}
|
|
41
|
-
// eslint-disable-next-line import/no-deprecated
|
|
42
|
-
function isMoved(segment) {
|
|
43
|
-
return (0, mergeTreeNodes_js_1.toMoveInfo)(segment) !== undefined;
|
|
44
|
-
}
|
|
45
|
-
// eslint-disable-next-line import/no-deprecated
|
|
46
|
-
function isRemoved(segment) {
|
|
47
|
-
return (0, mergeTreeNodes_js_1.toRemovalInfo)(segment) !== undefined;
|
|
48
|
-
}
|
|
49
|
-
// eslint-disable-next-line import/no-deprecated
|
|
50
31
|
function isRemovedAndAcked(segment) {
|
|
51
|
-
const removalInfo = (0,
|
|
32
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
52
33
|
return removalInfo !== undefined && removalInfo.removedSeq !== constants_js_1.UnassignedSequenceNumber;
|
|
53
34
|
}
|
|
54
|
-
// eslint-disable-next-line import/no-deprecated
|
|
55
35
|
function isMovedAndAcked(segment) {
|
|
56
|
-
const moveInfo = (0,
|
|
36
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
57
37
|
return moveInfo !== undefined && moveInfo.movedSeq !== constants_js_1.UnassignedSequenceNumber;
|
|
58
38
|
}
|
|
59
39
|
function isRemovedAndAckedOrMovedAndAcked(segment) {
|
|
60
40
|
return isRemovedAndAcked(segment) || isMovedAndAcked(segment);
|
|
61
41
|
}
|
|
62
42
|
function isRemovedOrMoved(segment) {
|
|
63
|
-
return isRemoved(segment) || isMoved(segment);
|
|
43
|
+
return (0, segmentInfos_js_1.isRemoved)(segment) || (0, segmentInfos_js_1.isMoved)(segment);
|
|
64
44
|
}
|
|
65
45
|
function nodeTotalLength(mergeTree, node) {
|
|
66
46
|
if (!node.isLeaf()) {
|
|
@@ -90,29 +70,25 @@ function ackSegment(segment, segmentGroup, opArgs) {
|
|
|
90
70
|
return true;
|
|
91
71
|
}
|
|
92
72
|
case ops_js_1.MergeTreeDeltaType.REMOVE: {
|
|
93
|
-
|
|
94
|
-
const removalInfo = (0, mergeTreeNodes_js_1.toRemovalInfo)(segment);
|
|
95
|
-
(0, internal_1.assert)(removalInfo !== undefined, 0x046 /* "On remove ack, missing removal info!" */);
|
|
73
|
+
(0, segmentInfos_js_1.assertRemoved)(segment);
|
|
96
74
|
segment.localRemovedSeq = undefined;
|
|
97
|
-
if (
|
|
98
|
-
|
|
75
|
+
if (segment.removedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
76
|
+
segment.removedSeq = sequenceNumber;
|
|
99
77
|
return true;
|
|
100
78
|
}
|
|
101
79
|
return false;
|
|
102
80
|
}
|
|
103
81
|
case ops_js_1.MergeTreeDeltaType.OBLITERATE:
|
|
104
82
|
case ops_js_1.MergeTreeDeltaType.OBLITERATE_SIDED: {
|
|
105
|
-
|
|
106
|
-
const moveInfo = (0, mergeTreeNodes_js_1.toMoveInfo)(segment);
|
|
107
|
-
(0, internal_1.assert)(moveInfo !== undefined, 0x86e /* On obliterate ack, missing move info! */);
|
|
83
|
+
(0, segmentInfos_js_1.assertMoved)(segment);
|
|
108
84
|
const obliterateInfo = segmentGroup.obliterateInfo;
|
|
109
85
|
(0, internal_1.assert)(obliterateInfo !== undefined, 0xa40 /* must have obliterate info */);
|
|
110
86
|
segment.localMovedSeq = obliterateInfo.localSeq = undefined;
|
|
111
|
-
const seqIdx =
|
|
87
|
+
const seqIdx = segment.movedSeqs.indexOf(constants_js_1.UnassignedSequenceNumber);
|
|
112
88
|
(0, internal_1.assert)(seqIdx !== -1, 0x86f /* expected movedSeqs to contain unacked seq */);
|
|
113
|
-
|
|
114
|
-
if (
|
|
115
|
-
|
|
89
|
+
segment.movedSeqs[seqIdx] = sequenceNumber;
|
|
90
|
+
if (segment.movedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
91
|
+
segment.movedSeq = sequenceNumber;
|
|
116
92
|
return true;
|
|
117
93
|
}
|
|
118
94
|
return false;
|
|
@@ -151,7 +127,6 @@ exports.findRootMergeBlock = findRootMergeBlock;
|
|
|
151
127
|
* entries for all segments visited during excursion.
|
|
152
128
|
* This can reduce the number of times the tree needs to be scanned if a range containing many
|
|
153
129
|
* SlideOnRemove references is removed.
|
|
154
|
-
* @internal
|
|
155
130
|
*/
|
|
156
131
|
function getSlideToSegment(segment, slidingPreference = localReference_js_1.SlidingPreference.FORWARD, cache, useNewSlidingBehavior = false) {
|
|
157
132
|
if (!segment ||
|
|
@@ -171,7 +146,8 @@ function getSlideToSegment(segment, slidingPreference = localReference_js_1.Slid
|
|
|
171
146
|
return false;
|
|
172
147
|
}
|
|
173
148
|
if (cache !== undefined &&
|
|
174
|
-
(seg
|
|
149
|
+
((0, segmentInfos_js_1.toRemovalInfo)(seg)?.removedSeq === (0, segmentInfos_js_1.toRemovalInfo)(segment)?.removedSeq ||
|
|
150
|
+
(0, segmentInfos_js_1.toMoveInfo)(seg)?.movedSeq === (0, segmentInfos_js_1.toMoveInfo)(segment)?.movedSeq)) {
|
|
175
151
|
cache.set(seg, result);
|
|
176
152
|
}
|
|
177
153
|
return true;
|
|
@@ -218,7 +194,7 @@ function getSlideToSegment(segment, slidingPreference = localReference_js_1.Slid
|
|
|
218
194
|
* @internal
|
|
219
195
|
*/
|
|
220
196
|
function getSlideToSegoff(segoff, slidingPreference = localReference_js_1.SlidingPreference.FORWARD, useNewSlidingBehavior = false) {
|
|
221
|
-
if (segoff.segment
|
|
197
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(segoff.segment)) {
|
|
222
198
|
return segoff;
|
|
223
199
|
}
|
|
224
200
|
const [segment, _] = getSlideToSegment(segoff.segment, slidingPreference, undefined, useNewSlidingBehavior);
|
|
@@ -246,7 +222,6 @@ class Obliterates {
|
|
|
246
222
|
* See https://github.com/microsoft/FluidFramework/blob/main/packages/dds/merge-tree/docs/Obliterate.md#remote-perspective
|
|
247
223
|
* for additional context
|
|
248
224
|
*/
|
|
249
|
-
// eslint-disable-next-line import/no-deprecated
|
|
250
225
|
this.seqOrdered = new index_js_1.DoublyLinkedList();
|
|
251
226
|
/**
|
|
252
227
|
* This contains a sorted lists of all obliterate starts
|
|
@@ -264,7 +239,6 @@ class Obliterates {
|
|
|
264
239
|
this.mergeTree.removeLocalReferencePosition(ob.data.end);
|
|
265
240
|
}
|
|
266
241
|
}
|
|
267
|
-
// eslint-disable-next-line import/no-deprecated
|
|
268
242
|
addOrUpdate(obliterateInfo) {
|
|
269
243
|
const { seq, start } = obliterateInfo;
|
|
270
244
|
if (seq !== constants_js_1.UnassignedSequenceNumber) {
|
|
@@ -275,14 +249,14 @@ class Obliterates {
|
|
|
275
249
|
empty() {
|
|
276
250
|
return this.startOrdered.size === 0;
|
|
277
251
|
}
|
|
278
|
-
// eslint-disable-next-line import/no-deprecated
|
|
279
252
|
findOverlapping(seg) {
|
|
280
|
-
// eslint-disable-next-line import/no-deprecated
|
|
281
253
|
const overlapping = [];
|
|
282
254
|
for (const start of this.startOrdered.items) {
|
|
283
|
-
|
|
255
|
+
const startSeg = start.getSegment();
|
|
256
|
+
if ((0, segmentInfos_js_1.isMergeNodeInfo)(startSeg) && startSeg.ordinal <= seg.ordinal) {
|
|
284
257
|
const ob = start.properties?.obliterate;
|
|
285
|
-
|
|
258
|
+
const endSeg = ob.end.getSegment();
|
|
259
|
+
if ((0, segmentInfos_js_1.isMergeNodeInfo)(endSeg) && endSeg.ordinal >= seg.ordinal) {
|
|
286
260
|
overlapping.push(ob);
|
|
287
261
|
}
|
|
288
262
|
}
|
|
@@ -300,9 +274,7 @@ class Obliterates {
|
|
|
300
274
|
class MergeTree {
|
|
301
275
|
constructor(options) {
|
|
302
276
|
this.options = options;
|
|
303
|
-
// eslint-disable-next-line import/no-deprecated
|
|
304
277
|
this.collabWindow = new mergeTreeNodes_js_1.CollaborationWindow();
|
|
305
|
-
// eslint-disable-next-line import/no-deprecated
|
|
306
278
|
this.pendingSegments = new index_js_1.DoublyLinkedList();
|
|
307
279
|
this.segmentsToScour = new internal_1.Heap(LRUSegmentComparer);
|
|
308
280
|
/**
|
|
@@ -320,6 +292,7 @@ class MergeTree {
|
|
|
320
292
|
return {};
|
|
321
293
|
}
|
|
322
294
|
const next = segment.splitAt(pos);
|
|
295
|
+
(0, mergeTreeNodes_js_1.assertSegmentLeaf)(next);
|
|
323
296
|
if (segment?.segmentGroups) {
|
|
324
297
|
next.segmentGroups ?? (next.segmentGroups = new segmentGroupCollection_js_1.SegmentGroupCollection(next));
|
|
325
298
|
segment.segmentGroups.copyTo(next.segmentGroups);
|
|
@@ -363,8 +336,8 @@ class MergeTree {
|
|
|
363
336
|
* numbers corresponding to un-acked operations give valid results.
|
|
364
337
|
*/
|
|
365
338
|
localNetLength(segment, refSeq, localSeq) {
|
|
366
|
-
const removalInfo = (0,
|
|
367
|
-
const moveInfo = (0,
|
|
339
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
340
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
368
341
|
if (localSeq === undefined) {
|
|
369
342
|
if (removalInfo !== undefined || moveInfo !== undefined) {
|
|
370
343
|
if ((!!removalInfo && !(0, mergeTreeNodes_js_1.seqLTE)(removalInfo.removedSeq, this.collabWindow.minSeq)) ||
|
|
@@ -382,7 +355,9 @@ class MergeTree {
|
|
|
382
355
|
}
|
|
383
356
|
(0, internal_1.assert)(refSeq !== undefined, 0x398 /* localSeq provided for local length without refSeq */);
|
|
384
357
|
(0, internal_1.assert)(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
|
|
385
|
-
const { seq
|
|
358
|
+
const { seq } = segment;
|
|
359
|
+
const { removedSeq, localRemovedSeq } = removalInfo ?? {};
|
|
360
|
+
const { movedSeq, localMovedSeq } = moveInfo ?? {};
|
|
386
361
|
if (seq === constants_js_1.UnassignedSequenceNumber) {
|
|
387
362
|
(0, internal_1.assert)(segment.localSeq !== undefined, 0x39a /* unacked segment with undefined localSeq */);
|
|
388
363
|
// inserted locally, still un-acked
|
|
@@ -418,7 +393,7 @@ class MergeTree {
|
|
|
418
393
|
}
|
|
419
394
|
addNode(block, node) {
|
|
420
395
|
const index = block.childCount++;
|
|
421
|
-
|
|
396
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, node, index, false);
|
|
422
397
|
return index;
|
|
423
398
|
}
|
|
424
399
|
reloadFromSegments(segments) {
|
|
@@ -512,12 +487,12 @@ class MergeTree {
|
|
|
512
487
|
(0, internal_1.assert)(localSeq === undefined || clientId === this.collabWindow.clientId, 0x39b /* localSeq provided for non-local client */);
|
|
513
488
|
let segment;
|
|
514
489
|
let offset;
|
|
515
|
-
const leaf = (leafSeg,
|
|
490
|
+
const leaf = (leafSeg, _, start) => {
|
|
516
491
|
segment = leafSeg;
|
|
517
492
|
offset = start;
|
|
518
493
|
return false;
|
|
519
494
|
};
|
|
520
|
-
this.nodeMap(refSeq, clientId, leaf, undefined,
|
|
495
|
+
this.nodeMap(refSeq, clientId, leaf, undefined, pos, pos + 1, localSeq);
|
|
521
496
|
return { segment, offset };
|
|
522
497
|
}
|
|
523
498
|
/**
|
|
@@ -542,9 +517,7 @@ class MergeTree {
|
|
|
542
517
|
*/
|
|
543
518
|
slideAckedRemovedSegmentReferences(segments) {
|
|
544
519
|
// References are slid in groups to preserve their order.
|
|
545
|
-
// eslint-disable-next-line import/no-deprecated
|
|
546
520
|
let currentForwardSlideGroup = [];
|
|
547
|
-
// eslint-disable-next-line import/no-deprecated
|
|
548
521
|
let currentBackwardSlideGroup = [];
|
|
549
522
|
let currentForwardMaybeEndpoint;
|
|
550
523
|
let currentForwardSlideDestination;
|
|
@@ -552,9 +525,7 @@ class MergeTree {
|
|
|
552
525
|
let currentBackwardMaybeEndpoint;
|
|
553
526
|
let currentBackwardSlideDestination;
|
|
554
527
|
let currentBackwardSlideIsForward;
|
|
555
|
-
const slideGroup = (currentSlideDestination, currentSlideIsForward,
|
|
556
|
-
// eslint-disable-next-line import/no-deprecated
|
|
557
|
-
currentSlideGroup, pred, maybeEndpoint) => {
|
|
528
|
+
const slideGroup = (currentSlideDestination, currentSlideIsForward, currentSlideGroup, pred, maybeEndpoint) => {
|
|
558
529
|
if (currentSlideIsForward === undefined) {
|
|
559
530
|
return;
|
|
560
531
|
}
|
|
@@ -562,7 +533,6 @@ class MergeTree {
|
|
|
562
533
|
const endpointRefsToAdd = currentSlideGroup.map((collection) => (0, localReference_js_1.filterLocalReferencePositions)(collection, (ref) => pred(ref) && !!ref.canSlideToEndpoint));
|
|
563
534
|
if (maybeEndpoint) {
|
|
564
535
|
const endpoint = maybeEndpoint === "start" ? this.startOfTree : this.endOfTree;
|
|
565
|
-
// eslint-disable-next-line import/no-deprecated
|
|
566
536
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(endpoint);
|
|
567
537
|
if (currentSlideIsForward) {
|
|
568
538
|
localRefs.addBeforeTombstones(...endpointRefsToAdd);
|
|
@@ -583,7 +553,6 @@ class MergeTree {
|
|
|
583
553
|
}
|
|
584
554
|
}
|
|
585
555
|
else {
|
|
586
|
-
// eslint-disable-next-line import/no-deprecated
|
|
587
556
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(currentSlideDestination);
|
|
588
557
|
if (currentSlideIsForward) {
|
|
589
558
|
localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
|
|
@@ -593,9 +562,7 @@ class MergeTree {
|
|
|
593
562
|
}
|
|
594
563
|
}
|
|
595
564
|
};
|
|
596
|
-
const trySlideSegment = (segment, currentSlideDestination, currentSlideIsForward,
|
|
597
|
-
// eslint-disable-next-line import/no-deprecated
|
|
598
|
-
currentSlideGroup, pred, slidingPreference, currentMaybeEndpoint, reassign) => {
|
|
565
|
+
const trySlideSegment = (segment, currentSlideDestination, currentSlideIsForward, currentSlideGroup, pred, slidingPreference, currentMaybeEndpoint, reassign) => {
|
|
599
566
|
// avoid sliding logic if this segment doesn't have any references
|
|
600
567
|
// with the given sliding preference
|
|
601
568
|
if (!segment.localRefs || !(0, localReference_js_1.anyLocalReferencePosition)(segment.localRefs, pred)) {
|
|
@@ -652,7 +619,6 @@ class MergeTree {
|
|
|
652
619
|
if (this.localPartialsComputed) {
|
|
653
620
|
return;
|
|
654
621
|
}
|
|
655
|
-
// eslint-disable-next-line import/no-deprecated
|
|
656
622
|
const rebaseCollabWindow = new mergeTreeNodes_js_1.CollaborationWindow();
|
|
657
623
|
rebaseCollabWindow.loadFrom(this.collabWindow);
|
|
658
624
|
if (refSeq < this.collabWindow.minSeq) {
|
|
@@ -682,8 +648,8 @@ class MergeTree {
|
|
|
682
648
|
// Sequence number within window
|
|
683
649
|
if (node.isLeaf()) {
|
|
684
650
|
const segment = node;
|
|
685
|
-
const removalInfo = (0,
|
|
686
|
-
const moveInfo = (0,
|
|
651
|
+
const removalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
652
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
687
653
|
if (removalInfo !== undefined) {
|
|
688
654
|
if ((0, mergeTreeNodes_js_1.seqLTE)(removalInfo.removedSeq, this.collabWindow.minSeq)) {
|
|
689
655
|
return undefined;
|
|
@@ -736,24 +702,26 @@ class MergeTree {
|
|
|
736
702
|
*/
|
|
737
703
|
referencePositionToLocalPosition(refPos, refSeq = Number.MAX_SAFE_INTEGER, clientId = this.collabWindow.clientId, localSeq = this.collabWindow.localSeq) {
|
|
738
704
|
const seg = refPos.getSegment();
|
|
739
|
-
if (
|
|
705
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(seg)) {
|
|
740
706
|
// We have no idea where this reference is, because it refers to a segment which is not in the tree.
|
|
741
707
|
return referencePositions_js_1.DetachedReferencePosition;
|
|
742
708
|
}
|
|
743
709
|
if (refPos.isLeaf()) {
|
|
744
|
-
return this.getPosition(
|
|
710
|
+
return this.getPosition(seg, refSeq, clientId, localSeq);
|
|
745
711
|
}
|
|
746
712
|
if ((0, referencePositions_js_1.refTypeIncludesFlag)(refPos, ops_js_1.ReferenceType.Transient) || seg.localRefs?.has(refPos)) {
|
|
747
713
|
if (seg !== this.startOfTree &&
|
|
748
714
|
seg !== this.endOfTree &&
|
|
749
715
|
!(0, perspective_js_1.isSegmentPresent)(seg, { refSeq, localSeq })) {
|
|
750
716
|
const forward = refPos.slidingPreference === localReference_js_1.SlidingPreference.FORWARD;
|
|
751
|
-
const
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
717
|
+
const moveInfo = (0, segmentInfos_js_1.toMoveInfo)(seg);
|
|
718
|
+
const removeInfo = (0, segmentInfos_js_1.toRemovalInfo)(seg);
|
|
719
|
+
const slideSeq = moveInfo !== undefined && moveInfo.movedSeq !== constants_js_1.UnassignedSequenceNumber
|
|
720
|
+
? moveInfo.movedSeq
|
|
721
|
+
: removeInfo !== undefined && removeInfo.removedSeq !== constants_js_1.UnassignedSequenceNumber
|
|
722
|
+
? removeInfo.removedSeq
|
|
755
723
|
: refSeq;
|
|
756
|
-
const slideLocalSeq =
|
|
724
|
+
const slideLocalSeq = moveInfo?.localMovedSeq ?? removeInfo?.localRemovedSeq;
|
|
757
725
|
const perspective = new perspective_js_1.PerspectiveImpl(this, {
|
|
758
726
|
refSeq: slideSeq,
|
|
759
727
|
localSeq: slideLocalSeq,
|
|
@@ -781,11 +749,10 @@ class MergeTree {
|
|
|
781
749
|
searchForMarker(startPos, clientId, markerLabel, forwards = true) {
|
|
782
750
|
let foundMarker;
|
|
783
751
|
const { segment } = this.getContainingSegment(startPos, constants_js_1.UniversalSequenceNumber, clientId);
|
|
784
|
-
|
|
785
|
-
if (segWithParent?.parent === undefined) {
|
|
752
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(segment)) {
|
|
786
753
|
return undefined;
|
|
787
754
|
}
|
|
788
|
-
(0, mergeTreeNodeWalk_js_1.depthFirstNodeWalk)(
|
|
755
|
+
(0, mergeTreeNodeWalk_js_1.depthFirstNodeWalk)(segment.parent, segment, (node) => {
|
|
789
756
|
if (node.isLeaf()) {
|
|
790
757
|
if (mergeTreeNodes_js_1.Marker.is(node) && (0, referencePositions_js_1.refHasTileLabel)(node, markerLabel)) {
|
|
791
758
|
foundMarker = node;
|
|
@@ -807,8 +774,8 @@ class MergeTree {
|
|
|
807
774
|
updateRoot(splitNode) {
|
|
808
775
|
if (splitNode !== undefined) {
|
|
809
776
|
const newRoot = this.makeBlock(2);
|
|
810
|
-
|
|
811
|
-
|
|
777
|
+
(0, mergeTreeNodes_js_1.assignChild)(newRoot, this.root, 0, false);
|
|
778
|
+
(0, mergeTreeNodes_js_1.assignChild)(newRoot, splitNode, 1, false);
|
|
812
779
|
this.root = newRoot;
|
|
813
780
|
this.nodeUpdateOrdinals(this.root);
|
|
814
781
|
this.nodeUpdateLengthNewStructure(this.root);
|
|
@@ -864,9 +831,7 @@ class MergeTree {
|
|
|
864
831
|
(0, zamboni_js_1.zamboniSegments)(this);
|
|
865
832
|
}
|
|
866
833
|
}
|
|
867
|
-
addToPendingList(segment,
|
|
868
|
-
// eslint-disable-next-line import/no-deprecated
|
|
869
|
-
segmentGroup, localSeq, previousProps) {
|
|
834
|
+
addToPendingList(segment, segmentGroup, localSeq, previousProps) {
|
|
870
835
|
let _segmentGroup = segmentGroup;
|
|
871
836
|
if (_segmentGroup === undefined) {
|
|
872
837
|
_segmentGroup = {
|
|
@@ -886,7 +851,6 @@ class MergeTree {
|
|
|
886
851
|
if (previousProps) {
|
|
887
852
|
_segmentGroup.previousProps.push(previousProps);
|
|
888
853
|
}
|
|
889
|
-
// eslint-disable-next-line import/no-deprecated
|
|
890
854
|
const segmentGroups = (segment.segmentGroups ?? (segment.segmentGroups = new segmentGroupCollection_js_1.SegmentGroupCollection(segment)));
|
|
891
855
|
segmentGroups.enqueue(_segmentGroup);
|
|
892
856
|
return _segmentGroup;
|
|
@@ -895,8 +859,8 @@ class MergeTree {
|
|
|
895
859
|
getMarkerFromId(id) {
|
|
896
860
|
const marker = this.idToMarker.get(id);
|
|
897
861
|
return marker === undefined ||
|
|
898
|
-
isRemoved(marker) ||
|
|
899
|
-
(isMoved(marker) && marker.moveDst === undefined)
|
|
862
|
+
(0, segmentInfos_js_1.isRemoved)(marker) ||
|
|
863
|
+
((0, segmentInfos_js_1.isMoved)(marker) && marker.moveDst === undefined)
|
|
900
864
|
? undefined
|
|
901
865
|
: marker;
|
|
902
866
|
}
|
|
@@ -913,7 +877,7 @@ class MergeTree {
|
|
|
913
877
|
if (relativePos.id) {
|
|
914
878
|
marker = this.getMarkerFromId(relativePos.id);
|
|
915
879
|
}
|
|
916
|
-
if (marker) {
|
|
880
|
+
if ((0, mergeTreeNodes_js_1.isSegmentLeaf)(marker)) {
|
|
917
881
|
pos = this.getPosition(marker, refseq, clientId);
|
|
918
882
|
if (relativePos.before) {
|
|
919
883
|
if (relativePos.offset !== undefined) {
|
|
@@ -936,7 +900,7 @@ class MergeTree {
|
|
|
936
900
|
// opArgs == undefined => loading snapshot or test code
|
|
937
901
|
if (opArgs !== undefined) {
|
|
938
902
|
const deltaSegments = segments
|
|
939
|
-
.filter((segment) => !(0,
|
|
903
|
+
.filter((segment) => !(0, segmentInfos_js_1.toMoveInfo)(segment))
|
|
940
904
|
.map((segment) => ({ segment }));
|
|
941
905
|
if (deltaSegments.length > 0) {
|
|
942
906
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
@@ -971,7 +935,7 @@ class MergeTree {
|
|
|
971
935
|
}
|
|
972
936
|
const segmentInfo = this.getContainingSegment(remoteClientPosition, remoteClientRefSeq, remoteClientId);
|
|
973
937
|
const { currentSeq, clientId } = this.collabWindow;
|
|
974
|
-
if (segmentInfo?.segment) {
|
|
938
|
+
if ((0, mergeTreeNodes_js_1.isSegmentLeaf)(segmentInfo?.segment)) {
|
|
975
939
|
const segmentPosition = this.getPosition(segmentInfo.segment, currentSeq, clientId);
|
|
976
940
|
return segmentPosition + segmentInfo.offset;
|
|
977
941
|
}
|
|
@@ -992,7 +956,6 @@ class MergeTree {
|
|
|
992
956
|
});
|
|
993
957
|
return siblingExists;
|
|
994
958
|
};
|
|
995
|
-
// eslint-disable-next-line import/no-deprecated
|
|
996
959
|
let segmentGroup;
|
|
997
960
|
const saveIfLocal = (locSegment) => {
|
|
998
961
|
// Save segment so we can assign sequence number when acked by server
|
|
@@ -1022,93 +985,94 @@ class MergeTree {
|
|
|
1022
985
|
}
|
|
1023
986
|
return segmentChanges;
|
|
1024
987
|
};
|
|
988
|
+
const insertInfo = {
|
|
989
|
+
clientId,
|
|
990
|
+
seq,
|
|
991
|
+
localSeq,
|
|
992
|
+
};
|
|
1025
993
|
// TODO: build tree from segs and insert all at once
|
|
1026
994
|
let insertPos = pos;
|
|
1027
|
-
for (const newSegment of newSegments
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
if (
|
|
1033
|
-
|
|
1034
|
-
if (markerId) {
|
|
1035
|
-
this.idToMarker.set(markerId, newSegment);
|
|
1036
|
-
}
|
|
995
|
+
for (const newSegment of newSegments
|
|
996
|
+
.filter((s) => s.cachedLength > 0)
|
|
997
|
+
.map((s) => (0, segmentInfos_js_1.overwriteInfo)(s, insertInfo))) {
|
|
998
|
+
if (mergeTreeNodes_js_1.Marker.is(newSegment)) {
|
|
999
|
+
const markerId = newSegment.getId();
|
|
1000
|
+
if (markerId) {
|
|
1001
|
+
this.idToMarker.set(markerId, newSegment);
|
|
1037
1002
|
}
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1003
|
+
}
|
|
1004
|
+
const splitNode = this.insertingWalk(this.root, insertPos, refSeq, clientId, seq, {
|
|
1005
|
+
leaf: onLeaf,
|
|
1006
|
+
candidateSegment: newSegment,
|
|
1007
|
+
continuePredicate: continueFrom,
|
|
1008
|
+
});
|
|
1009
|
+
if (!(0, mergeTreeNodes_js_1.isSegmentLeaf)(newSegment)) {
|
|
1010
|
+
// Indicates an attempt to insert past the end of the merge-tree's content.
|
|
1011
|
+
const errorConstructor = localSeq === undefined ? internal_2.DataProcessingError : internal_2.UsageError;
|
|
1012
|
+
throw new errorConstructor("MergeTree insert failed", {
|
|
1013
|
+
currentSeq: this.collabWindow.currentSeq,
|
|
1014
|
+
minSeq: this.collabWindow.minSeq,
|
|
1015
|
+
segSeq: insertInfo.seq,
|
|
1042
1016
|
});
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq
|
|
1071
|
-
: ob.seq;
|
|
1072
|
-
if (normalizedObSeq > refSeq) {
|
|
1073
|
-
if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
|
|
1074
|
-
normalizedOldestSeq = normalizedObSeq;
|
|
1075
|
-
oldest = ob;
|
|
1076
|
-
movedClientIds.unshift(ob.clientId);
|
|
1077
|
-
movedSeqs.unshift(ob.seq);
|
|
1078
|
-
}
|
|
1079
|
-
else {
|
|
1080
|
-
movedClientIds.push(ob.clientId);
|
|
1081
|
-
movedSeqs.push(ob.seq);
|
|
1082
|
-
}
|
|
1083
|
-
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1084
|
-
normalizedNewestSeq = normalizedObSeq;
|
|
1085
|
-
newest = ob;
|
|
1086
|
-
}
|
|
1017
|
+
}
|
|
1018
|
+
this.updateRoot(splitNode);
|
|
1019
|
+
insertPos += newSegment.cachedLength;
|
|
1020
|
+
if (!this.options?.mergeTreeEnableObliterate || this.obliterates.empty()) {
|
|
1021
|
+
saveIfLocal(newSegment);
|
|
1022
|
+
continue;
|
|
1023
|
+
}
|
|
1024
|
+
let oldest;
|
|
1025
|
+
let normalizedOldestSeq = 0;
|
|
1026
|
+
let newest;
|
|
1027
|
+
let normalizedNewestSeq = 0;
|
|
1028
|
+
const movedClientIds = [];
|
|
1029
|
+
const movedSeqs = [];
|
|
1030
|
+
for (const ob of this.obliterates.findOverlapping(newSegment)) {
|
|
1031
|
+
// compute a normalized seq that takes into account local seqs
|
|
1032
|
+
// but is still comparable to remote seqs to keep the checks below easy
|
|
1033
|
+
// REMOTE SEQUENCE NUMBERS LOCAL SEQUENCE NUMBERS
|
|
1034
|
+
// [0, 1, 2, 3, ..., 100, ..., 1000, ..., (MAX - MaxLocalSeq), L1, L2, L3, L4, ..., L100, ..., L1000, ...(MAX)]
|
|
1035
|
+
const normalizedObSeq = ob.seq === constants_js_1.UnassignedSequenceNumber
|
|
1036
|
+
? Number.MAX_SAFE_INTEGER - this.collabWindow.localSeq + ob.localSeq
|
|
1037
|
+
: ob.seq;
|
|
1038
|
+
if (normalizedObSeq > refSeq) {
|
|
1039
|
+
if (oldest === undefined || normalizedOldestSeq > normalizedObSeq) {
|
|
1040
|
+
normalizedOldestSeq = normalizedObSeq;
|
|
1041
|
+
oldest = ob;
|
|
1042
|
+
movedClientIds.unshift(ob.clientId);
|
|
1043
|
+
movedSeqs.unshift(ob.seq);
|
|
1087
1044
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
const moveInfo = {
|
|
1092
|
-
movedClientIds,
|
|
1093
|
-
movedSeq: oldest.seq,
|
|
1094
|
-
movedSeqs,
|
|
1095
|
-
localMovedSeq: oldest.localSeq,
|
|
1096
|
-
wasMovedOnInsert: oldest.seq !== constants_js_1.UnassignedSequenceNumber,
|
|
1097
|
-
};
|
|
1098
|
-
markSegmentMoved(newSegment, moveInfo);
|
|
1099
|
-
if (moveInfo.localMovedSeq !== undefined) {
|
|
1100
|
-
(0, internal_1.assert)(oldest.segmentGroup !== undefined, 0x86c /* expected segment group to exist */);
|
|
1101
|
-
this.addToPendingList(newSegment, oldest.segmentGroup);
|
|
1045
|
+
else {
|
|
1046
|
+
movedClientIds.push(ob.clientId);
|
|
1047
|
+
movedSeqs.push(ob.seq);
|
|
1102
1048
|
}
|
|
1103
|
-
if (
|
|
1104
|
-
|
|
1049
|
+
if (newest === undefined || normalizedNewestSeq < normalizedObSeq) {
|
|
1050
|
+
normalizedNewestSeq = normalizedObSeq;
|
|
1051
|
+
newest = ob;
|
|
1105
1052
|
}
|
|
1106
1053
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1054
|
+
}
|
|
1055
|
+
if (oldest && newest?.clientId !== clientId) {
|
|
1056
|
+
const moveInfo = {
|
|
1057
|
+
movedClientIds,
|
|
1058
|
+
movedSeq: oldest.seq,
|
|
1059
|
+
movedSeqs,
|
|
1060
|
+
localMovedSeq: oldest.localSeq,
|
|
1061
|
+
wasMovedOnInsert: oldest.seq !== constants_js_1.UnassignedSequenceNumber,
|
|
1062
|
+
};
|
|
1063
|
+
(0, segmentInfos_js_1.overwriteInfo)(newSegment, moveInfo);
|
|
1064
|
+
if (moveInfo.localMovedSeq !== undefined) {
|
|
1065
|
+
(0, internal_1.assert)(oldest.segmentGroup !== undefined, 0x86c /* expected segment group to exist */);
|
|
1066
|
+
this.addToPendingList(newSegment, oldest.segmentGroup);
|
|
1067
|
+
}
|
|
1068
|
+
if (newSegment.parent) {
|
|
1069
|
+
this.blockUpdatePathLengths(newSegment.parent, seq, clientId);
|
|
1109
1070
|
}
|
|
1110
|
-
saveIfLocal(newSegment);
|
|
1111
1071
|
}
|
|
1072
|
+
else if (oldest && newest?.clientId === clientId) {
|
|
1073
|
+
newSegment.prevObliterateByInserter = newest;
|
|
1074
|
+
}
|
|
1075
|
+
saveIfLocal(newSegment);
|
|
1112
1076
|
}
|
|
1113
1077
|
}
|
|
1114
1078
|
ensureIntervalBoundary(pos, refSeq, clientId) {
|
|
@@ -1129,10 +1093,8 @@ class MergeTree {
|
|
|
1129
1093
|
const newSeq = seq === constants_js_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
|
|
1130
1094
|
const segSeq = node.seq === constants_js_1.UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER - 1 : (node.seq ?? 0);
|
|
1131
1095
|
return (newSeq > segSeq ||
|
|
1132
|
-
(node.movedSeq !==
|
|
1133
|
-
|
|
1134
|
-
node.movedSeq > seq) ||
|
|
1135
|
-
(node.removedSeq !== undefined &&
|
|
1096
|
+
((0, segmentInfos_js_1.isMoved)(node) && node.movedSeq !== constants_js_1.UnassignedSequenceNumber && node.movedSeq > seq) ||
|
|
1097
|
+
((0, segmentInfos_js_1.isRemoved)(node) &&
|
|
1136
1098
|
node.removedSeq !== constants_js_1.UnassignedSequenceNumber &&
|
|
1137
1099
|
node.removedSeq > seq));
|
|
1138
1100
|
}
|
|
@@ -1164,7 +1126,7 @@ class MergeTree {
|
|
|
1164
1126
|
const segment = child;
|
|
1165
1127
|
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1166
1128
|
if (segmentChanges.replaceCurrent) {
|
|
1167
|
-
|
|
1129
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, segmentChanges.replaceCurrent, childIndex, false);
|
|
1168
1130
|
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1169
1131
|
}
|
|
1170
1132
|
if (segmentChanges.next) {
|
|
@@ -1215,7 +1177,7 @@ class MergeTree {
|
|
|
1215
1177
|
block.children[i] = block.children[i - 1];
|
|
1216
1178
|
block.children[i].index = i;
|
|
1217
1179
|
}
|
|
1218
|
-
|
|
1180
|
+
(0, mergeTreeNodes_js_1.assignChild)(block, newNode, childIndex, false);
|
|
1219
1181
|
block.childCount++;
|
|
1220
1182
|
block.setOrdinal(newNode, childIndex);
|
|
1221
1183
|
if (block.childCount < mergeTreeNodes_js_1.MaxNodesInBlock) {
|
|
@@ -1244,7 +1206,7 @@ class MergeTree {
|
|
|
1244
1206
|
// Update ordinals to reflect lowered child count
|
|
1245
1207
|
this.nodeUpdateOrdinals(node);
|
|
1246
1208
|
for (let i = 0; i < halfCount; i++) {
|
|
1247
|
-
|
|
1209
|
+
(0, mergeTreeNodes_js_1.assignChild)(newNode, node.children[halfCount + i], i, false);
|
|
1248
1210
|
node.children[halfCount + i] = undefined;
|
|
1249
1211
|
}
|
|
1250
1212
|
this.nodeUpdateLengthNewStructure(node);
|
|
@@ -1271,9 +1233,7 @@ class MergeTree {
|
|
|
1271
1233
|
* @param opArgs - The op args for the annotate op. this is passed to the merge tree callback if there is one
|
|
1272
1234
|
* @param rollback - Whether this is for a local rollback and what kind
|
|
1273
1235
|
*/
|
|
1274
|
-
annotateRange(start, end, propsOrAdjust, refSeq, clientId, seq, opArgs,
|
|
1275
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1276
|
-
rollback = segmentPropertiesManager_js_1.PropertiesRollback.None) {
|
|
1236
|
+
annotateRange(start, end, propsOrAdjust, refSeq, clientId, seq, opArgs, rollback = segmentPropertiesManager_js_1.PropertiesRollback.None) {
|
|
1277
1237
|
if (propsOrAdjust.adjust !== undefined) {
|
|
1278
1238
|
errorIfOptionNotTrue(this.options, "mergeTreeEnableAnnotateAdjust");
|
|
1279
1239
|
}
|
|
@@ -1281,7 +1241,6 @@ class MergeTree {
|
|
|
1281
1241
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1282
1242
|
const deltaSegments = [];
|
|
1283
1243
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1284
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1285
1244
|
let segmentGroup;
|
|
1286
1245
|
const opObj = propsOrAdjust.props ?? propsOrAdjust.adjust;
|
|
1287
1246
|
const annotateSegment = (segment) => {
|
|
@@ -1305,7 +1264,7 @@ class MergeTree {
|
|
|
1305
1264
|
}
|
|
1306
1265
|
return true;
|
|
1307
1266
|
};
|
|
1308
|
-
this.nodeMap(refSeq, clientId, annotateSegment, undefined,
|
|
1267
|
+
this.nodeMap(refSeq, clientId, annotateSegment, undefined, start, end);
|
|
1309
1268
|
// OpArgs == undefined => test code
|
|
1310
1269
|
if (deltaSegments.length > 0) {
|
|
1311
1270
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
@@ -1328,7 +1287,6 @@ class MergeTree {
|
|
|
1328
1287
|
const localOverlapWithRefs = [];
|
|
1329
1288
|
const movedSegments = [];
|
|
1330
1289
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1331
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1332
1290
|
const obliterate = {
|
|
1333
1291
|
clientId,
|
|
1334
1292
|
end: (0, localReference_js_1.createDetachedLocalReferencePosition)(undefined),
|
|
@@ -1340,7 +1298,7 @@ class MergeTree {
|
|
|
1340
1298
|
};
|
|
1341
1299
|
const { segment: startSeg } = this.getContainingSegment(start.pos, refSeq, clientId);
|
|
1342
1300
|
const { segment: endSeg } = this.getContainingSegment(end.pos, refSeq, clientId);
|
|
1343
|
-
(0, internal_1.assert)(startSeg
|
|
1301
|
+
(0, internal_1.assert)((0, mergeTreeNodes_js_1.isSegmentLeaf)(startSeg) && (0, mergeTreeNodes_js_1.isSegmentLeaf)(endSeg), 0xa3f /* segments cannot be undefined */);
|
|
1344
1302
|
obliterate.start = this.createLocalReferencePosition(startSeg, start.side === sequencePlace_js_1.Side.Before ? 0 : Math.max(startSeg.cachedLength - 1, 0), ops_js_1.ReferenceType.StayOnRemove, {
|
|
1345
1303
|
obliterate,
|
|
1346
1304
|
});
|
|
@@ -1361,7 +1319,7 @@ class MergeTree {
|
|
|
1361
1319
|
this.pendingSegments.push(obliterate.segmentGroup);
|
|
1362
1320
|
}
|
|
1363
1321
|
this.obliterates.addOrUpdate(obliterate);
|
|
1364
|
-
const markMoved = (segment, pos
|
|
1322
|
+
const markMoved = (segment, pos) => {
|
|
1365
1323
|
if ((start.side === sequencePlace_js_1.Side.After && startPos === pos + segment.cachedLength) || // exclusive start segment
|
|
1366
1324
|
(end.side === sequencePlace_js_1.Side.Before &&
|
|
1367
1325
|
endPos === pos &&
|
|
@@ -1371,30 +1329,33 @@ class MergeTree {
|
|
|
1371
1329
|
// These segments are outside of the obliteration range though, so return true to keep walking.
|
|
1372
1330
|
return true;
|
|
1373
1331
|
}
|
|
1374
|
-
const existingMoveInfo = (0,
|
|
1332
|
+
const existingMoveInfo = (0, segmentInfos_js_1.toMoveInfo)(segment);
|
|
1375
1333
|
if (segment.prevObliterateByInserter?.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1376
1334
|
// We chose to not obliterate this segment because we are aware of an unacked local obliteration.
|
|
1377
1335
|
// The local obliterate has not been sequenced yet, so it is still the newest obliterate we are aware of.
|
|
1378
1336
|
// Other clients will also choose not to obliterate this segment because the most recent obliteration has the same clientId
|
|
1379
1337
|
return true;
|
|
1380
1338
|
}
|
|
1381
|
-
|
|
1339
|
+
const wasMovedOnInsert = clientId !== segment.clientId &&
|
|
1382
1340
|
segment.seq !== undefined &&
|
|
1383
1341
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
1384
|
-
(refSeq < segment.seq || segment.seq === constants_js_1.UnassignedSequenceNumber)
|
|
1385
|
-
segment.wasMovedOnInsert = true;
|
|
1386
|
-
}
|
|
1342
|
+
(refSeq < segment.seq || segment.seq === constants_js_1.UnassignedSequenceNumber);
|
|
1387
1343
|
if (existingMoveInfo === undefined) {
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1344
|
+
const movedSeg = (0, segmentInfos_js_1.overwriteInfo)(segment, {
|
|
1345
|
+
movedClientIds: [clientId],
|
|
1346
|
+
movedSeq: seq,
|
|
1347
|
+
localMovedSeq: localSeq,
|
|
1348
|
+
movedSeqs: [seq],
|
|
1349
|
+
wasMovedOnInsert,
|
|
1350
|
+
});
|
|
1351
|
+
if (!(0, segmentInfos_js_1.toRemovalInfo)(movedSeg)) {
|
|
1352
|
+
movedSegments.push(movedSeg);
|
|
1394
1353
|
}
|
|
1395
1354
|
}
|
|
1396
1355
|
else {
|
|
1397
1356
|
_overwrite = true;
|
|
1357
|
+
// never move wasMovedOnInsert from true to false
|
|
1358
|
+
existingMoveInfo.wasMovedOnInsert || (existingMoveInfo.wasMovedOnInsert = wasMovedOnInsert);
|
|
1398
1359
|
if (existingMoveInfo.movedSeq === constants_js_1.UnassignedSequenceNumber) {
|
|
1399
1360
|
// we moved this locally, but someone else moved it first
|
|
1400
1361
|
// so put them at the head of the list
|
|
@@ -1413,6 +1374,7 @@ class MergeTree {
|
|
|
1413
1374
|
existingMoveInfo.movedSeqs.push(seq);
|
|
1414
1375
|
}
|
|
1415
1376
|
}
|
|
1377
|
+
(0, segmentInfos_js_1.assertMoved)(segment);
|
|
1416
1378
|
// Save segment so can assign moved sequence number when acked by server
|
|
1417
1379
|
if (this.collabWindow.collaborating) {
|
|
1418
1380
|
if (segment.movedSeq === constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1427,7 +1389,7 @@ class MergeTree {
|
|
|
1427
1389
|
}
|
|
1428
1390
|
return true;
|
|
1429
1391
|
};
|
|
1430
|
-
const afterMarkMoved = (node
|
|
1392
|
+
const afterMarkMoved = (node) => {
|
|
1431
1393
|
if (_overwrite) {
|
|
1432
1394
|
this.nodeUpdateLengthNewStructure(node);
|
|
1433
1395
|
}
|
|
@@ -1436,21 +1398,21 @@ class MergeTree {
|
|
|
1436
1398
|
}
|
|
1437
1399
|
return true;
|
|
1438
1400
|
};
|
|
1439
|
-
this.nodeMap(refSeq, clientId, markMoved,
|
|
1401
|
+
this.nodeMap(refSeq, clientId, markMoved, afterMarkMoved, start.pos, end.pos + 1, // include the segment containing the end reference
|
|
1440
1402
|
undefined, seq === constants_js_1.UnassignedSequenceNumber ? undefined : seq);
|
|
1441
1403
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
1442
1404
|
// opArgs == undefined => test code
|
|
1443
1405
|
if (start.pos !== end.pos || start.side !== end.side) {
|
|
1444
1406
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1445
1407
|
operation: ops_js_1.MergeTreeDeltaType.OBLITERATE,
|
|
1446
|
-
deltaSegments: movedSegments,
|
|
1408
|
+
deltaSegments: movedSegments.map((segment) => ({ segment })),
|
|
1447
1409
|
});
|
|
1448
1410
|
}
|
|
1449
1411
|
// these events are newly removed
|
|
1450
1412
|
// so we slide after eventing in case the consumer wants to make reference
|
|
1451
1413
|
// changes at remove time, like add a ref to track undo redo.
|
|
1452
1414
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1453
|
-
this.slideAckedRemovedSegmentReferences(movedSegments
|
|
1415
|
+
this.slideAckedRemovedSegmentReferences(movedSegments);
|
|
1454
1416
|
}
|
|
1455
1417
|
if (this.collabWindow.collaborating &&
|
|
1456
1418
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1473,19 +1435,20 @@ class MergeTree {
|
|
|
1473
1435
|
let _overwrite = false;
|
|
1474
1436
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1475
1437
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1476
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1477
1438
|
let segmentGroup;
|
|
1478
1439
|
const removedSegments = [];
|
|
1479
1440
|
const localOverlapWithRefs = [];
|
|
1480
1441
|
const localSeq = seq === constants_js_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1481
1442
|
const markRemoved = (segment, pos, _start, _end) => {
|
|
1482
|
-
const existingRemovalInfo = (0,
|
|
1443
|
+
const existingRemovalInfo = (0, segmentInfos_js_1.toRemovalInfo)(segment);
|
|
1483
1444
|
if (existingRemovalInfo === undefined) {
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1445
|
+
const removed = (0, segmentInfos_js_1.overwriteInfo)(segment, {
|
|
1446
|
+
removedClientIds: [clientId],
|
|
1447
|
+
removedSeq: seq,
|
|
1448
|
+
localRemovedSeq: localSeq,
|
|
1449
|
+
});
|
|
1450
|
+
if (!(0, segmentInfos_js_1.toMoveInfo)(removed)) {
|
|
1451
|
+
removedSegments.push(removed);
|
|
1489
1452
|
}
|
|
1490
1453
|
}
|
|
1491
1454
|
else {
|
|
@@ -1506,6 +1469,7 @@ class MergeTree {
|
|
|
1506
1469
|
existingRemovalInfo.removedClientIds.push(clientId);
|
|
1507
1470
|
}
|
|
1508
1471
|
}
|
|
1472
|
+
(0, segmentInfos_js_1.assertRemoved)(segment);
|
|
1509
1473
|
// Save segment so we can assign removed sequence number when acked by server
|
|
1510
1474
|
if (this.collabWindow.collaborating) {
|
|
1511
1475
|
if (segment.removedSeq === constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1520,7 +1484,7 @@ class MergeTree {
|
|
|
1520
1484
|
}
|
|
1521
1485
|
return true;
|
|
1522
1486
|
};
|
|
1523
|
-
const afterMarkRemoved = (node
|
|
1487
|
+
const afterMarkRemoved = (node) => {
|
|
1524
1488
|
if (_overwrite) {
|
|
1525
1489
|
this.nodeUpdateLengthNewStructure(node);
|
|
1526
1490
|
}
|
|
@@ -1529,7 +1493,7 @@ class MergeTree {
|
|
|
1529
1493
|
}
|
|
1530
1494
|
return true;
|
|
1531
1495
|
};
|
|
1532
|
-
this.nodeMap(refSeq, clientId, markRemoved,
|
|
1496
|
+
this.nodeMap(refSeq, clientId, markRemoved, afterMarkRemoved, start, end);
|
|
1533
1497
|
// these segments are already viewed as being removed locally and are not event-ed
|
|
1534
1498
|
// so can slide non-StayOnRemove refs immediately
|
|
1535
1499
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
@@ -1537,14 +1501,14 @@ class MergeTree {
|
|
|
1537
1501
|
if (removedSegments.length > 0) {
|
|
1538
1502
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1539
1503
|
operation: ops_js_1.MergeTreeDeltaType.REMOVE,
|
|
1540
|
-
deltaSegments: removedSegments,
|
|
1504
|
+
deltaSegments: removedSegments.map((segment) => ({ segment })),
|
|
1541
1505
|
});
|
|
1542
1506
|
}
|
|
1543
1507
|
// these events are newly removed
|
|
1544
1508
|
// so we slide after eventing in case the consumer wants to make reference
|
|
1545
1509
|
// changes at remove time, like add a ref to track undo redo.
|
|
1546
1510
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1547
|
-
this.slideAckedRemovedSegmentReferences(removedSegments
|
|
1511
|
+
this.slideAckedRemovedSegmentReferences(removedSegments);
|
|
1548
1512
|
}
|
|
1549
1513
|
if (this.collabWindow.collaborating &&
|
|
1550
1514
|
seq !== constants_js_1.UnassignedSequenceNumber &&
|
|
@@ -1555,24 +1519,21 @@ class MergeTree {
|
|
|
1555
1519
|
/**
|
|
1556
1520
|
* Revert an unacked local op
|
|
1557
1521
|
*/
|
|
1558
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1559
1522
|
rollback(op, localOpMetadata) {
|
|
1560
1523
|
if (op.type === ops_js_1.MergeTreeDeltaType.REMOVE) {
|
|
1561
|
-
const pendingSegmentGroup = this.pendingSegments.pop
|
|
1524
|
+
const pendingSegmentGroup = this.pendingSegments.pop()?.data;
|
|
1562
1525
|
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
|
|
1563
1526
|
throw new Error("Rollback op doesn't match last edit");
|
|
1564
1527
|
}
|
|
1565
1528
|
// Disabling because a for of loop causes the type of segment to be ISegmentLeaf, which does not have parent information stored
|
|
1566
1529
|
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1567
1530
|
pendingSegmentGroup.segments.forEach((segment) => {
|
|
1568
|
-
const segmentSegmentGroup = segment?.segmentGroups?.pop
|
|
1531
|
+
const segmentSegmentGroup = segment?.segmentGroups?.pop();
|
|
1569
1532
|
(0, internal_1.assert)(segmentSegmentGroup === pendingSegmentGroup, 0x3ee /* Unexpected segmentGroup in segment */);
|
|
1570
|
-
(0, internal_1.assert)(segment.removedClientIds
|
|
1571
|
-
|
|
1572
|
-
segment
|
|
1573
|
-
|
|
1574
|
-
segment.localRemovedSeq = undefined;
|
|
1575
|
-
for (let updateNode = segment.parent; updateNode !== undefined; updateNode = updateNode.parent) {
|
|
1533
|
+
(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 */);
|
|
1534
|
+
let updateNode = segment.parent;
|
|
1535
|
+
(0, segmentInfos_js_1.removeRemovalInfo)(segment);
|
|
1536
|
+
for (updateNode; updateNode !== undefined; updateNode = updateNode.parent) {
|
|
1576
1537
|
this.blockUpdateLength(updateNode, constants_js_1.UnassignedSequenceNumber, this.collabWindow.clientId);
|
|
1577
1538
|
}
|
|
1578
1539
|
// Note: optional chaining short-circuits:
|
|
@@ -1585,7 +1546,7 @@ class MergeTree {
|
|
|
1585
1546
|
}
|
|
1586
1547
|
else if (op.type === ops_js_1.MergeTreeDeltaType.INSERT ||
|
|
1587
1548
|
op.type === ops_js_1.MergeTreeDeltaType.ANNOTATE) {
|
|
1588
|
-
const pendingSegmentGroup = this.pendingSegments.pop
|
|
1549
|
+
const pendingSegmentGroup = this.pendingSegments.pop()?.data;
|
|
1589
1550
|
if (pendingSegmentGroup === undefined ||
|
|
1590
1551
|
pendingSegmentGroup !== localOpMetadata ||
|
|
1591
1552
|
(op.type === ops_js_1.MergeTreeDeltaType.ANNOTATE && !pendingSegmentGroup.previousProps)) {
|
|
@@ -1593,7 +1554,7 @@ class MergeTree {
|
|
|
1593
1554
|
}
|
|
1594
1555
|
let i = 0;
|
|
1595
1556
|
for (const segment of pendingSegmentGroup.segments) {
|
|
1596
|
-
const segmentSegmentGroup = segment?.segmentGroups?.pop
|
|
1557
|
+
const segmentSegmentGroup = segment?.segmentGroups?.pop();
|
|
1597
1558
|
(0, internal_1.assert)(segmentSegmentGroup === pendingSegmentGroup, 0x3ef /* Unexpected segmentGroup in segment */);
|
|
1598
1559
|
const start = this.findRollbackPosition(segment);
|
|
1599
1560
|
if (op.type === ops_js_1.MergeTreeDeltaType.INSERT) {
|
|
@@ -1625,7 +1586,7 @@ class MergeTree {
|
|
|
1625
1586
|
return false;
|
|
1626
1587
|
}
|
|
1627
1588
|
// If not removed, increase position
|
|
1628
|
-
if (
|
|
1589
|
+
if (!(0, segmentInfos_js_1.isRemoved)(seg)) {
|
|
1629
1590
|
segmentPosition += seg.cachedLength;
|
|
1630
1591
|
}
|
|
1631
1592
|
return true;
|
|
@@ -1659,9 +1620,9 @@ class MergeTree {
|
|
|
1659
1620
|
segment = this.endOfTree;
|
|
1660
1621
|
}
|
|
1661
1622
|
else {
|
|
1623
|
+
(0, mergeTreeNodes_js_1.assertSegmentLeaf)(_segment);
|
|
1662
1624
|
segment = _segment;
|
|
1663
1625
|
}
|
|
1664
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1665
1626
|
const localRefs = localReference_js_1.LocalReferenceCollection.setOrGet(segment);
|
|
1666
1627
|
const segRef = localRefs.createLocalRef(offset, refType, properties, slidingPreference, canSlideToEndpoint);
|
|
1667
1628
|
return segRef;
|
|
@@ -1689,7 +1650,7 @@ class MergeTree {
|
|
|
1689
1650
|
affectedSegments.remove(segmentToSlide);
|
|
1690
1651
|
affectedSegments.insertAfter(lastLocalSegment, segmentToSlide.data);
|
|
1691
1652
|
}
|
|
1692
|
-
else if (isRemoved(segmentToSlide.data)) {
|
|
1653
|
+
else if ((0, segmentInfos_js_1.isRemoved)(segmentToSlide.data)) {
|
|
1693
1654
|
(0, internal_1.assert)(segmentToSlide.data.localRemovedSeq !== undefined, 0x54d /* Removed segment that hasnt had its removal acked should be locally removed */);
|
|
1694
1655
|
// Slide each locally removed item past all segments that have localSeq > lremoveItem.localSeq
|
|
1695
1656
|
// but not past remotely removed segments;
|
|
@@ -1723,7 +1684,7 @@ class MergeTree {
|
|
|
1723
1684
|
for (let i = 0; i < newOrder.length; i++) {
|
|
1724
1685
|
const seg = newOrder[i];
|
|
1725
1686
|
const { parent, index, ordinal } = currentOrder[i];
|
|
1726
|
-
|
|
1687
|
+
(0, mergeTreeNodes_js_1.assignChild)(parent, seg, index, false);
|
|
1727
1688
|
seg.ordinal = ordinal;
|
|
1728
1689
|
}
|
|
1729
1690
|
for (const [segment, groups] of perSegmentTrackingGroups.entries()) {
|
|
@@ -1783,7 +1744,7 @@ class MergeTree {
|
|
|
1783
1744
|
}
|
|
1784
1745
|
};
|
|
1785
1746
|
(0, mergeTreeNodeWalk_js_1.walkAllChildSegments)(this.root, (seg) => {
|
|
1786
|
-
if (isRemoved(seg) || seg.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1747
|
+
if ((0, segmentInfos_js_1.isRemoved)(seg) || seg.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
1787
1748
|
if (isRemovedAndAcked(seg)) {
|
|
1788
1749
|
rangeContainsRemoteRemovedSegs = true;
|
|
1789
1750
|
}
|
|
@@ -1890,7 +1851,7 @@ class MergeTree {
|
|
|
1890
1851
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1891
1852
|
}
|
|
1892
1853
|
}
|
|
1893
|
-
this.nodeMap(refSeq, clientId, handler, accum, undefined, start, end, undefined, visibilitySeq);
|
|
1854
|
+
this.nodeMap(refSeq, clientId, (seg, pos, _start, _end) => handler(seg, pos, refSeq, clientId, _start, _end, accum), undefined, start, end, undefined, visibilitySeq);
|
|
1894
1855
|
}
|
|
1895
1856
|
/**
|
|
1896
1857
|
* Map over all visible segments in a given range
|
|
@@ -1915,7 +1876,7 @@ class MergeTree {
|
|
|
1915
1876
|
* but it will not count as a segment within the range. That is, it will be
|
|
1916
1877
|
* ignored for the purposes of tracking when traversal should end.
|
|
1917
1878
|
*/
|
|
1918
|
-
nodeMap(refSeq, clientId, leaf,
|
|
1879
|
+
nodeMap(refSeq, clientId, leaf, post, start = 0, end, localSeq, visibilitySeq = refSeq) {
|
|
1919
1880
|
const endPos = end ?? this.nodeLength(this.root, refSeq, clientId, localSeq) ?? 0;
|
|
1920
1881
|
if (endPos === start) {
|
|
1921
1882
|
return;
|
|
@@ -1942,14 +1903,12 @@ class MergeTree {
|
|
|
1942
1903
|
return mergeTreeNodeWalk_js_1.NodeAction.Skip;
|
|
1943
1904
|
}
|
|
1944
1905
|
if (node.isLeaf()) {
|
|
1945
|
-
if (leaf(node, pos,
|
|
1906
|
+
if (leaf(node, pos, start - pos, endPos - pos) === false) {
|
|
1946
1907
|
return mergeTreeNodeWalk_js_1.NodeAction.Exit;
|
|
1947
1908
|
}
|
|
1948
1909
|
pos = nextPos;
|
|
1949
1910
|
}
|
|
1950
|
-
}, undefined, post
|
|
1951
|
-
? undefined
|
|
1952
|
-
: (block) => post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum));
|
|
1911
|
+
}, undefined, post);
|
|
1953
1912
|
}
|
|
1954
1913
|
}
|
|
1955
1914
|
exports.MergeTree = MergeTree;
|