@fluidframework/merge-tree 1.2.1 → 2.0.0-internal.1.0.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/DEV.md +2 -2
- package/README.md +1 -1
- package/REFERENCEPOSITIONS.md +2 -2
- package/dist/MergeTreeTextHelper.d.ts +23 -0
- package/dist/MergeTreeTextHelper.d.ts.map +1 -0
- package/dist/MergeTreeTextHelper.js +136 -0
- package/dist/MergeTreeTextHelper.js.map +1 -0
- package/dist/base.d.ts +2 -26
- package/dist/base.d.ts.map +1 -1
- package/dist/base.js.map +1 -1
- package/dist/client.d.ts +21 -12
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +87 -27
- package/dist/client.js.map +1 -1
- package/dist/collections/heap.d.ts +28 -0
- package/dist/collections/heap.d.ts.map +1 -0
- package/dist/collections/heap.js +65 -0
- package/dist/collections/heap.js.map +1 -0
- package/dist/collections/index.d.ts +11 -0
- package/dist/collections/index.d.ts.map +1 -0
- package/dist/collections/index.js +23 -0
- package/dist/collections/index.js.map +1 -0
- package/dist/collections/intervalTree.d.ts +60 -0
- package/dist/collections/intervalTree.d.ts.map +1 -0
- package/dist/collections/intervalTree.js +99 -0
- package/dist/collections/intervalTree.js.map +1 -0
- package/dist/collections/list.d.ts +39 -0
- package/dist/collections/list.d.ts.map +1 -0
- package/dist/collections/list.js +155 -0
- package/dist/collections/list.js.map +1 -0
- package/dist/collections/rbTree.d.ts +154 -0
- package/dist/collections/rbTree.d.ts.map +1 -0
- package/dist/{collections.js → collections/rbTree.js} +10 -448
- package/dist/collections/rbTree.js.map +1 -0
- package/dist/collections/stack.d.ts +16 -0
- package/dist/collections/stack.d.ts.map +1 -0
- package/dist/collections/stack.js +30 -0
- package/dist/collections/stack.js.map +1 -0
- package/dist/collections/tst.d.ts +55 -0
- package/dist/collections/tst.d.ts.map +1 -0
- package/dist/collections/tst.js +171 -0
- package/dist/collections/tst.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/localReference.d.ts +48 -99
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +132 -169
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +38 -299
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +214 -598
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/dist/mergeTreeDeltaCallback.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +269 -0
- package/dist/mergeTreeNodes.d.ts.map +1 -0
- package/dist/mergeTreeNodes.js +383 -0
- package/dist/mergeTreeNodes.js.map +1 -0
- package/dist/mergeTreeTracking.d.ts +1 -1
- package/dist/mergeTreeTracking.d.ts.map +1 -1
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/opBuilder.d.ts +1 -1
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js.map +1 -1
- package/dist/partialLengths.d.ts +130 -15
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +230 -138
- package/dist/partialLengths.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js.map +1 -1
- package/dist/referencePositions.d.ts +6 -26
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts +2 -1
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +3 -0
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts +10 -1
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +41 -6
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +5 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +4 -0
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +1 -1
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/textSegment.d.ts +7 -7
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js +3 -125
- package/dist/textSegment.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts +23 -0
- package/lib/MergeTreeTextHelper.d.ts.map +1 -0
- package/lib/MergeTreeTextHelper.js +132 -0
- package/lib/MergeTreeTextHelper.js.map +1 -0
- package/lib/base.d.ts +2 -26
- package/lib/base.d.ts.map +1 -1
- package/lib/base.js.map +1 -1
- package/lib/client.d.ts +21 -12
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +85 -25
- package/lib/client.js.map +1 -1
- package/lib/collections/heap.d.ts +28 -0
- package/lib/collections/heap.d.ts.map +1 -0
- package/lib/collections/heap.js +61 -0
- package/lib/collections/heap.js.map +1 -0
- package/lib/collections/index.d.ts +11 -0
- package/lib/collections/index.d.ts.map +1 -0
- package/lib/collections/index.js +11 -0
- package/lib/collections/index.js.map +1 -0
- package/lib/collections/intervalTree.d.ts +60 -0
- package/lib/collections/intervalTree.d.ts.map +1 -0
- package/lib/collections/intervalTree.js +94 -0
- package/lib/collections/intervalTree.js.map +1 -0
- package/lib/collections/list.d.ts +39 -0
- package/lib/collections/list.d.ts.map +1 -0
- package/lib/collections/list.js +149 -0
- package/lib/collections/list.js.map +1 -0
- package/lib/collections/rbTree.d.ts +154 -0
- package/lib/collections/rbTree.d.ts.map +1 -0
- package/lib/{collections.js → collections/rbTree.js} +9 -439
- package/lib/collections/rbTree.js.map +1 -0
- package/lib/collections/stack.d.ts +16 -0
- package/lib/collections/stack.d.ts.map +1 -0
- package/lib/collections/stack.js +26 -0
- package/lib/collections/stack.js.map +1 -0
- package/lib/collections/tst.d.ts +55 -0
- package/lib/collections/tst.d.ts.map +1 -0
- package/lib/collections/tst.js +167 -0
- package/lib/collections/tst.js.map +1 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/localReference.d.ts +48 -99
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +132 -170
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +38 -299
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +190 -563
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/lib/mergeTreeDeltaCallback.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +269 -0
- package/lib/mergeTreeNodes.d.ts.map +1 -0
- package/lib/mergeTreeNodes.js +369 -0
- package/lib/mergeTreeNodes.js.map +1 -0
- package/lib/mergeTreeTracking.d.ts +1 -1
- package/lib/mergeTreeTracking.d.ts.map +1 -1
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/opBuilder.d.ts +1 -1
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js.map +1 -1
- package/lib/partialLengths.d.ts +130 -15
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +227 -135
- package/lib/partialLengths.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js.map +1 -1
- package/lib/referencePositions.d.ts +6 -26
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts +2 -1
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +3 -0
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts +10 -1
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +41 -6
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +5 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +4 -0
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +1 -1
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/textSegment.d.ts +7 -7
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js +1 -122
- package/lib/textSegment.js.map +1 -1
- package/package.json +93 -17
- package/src/MergeTreeTextHelper.ts +172 -0
- package/src/base.ts +2 -35
- package/src/client.ts +114 -30
- package/src/collections/heap.ts +75 -0
- package/src/collections/index.ts +11 -0
- package/src/collections/intervalTree.ts +140 -0
- package/src/collections/list.ts +165 -0
- package/src/{collections.ts → collections/rbTree.ts} +79 -538
- package/src/collections/stack.ts +27 -0
- package/src/collections/tst.ts +212 -0
- package/src/index.ts +8 -2
- package/src/localReference.ts +152 -203
- package/src/mergeTree.ts +265 -868
- package/src/mergeTreeDeltaCallback.ts +1 -1
- package/src/mergeTreeNodes.ts +676 -0
- package/src/mergeTreeTracking.ts +1 -1
- package/src/opBuilder.ts +1 -1
- package/src/partialLengths.ts +295 -150
- package/src/properties.ts +1 -0
- package/src/referencePositions.ts +7 -27
- package/src/segmentGroupCollection.ts +5 -1
- package/src/segmentPropertiesManager.ts +45 -6
- package/src/snapshotLoader.ts +2 -1
- package/src/snapshotV1.ts +2 -2
- package/src/snapshotlegacy.ts +6 -2
- package/src/sortedSegmentSet.ts +1 -1
- package/src/textSegment.ts +10 -157
- package/dist/collections.d.ts +0 -197
- package/dist/collections.d.ts.map +0 -1
- package/dist/collections.js.map +0 -1
- package/lib/collections.d.ts +0 -197
- package/lib/collections.d.ts.map +0 -1
- package/lib/collections.js.map +0 -1
package/dist/mergeTree.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.MergeTree = exports.clientSeqComparer =
|
|
7
|
+
exports.MergeTree = exports.clientSeqComparer = void 0;
|
|
8
8
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
9
9
|
/* eslint-disable @typescript-eslint/consistent-type-assertions */
|
|
10
10
|
/* eslint-disable @typescript-eslint/prefer-optional-chain, no-bitwise */
|
|
@@ -13,39 +13,104 @@ const container_utils_1 = require("@fluidframework/container-utils");
|
|
|
13
13
|
const collections_1 = require("./collections");
|
|
14
14
|
const constants_1 = require("./constants");
|
|
15
15
|
const localReference_1 = require("./localReference");
|
|
16
|
+
const mergeTreeNodes_1 = require("./mergeTreeNodes");
|
|
16
17
|
const mergeTreeDeltaCallback_1 = require("./mergeTreeDeltaCallback");
|
|
17
|
-
const mergeTreeTracking_1 = require("./mergeTreeTracking");
|
|
18
18
|
const ops_1 = require("./ops");
|
|
19
19
|
const partialLengths_1 = require("./partialLengths");
|
|
20
20
|
const properties_1 = require("./properties");
|
|
21
21
|
const referencePositions_1 = require("./referencePositions");
|
|
22
|
-
const segmentGroupCollection_1 = require("./segmentGroupCollection");
|
|
23
22
|
const segmentPropertiesManager_1 = require("./segmentPropertiesManager");
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
(0, common_utils_1.assert)((maybe === null || maybe === void 0 ? void 0 : maybe.removedClientIds) === undefined && (maybe === null || maybe === void 0 ? void 0 : maybe.removedSeq) === undefined, 0x2bf /* "both removedClientIds and removedSeq should be set or not set" */);
|
|
29
|
-
}
|
|
30
|
-
exports.toRemovalInfo = toRemovalInfo;
|
|
23
|
+
const minListenerComparer = {
|
|
24
|
+
min: { minRequired: Number.MIN_VALUE, onMinGE: () => { (0, common_utils_1.assert)(false, 0x048 /* "onMinGE()" */); } },
|
|
25
|
+
compare: (a, b) => a.minRequired - b.minRequired,
|
|
26
|
+
};
|
|
31
27
|
function isRemoved(segment) {
|
|
32
|
-
return toRemovalInfo(segment) !== undefined;
|
|
28
|
+
return (0, mergeTreeNodes_1.toRemovalInfo)(segment) !== undefined;
|
|
33
29
|
}
|
|
34
30
|
function isRemovedAndAcked(segment) {
|
|
35
|
-
const removalInfo = toRemovalInfo(segment);
|
|
31
|
+
const removalInfo = (0, mergeTreeNodes_1.toRemovalInfo)(segment);
|
|
36
32
|
return removalInfo !== undefined && removalInfo.removedSeq !== constants_1.UnassignedSequenceNumber;
|
|
37
33
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.ordinal = "";
|
|
42
|
-
this.cachedLength = 0;
|
|
34
|
+
function nodeTotalLength(mergeTree, node) {
|
|
35
|
+
if (!node.isLeaf()) {
|
|
36
|
+
return node.cachedLength;
|
|
43
37
|
}
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
return mergeTree.localNetLength(node);
|
|
39
|
+
}
|
|
40
|
+
const LRUSegmentComparer = {
|
|
41
|
+
min: { maxSeq: -2 },
|
|
42
|
+
compare: (a, b) => a.maxSeq - b.maxSeq,
|
|
43
|
+
};
|
|
44
|
+
function applyLeafRangeMarker(marker, searchInfo) {
|
|
45
|
+
for (const rangeLabel of searchInfo.rangeLabels) {
|
|
46
|
+
if ((0, referencePositions_1.refHasRangeLabel)(marker, rangeLabel)) {
|
|
47
|
+
let currentStack = searchInfo.stacks[rangeLabel];
|
|
48
|
+
if (currentStack === undefined) {
|
|
49
|
+
currentStack = new collections_1.Stack();
|
|
50
|
+
searchInfo.stacks[rangeLabel] = currentStack;
|
|
51
|
+
}
|
|
52
|
+
applyRangeReference(currentStack, marker);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function recordRangeLeaf(segment, segpos, refSeq, clientId, start, end, searchInfo) {
|
|
57
|
+
if (mergeTreeNodes_1.Marker.is(segment)) {
|
|
58
|
+
if (segment.refType &
|
|
59
|
+
(ops_1.ReferenceType.NestBegin | ops_1.ReferenceType.NestEnd)) {
|
|
60
|
+
applyLeafRangeMarker(segment, searchInfo);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
function rangeShift(node, segpos, refSeq, clientId, offset, end, searchInfo) {
|
|
66
|
+
var _a;
|
|
67
|
+
if (node.isLeaf()) {
|
|
68
|
+
const seg = node;
|
|
69
|
+
if ((((_a = searchInfo.mergeTree.localNetLength(seg)) !== null && _a !== void 0 ? _a : 0) > 0) && mergeTreeNodes_1.Marker.is(seg)) {
|
|
70
|
+
if (seg.refType &
|
|
71
|
+
(ops_1.ReferenceType.NestBegin | ops_1.ReferenceType.NestEnd)) {
|
|
72
|
+
applyLeafRangeMarker(seg, searchInfo);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const block = node;
|
|
78
|
+
applyStackDelta(searchInfo.stacks, block.rangeStacks);
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
function recordTileStart(segment, segpos, refSeq, clientId, start, end, searchInfo) {
|
|
83
|
+
if (mergeTreeNodes_1.Marker.is(segment)) {
|
|
84
|
+
if ((0, referencePositions_1.refHasTileLabel)(segment, searchInfo.tileLabel)) {
|
|
85
|
+
searchInfo.tile = segment;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
function tileShift(node, segpos, refSeq, clientId, offset, end, searchInfo) {
|
|
91
|
+
if (node.isLeaf()) {
|
|
92
|
+
const seg = node;
|
|
93
|
+
if ((searchInfo.mergeTree.localNetLength(seg) > 0) && mergeTreeNodes_1.Marker.is(seg)) {
|
|
94
|
+
if ((0, referencePositions_1.refHasTileLabel)(seg, searchInfo.tileLabel)) {
|
|
95
|
+
searchInfo.tile = seg;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
const block = node;
|
|
101
|
+
let marker;
|
|
102
|
+
if (searchInfo.posPrecedesTile) {
|
|
103
|
+
marker = block.rightmostTiles[searchInfo.tileLabel];
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
marker = block.leftmostTiles[searchInfo.tileLabel];
|
|
107
|
+
}
|
|
108
|
+
if (marker !== undefined) {
|
|
109
|
+
searchInfo.tile = marker;
|
|
110
|
+
}
|
|
46
111
|
}
|
|
112
|
+
return true;
|
|
47
113
|
}
|
|
48
|
-
exports.MergeNode = MergeNode;
|
|
49
114
|
function addTile(tile, tiles) {
|
|
50
115
|
const tileLabels = (0, referencePositions_1.refGetTileLabels)(tile);
|
|
51
116
|
if (tileLabels) {
|
|
@@ -111,7 +176,7 @@ function addNodeReferences(mergeTree, node, rightmostTiles, leftmostTiles, range
|
|
|
111
176
|
if (node.isLeaf()) {
|
|
112
177
|
const segment = node;
|
|
113
178
|
if (((_a = mergeTree.localNetLength(segment)) !== null && _a !== void 0 ? _a : 0) > 0) {
|
|
114
|
-
if (Marker.is(segment)) {
|
|
179
|
+
if (mergeTreeNodes_1.Marker.is(segment)) {
|
|
115
180
|
const markerId = segment.getId();
|
|
116
181
|
// Also in insertMarker but need for reload segs case
|
|
117
182
|
// can add option for this only from reload segs
|
|
@@ -154,72 +219,31 @@ function addNodeReferences(mergeTree, node, rightmostTiles, leftmostTiles, range
|
|
|
154
219
|
const block = node;
|
|
155
220
|
applyStackDelta(rangeStacks, block.rangeStacks);
|
|
156
221
|
(0, properties_1.extend)(rightmostTiles, block.rightmostTiles);
|
|
157
|
-
|
|
222
|
+
extendIfUndefined(leftmostTiles, block.leftmostTiles);
|
|
158
223
|
}
|
|
159
224
|
}
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for (
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
return a;
|
|
168
|
-
}
|
|
169
|
-
exports.ordinalToArray = ordinalToArray;
|
|
170
|
-
// Note that the actual branching factor of the MergeTree is `MaxNodesInBlock - 1`. This is because
|
|
171
|
-
// the MergeTree always inserts first, then checks for overflow and splits if the child count equals
|
|
172
|
-
// `MaxNodesInBlock`. (i.e., `MaxNodesInBlock` contains 1 extra slot for temporary storage to
|
|
173
|
-
// facilitate splits.)
|
|
174
|
-
exports.MaxNodesInBlock = 8;
|
|
175
|
-
class MergeBlock extends MergeNode {
|
|
176
|
-
constructor(childCount) {
|
|
177
|
-
super();
|
|
178
|
-
this.childCount = childCount;
|
|
179
|
-
this.children = new Array(exports.MaxNodesInBlock);
|
|
180
|
-
}
|
|
181
|
-
hierBlock() {
|
|
182
|
-
return undefined;
|
|
183
|
-
}
|
|
184
|
-
setOrdinal(child, index) {
|
|
185
|
-
let childCount = this.childCount;
|
|
186
|
-
if (childCount === 8) {
|
|
187
|
-
childCount = 7;
|
|
188
|
-
}
|
|
189
|
-
(0, common_utils_1.assert)((childCount >= 1) && (childCount <= 7), 0x040 /* "Child count is not within [1,7] range!" */);
|
|
190
|
-
let localOrdinal;
|
|
191
|
-
const ordinalWidth = 1 << (exports.MaxNodesInBlock - (childCount + 1));
|
|
192
|
-
if (index === 0) {
|
|
193
|
-
localOrdinal = ordinalWidth - 1;
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
const prevOrd = this.children[index - 1].ordinal;
|
|
197
|
-
const prevOrdCode = prevOrd.charCodeAt(prevOrd.length - 1);
|
|
198
|
-
localOrdinal = prevOrdCode + ordinalWidth;
|
|
199
|
-
}
|
|
200
|
-
child.ordinal = this.ordinal + String.fromCharCode(localOrdinal);
|
|
201
|
-
(0, common_utils_1.assert)(child.ordinal.length === (this.ordinal.length + 1), 0x041 /* "Unexpected child ordinal length!" */);
|
|
202
|
-
if (index > 0) {
|
|
203
|
-
(0, common_utils_1.assert)(child.ordinal > this.children[index - 1].ordinal, 0x042);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
assignChild(child, index, updateOrdinal = true) {
|
|
207
|
-
child.parent = this;
|
|
208
|
-
child.index = index;
|
|
209
|
-
if (updateOrdinal) {
|
|
210
|
-
this.setOrdinal(child, index);
|
|
225
|
+
function extendIfUndefined(base, extension) {
|
|
226
|
+
if (extension !== undefined) {
|
|
227
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
228
|
+
for (const key in extension) {
|
|
229
|
+
if (base[key] === undefined) {
|
|
230
|
+
base[key] = extension[key];
|
|
231
|
+
}
|
|
211
232
|
}
|
|
212
|
-
this.children[index] = child;
|
|
213
233
|
}
|
|
234
|
+
return base;
|
|
214
235
|
}
|
|
215
|
-
|
|
216
|
-
class HierMergeBlock extends MergeBlock {
|
|
236
|
+
class HierMergeBlock extends mergeTreeNodes_1.MergeBlock {
|
|
217
237
|
constructor(childCount) {
|
|
218
238
|
super(childCount);
|
|
219
239
|
this.rightmostTiles = (0, properties_1.createMap)();
|
|
220
240
|
this.leftmostTiles = (0, properties_1.createMap)();
|
|
221
241
|
this.rangeStacks = (0, properties_1.createMap)();
|
|
222
242
|
}
|
|
243
|
+
/**
|
|
244
|
+
* @deprecated for internal use only. public export will be removed.
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
223
247
|
addNodeReferences(mergeTree, node) {
|
|
224
248
|
addNodeReferences(mergeTree, node, this.rightmostTiles, this.leftmostTiles, this.rangeStacks);
|
|
225
249
|
}
|
|
@@ -231,7 +255,7 @@ class HierMergeBlock extends MergeBlock {
|
|
|
231
255
|
// eslint-disable-next-line guard-for-in, no-restricted-syntax
|
|
232
256
|
for (const key in this.rangeStacks) {
|
|
233
257
|
const stack = this.rangeStacks[key];
|
|
234
|
-
strbuf += internedSpaces(indentCount);
|
|
258
|
+
strbuf += (0, mergeTreeNodes_1.internedSpaces)(indentCount);
|
|
235
259
|
strbuf += `${key}: `;
|
|
236
260
|
for (const item of stack.items) {
|
|
237
261
|
strbuf += `${item.toString()} `;
|
|
@@ -241,424 +265,24 @@ class HierMergeBlock extends MergeBlock {
|
|
|
241
265
|
return strbuf;
|
|
242
266
|
}
|
|
243
267
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
return mergeTree.localNetLength(node);
|
|
249
|
-
}
|
|
250
|
-
class BaseSegment extends MergeNode {
|
|
251
|
-
constructor() {
|
|
252
|
-
super(...arguments);
|
|
253
|
-
this.clientId = constants_1.LocalClientId;
|
|
254
|
-
this.seq = constants_1.UniversalSequenceNumber;
|
|
255
|
-
this.segmentGroups = new segmentGroupCollection_1.SegmentGroupCollection(this);
|
|
256
|
-
this.trackingCollection = new mergeTreeTracking_1.TrackingGroupCollection(this);
|
|
257
|
-
}
|
|
258
|
-
addProperties(newProps, op, seq, collabWindow) {
|
|
259
|
-
if (!this.propertyManager) {
|
|
260
|
-
this.propertyManager = new segmentPropertiesManager_1.PropertiesManager();
|
|
261
|
-
}
|
|
262
|
-
if (!this.properties) {
|
|
263
|
-
this.properties = (0, properties_1.createMap)();
|
|
264
|
-
}
|
|
265
|
-
return this.propertyManager.addProperties(this.properties, newProps, op, seq, collabWindow && collabWindow.collaborating);
|
|
266
|
-
}
|
|
267
|
-
hasProperty(key) {
|
|
268
|
-
return !!this.properties && (this.properties[key] !== undefined);
|
|
269
|
-
}
|
|
270
|
-
isLeaf() {
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
cloneInto(b) {
|
|
274
|
-
var _a;
|
|
275
|
-
b.clientId = this.clientId;
|
|
276
|
-
// TODO: deep clone properties
|
|
277
|
-
b.properties = (0, properties_1.clone)(this.properties);
|
|
278
|
-
b.removedClientIds = (_a = this.removedClientIds) === null || _a === void 0 ? void 0 : _a.slice();
|
|
279
|
-
// TODO: copy removed client overlap and branch removal info
|
|
280
|
-
b.removedSeq = this.removedSeq;
|
|
281
|
-
b.seq = this.seq;
|
|
282
|
-
}
|
|
283
|
-
canAppend(segment) {
|
|
284
|
-
return false;
|
|
285
|
-
}
|
|
286
|
-
addSerializedProps(jseg) {
|
|
287
|
-
if (this.properties) {
|
|
288
|
-
jseg.props = this.properties;
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
ack(segmentGroup, opArgs, mergeTree) {
|
|
292
|
-
const currentSegmentGroup = this.segmentGroups.dequeue();
|
|
293
|
-
(0, common_utils_1.assert)(currentSegmentGroup === segmentGroup, 0x043 /* "On ack, unexpected segmentGroup!" */);
|
|
294
|
-
switch (opArgs.op.type) {
|
|
295
|
-
case ops_1.MergeTreeDeltaType.ANNOTATE:
|
|
296
|
-
(0, common_utils_1.assert)(!!this.propertyManager, 0x044 /* "On annotate ack, missing segment property manager!" */);
|
|
297
|
-
this.propertyManager.ackPendingProperties(opArgs.op);
|
|
298
|
-
return true;
|
|
299
|
-
case ops_1.MergeTreeDeltaType.INSERT:
|
|
300
|
-
(0, common_utils_1.assert)(this.seq === constants_1.UnassignedSequenceNumber, 0x045 /* "On insert, seq number already assigned!" */);
|
|
301
|
-
this.seq = opArgs.sequencedMessage.sequenceNumber;
|
|
302
|
-
this.localSeq = undefined;
|
|
303
|
-
return true;
|
|
304
|
-
case ops_1.MergeTreeDeltaType.REMOVE:
|
|
305
|
-
const removalInfo = toRemovalInfo(this);
|
|
306
|
-
(0, common_utils_1.assert)(removalInfo !== undefined, 0x046 /* "On remove ack, missing removal info!" */);
|
|
307
|
-
this.localRemovedSeq = undefined;
|
|
308
|
-
if (removalInfo.removedSeq === constants_1.UnassignedSequenceNumber) {
|
|
309
|
-
removalInfo.removedSeq = opArgs.sequencedMessage.sequenceNumber;
|
|
310
|
-
return true;
|
|
311
|
-
}
|
|
312
|
-
return false;
|
|
313
|
-
default:
|
|
314
|
-
throw new Error(`${opArgs.op.type} is in unrecognized operation type`);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
splitAt(pos) {
|
|
318
|
-
var _a;
|
|
319
|
-
if (pos > 0) {
|
|
320
|
-
const leafSegment = this.createSplitSegmentAt(pos);
|
|
321
|
-
if (leafSegment) {
|
|
322
|
-
this.copyPropertiesTo(leafSegment);
|
|
323
|
-
leafSegment.parent = this.parent;
|
|
324
|
-
// Give the leaf a temporary yet valid ordinal.
|
|
325
|
-
// when this segment is put in the tree, it will get it's real ordinal,
|
|
326
|
-
// but this ordinal meets all the necessary invariants for now.
|
|
327
|
-
leafSegment.ordinal = this.ordinal + String.fromCharCode(0);
|
|
328
|
-
leafSegment.removedClientIds = (_a = this.removedClientIds) === null || _a === void 0 ? void 0 : _a.slice();
|
|
329
|
-
leafSegment.removedSeq = this.removedSeq;
|
|
330
|
-
leafSegment.localRemovedSeq = this.localRemovedSeq;
|
|
331
|
-
leafSegment.seq = this.seq;
|
|
332
|
-
leafSegment.localSeq = this.localSeq;
|
|
333
|
-
leafSegment.clientId = this.clientId;
|
|
334
|
-
this.segmentGroups.copyTo(leafSegment);
|
|
335
|
-
this.trackingCollection.copyTo(leafSegment);
|
|
336
|
-
if (this.localRefs) {
|
|
337
|
-
this.localRefs.split(pos, leafSegment);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
return leafSegment;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
copyPropertiesTo(other) {
|
|
344
|
-
if (this.propertyManager) {
|
|
345
|
-
if (this.properties) {
|
|
346
|
-
other.propertyManager = new segmentPropertiesManager_1.PropertiesManager();
|
|
347
|
-
other.properties = this.propertyManager.copyTo(this.properties, other.properties, other.propertyManager);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
exports.BaseSegment = BaseSegment;
|
|
353
|
-
exports.reservedMarkerIdKey = "markerId";
|
|
354
|
-
exports.reservedMarkerSimpleTypeKey = "markerSimpleType";
|
|
355
|
-
class Marker extends BaseSegment {
|
|
356
|
-
constructor(refType) {
|
|
357
|
-
super();
|
|
358
|
-
this.refType = refType;
|
|
359
|
-
this.type = Marker.type;
|
|
360
|
-
this.cachedLength = 1;
|
|
361
|
-
}
|
|
362
|
-
static is(segment) {
|
|
363
|
-
return segment.type === Marker.type;
|
|
364
|
-
}
|
|
365
|
-
static make(refType, props) {
|
|
366
|
-
const marker = new Marker(refType);
|
|
367
|
-
if (props) {
|
|
368
|
-
marker.addProperties(props);
|
|
369
|
-
}
|
|
370
|
-
return marker;
|
|
371
|
-
}
|
|
372
|
-
toJSONObject() {
|
|
373
|
-
const obj = { marker: { refType: this.refType } };
|
|
374
|
-
super.addSerializedProps(obj);
|
|
375
|
-
return obj;
|
|
376
|
-
}
|
|
377
|
-
static fromJSONObject(spec) {
|
|
378
|
-
if (spec && typeof spec === "object" && "marker" in spec) {
|
|
379
|
-
return Marker.make(spec.marker.refType, spec.props);
|
|
380
|
-
}
|
|
381
|
-
return undefined;
|
|
382
|
-
}
|
|
383
|
-
clone() {
|
|
384
|
-
const b = Marker.make(this.refType, this.properties);
|
|
385
|
-
this.cloneInto(b);
|
|
386
|
-
return b;
|
|
387
|
-
}
|
|
388
|
-
getSegment() {
|
|
389
|
-
return this;
|
|
390
|
-
}
|
|
391
|
-
getOffset() {
|
|
392
|
-
return 0;
|
|
393
|
-
}
|
|
394
|
-
hasSimpleType(simpleTypeName) {
|
|
395
|
-
return !!this.properties &&
|
|
396
|
-
this.properties[exports.reservedMarkerSimpleTypeKey] === simpleTypeName;
|
|
397
|
-
}
|
|
398
|
-
getProperties() {
|
|
399
|
-
return this.properties;
|
|
400
|
-
}
|
|
401
|
-
getId() {
|
|
402
|
-
if (this.properties && this.properties[exports.reservedMarkerIdKey]) {
|
|
403
|
-
return this.properties[exports.reservedMarkerIdKey];
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
/**
|
|
407
|
-
* @deprecated - use refHasTileLabels
|
|
408
|
-
*/
|
|
409
|
-
hasTileLabels() {
|
|
410
|
-
return (0, referencePositions_1.refHasTileLabels)(this);
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* @deprecated - use refHasRangeLabels
|
|
414
|
-
*/
|
|
415
|
-
hasRangeLabels() {
|
|
416
|
-
return (0, referencePositions_1.refHasRangeLabels)(this);
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* @deprecated - use refHasTileLabel
|
|
420
|
-
*/
|
|
421
|
-
hasTileLabel(label) {
|
|
422
|
-
return (0, referencePositions_1.refHasTileLabel)(this, label);
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* @deprecated - use refHasRangeLabel
|
|
426
|
-
*/
|
|
427
|
-
hasRangeLabel(label) {
|
|
428
|
-
return (0, referencePositions_1.refHasRangeLabel)(this, label);
|
|
429
|
-
}
|
|
430
|
-
/**
|
|
431
|
-
* @deprecated - use refGetTileLabels
|
|
432
|
-
*/
|
|
433
|
-
getTileLabels() {
|
|
434
|
-
return (0, referencePositions_1.refGetTileLabels)(this);
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* @deprecated - use refGetRangeLabels
|
|
438
|
-
*/
|
|
439
|
-
getRangeLabels() {
|
|
440
|
-
return (0, referencePositions_1.refGetRangeLabels)(this);
|
|
441
|
-
}
|
|
442
|
-
toString() {
|
|
443
|
-
let bbuf = "";
|
|
444
|
-
if ((0, referencePositions_1.refTypeIncludesFlag)(this, ops_1.ReferenceType.Tile)) {
|
|
445
|
-
bbuf += "Tile";
|
|
446
|
-
}
|
|
447
|
-
if ((0, referencePositions_1.refTypeIncludesFlag)(this, ops_1.ReferenceType.NestBegin)) {
|
|
448
|
-
if (bbuf.length > 0) {
|
|
449
|
-
bbuf += "; ";
|
|
450
|
-
}
|
|
451
|
-
bbuf += "RangeBegin";
|
|
452
|
-
}
|
|
453
|
-
if ((0, referencePositions_1.refTypeIncludesFlag)(this, ops_1.ReferenceType.NestEnd)) {
|
|
454
|
-
if (bbuf.length > 0) {
|
|
455
|
-
bbuf += "; ";
|
|
456
|
-
}
|
|
457
|
-
bbuf += "RangeEnd";
|
|
458
|
-
}
|
|
459
|
-
let lbuf = "";
|
|
460
|
-
const id = this.getId();
|
|
461
|
-
if (id) {
|
|
462
|
-
bbuf += ` (${id}) `;
|
|
463
|
-
}
|
|
464
|
-
const tileLabels = (0, referencePositions_1.refGetTileLabels)(this);
|
|
465
|
-
if (tileLabels) {
|
|
466
|
-
lbuf += "tile -- ";
|
|
467
|
-
for (let i = 0, len = tileLabels.length; i < len; i++) {
|
|
468
|
-
const tileLabel = tileLabels[i];
|
|
469
|
-
if (i > 0) {
|
|
470
|
-
lbuf += "; ";
|
|
471
|
-
}
|
|
472
|
-
lbuf += tileLabel;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
const rangeLabels = (0, referencePositions_1.refGetRangeLabels)(this);
|
|
476
|
-
if (rangeLabels) {
|
|
477
|
-
let rangeKind = "begin";
|
|
478
|
-
if ((0, referencePositions_1.refTypeIncludesFlag)(this, ops_1.ReferenceType.NestEnd)) {
|
|
479
|
-
rangeKind = "end";
|
|
480
|
-
}
|
|
481
|
-
if (tileLabels) {
|
|
482
|
-
lbuf += " ";
|
|
483
|
-
}
|
|
484
|
-
lbuf += `range ${rangeKind} -- `;
|
|
485
|
-
const labels = rangeLabels;
|
|
486
|
-
for (let i = 0, len = labels.length; i < len; i++) {
|
|
487
|
-
const rangeLabel = labels[i];
|
|
488
|
-
if (i > 0) {
|
|
489
|
-
lbuf += "; ";
|
|
490
|
-
}
|
|
491
|
-
lbuf += rangeLabel;
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
let pbuf = "";
|
|
495
|
-
if (this.properties) {
|
|
496
|
-
pbuf += JSON.stringify(this.properties, (key, value) => {
|
|
497
|
-
// Avoid circular reference when stringifying makers containing handles.
|
|
498
|
-
// (Substitute a debug string instead.)
|
|
499
|
-
const handle = !!value && value.IFluidHandle;
|
|
500
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
501
|
-
return handle
|
|
502
|
-
? `#Handle(${handle.routeContext.path}/${handle.path})`
|
|
503
|
-
: value;
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
|
-
return `M ${bbuf}: ${lbuf} ${pbuf}`;
|
|
507
|
-
}
|
|
508
|
-
createSplitSegmentAt(pos) {
|
|
509
|
-
return undefined;
|
|
510
|
-
}
|
|
511
|
-
canAppend(segment) {
|
|
512
|
-
return false;
|
|
513
|
-
}
|
|
514
|
-
append() { throw new Error("Can not append to marker"); }
|
|
515
|
-
}
|
|
516
|
-
exports.Marker = Marker;
|
|
517
|
-
Marker.type = "Marker";
|
|
518
|
-
var IncrementalExecOp;
|
|
519
|
-
(function (IncrementalExecOp) {
|
|
520
|
-
IncrementalExecOp[IncrementalExecOp["Go"] = 0] = "Go";
|
|
521
|
-
IncrementalExecOp[IncrementalExecOp["Stop"] = 1] = "Stop";
|
|
522
|
-
IncrementalExecOp[IncrementalExecOp["Yield"] = 2] = "Yield";
|
|
523
|
-
})(IncrementalExecOp = exports.IncrementalExecOp || (exports.IncrementalExecOp = {}));
|
|
524
|
-
class IncrementalMapState {
|
|
525
|
-
constructor(block, actions, pos, refSeq, clientId, context, start, end, childIndex = 0) {
|
|
526
|
-
this.block = block;
|
|
527
|
-
this.actions = actions;
|
|
528
|
-
this.pos = pos;
|
|
529
|
-
this.refSeq = refSeq;
|
|
530
|
-
this.clientId = clientId;
|
|
531
|
-
this.context = context;
|
|
532
|
-
this.start = start;
|
|
533
|
-
this.end = end;
|
|
534
|
-
this.childIndex = childIndex;
|
|
535
|
-
this.op = IncrementalExecOp.Go;
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
exports.IncrementalMapState = IncrementalMapState;
|
|
539
|
-
class CollaborationWindow {
|
|
540
|
-
constructor() {
|
|
541
|
-
this.clientId = constants_1.LocalClientId;
|
|
542
|
-
this.collaborating = false;
|
|
543
|
-
// Lowest-numbered segment in window; no client can reference a state before this one
|
|
544
|
-
this.minSeq = 0;
|
|
545
|
-
// Highest-numbered segment in window and current
|
|
546
|
-
// reference segment for this client
|
|
547
|
-
this.currentSeq = 0;
|
|
548
|
-
this.localSeq = 0;
|
|
549
|
-
}
|
|
550
|
-
loadFrom(a) {
|
|
551
|
-
this.clientId = a.clientId;
|
|
552
|
-
this.collaborating = a.collaborating;
|
|
553
|
-
this.minSeq = a.minSeq;
|
|
554
|
-
this.currentSeq = a.currentSeq;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
exports.CollaborationWindow = CollaborationWindow;
|
|
558
|
-
const compareNumbers = (a, b) => a - b;
|
|
559
|
-
exports.compareNumbers = compareNumbers;
|
|
560
|
-
const compareStrings = (a, b) => a.localeCompare(b);
|
|
561
|
-
exports.compareStrings = compareStrings;
|
|
562
|
-
const indentStrings = ["", " ", " "];
|
|
563
|
-
function internedSpaces(n) {
|
|
564
|
-
if (indentStrings[n] === undefined) {
|
|
565
|
-
indentStrings[n] = "";
|
|
566
|
-
for (let i = 0; i < n; i++) {
|
|
567
|
-
indentStrings[n] += " ";
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
return indentStrings[n];
|
|
571
|
-
}
|
|
572
|
-
exports.internedSpaces = internedSpaces;
|
|
268
|
+
/**
|
|
269
|
+
* @deprecated for internal use only. public export will be removed.
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
573
272
|
exports.clientSeqComparer = {
|
|
574
273
|
min: { refSeq: -1, clientId: "" },
|
|
575
274
|
compare: (a, b) => a.refSeq - b.refSeq,
|
|
576
275
|
};
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
function applyLeafRangeMarker(marker, searchInfo) {
|
|
582
|
-
for (const rangeLabel of searchInfo.rangeLabels) {
|
|
583
|
-
if ((0, referencePositions_1.refHasRangeLabel)(marker, rangeLabel)) {
|
|
584
|
-
let currentStack = searchInfo.stacks[rangeLabel];
|
|
585
|
-
if (currentStack === undefined) {
|
|
586
|
-
currentStack = new collections_1.Stack();
|
|
587
|
-
searchInfo.stacks[rangeLabel] = currentStack;
|
|
588
|
-
}
|
|
589
|
-
applyRangeReference(currentStack, marker);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
}
|
|
593
|
-
function recordRangeLeaf(segment, segpos, refSeq, clientId, start, end, searchInfo) {
|
|
594
|
-
if (Marker.is(segment)) {
|
|
595
|
-
if (segment.refType &
|
|
596
|
-
(ops_1.ReferenceType.NestBegin | ops_1.ReferenceType.NestEnd)) {
|
|
597
|
-
applyLeafRangeMarker(segment, searchInfo);
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return false;
|
|
601
|
-
}
|
|
602
|
-
function rangeShift(node, segpos, refSeq, clientId, offset, end, searchInfo) {
|
|
603
|
-
var _a;
|
|
604
|
-
if (node.isLeaf()) {
|
|
605
|
-
const seg = node;
|
|
606
|
-
if ((((_a = searchInfo.mergeTree.localNetLength(seg)) !== null && _a !== void 0 ? _a : 0) > 0) && Marker.is(seg)) {
|
|
607
|
-
if (seg.refType &
|
|
608
|
-
(ops_1.ReferenceType.NestBegin | ops_1.ReferenceType.NestEnd)) {
|
|
609
|
-
applyLeafRangeMarker(seg, searchInfo);
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
}
|
|
613
|
-
else {
|
|
614
|
-
const block = node;
|
|
615
|
-
applyStackDelta(searchInfo.stacks, block.rangeStacks);
|
|
616
|
-
}
|
|
617
|
-
return true;
|
|
618
|
-
}
|
|
619
|
-
function recordTileStart(segment, segpos, refSeq, clientId, start, end, searchInfo) {
|
|
620
|
-
if (Marker.is(segment)) {
|
|
621
|
-
if ((0, referencePositions_1.refHasTileLabel)(segment, searchInfo.tileLabel)) {
|
|
622
|
-
searchInfo.tile = segment;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
return false;
|
|
626
|
-
}
|
|
627
|
-
function tileShift(node, segpos, refSeq, clientId, offset, end, searchInfo) {
|
|
628
|
-
if (node.isLeaf()) {
|
|
629
|
-
const seg = node;
|
|
630
|
-
if ((searchInfo.mergeTree.localNetLength(seg) > 0) && Marker.is(seg)) {
|
|
631
|
-
if ((0, referencePositions_1.refHasTileLabel)(seg, searchInfo.tileLabel)) {
|
|
632
|
-
searchInfo.tile = seg;
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
else {
|
|
637
|
-
const block = node;
|
|
638
|
-
let marker;
|
|
639
|
-
if (searchInfo.posPrecedesTile) {
|
|
640
|
-
marker = block.rightmostTiles[searchInfo.tileLabel];
|
|
641
|
-
}
|
|
642
|
-
else {
|
|
643
|
-
marker = block.leftmostTiles[searchInfo.tileLabel];
|
|
644
|
-
}
|
|
645
|
-
if (marker !== undefined) {
|
|
646
|
-
searchInfo.tile = marker;
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
return true;
|
|
650
|
-
}
|
|
651
|
-
const minListenerComparer = {
|
|
652
|
-
min: { minRequired: Number.MIN_VALUE, onMinGE: () => { (0, common_utils_1.assert)(false, 0x048 /* "onMinGE()" */); } },
|
|
653
|
-
compare: (a, b) => a.minRequired - b.minRequired,
|
|
654
|
-
};
|
|
655
|
-
// Represents a sequence of text segments
|
|
276
|
+
/**
|
|
277
|
+
* @deprecated for internal use only. public export will be removed.
|
|
278
|
+
* @internal
|
|
279
|
+
*/
|
|
656
280
|
class MergeTree {
|
|
657
281
|
// TODO: make and use interface describing options
|
|
658
282
|
constructor(options) {
|
|
659
283
|
this.options = options;
|
|
660
284
|
this.blockUpdateActions = MergeTree.initBlockUpdateActions;
|
|
661
|
-
this.collabWindow = new CollaborationWindow();
|
|
285
|
+
this.collabWindow = new mergeTreeNodes_1.CollaborationWindow();
|
|
662
286
|
// TODO: add remove on segment remove
|
|
663
287
|
// for now assume only markers have ids and so point directly at the Segment
|
|
664
288
|
// if we need to have pointers to non-markers, we can change to point at local refs
|
|
@@ -712,7 +336,7 @@ class MergeTree {
|
|
|
712
336
|
return b;
|
|
713
337
|
}
|
|
714
338
|
localNetLength(segment) {
|
|
715
|
-
const removalInfo = toRemovalInfo(segment);
|
|
339
|
+
const removalInfo = (0, mergeTreeNodes_1.toRemovalInfo)(segment);
|
|
716
340
|
if (removalInfo !== undefined) {
|
|
717
341
|
return 0;
|
|
718
342
|
}
|
|
@@ -733,7 +357,7 @@ class MergeTree {
|
|
|
733
357
|
reloadFromSegments(segments) {
|
|
734
358
|
// This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
|
|
735
359
|
(0, common_utils_1.assert)(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
|
|
736
|
-
const maxChildren =
|
|
360
|
+
const maxChildren = mergeTreeNodes_1.MaxNodesInBlock - 1;
|
|
737
361
|
// Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
|
|
738
362
|
const buildMergeBlock = (nodes) => {
|
|
739
363
|
const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
|
|
@@ -792,7 +416,7 @@ class MergeTree {
|
|
|
792
416
|
}
|
|
793
417
|
}
|
|
794
418
|
underflow(node) {
|
|
795
|
-
return node.childCount < (
|
|
419
|
+
return node.childCount < (mergeTreeNodes_1.MaxNodesInBlock / 2);
|
|
796
420
|
}
|
|
797
421
|
scourNode(node, holdNodes) {
|
|
798
422
|
let prevSegment;
|
|
@@ -879,14 +503,14 @@ class MergeTree {
|
|
|
879
503
|
childBlock.parent = undefined;
|
|
880
504
|
}
|
|
881
505
|
const totalNodeCount = holdNodes.length;
|
|
882
|
-
const halfCount =
|
|
883
|
-
let childCount = Math.min(
|
|
506
|
+
const halfCount = mergeTreeNodes_1.MaxNodesInBlock / 2;
|
|
507
|
+
let childCount = Math.min(mergeTreeNodes_1.MaxNodesInBlock - 1, Math.floor(totalNodeCount / halfCount));
|
|
884
508
|
if (childCount < 1) {
|
|
885
509
|
childCount = 1;
|
|
886
510
|
}
|
|
887
511
|
const baseCount = Math.floor(totalNodeCount / childCount);
|
|
888
512
|
let extraCount = totalNodeCount % childCount;
|
|
889
|
-
const packedBlocks = new Array(
|
|
513
|
+
const packedBlocks = new Array(mergeTreeNodes_1.MaxNodesInBlock);
|
|
890
514
|
let readCount = 0;
|
|
891
515
|
for (let nodeIndex = 0; nodeIndex < childCount; nodeIndex++) {
|
|
892
516
|
let nodeCount = baseCount;
|
|
@@ -965,7 +589,7 @@ class MergeTree {
|
|
|
965
589
|
liveCount: 0,
|
|
966
590
|
histo: [],
|
|
967
591
|
};
|
|
968
|
-
for (let k = 0; k <
|
|
592
|
+
for (let k = 0; k < mergeTreeNodes_1.MaxNodesInBlock; k++) {
|
|
969
593
|
stats.histo[k] = 0;
|
|
970
594
|
}
|
|
971
595
|
for (let i = 0; i < block.childCount; i++) {
|
|
@@ -978,7 +602,7 @@ class MergeTree {
|
|
|
978
602
|
stats.leafCount += childStats.leafCount;
|
|
979
603
|
stats.removedLeafCount += childStats.removedLeafCount;
|
|
980
604
|
stats.liveCount += childStats.liveCount;
|
|
981
|
-
for (let j = 0; j <
|
|
605
|
+
for (let j = 0; j < mergeTreeNodes_1.MaxNodesInBlock; j++) {
|
|
982
606
|
stats.histo[j] += childStats.histo[j];
|
|
983
607
|
}
|
|
984
608
|
}
|
|
@@ -1040,12 +664,12 @@ class MergeTree {
|
|
|
1040
664
|
}
|
|
1041
665
|
/**
|
|
1042
666
|
* @internal must only be used by client
|
|
1043
|
-
* @param
|
|
1044
|
-
* @returns The segment
|
|
667
|
+
* @param segment - The segment to slide from
|
|
668
|
+
* @returns The segment to
|
|
1045
669
|
*/
|
|
1046
|
-
_getSlideToSegment(
|
|
1047
|
-
if (!
|
|
1048
|
-
return
|
|
670
|
+
_getSlideToSegment(segment) {
|
|
671
|
+
if (!segment || !isRemovedAndAcked(segment)) {
|
|
672
|
+
return segment;
|
|
1049
673
|
}
|
|
1050
674
|
let slideToSegment;
|
|
1051
675
|
const goFurtherToFindSlideToSegment = (seg) => {
|
|
@@ -1056,19 +680,13 @@ class MergeTree {
|
|
|
1056
680
|
return true;
|
|
1057
681
|
};
|
|
1058
682
|
// Slide to the next farthest valid segment in the tree.
|
|
1059
|
-
this.rightExcursion(
|
|
683
|
+
this.rightExcursion(segment, goFurtherToFindSlideToSegment);
|
|
1060
684
|
if (slideToSegment) {
|
|
1061
|
-
return
|
|
685
|
+
return slideToSegment;
|
|
1062
686
|
}
|
|
1063
687
|
// If no such segment is found, slide to the last valid segment.
|
|
1064
|
-
this.leftExcursion(
|
|
1065
|
-
|
|
1066
|
-
slideToSegment = slideToSegment;
|
|
1067
|
-
if (slideToSegment) {
|
|
1068
|
-
// If slid nearer then offset should be at the end of the segment
|
|
1069
|
-
return { segment: slideToSegment, offset: slideToSegment.cachedLength - 1 };
|
|
1070
|
-
}
|
|
1071
|
-
return { segment: undefined, offset: 0 };
|
|
688
|
+
this.leftExcursion(segment, goFurtherToFindSlideToSegment);
|
|
689
|
+
return slideToSegment;
|
|
1072
690
|
}
|
|
1073
691
|
/**
|
|
1074
692
|
* This method should only be called when the current client sequence number is
|
|
@@ -1080,27 +698,23 @@ class MergeTree {
|
|
|
1080
698
|
var _a, _b, _c, _d, _e;
|
|
1081
699
|
(0, common_utils_1.assert)(isRemovedAndAcked(segment), 0x2f1 /* slideReferences from a segment which has not been removed and acked */);
|
|
1082
700
|
(0, common_utils_1.assert)(!!segment.localRefs, 0x2f2 /* Ref not in the segment localRefs */);
|
|
1083
|
-
const
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
newSegment.
|
|
1087
|
-
|
|
1088
|
-
for (const ref of refsToSlide) {
|
|
1089
|
-
(_b = (_a = ref.callbacks) === null || _a === void 0 ? void 0 : _a.beforeSlide) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
1090
|
-
const removedRef = segment.localRefs.removeLocalRef(ref);
|
|
1091
|
-
(0, common_utils_1.assert)(ref === removedRef, 0x2f3 /* Ref not in the segment localRefs */);
|
|
1092
|
-
if (!newSegment) {
|
|
1093
|
-
// No valid segments (all nodes removed or not yet created)
|
|
1094
|
-
ref.segment = undefined;
|
|
1095
|
-
ref.offset = 0;
|
|
701
|
+
const newSegment = this._getSlideToSegment(segment);
|
|
702
|
+
if (newSegment) {
|
|
703
|
+
const localRefs = (_a = newSegment.localRefs) !== null && _a !== void 0 ? _a : (newSegment.localRefs = new localReference_1.LocalReferenceCollection(newSegment));
|
|
704
|
+
if (newSegment.ordinal < segment.ordinal) {
|
|
705
|
+
localRefs.addAfterTombstones(refsToSlide);
|
|
1096
706
|
}
|
|
1097
707
|
else {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
708
|
+
localRefs.addBeforeTombstones(refsToSlide);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
for (const ref of refsToSlide) {
|
|
713
|
+
(_c = (_b = ref.callbacks) === null || _b === void 0 ? void 0 : _b.beforeSlide) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
714
|
+
(0, localReference_1.assertLocalReferences)(ref);
|
|
715
|
+
ref.link(undefined, 0, undefined);
|
|
716
|
+
(_e = (_d = ref.callbacks) === null || _d === void 0 ? void 0 : _d.afterSlide) === null || _e === void 0 ? void 0 : _e.call(_d);
|
|
1102
717
|
}
|
|
1103
|
-
(_e = (_d = ref.callbacks) === null || _d === void 0 ? void 0 : _d.afterSlide) === null || _e === void 0 ? void 0 : _e.call(_d);
|
|
1104
718
|
}
|
|
1105
719
|
// TODO is it required to update the path lengths?
|
|
1106
720
|
if (newSegment) {
|
|
@@ -1112,30 +726,24 @@ class MergeTree {
|
|
|
1112
726
|
return;
|
|
1113
727
|
}
|
|
1114
728
|
const refsToSlide = [];
|
|
1115
|
-
const refsToStay = [];
|
|
1116
729
|
for (const lref of segment.localRefs) {
|
|
1117
730
|
if ((0, referencePositions_1.refTypeIncludesFlag)(lref, ops_1.ReferenceType.StayOnRemove)) {
|
|
1118
|
-
|
|
731
|
+
continue;
|
|
1119
732
|
}
|
|
1120
|
-
|
|
1121
|
-
if (pending) {
|
|
1122
|
-
refsToStay.push(lref);
|
|
1123
|
-
}
|
|
1124
|
-
else {
|
|
733
|
+
if ((0, referencePositions_1.refTypeIncludesFlag)(lref, ops_1.ReferenceType.SlideOnRemove)) {
|
|
734
|
+
if (!pending) {
|
|
1125
735
|
refsToSlide.push(lref);
|
|
1126
736
|
}
|
|
1127
737
|
}
|
|
738
|
+
else {
|
|
739
|
+
segment.localRefs.removeLocalRef(lref);
|
|
740
|
+
}
|
|
1128
741
|
}
|
|
1129
742
|
// Rethink implementation of keeping and sliding refs once other reference
|
|
1130
743
|
// changes are complete. This works but is fragile and possibly slow.
|
|
1131
744
|
if (!pending) {
|
|
1132
745
|
this.slideReferences(segment, refsToSlide);
|
|
1133
746
|
}
|
|
1134
|
-
segment.localRefs.clear();
|
|
1135
|
-
for (const lref of refsToStay) {
|
|
1136
|
-
lref.segment = segment;
|
|
1137
|
-
segment.localRefs.addLocalRef(lref);
|
|
1138
|
-
}
|
|
1139
747
|
}
|
|
1140
748
|
blockLength(node, refSeq, clientId) {
|
|
1141
749
|
if ((this.collabWindow.collaborating) && (clientId !== this.collabWindow.clientId)) {
|
|
@@ -1162,7 +770,7 @@ class MergeTree {
|
|
|
1162
770
|
}
|
|
1163
771
|
else {
|
|
1164
772
|
const segment = node;
|
|
1165
|
-
const removalInfo = toRemovalInfo(segment);
|
|
773
|
+
const removalInfo = (0, mergeTreeNodes_1.toRemovalInfo)(segment);
|
|
1166
774
|
if (removalInfo !== undefined
|
|
1167
775
|
&& removalInfo.removedSeq !== constants_1.UnassignedSequenceNumber
|
|
1168
776
|
&& removalInfo.removedSeq <= refSeq) {
|
|
@@ -1228,13 +836,25 @@ class MergeTree {
|
|
|
1228
836
|
}
|
|
1229
837
|
}
|
|
1230
838
|
referencePositionToLocalPosition(refPos, refSeq = this.collabWindow.currentSeq, clientId = this.collabWindow.clientId) {
|
|
839
|
+
var _a;
|
|
1231
840
|
const seg = refPos.getSegment();
|
|
1232
|
-
if (seg
|
|
1233
|
-
|
|
841
|
+
if ((seg === null || seg === void 0 ? void 0 : seg.parent) === undefined) {
|
|
842
|
+
return referencePositions_1.DetachedReferencePosition;
|
|
843
|
+
}
|
|
844
|
+
if (refPos.isLeaf()) {
|
|
845
|
+
return this.getPosition(refPos, refSeq, clientId);
|
|
846
|
+
}
|
|
847
|
+
if ((0, referencePositions_1.refTypeIncludesFlag)(refPos, ops_1.ReferenceType.Transient)
|
|
848
|
+
|| ((_a = seg.localRefs) === null || _a === void 0 ? void 0 : _a.has(refPos))) {
|
|
849
|
+
const offset = isRemoved(seg) ? 0 : refPos.getOffset();
|
|
1234
850
|
return offset + this.getPosition(seg, refSeq, clientId);
|
|
1235
851
|
}
|
|
1236
|
-
return
|
|
852
|
+
return referencePositions_1.DetachedReferencePosition;
|
|
1237
853
|
}
|
|
854
|
+
/**
|
|
855
|
+
* @deprecated for internal use only. public export will be removed.
|
|
856
|
+
* @internal
|
|
857
|
+
*/
|
|
1238
858
|
getStackContext(startPos, clientId, rangeLabels) {
|
|
1239
859
|
const searchInfo = {
|
|
1240
860
|
mergeTree: this,
|
|
@@ -1265,7 +885,7 @@ class MergeTree {
|
|
|
1265
885
|
}
|
|
1266
886
|
else {
|
|
1267
887
|
const localRef = searchInfo.tile;
|
|
1268
|
-
pos = localRef.
|
|
888
|
+
pos = this.referencePositionToLocalPosition(localRef, constants_1.UniversalSequenceNumber, clientId);
|
|
1269
889
|
}
|
|
1270
890
|
return { tile: searchInfo.tile, pos };
|
|
1271
891
|
}
|
|
@@ -1406,13 +1026,23 @@ class MergeTree {
|
|
|
1406
1026
|
this.zamboniSegments();
|
|
1407
1027
|
}
|
|
1408
1028
|
}
|
|
1409
|
-
addToPendingList(segment, segmentGroup, localSeq) {
|
|
1029
|
+
addToPendingList(segment, segmentGroup, localSeq, previousProps) {
|
|
1410
1030
|
let _segmentGroup = segmentGroup;
|
|
1411
1031
|
if (_segmentGroup === undefined) {
|
|
1412
1032
|
// TODO: review the cast
|
|
1413
1033
|
_segmentGroup = { segments: [], localSeq };
|
|
1034
|
+
if (previousProps) {
|
|
1035
|
+
_segmentGroup.previousProps = [];
|
|
1036
|
+
}
|
|
1414
1037
|
this.pendingSegments.enqueue(_segmentGroup);
|
|
1415
1038
|
}
|
|
1039
|
+
if ((!_segmentGroup.previousProps && previousProps) ||
|
|
1040
|
+
(_segmentGroup.previousProps && !previousProps)) {
|
|
1041
|
+
throw new Error("All segments in group should have previousProps or none");
|
|
1042
|
+
}
|
|
1043
|
+
if (previousProps) {
|
|
1044
|
+
_segmentGroup.previousProps.push(previousProps);
|
|
1045
|
+
}
|
|
1416
1046
|
segment.segmentGroups.enqueue(_segmentGroup);
|
|
1417
1047
|
return _segmentGroup;
|
|
1418
1048
|
}
|
|
@@ -1483,7 +1113,7 @@ class MergeTree {
|
|
|
1483
1113
|
let block = segment.parent;
|
|
1484
1114
|
let ordinalUpdateNode = block;
|
|
1485
1115
|
while (block !== undefined) {
|
|
1486
|
-
if (block.childCount >=
|
|
1116
|
+
if (block.childCount >= mergeTreeNodes_1.MaxNodesInBlock) {
|
|
1487
1117
|
const splitNode = this.split(block);
|
|
1488
1118
|
if (block === this.root) {
|
|
1489
1119
|
this.updateRoot(splitNode);
|
|
@@ -1548,7 +1178,7 @@ class MergeTree {
|
|
|
1548
1178
|
insertSegment.seq = constants_1.UniversalSequenceNumber;
|
|
1549
1179
|
}
|
|
1550
1180
|
insertSegment.clientId = clientId;
|
|
1551
|
-
if (Marker.is(insertSegment)) {
|
|
1181
|
+
if (mergeTreeNodes_1.Marker.is(insertSegment)) {
|
|
1552
1182
|
const markerId = insertSegment.getId();
|
|
1553
1183
|
if (markerId) {
|
|
1554
1184
|
this.mapIdToSegment(markerId, insertSegment);
|
|
@@ -1597,7 +1227,7 @@ class MergeTree {
|
|
|
1597
1227
|
}
|
|
1598
1228
|
}
|
|
1599
1229
|
insertChildNode(block, child, childIndex) {
|
|
1600
|
-
(0, common_utils_1.assert)(block.childCount <
|
|
1230
|
+
(0, common_utils_1.assert)(block.childCount < mergeTreeNodes_1.MaxNodesInBlock, 0x051 /* "Too many children on merge block!" */);
|
|
1601
1231
|
for (let i = block.childCount; i > childIndex; i--) {
|
|
1602
1232
|
block.children[i] = block.children[i - 1];
|
|
1603
1233
|
block.children[i].index = i;
|
|
@@ -1656,7 +1286,7 @@ class MergeTree {
|
|
|
1656
1286
|
newSegment.seq = seq;
|
|
1657
1287
|
newSegment.localSeq = localSeq;
|
|
1658
1288
|
newSegment.clientId = clientId;
|
|
1659
|
-
if (Marker.is(newSegment)) {
|
|
1289
|
+
if (mergeTreeNodes_1.Marker.is(newSegment)) {
|
|
1660
1290
|
const markerId = newSegment.getId();
|
|
1661
1291
|
if (markerId) {
|
|
1662
1292
|
this.mapIdToSegment(markerId, newSegment);
|
|
@@ -1853,7 +1483,7 @@ class MergeTree {
|
|
|
1853
1483
|
block.assignChild(newNode, childIndex, false);
|
|
1854
1484
|
block.childCount++;
|
|
1855
1485
|
block.setOrdinal(newNode, childIndex);
|
|
1856
|
-
if (block.childCount <
|
|
1486
|
+
if (block.childCount < mergeTreeNodes_1.MaxNodesInBlock) {
|
|
1857
1487
|
if (fromSplit) {
|
|
1858
1488
|
this.nodeUpdateOrdinals(fromSplit);
|
|
1859
1489
|
}
|
|
@@ -1875,7 +1505,7 @@ class MergeTree {
|
|
|
1875
1505
|
}
|
|
1876
1506
|
}
|
|
1877
1507
|
split(node) {
|
|
1878
|
-
const halfCount =
|
|
1508
|
+
const halfCount = mergeTreeNodes_1.MaxNodesInBlock / 2;
|
|
1879
1509
|
const newNode = this.makeBlock(halfCount);
|
|
1880
1510
|
node.childCount = halfCount;
|
|
1881
1511
|
// Update ordinals to reflect lowered child count
|
|
@@ -1907,19 +1537,20 @@ class MergeTree {
|
|
|
1907
1537
|
* @param clientId - The id of the client making the annotate
|
|
1908
1538
|
* @param seq - The sequence number of the annotate operation
|
|
1909
1539
|
* @param opArgs - The op args for the annotate op. this is passed to the merge tree callback if there is one
|
|
1540
|
+
* @param rollback - Whether this is for a local rollback and what kind
|
|
1910
1541
|
*/
|
|
1911
|
-
annotateRange(start, end, props, combiningOp, refSeq, clientId, seq, opArgs) {
|
|
1542
|
+
annotateRange(start, end, props, combiningOp, refSeq, clientId, seq, opArgs, rollback = segmentPropertiesManager_1.PropertiesRollback.None) {
|
|
1912
1543
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1913
1544
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1914
1545
|
const deltaSegments = [];
|
|
1915
1546
|
const localSeq = seq === constants_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1916
1547
|
let segmentGroup;
|
|
1917
1548
|
const annotateSegment = (segment) => {
|
|
1918
|
-
const propertyDeltas = segment.addProperties(props, combiningOp, seq, this.collabWindow);
|
|
1549
|
+
const propertyDeltas = segment.addProperties(props, combiningOp, seq, this.collabWindow, rollback);
|
|
1919
1550
|
deltaSegments.push({ segment, propertyDeltas });
|
|
1920
1551
|
if (this.collabWindow.collaborating) {
|
|
1921
1552
|
if (seq === constants_1.UnassignedSequenceNumber) {
|
|
1922
|
-
segmentGroup = this.addToPendingList(segment, segmentGroup, localSeq);
|
|
1553
|
+
segmentGroup = this.addToPendingList(segment, segmentGroup, localSeq, propertyDeltas ? propertyDeltas : {});
|
|
1923
1554
|
}
|
|
1924
1555
|
else {
|
|
1925
1556
|
if (MergeTree.options.zamboniSegments) {
|
|
@@ -1949,10 +1580,11 @@ class MergeTree {
|
|
|
1949
1580
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1950
1581
|
let segmentGroup;
|
|
1951
1582
|
const removedSegments = [];
|
|
1952
|
-
const
|
|
1583
|
+
const localOverlapWithRefs = [];
|
|
1953
1584
|
const localSeq = seq === constants_1.UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1954
1585
|
const markRemoved = (segment, pos, _start, _end) => {
|
|
1955
|
-
|
|
1586
|
+
var _a;
|
|
1587
|
+
const existingRemovalInfo = (0, mergeTreeNodes_1.toRemovalInfo)(segment);
|
|
1956
1588
|
if (existingRemovalInfo !== undefined) {
|
|
1957
1589
|
_overwrite = true;
|
|
1958
1590
|
if (existingRemovalInfo.removedSeq === constants_1.UnassignedSequenceNumber) {
|
|
@@ -1962,7 +1594,9 @@ class MergeTree {
|
|
|
1962
1594
|
// keep first removal at the head.
|
|
1963
1595
|
existingRemovalInfo.removedClientIds.unshift(clientId);
|
|
1964
1596
|
existingRemovalInfo.removedSeq = seq;
|
|
1965
|
-
segment.
|
|
1597
|
+
if (((_a = segment.localRefs) === null || _a === void 0 ? void 0 : _a.empty) === false) {
|
|
1598
|
+
localOverlapWithRefs.push(segment);
|
|
1599
|
+
}
|
|
1966
1600
|
}
|
|
1967
1601
|
else {
|
|
1968
1602
|
// Do not replace earlier sequence number for remove
|
|
@@ -1975,9 +1609,6 @@ class MergeTree {
|
|
|
1975
1609
|
segment.localRemovedSeq = localSeq;
|
|
1976
1610
|
removedSegments.push({ segment });
|
|
1977
1611
|
}
|
|
1978
|
-
if (segment.localRefs && !segment.localRefs.empty) {
|
|
1979
|
-
segmentsWithRefs.push(segment);
|
|
1980
|
-
}
|
|
1981
1612
|
// Save segment so can assign removed sequence number when acked by server
|
|
1982
1613
|
if (this.collabWindow.collaborating) {
|
|
1983
1614
|
if (segment.removedSeq === constants_1.UnassignedSequenceNumber && clientId === this.collabWindow.clientId) {
|
|
@@ -2001,10 +1632,10 @@ class MergeTree {
|
|
|
2001
1632
|
return true;
|
|
2002
1633
|
};
|
|
2003
1634
|
this.mapRange({ leaf: markRemoved, post: afterMarkRemoved }, refSeq, clientId, undefined, start, end);
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
1635
|
+
// these segments are already viewed as being removed locally and are not event-ed
|
|
1636
|
+
// so can slide non-StayOnRemove refs immediately
|
|
1637
|
+
localOverlapWithRefs.forEach((s) => this.slideReferences(s, Array.from(s.localRefs)
|
|
1638
|
+
.filter((localRef) => !(0, referencePositions_1.refTypeIncludesFlag)(localRef, ops_1.ReferenceType.StayOnRemove))));
|
|
2008
1639
|
// opArgs == undefined => test code
|
|
2009
1640
|
if (this.mergeTreeDeltaCallback && removedSegments.length > 0) {
|
|
2010
1641
|
this.mergeTreeDeltaCallback(opArgs, {
|
|
@@ -2012,6 +1643,11 @@ class MergeTree {
|
|
|
2012
1643
|
deltaSegments: removedSegments,
|
|
2013
1644
|
});
|
|
2014
1645
|
}
|
|
1646
|
+
const pending = this.collabWindow.collaborating && clientId === this.collabWindow.clientId;
|
|
1647
|
+
// these events are newly removed
|
|
1648
|
+
// so we slide after eventing in case the consumer wants to make reference
|
|
1649
|
+
// changes at remove time, like add a ref to track undo redo.
|
|
1650
|
+
removedSegments.forEach((rSeg) => this.updateSegmentRefsAfterMarkRemoved(rSeg.segment, pending));
|
|
2015
1651
|
if (this.collabWindow.collaborating && (seq !== constants_1.UnassignedSequenceNumber)) {
|
|
2016
1652
|
if (MergeTree.options.zamboniSegments) {
|
|
2017
1653
|
this.zamboniSegments();
|
|
@@ -2021,7 +1657,7 @@ class MergeTree {
|
|
|
2021
1657
|
nodeUpdateLengthNewStructure(node, recur = false) {
|
|
2022
1658
|
this.blockUpdate(node);
|
|
2023
1659
|
if (this.collabWindow.collaborating) {
|
|
2024
|
-
node.partialLengths = partialLengths_1.PartialSequenceLengths.combine(
|
|
1660
|
+
node.partialLengths = partialLengths_1.PartialSequenceLengths.combine(node, this.collabWindow, recur);
|
|
2025
1661
|
}
|
|
2026
1662
|
}
|
|
2027
1663
|
removeLocalReferencePosition(lref) {
|
|
@@ -2035,7 +1671,7 @@ class MergeTree {
|
|
|
2035
1671
|
return removedRefs;
|
|
2036
1672
|
}
|
|
2037
1673
|
}
|
|
2038
|
-
createLocalReferencePosition(segment, offset, refType, properties
|
|
1674
|
+
createLocalReferencePosition(segment, offset, refType, properties) {
|
|
2039
1675
|
var _a;
|
|
2040
1676
|
if (isRemoved(segment)) {
|
|
2041
1677
|
if (!(0, referencePositions_1.refTypeIncludesFlag)(refType, ops_1.ReferenceType.SlideOnRemove | ops_1.ReferenceType.Transient)) {
|
|
@@ -2044,34 +1680,10 @@ class MergeTree {
|
|
|
2044
1680
|
}
|
|
2045
1681
|
const localRefs = (_a = segment.localRefs) !== null && _a !== void 0 ? _a : new localReference_1.LocalReferenceCollection(segment);
|
|
2046
1682
|
segment.localRefs = localRefs;
|
|
2047
|
-
const segRef = localRefs.createLocalRef(offset, refType, properties
|
|
1683
|
+
const segRef = localRefs.createLocalRef(offset, refType, properties);
|
|
2048
1684
|
this.blockUpdatePathLengths(segment.parent, constants_1.TreeMaintenanceSequenceNumber, constants_1.LocalClientId);
|
|
2049
1685
|
return segRef;
|
|
2050
1686
|
}
|
|
2051
|
-
/**
|
|
2052
|
-
* @deprecated - use removeLocalReferencePosition
|
|
2053
|
-
*/
|
|
2054
|
-
removeLocalReference(segment, lref) {
|
|
2055
|
-
if (segment.localRefs) {
|
|
2056
|
-
const removedRef = segment.localRefs.removeLocalRef(lref);
|
|
2057
|
-
if (removedRef) {
|
|
2058
|
-
this.blockUpdatePathLengths(segment.parent, constants_1.TreeMaintenanceSequenceNumber, constants_1.LocalClientId);
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
}
|
|
2062
|
-
/**
|
|
2063
|
-
* @deprecated - use createLocalReference
|
|
2064
|
-
*/
|
|
2065
|
-
addLocalReference(lref) {
|
|
2066
|
-
const segment = lref.segment;
|
|
2067
|
-
let localRefs = segment.localRefs;
|
|
2068
|
-
if (!localRefs) {
|
|
2069
|
-
localRefs = new localReference_1.LocalReferenceCollection(segment);
|
|
2070
|
-
segment.localRefs = localRefs;
|
|
2071
|
-
}
|
|
2072
|
-
localRefs.addLocalRef(lref);
|
|
2073
|
-
this.blockUpdatePathLengths(segment.parent, constants_1.TreeMaintenanceSequenceNumber, constants_1.LocalClientId);
|
|
2074
|
-
}
|
|
2075
1687
|
blockUpdate(block) {
|
|
2076
1688
|
var _a;
|
|
2077
1689
|
let len = 0;
|
|
@@ -2085,7 +1697,7 @@ class MergeTree {
|
|
|
2085
1697
|
const child = block.children[i];
|
|
2086
1698
|
len += (_a = nodeTotalLength(this, child)) !== null && _a !== void 0 ? _a : 0;
|
|
2087
1699
|
if (hierBlock) {
|
|
2088
|
-
|
|
1700
|
+
addNodeReferences(this, child, hierBlock.rightmostTiles, hierBlock.leftmostTiles, hierBlock.rangeStacks);
|
|
2089
1701
|
}
|
|
2090
1702
|
if (this.blockUpdateActions) {
|
|
2091
1703
|
this.blockUpdateActions.child(block, i);
|
|
@@ -2113,10 +1725,10 @@ class MergeTree {
|
|
|
2113
1725
|
if (node.partialLengths !== undefined
|
|
2114
1726
|
&& MergeTree.options.incrementalUpdate
|
|
2115
1727
|
&& clientId !== constants_1.NonCollabClient) {
|
|
2116
|
-
node.partialLengths.update(
|
|
1728
|
+
node.partialLengths.update(node, seq, clientId, this.collabWindow);
|
|
2117
1729
|
}
|
|
2118
1730
|
else {
|
|
2119
|
-
node.partialLengths = partialLengths_1.PartialSequenceLengths.combine(
|
|
1731
|
+
node.partialLengths = partialLengths_1.PartialSequenceLengths.combine(node, this.collabWindow);
|
|
2120
1732
|
}
|
|
2121
1733
|
}
|
|
2122
1734
|
}
|
|
@@ -2135,12 +1747,16 @@ class MergeTree {
|
|
|
2135
1747
|
}
|
|
2136
1748
|
this.nodeMap(this.root, actions, 0, refSeq, clientId, accum, start, end);
|
|
2137
1749
|
}
|
|
1750
|
+
/**
|
|
1751
|
+
* @deprecated for internal use only. public export will be removed.
|
|
1752
|
+
* @internal
|
|
1753
|
+
*/
|
|
2138
1754
|
incrementalBlockMap(stateStack) {
|
|
2139
1755
|
var _a;
|
|
2140
1756
|
while (!stateStack.empty()) {
|
|
2141
1757
|
// We already check the stack is not empty
|
|
2142
1758
|
const state = stateStack.top();
|
|
2143
|
-
if (state.op !== IncrementalExecOp.Go) {
|
|
1759
|
+
if (state.op !== mergeTreeNodes_1.IncrementalExecOp.Go) {
|
|
2144
1760
|
return;
|
|
2145
1761
|
}
|
|
2146
1762
|
if (state.childIndex === 0) {
|
|
@@ -2154,12 +1770,12 @@ class MergeTree {
|
|
|
2154
1770
|
state.actions.pre(state);
|
|
2155
1771
|
}
|
|
2156
1772
|
}
|
|
2157
|
-
if ((state.op === IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
|
|
1773
|
+
if ((state.op === mergeTreeNodes_1.IncrementalExecOp.Go) && (state.childIndex < state.block.childCount)) {
|
|
2158
1774
|
const child = state.block.children[state.childIndex];
|
|
2159
1775
|
const len = (_a = this.nodeLength(child, state.refSeq, state.clientId)) !== null && _a !== void 0 ? _a : 0;
|
|
2160
1776
|
if ((len > 0) && (state.start < len) && (state.end > 0)) {
|
|
2161
1777
|
if (!child.isLeaf()) {
|
|
2162
|
-
const childState = new IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
|
|
1778
|
+
const childState = new mergeTreeNodes_1.IncrementalMapState(child, state.actions, state.pos, state.refSeq, state.clientId, state.context, state.start, state.end, 0);
|
|
2163
1779
|
stateStack.push(childState);
|
|
2164
1780
|
}
|
|
2165
1781
|
else {
|
|
@@ -2173,7 +1789,7 @@ class MergeTree {
|
|
|
2173
1789
|
}
|
|
2174
1790
|
else {
|
|
2175
1791
|
if (state.childIndex === state.block.childCount) {
|
|
2176
|
-
if ((state.op === IncrementalExecOp.Go) && state.actions.post) {
|
|
1792
|
+
if ((state.op === mergeTreeNodes_1.IncrementalExecOp.Go) && state.actions.post) {
|
|
2177
1793
|
state.actions.post(state);
|
|
2178
1794
|
}
|
|
2179
1795
|
stateStack.pop();
|