@fluidframework/merge-tree 2.12.0 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- 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 +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +8 -7
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +190 -216
- 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 +76 -162
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +100 -112
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/mergeTreeTracking.d.ts.map +1 -1
- package/dist/mergeTreeTracking.js +0 -2
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +28 -26
- 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 +11 -4
- package/dist/perspective.js.map +1 -1
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js +4 -1
- package/dist/referencePositions.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +10 -11
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts +4 -4
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +0 -6
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentInfos.d.ts +257 -0
- package/dist/segmentInfos.d.ts.map +1 -0
- package/dist/segmentInfos.js +166 -0
- package/dist/segmentInfos.js.map +1 -0
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +38 -44
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +9 -12
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts +2 -2
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +5 -3
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts.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 +29 -27
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +6 -4
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testUtils.d.ts +2 -2
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +32 -8
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts +2 -2
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +12 -6
- package/dist/test/text.js.map +1 -1
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.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 +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +8 -7
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +177 -205
- 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 +76 -162
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +95 -108
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/mergeTreeTracking.d.ts.map +1 -1
- package/lib/mergeTreeTracking.js +0 -2
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +25 -23
- 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 +11 -4
- package/lib/perspective.js.map +1 -1
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js +4 -1
- package/lib/referencePositions.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +8 -9
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts +4 -4
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +0 -6
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentInfos.d.ts +257 -0
- package/lib/segmentInfos.d.ts.map +1 -0
- package/lib/segmentInfos.js +145 -0
- package/lib/segmentInfos.js.map +1 -0
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +38 -44
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +9 -12
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts +2 -2
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +5 -3
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts.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 +30 -28
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +5 -3
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testUtils.d.ts +2 -2
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +9 -8
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts +2 -2
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +12 -6
- package/lib/test/text.js.map +1 -1
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.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 +17 -17
- package/src/MergeTreeTextHelper.ts +2 -4
- package/src/attributionPolicy.ts +5 -13
- package/src/client.ts +55 -44
- package/src/endOfTreeSegment.ts +3 -3
- package/src/index.ts +4 -6
- package/src/mergeTree.ts +245 -282
- package/src/mergeTreeNodeWalk.ts +3 -2
- package/src/mergeTreeNodes.ts +190 -322
- package/src/mergeTreeTracking.ts +0 -3
- package/src/partialLengths.ts +42 -27
- package/src/perspective.ts +27 -4
- package/src/referencePositions.ts +4 -1
- package/src/revertibles.ts +19 -13
- package/src/segmentGroupCollection.ts +7 -18
- package/src/segmentInfos.ts +377 -0
- package/src/snapshotLoader.ts +60 -57
- package/src/snapshotV1.ts +14 -16
- package/src/snapshotlegacy.ts +12 -17
- package/src/sortedSegmentSet.ts +6 -8
- package/src/zamboni.ts +10 -12
package/lib/zamboni.js
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
6
|
import { UnassignedSequenceNumber } from "./constants.js";
|
|
7
7
|
import { MergeTreeMaintenanceType } from "./mergeTreeDeltaCallback.js";
|
|
8
|
-
import { Marker, MaxNodesInBlock, seqLTE,
|
|
8
|
+
import { assignChild, Marker, MaxNodesInBlock, seqLTE, } from "./mergeTreeNodes.js";
|
|
9
9
|
import { matchProperties } from "./properties.js";
|
|
10
|
+
import { toRemovalInfo, toMoveInfo, removeMergeNodeInfo } from "./segmentInfos.js";
|
|
10
11
|
export const zamboniSegmentsMax = 2;
|
|
11
12
|
function underflow(node) {
|
|
12
13
|
return node.childCount < MaxNodesInBlock / 2;
|
|
@@ -36,7 +37,7 @@ export function zamboniSegments(mergeTree, zamboniSegmentsMaxCount = zamboniSegm
|
|
|
36
37
|
block.childCount = newChildCount;
|
|
37
38
|
block.children = childrenCopy;
|
|
38
39
|
for (let j = 0; j < newChildCount; j++) {
|
|
39
|
-
|
|
40
|
+
assignChild(block, childrenCopy[j], j, false);
|
|
40
41
|
}
|
|
41
42
|
if (underflow(block) && block.parent) {
|
|
42
43
|
packParent(block.parent, mergeTree);
|
|
@@ -82,7 +83,7 @@ export function packParent(parent, mergeTree) {
|
|
|
82
83
|
const packedBlock = mergeTree.makeBlock(nodeCount);
|
|
83
84
|
for (let packedNodeIndex = 0; packedNodeIndex < nodeCount; packedNodeIndex++) {
|
|
84
85
|
const nodeToPack = holdNodes[childrenPackedCount++];
|
|
85
|
-
|
|
86
|
+
assignChild(packedBlock, nodeToPack, packedNodeIndex, false);
|
|
86
87
|
}
|
|
87
88
|
packedBlock.parent = parent;
|
|
88
89
|
packedBlocks[nodeIndex] = packedBlock;
|
|
@@ -90,7 +91,7 @@ export function packParent(parent, mergeTree) {
|
|
|
90
91
|
}
|
|
91
92
|
parent.children = packedBlocks;
|
|
92
93
|
for (let j = 0; j < childCount; j++) {
|
|
93
|
-
|
|
94
|
+
assignChild(parent, packedBlocks[j], j, false);
|
|
94
95
|
}
|
|
95
96
|
parent.childCount = childCount;
|
|
96
97
|
}
|
|
@@ -131,10 +132,10 @@ function scourNode(node, holdNodes, mergeTree) {
|
|
|
131
132
|
operation: MergeTreeMaintenanceType.UNLINK,
|
|
132
133
|
deltaSegments: [{ segment }],
|
|
133
134
|
}, undefined);
|
|
134
|
-
segment.parent = undefined;
|
|
135
135
|
if (Marker.is(segment)) {
|
|
136
136
|
mergeTree.unlinkMarker(segment);
|
|
137
137
|
}
|
|
138
|
+
removeMergeNodeInfo(segment);
|
|
138
139
|
}
|
|
139
140
|
else {
|
|
140
141
|
holdNodes.push(segment);
|
|
@@ -154,9 +155,9 @@ function scourNode(node, holdNodes, mergeTree) {
|
|
|
154
155
|
operation: MergeTreeMaintenanceType.APPEND,
|
|
155
156
|
deltaSegments: [{ segment: prevSegment }, { segment }],
|
|
156
157
|
}, undefined);
|
|
157
|
-
segment.parent = undefined;
|
|
158
158
|
for (const tg of segment.trackingCollection.trackingGroups)
|
|
159
159
|
tg.unlink(segment);
|
|
160
|
+
removeMergeNodeInfo(segment);
|
|
160
161
|
}
|
|
161
162
|
else {
|
|
162
163
|
holdNodes.push(segment);
|
package/lib/zamboni.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zamboni.js","sourceRoot":"","sources":["../src/zamboni.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { UnassignedSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport { MergeTreeMaintenanceType } from \"./mergeTreeDeltaCallback.js\";\nimport {\n\ttype MergeBlock,\n\tIMergeNode,\n\tISegmentLeaf,\n\tMarker,\n\tMaxNodesInBlock,\n\tseqLTE,\n\ttoMoveInfo,\n\ttoRemovalInfo,\n} from \"./mergeTreeNodes.js\";\nimport { matchProperties } from \"./properties.js\";\n\nexport const zamboniSegmentsMax = 2;\nfunction underflow(node: MergeBlock): boolean {\n\treturn node.childCount < MaxNodesInBlock / 2;\n}\n\nexport function zamboniSegments(\n\tmergeTree: MergeTree,\n\tzamboniSegmentsMaxCount = zamboniSegmentsMax,\n): void {\n\tif (!mergeTree.collabWindow.collaborating) {\n\t\treturn;\n\t}\n\n\tfor (let i = 0; i < zamboniSegmentsMaxCount; i++) {\n\t\tlet segmentToScour = mergeTree.segmentsToScour.peek()?.value;\n\n\t\tsegmentToScour?.segment?.propertyManager?.updateMsn(mergeTree.collabWindow.minSeq);\n\n\t\tif (!segmentToScour || segmentToScour.maxSeq > mergeTree.collabWindow.minSeq) {\n\t\t\tbreak;\n\t\t}\n\t\tsegmentToScour = mergeTree.segmentsToScour.get()!;\n\t\t// Only skip scouring if needs scour is explicitly false, not true or undefined\n\t\tif (\n\t\t\tsegmentToScour?.segment?.parent &&\n\t\t\tsegmentToScour.segment.parent.needsScour !== false\n\t\t) {\n\t\t\tconst block = segmentToScour.segment.parent;\n\t\t\tconst childrenCopy: IMergeNode[] = [];\n\t\t\tscourNode(block, childrenCopy, mergeTree);\n\t\t\t// This will avoid the cost of re-scouring nodes\n\t\t\t// that have recently been scoured\n\t\t\tblock.needsScour = false;\n\n\t\t\tconst newChildCount = childrenCopy.length;\n\n\t\t\tif (newChildCount < block.childCount) {\n\t\t\t\tblock.childCount = newChildCount;\n\t\t\t\tblock.children = childrenCopy;\n\t\t\t\tfor (let j = 0; j < newChildCount; j++) {\n\t\t\t\t\tblock.assignChild(childrenCopy[j], j, false);\n\t\t\t\t}\n\n\t\t\t\tif (underflow(block) && block.parent) {\n\t\t\t\t\tpackParent(block.parent, mergeTree);\n\t\t\t\t} else {\n\t\t\t\t\tmergeTree.nodeUpdateOrdinals(block);\n\t\t\t\t\tmergeTree.blockUpdatePathLengths(block, UnassignedSequenceNumber, -1, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Interior node with all node children\nexport function packParent(parent: MergeBlock, mergeTree: MergeTree): void {\n\tconst children = parent.children;\n\tlet childIndex: number;\n\tlet childBlock: MergeBlock;\n\tconst holdNodes: IMergeNode[] = [];\n\tfor (childIndex = 0; childIndex < parent.childCount; childIndex++) {\n\t\t// Debug assert not isLeaf()\n\t\tchildBlock = children[childIndex] as MergeBlock;\n\t\tscourNode(childBlock, holdNodes, mergeTree);\n\t\t// Will replace this block with a packed block\n\t\tchildBlock.parent = undefined;\n\t}\n\tif (holdNodes.length > 0) {\n\t\tconst totalNodeCount = holdNodes.length;\n\t\tconst halfOfMaxNodeCount = MaxNodesInBlock / 2;\n\t\tlet childCount = Math.min(\n\t\t\tMaxNodesInBlock - 1,\n\t\t\tMath.floor(totalNodeCount / halfOfMaxNodeCount),\n\t\t);\n\t\tif (childCount < 1) {\n\t\t\tchildCount = 1;\n\t\t}\n\t\tconst baseNodesInBlockCount = Math.floor(totalNodeCount / childCount);\n\t\tlet remainderCount = totalNodeCount % childCount;\n\t\tconst packedBlocks: IMergeNode[] = Array.from({ length: MaxNodesInBlock });\n\t\tlet childrenPackedCount = 0;\n\t\tfor (let nodeIndex = 0; nodeIndex < childCount; nodeIndex++) {\n\t\t\tlet nodeCount = baseNodesInBlockCount;\n\t\t\tif (remainderCount > 0) {\n\t\t\t\tnodeCount++;\n\t\t\t\tremainderCount--;\n\t\t\t}\n\t\t\tconst packedBlock = mergeTree.makeBlock(nodeCount);\n\t\t\tfor (let packedNodeIndex = 0; packedNodeIndex < nodeCount; packedNodeIndex++) {\n\t\t\t\tconst nodeToPack = holdNodes[childrenPackedCount++];\n\t\t\t\tpackedBlock.assignChild(nodeToPack, packedNodeIndex, false);\n\t\t\t}\n\t\t\tpackedBlock.parent = parent;\n\t\t\tpackedBlocks[nodeIndex] = packedBlock;\n\t\t\tmergeTree.nodeUpdateLengthNewStructure(packedBlock);\n\t\t}\n\t\tparent.children = packedBlocks;\n\t\tfor (let j = 0; j < childCount; j++) {\n\t\t\tparent.assignChild(packedBlocks[j], j, false);\n\t\t}\n\t\tparent.childCount = childCount;\n\t} else {\n\t\tparent.children = [];\n\t\tparent.childCount = 0;\n\t}\n\tif (underflow(parent) && parent.parent) {\n\t\tpackParent(parent.parent, mergeTree);\n\t} else {\n\t\tmergeTree.nodeUpdateOrdinals(parent);\n\t\tmergeTree.blockUpdatePathLengths(parent, UnassignedSequenceNumber, -1, true);\n\t}\n}\n\nfunction scourNode(node: MergeBlock, holdNodes: IMergeNode[], mergeTree: MergeTree): void {\n\t// The previous segment is tracked while scouring for the purposes of merging adjacent segments\n\t// when possible.\n\tlet prevSegment: ISegmentLeaf | undefined;\n\tfor (let k = 0; k < node.childCount; k++) {\n\t\t// TODO Non null asserting, why is this not null?\n\t\tconst childNode = node.children[k]!;\n\t\tif (!childNode.isLeaf() || childNode.segmentGroups?.empty === false) {\n\t\t\tholdNodes.push(childNode);\n\t\t\tprevSegment = undefined;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst segment = childNode;\n\t\tconst removalInfo = toRemovalInfo(segment);\n\t\tconst moveInfo = toMoveInfo(segment);\n\t\tif (removalInfo !== undefined || moveInfo !== undefined) {\n\t\t\t// If the segment's removal is below the MSN and it's not being held onto by a tracking group,\n\t\t\t// it can be unlinked (i.e. removed from the merge-tree)\n\t\t\tif (\n\t\t\t\t((!!removalInfo && seqLTE(removalInfo.removedSeq, mergeTree.collabWindow.minSeq)) ||\n\t\t\t\t\t(!!moveInfo && seqLTE(moveInfo.movedSeq, mergeTree.collabWindow.minSeq))) &&\n\t\t\t\tsegment.trackingCollection.empty\n\t\t\t) {\n\t\t\t\tmergeTree.mergeTreeMaintenanceCallback?.(\n\t\t\t\t\t{\n\t\t\t\t\t\toperation: MergeTreeMaintenanceType.UNLINK,\n\t\t\t\t\t\tdeltaSegments: [{ segment }],\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\n\t\t\t\tsegment.parent = undefined;\n\n\t\t\t\tif (Marker.is(segment)) {\n\t\t\t\t\tmergeTree.unlinkMarker(segment);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tholdNodes.push(segment);\n\t\t\t}\n\n\t\t\tprevSegment = undefined;\n\t\t} else {\n\t\t\tif (segment.seq! <= mergeTree.collabWindow.minSeq) {\n\t\t\t\tconst segmentHasPositiveLength = (mergeTree.localNetLength(segment) ?? 0) > 0;\n\t\t\t\tconst canAppend =\n\t\t\t\t\tprevSegment?.canAppend(segment) &&\n\t\t\t\t\tmatchProperties(prevSegment.properties, segment.properties) &&\n\t\t\t\t\tprevSegment.trackingCollection.matches(segment.trackingCollection) &&\n\t\t\t\t\tsegmentHasPositiveLength;\n\n\t\t\t\tif (canAppend) {\n\t\t\t\t\tprevSegment!.append(segment);\n\t\t\t\t\tmergeTree.mergeTreeMaintenanceCallback?.(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toperation: MergeTreeMaintenanceType.APPEND,\n\t\t\t\t\t\t\tdeltaSegments: [{ segment: prevSegment! }, { segment }],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\n\t\t\t\t\tsegment.parent = undefined;\n\t\t\t\t\tfor (const tg of segment.trackingCollection.trackingGroups) tg.unlink(segment);\n\t\t\t\t} else {\n\t\t\t\t\tholdNodes.push(segment);\n\t\t\t\t\tprevSegment = segmentHasPositiveLength ? segment : undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tholdNodes.push(segment);\n\t\t\t\tprevSegment = undefined;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"zamboni.js","sourceRoot":"","sources":["../src/zamboni.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { UnassignedSequenceNumber } from \"./constants.js\";\nimport { MergeTree } from \"./mergeTree.js\";\nimport { MergeTreeMaintenanceType } from \"./mergeTreeDeltaCallback.js\";\nimport {\n\ttype MergeBlock,\n\tassignChild,\n\tIMergeNode,\n\tISegmentPrivate,\n\tMarker,\n\tMaxNodesInBlock,\n\tseqLTE,\n} from \"./mergeTreeNodes.js\";\nimport { matchProperties } from \"./properties.js\";\nimport { toRemovalInfo, toMoveInfo, removeMergeNodeInfo } from \"./segmentInfos.js\";\n\nexport const zamboniSegmentsMax = 2;\nfunction underflow(node: MergeBlock): boolean {\n\treturn node.childCount < MaxNodesInBlock / 2;\n}\n\nexport function zamboniSegments(\n\tmergeTree: MergeTree,\n\tzamboniSegmentsMaxCount = zamboniSegmentsMax,\n): void {\n\tif (!mergeTree.collabWindow.collaborating) {\n\t\treturn;\n\t}\n\n\tfor (let i = 0; i < zamboniSegmentsMaxCount; i++) {\n\t\tlet segmentToScour = mergeTree.segmentsToScour.peek()?.value;\n\n\t\tsegmentToScour?.segment?.propertyManager?.updateMsn(mergeTree.collabWindow.minSeq);\n\n\t\tif (!segmentToScour || segmentToScour.maxSeq > mergeTree.collabWindow.minSeq) {\n\t\t\tbreak;\n\t\t}\n\t\tsegmentToScour = mergeTree.segmentsToScour.get()!;\n\t\t// Only skip scouring if needs scour is explicitly false, not true or undefined\n\t\tif (\n\t\t\tsegmentToScour?.segment?.parent &&\n\t\t\tsegmentToScour.segment.parent.needsScour !== false\n\t\t) {\n\t\t\tconst block = segmentToScour.segment.parent;\n\t\t\tconst childrenCopy: IMergeNode[] = [];\n\t\t\tscourNode(block, childrenCopy, mergeTree);\n\t\t\t// This will avoid the cost of re-scouring nodes\n\t\t\t// that have recently been scoured\n\t\t\tblock.needsScour = false;\n\n\t\t\tconst newChildCount = childrenCopy.length;\n\n\t\t\tif (newChildCount < block.childCount) {\n\t\t\t\tblock.childCount = newChildCount;\n\t\t\t\tblock.children = childrenCopy;\n\t\t\t\tfor (let j = 0; j < newChildCount; j++) {\n\t\t\t\t\tassignChild(block, childrenCopy[j], j, false);\n\t\t\t\t}\n\n\t\t\t\tif (underflow(block) && block.parent) {\n\t\t\t\t\tpackParent(block.parent, mergeTree);\n\t\t\t\t} else {\n\t\t\t\t\tmergeTree.nodeUpdateOrdinals(block);\n\t\t\t\t\tmergeTree.blockUpdatePathLengths(block, UnassignedSequenceNumber, -1, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n// Interior node with all node children\nexport function packParent(parent: MergeBlock, mergeTree: MergeTree): void {\n\tconst children = parent.children;\n\tlet childIndex: number;\n\tlet childBlock: MergeBlock;\n\tconst holdNodes: IMergeNode[] = [];\n\tfor (childIndex = 0; childIndex < parent.childCount; childIndex++) {\n\t\t// Debug assert not isLeaf()\n\t\tchildBlock = children[childIndex] as MergeBlock;\n\t\tscourNode(childBlock, holdNodes, mergeTree);\n\t\t// Will replace this block with a packed block\n\t\tchildBlock.parent = undefined;\n\t}\n\tif (holdNodes.length > 0) {\n\t\tconst totalNodeCount = holdNodes.length;\n\t\tconst halfOfMaxNodeCount = MaxNodesInBlock / 2;\n\t\tlet childCount = Math.min(\n\t\t\tMaxNodesInBlock - 1,\n\t\t\tMath.floor(totalNodeCount / halfOfMaxNodeCount),\n\t\t);\n\t\tif (childCount < 1) {\n\t\t\tchildCount = 1;\n\t\t}\n\t\tconst baseNodesInBlockCount = Math.floor(totalNodeCount / childCount);\n\t\tlet remainderCount = totalNodeCount % childCount;\n\t\tconst packedBlocks: IMergeNode[] = Array.from({ length: MaxNodesInBlock });\n\t\tlet childrenPackedCount = 0;\n\t\tfor (let nodeIndex = 0; nodeIndex < childCount; nodeIndex++) {\n\t\t\tlet nodeCount = baseNodesInBlockCount;\n\t\t\tif (remainderCount > 0) {\n\t\t\t\tnodeCount++;\n\t\t\t\tremainderCount--;\n\t\t\t}\n\t\t\tconst packedBlock = mergeTree.makeBlock(nodeCount);\n\t\t\tfor (let packedNodeIndex = 0; packedNodeIndex < nodeCount; packedNodeIndex++) {\n\t\t\t\tconst nodeToPack = holdNodes[childrenPackedCount++];\n\t\t\t\tassignChild(packedBlock, nodeToPack, packedNodeIndex, false);\n\t\t\t}\n\t\t\tpackedBlock.parent = parent;\n\t\t\tpackedBlocks[nodeIndex] = packedBlock;\n\t\t\tmergeTree.nodeUpdateLengthNewStructure(packedBlock);\n\t\t}\n\t\tparent.children = packedBlocks;\n\t\tfor (let j = 0; j < childCount; j++) {\n\t\t\tassignChild(parent, packedBlocks[j], j, false);\n\t\t}\n\t\tparent.childCount = childCount;\n\t} else {\n\t\tparent.children = [];\n\t\tparent.childCount = 0;\n\t}\n\tif (underflow(parent) && parent.parent) {\n\t\tpackParent(parent.parent, mergeTree);\n\t} else {\n\t\tmergeTree.nodeUpdateOrdinals(parent);\n\t\tmergeTree.blockUpdatePathLengths(parent, UnassignedSequenceNumber, -1, true);\n\t}\n}\n\nfunction scourNode(node: MergeBlock, holdNodes: IMergeNode[], mergeTree: MergeTree): void {\n\t// The previous segment is tracked while scouring for the purposes of merging adjacent segments\n\t// when possible.\n\tlet prevSegment: ISegmentPrivate | undefined;\n\tfor (let k = 0; k < node.childCount; k++) {\n\t\t// TODO Non null asserting, why is this not null?\n\t\tconst childNode = node.children[k]!;\n\t\tif (!childNode.isLeaf() || childNode.segmentGroups?.empty === false) {\n\t\t\tholdNodes.push(childNode);\n\t\t\tprevSegment = undefined;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst segment = childNode;\n\t\tconst removalInfo = toRemovalInfo(segment);\n\t\tconst moveInfo = toMoveInfo(segment);\n\t\tif (removalInfo !== undefined || moveInfo !== undefined) {\n\t\t\t// If the segment's removal is below the MSN and it's not being held onto by a tracking group,\n\t\t\t// it can be unlinked (i.e. removed from the merge-tree)\n\t\t\tif (\n\t\t\t\t((!!removalInfo && seqLTE(removalInfo.removedSeq, mergeTree.collabWindow.minSeq)) ||\n\t\t\t\t\t(!!moveInfo && seqLTE(moveInfo.movedSeq, mergeTree.collabWindow.minSeq))) &&\n\t\t\t\tsegment.trackingCollection.empty\n\t\t\t) {\n\t\t\t\tmergeTree.mergeTreeMaintenanceCallback?.(\n\t\t\t\t\t{\n\t\t\t\t\t\toperation: MergeTreeMaintenanceType.UNLINK,\n\t\t\t\t\t\tdeltaSegments: [{ segment }],\n\t\t\t\t\t},\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\tif (Marker.is(segment)) {\n\t\t\t\t\tmergeTree.unlinkMarker(segment);\n\t\t\t\t}\n\t\t\t\tremoveMergeNodeInfo(segment);\n\t\t\t} else {\n\t\t\t\tholdNodes.push(segment);\n\t\t\t}\n\n\t\t\tprevSegment = undefined;\n\t\t} else {\n\t\t\tif (segment.seq <= mergeTree.collabWindow.minSeq) {\n\t\t\t\tconst segmentHasPositiveLength = (mergeTree.localNetLength(segment) ?? 0) > 0;\n\t\t\t\tconst canAppend =\n\t\t\t\t\tprevSegment?.canAppend(segment) &&\n\t\t\t\t\tmatchProperties(prevSegment.properties, segment.properties) &&\n\t\t\t\t\tprevSegment.trackingCollection.matches(segment.trackingCollection) &&\n\t\t\t\t\tsegmentHasPositiveLength;\n\n\t\t\t\tif (canAppend) {\n\t\t\t\t\tprevSegment!.append(segment);\n\t\t\t\t\tmergeTree.mergeTreeMaintenanceCallback?.(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\toperation: MergeTreeMaintenanceType.APPEND,\n\t\t\t\t\t\t\tdeltaSegments: [{ segment: prevSegment! }, { segment }],\n\t\t\t\t\t\t},\n\t\t\t\t\t\tundefined,\n\t\t\t\t\t);\n\n\t\t\t\t\tfor (const tg of segment.trackingCollection.trackingGroups) tg.unlink(segment);\n\t\t\t\t\tremoveMergeNodeInfo(segment);\n\t\t\t\t} else {\n\t\t\t\t\tholdNodes.push(segment);\n\t\t\t\t\tprevSegment = segmentHasPositiveLength ? segment : undefined;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tholdNodes.push(segment);\n\t\t\t\tprevSegment = undefined;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/merge-tree",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Merge tree",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -81,33 +81,33 @@
|
|
|
81
81
|
"temp-directory": "nyc/.nyc_output"
|
|
82
82
|
},
|
|
83
83
|
"dependencies": {
|
|
84
|
-
"@fluid-internal/client-utils": "~2.
|
|
85
|
-
"@fluidframework/container-definitions": "~2.
|
|
86
|
-
"@fluidframework/core-interfaces": "~2.
|
|
87
|
-
"@fluidframework/core-utils": "~2.
|
|
88
|
-
"@fluidframework/datastore-definitions": "~2.
|
|
89
|
-
"@fluidframework/driver-definitions": "~2.
|
|
90
|
-
"@fluidframework/runtime-definitions": "~2.
|
|
91
|
-
"@fluidframework/runtime-utils": "~2.
|
|
92
|
-
"@fluidframework/shared-object-base": "~2.
|
|
93
|
-
"@fluidframework/telemetry-utils": "~2.
|
|
84
|
+
"@fluid-internal/client-utils": "~2.13.0",
|
|
85
|
+
"@fluidframework/container-definitions": "~2.13.0",
|
|
86
|
+
"@fluidframework/core-interfaces": "~2.13.0",
|
|
87
|
+
"@fluidframework/core-utils": "~2.13.0",
|
|
88
|
+
"@fluidframework/datastore-definitions": "~2.13.0",
|
|
89
|
+
"@fluidframework/driver-definitions": "~2.13.0",
|
|
90
|
+
"@fluidframework/runtime-definitions": "~2.13.0",
|
|
91
|
+
"@fluidframework/runtime-utils": "~2.13.0",
|
|
92
|
+
"@fluidframework/shared-object-base": "~2.13.0",
|
|
93
|
+
"@fluidframework/telemetry-utils": "~2.13.0"
|
|
94
94
|
},
|
|
95
95
|
"devDependencies": {
|
|
96
96
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
97
97
|
"@biomejs/biome": "~1.9.3",
|
|
98
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
99
|
-
"@fluid-private/stochastic-test-utils": "~2.
|
|
100
|
-
"@fluid-private/test-pairwise-generator": "~2.
|
|
98
|
+
"@fluid-internal/mocha-test-setup": "~2.13.0",
|
|
99
|
+
"@fluid-private/stochastic-test-utils": "~2.13.0",
|
|
100
|
+
"@fluid-private/test-pairwise-generator": "~2.13.0",
|
|
101
101
|
"@fluid-tools/benchmark": "^0.50.0",
|
|
102
102
|
"@fluid-tools/build-cli": "^0.51.0",
|
|
103
103
|
"@fluidframework/build-common": "^2.0.3",
|
|
104
104
|
"@fluidframework/build-tools": "^0.51.0",
|
|
105
105
|
"@fluidframework/eslint-config-fluid": "^5.6.0",
|
|
106
|
-
"@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.
|
|
107
|
-
"@fluidframework/test-runtime-utils": "~2.
|
|
106
|
+
"@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.12.0",
|
|
107
|
+
"@fluidframework/test-runtime-utils": "~2.13.0",
|
|
108
108
|
"@microsoft/api-extractor": "7.47.8",
|
|
109
109
|
"@types/diff": "^3.5.1",
|
|
110
|
-
"@types/mocha": "^
|
|
110
|
+
"@types/mocha": "^10.0.10",
|
|
111
111
|
"@types/node": "^18.19.0",
|
|
112
112
|
"c8": "^8.0.1",
|
|
113
113
|
"concurrently": "^8.2.1",
|
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { IIntegerRange } from "./client.js";
|
|
7
7
|
import { MergeTree } from "./mergeTree.js";
|
|
8
|
-
import {
|
|
9
|
-
// eslint-disable-next-line import/no-deprecated
|
|
8
|
+
import { ISegmentPrivate } from "./mergeTreeNodes.js";
|
|
10
9
|
import { IMergeTreeTextHelper, TextSegment } from "./textSegment.js";
|
|
11
10
|
|
|
12
11
|
interface ITextAccumulator {
|
|
@@ -15,7 +14,6 @@ interface ITextAccumulator {
|
|
|
15
14
|
parallelArrays?: boolean;
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
// eslint-disable-next-line import/no-deprecated
|
|
19
17
|
export class MergeTreeTextHelper implements IMergeTreeTextHelper {
|
|
20
18
|
constructor(private readonly mergeTree: MergeTree) {}
|
|
21
19
|
|
|
@@ -56,7 +54,7 @@ export class MergeTreeTextHelper implements IMergeTreeTextHelper {
|
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
function gatherText(
|
|
59
|
-
segment:
|
|
57
|
+
segment: ISegmentPrivate,
|
|
60
58
|
pos: number,
|
|
61
59
|
refSeq: number,
|
|
62
60
|
clientId: number,
|
package/src/attributionPolicy.ts
CHANGED
|
@@ -8,9 +8,7 @@ import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/in
|
|
|
8
8
|
import { AttributionKey } from "@fluidframework/runtime-definitions/internal";
|
|
9
9
|
|
|
10
10
|
import { AttributionCollection } from "./attributionCollection.js";
|
|
11
|
-
// eslint-disable-next-line import/no-deprecated
|
|
12
11
|
import { Client } from "./client.js";
|
|
13
|
-
// eslint-disable-next-line import/no-deprecated
|
|
14
12
|
import { AttributionPolicy } from "./mergeTree.js";
|
|
15
13
|
import {
|
|
16
14
|
IMergeTreeDeltaCallbackArgs,
|
|
@@ -19,8 +17,8 @@ import {
|
|
|
19
17
|
IMergeTreeSegmentDelta,
|
|
20
18
|
MergeTreeMaintenanceType,
|
|
21
19
|
} from "./mergeTreeDeltaCallback.js";
|
|
22
|
-
import type { ISegmentLeaf } from "./mergeTreeNodes.js";
|
|
23
20
|
import { MergeTreeDeltaType } from "./ops.js";
|
|
21
|
+
import { isInserted } from "./segmentInfos.js";
|
|
24
22
|
|
|
25
23
|
// Note: these thinly wrap MergeTreeDeltaCallback and MergeTreeMaintenanceCallback to provide the client.
|
|
26
24
|
// This is because the base callbacks don't always have enough information to infer whether the op being
|
|
@@ -29,13 +27,13 @@ interface AttributionCallbacks {
|
|
|
29
27
|
delta: (
|
|
30
28
|
opArgs: IMergeTreeDeltaOpArgs,
|
|
31
29
|
deltaArgs: IMergeTreeDeltaCallbackArgs,
|
|
32
|
-
|
|
30
|
+
|
|
33
31
|
client: Client,
|
|
34
32
|
) => void;
|
|
35
33
|
maintenance: (
|
|
36
34
|
maintenanceArgs: IMergeTreeMaintenanceCallbackArgs,
|
|
37
35
|
opArgs: IMergeTreeDeltaOpArgs | undefined,
|
|
38
|
-
|
|
36
|
+
|
|
39
37
|
client: Client,
|
|
40
38
|
) => void;
|
|
41
39
|
}
|
|
@@ -43,11 +41,9 @@ interface AttributionCallbacks {
|
|
|
43
41
|
function createAttributionPolicyFromCallbacks({
|
|
44
42
|
delta,
|
|
45
43
|
maintenance,
|
|
46
|
-
// eslint-disable-next-line import/no-deprecated
|
|
47
44
|
}: AttributionCallbacks): AttributionPolicy {
|
|
48
45
|
let unsubscribe: undefined | (() => void);
|
|
49
46
|
return {
|
|
50
|
-
// eslint-disable-next-line import/no-deprecated
|
|
51
47
|
attach: (client: Client): void => {
|
|
52
48
|
assert(unsubscribe === undefined, 0x557 /* cannot attach to multiple clients at once */);
|
|
53
49
|
|
|
@@ -87,7 +83,6 @@ const ensureAttributionCollectionCallbacks: AttributionCallbacks = {
|
|
|
87
83
|
};
|
|
88
84
|
|
|
89
85
|
const getAttributionKey = (
|
|
90
|
-
// eslint-disable-next-line import/no-deprecated
|
|
91
86
|
client: Client,
|
|
92
87
|
msg: ISequencedDocumentMessage | undefined,
|
|
93
88
|
): AttributionKey => {
|
|
@@ -103,8 +98,7 @@ const attributeInsertionOnSegments = (
|
|
|
103
98
|
key: AttributionKey,
|
|
104
99
|
): void => {
|
|
105
100
|
for (const { segment } of deltaSegments) {
|
|
106
|
-
|
|
107
|
-
if (seg.seq !== undefined) {
|
|
101
|
+
if (isInserted(segment)) {
|
|
108
102
|
segment.attribution?.update(
|
|
109
103
|
undefined,
|
|
110
104
|
new AttributionCollection(segment.cachedLength, key),
|
|
@@ -206,7 +200,7 @@ function combineMergeTreeCallbacks(callbacks: AttributionCallbacks[]): Attributi
|
|
|
206
200
|
* Creates an {@link AttributionPolicy} which only tracks initial insertion of content.
|
|
207
201
|
* @internal
|
|
208
202
|
*/
|
|
209
|
-
|
|
203
|
+
|
|
210
204
|
export function createInsertOnlyAttributionPolicy(): AttributionPolicy {
|
|
211
205
|
return createAttributionPolicyFromCallbacks(
|
|
212
206
|
combineMergeTreeCallbacks([
|
|
@@ -236,7 +230,6 @@ export function createInsertOnlyAttributionPolicy(): AttributionPolicy {
|
|
|
236
230
|
*/
|
|
237
231
|
export function createPropertyTrackingAttributionPolicyFactory(
|
|
238
232
|
...propNames: string[]
|
|
239
|
-
// eslint-disable-next-line import/no-deprecated
|
|
240
233
|
): () => AttributionPolicy {
|
|
241
234
|
return () =>
|
|
242
235
|
createAttributionPolicyFromCallbacks(
|
|
@@ -255,7 +248,6 @@ export function createPropertyTrackingAttributionPolicyFactory(
|
|
|
255
248
|
*/
|
|
256
249
|
export function createPropertyTrackingAndInsertionAttributionPolicyFactory(
|
|
257
250
|
...propNames: string[]
|
|
258
|
-
// eslint-disable-next-line import/no-deprecated
|
|
259
251
|
): () => AttributionPolicy {
|
|
260
252
|
return () =>
|
|
261
253
|
createAttributionPolicyFromCallbacks(
|
package/src/client.ts
CHANGED
|
@@ -27,7 +27,11 @@ import {
|
|
|
27
27
|
|
|
28
28
|
import { MergeTreeTextHelper } from "./MergeTreeTextHelper.js";
|
|
29
29
|
import { DoublyLinkedList, RedBlackTree } from "./collections/index.js";
|
|
30
|
-
import {
|
|
30
|
+
import {
|
|
31
|
+
NonCollabClient,
|
|
32
|
+
UnassignedSequenceNumber,
|
|
33
|
+
UniversalSequenceNumber,
|
|
34
|
+
} from "./constants.js";
|
|
31
35
|
import { LocalReferencePosition, SlidingPreference } from "./localReference.js";
|
|
32
36
|
import {
|
|
33
37
|
MergeTree,
|
|
@@ -42,16 +46,14 @@ import type {
|
|
|
42
46
|
} from "./mergeTreeDeltaCallback.js";
|
|
43
47
|
import { walkAllChildSegments } from "./mergeTreeNodeWalk.js";
|
|
44
48
|
import {
|
|
45
|
-
// eslint-disable-next-line import/no-deprecated
|
|
46
49
|
CollaborationWindow,
|
|
47
50
|
ISegment,
|
|
48
51
|
ISegmentAction,
|
|
49
|
-
|
|
52
|
+
ISegmentPrivate,
|
|
50
53
|
Marker,
|
|
51
|
-
// eslint-disable-next-line import/no-deprecated
|
|
52
54
|
SegmentGroup,
|
|
53
55
|
compareStrings,
|
|
54
|
-
|
|
56
|
+
isSegmentLeaf,
|
|
55
57
|
} from "./mergeTreeNodes.js";
|
|
56
58
|
import {
|
|
57
59
|
createAdjustRangeOp,
|
|
@@ -84,11 +86,18 @@ import {
|
|
|
84
86
|
} from "./ops.js";
|
|
85
87
|
import { PropertySet, type MapLike } from "./properties.js";
|
|
86
88
|
import { DetachedReferencePosition, ReferencePosition } from "./referencePositions.js";
|
|
89
|
+
import {
|
|
90
|
+
isInserted,
|
|
91
|
+
isMoved,
|
|
92
|
+
isRemoved,
|
|
93
|
+
overwriteInfo,
|
|
94
|
+
toMoveInfo,
|
|
95
|
+
type IInsertionInfo,
|
|
96
|
+
} from "./segmentInfos.js";
|
|
87
97
|
import { Side, type InteriorSequencePlace } from "./sequencePlace.js";
|
|
88
98
|
import { SnapshotLoader } from "./snapshotLoader.js";
|
|
89
99
|
import { SnapshotV1 } from "./snapshotV1.js";
|
|
90
100
|
import { SnapshotLegacy } from "./snapshotlegacy.js";
|
|
91
|
-
// eslint-disable-next-line import/no-deprecated
|
|
92
101
|
import { IMergeTreeTextHelper } from "./textSegment.js";
|
|
93
102
|
|
|
94
103
|
type IMergeTreeDeltaRemoteOpArgs = Omit<IMergeTreeDeltaOpArgs, "sequencedMessage"> &
|
|
@@ -129,6 +138,8 @@ export interface IClientEvents {
|
|
|
129
138
|
): void;
|
|
130
139
|
}
|
|
131
140
|
|
|
141
|
+
const UNBOUND_SEGMENT_ERROR = "The provided segment is not bound to this DDS.";
|
|
142
|
+
|
|
132
143
|
/**
|
|
133
144
|
* This class encapsulates a merge-tree, and provides a local client specific view over it and
|
|
134
145
|
* the capability to modify it as the local client. Additionally it provides
|
|
@@ -194,20 +205,14 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
194
205
|
* It is used to get the segment group(s) for the previous operations.
|
|
195
206
|
* @param count - The number segment groups to get peek from the tail of the queue. Default 1.
|
|
196
207
|
*/
|
|
197
|
-
|
|
198
|
-
public peekPendingSegmentGroups():
|
|
199
|
-
// eslint-disable-next-line import/no-deprecated
|
|
200
|
-
public peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;
|
|
201
|
-
public peekPendingSegmentGroups(
|
|
202
|
-
count: number = 1,
|
|
203
|
-
// eslint-disable-next-line import/no-deprecated
|
|
204
|
-
): SegmentGroup | SegmentGroup[] | undefined {
|
|
208
|
+
|
|
209
|
+
public peekPendingSegmentGroups(count: number = 1): unknown {
|
|
205
210
|
const pending = this._mergeTree.pendingSegments;
|
|
206
211
|
let node = pending?.last;
|
|
207
212
|
if (count === 1 || pending === undefined) {
|
|
208
213
|
return node?.data;
|
|
209
214
|
}
|
|
210
|
-
|
|
215
|
+
|
|
211
216
|
const taken: SegmentGroup[] = Array.from({ length: Math.min(count, pending.length) });
|
|
212
217
|
for (let i = taken.length - 1; i >= 0; i--) {
|
|
213
218
|
taken[i] = node!.data;
|
|
@@ -396,15 +401,15 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
396
401
|
): void {
|
|
397
402
|
let localInserts = 0;
|
|
398
403
|
let localRemoves = 0;
|
|
399
|
-
walkAllChildSegments(this._mergeTree.root, (seg:
|
|
400
|
-
if (seg.seq === UnassignedSequenceNumber) {
|
|
404
|
+
walkAllChildSegments(this._mergeTree.root, (seg: ISegmentPrivate) => {
|
|
405
|
+
if (isInserted(seg) && seg.seq === UnassignedSequenceNumber) {
|
|
401
406
|
localInserts++;
|
|
402
407
|
}
|
|
403
|
-
if (seg.removedSeq === UnassignedSequenceNumber) {
|
|
408
|
+
if (isRemoved(seg) && seg.removedSeq === UnassignedSequenceNumber) {
|
|
404
409
|
localRemoves++;
|
|
405
410
|
}
|
|
406
411
|
// Only serialize segments that have not been removed.
|
|
407
|
-
if (seg
|
|
412
|
+
if (!isRemoved(seg)) {
|
|
408
413
|
handleCollectingSerializer.stringify(seg.clone().toJSONObject(), handle);
|
|
409
414
|
}
|
|
410
415
|
return true;
|
|
@@ -419,7 +424,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
419
424
|
}
|
|
420
425
|
}
|
|
421
426
|
|
|
422
|
-
// eslint-disable-next-line import/no-deprecated
|
|
423
427
|
public getCollabWindow(): CollaborationWindow {
|
|
424
428
|
return this._mergeTree.collabWindow;
|
|
425
429
|
}
|
|
@@ -430,12 +434,11 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
430
434
|
* @param segment - The segment to get the position of
|
|
431
435
|
*/
|
|
432
436
|
public getPosition(segment: ISegment | undefined, localSeq?: number): number {
|
|
433
|
-
|
|
434
|
-
if (mergeSegment?.parent === undefined) {
|
|
437
|
+
if (!isSegmentLeaf(segment)) {
|
|
435
438
|
return -1;
|
|
436
439
|
}
|
|
437
440
|
return this._mergeTree.getPosition(
|
|
438
|
-
|
|
441
|
+
segment,
|
|
439
442
|
this.getCurrentSeq(),
|
|
440
443
|
this.getClientId(),
|
|
441
444
|
localSeq,
|
|
@@ -461,6 +464,9 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
461
464
|
slidingPreference?: SlidingPreference,
|
|
462
465
|
canSlideToEndpoint?: boolean,
|
|
463
466
|
): LocalReferencePosition {
|
|
467
|
+
if (!isSegmentLeaf(segment) && typeof segment !== "string") {
|
|
468
|
+
throw new UsageError(UNBOUND_SEGMENT_ERROR);
|
|
469
|
+
}
|
|
464
470
|
return this._mergeTree.createLocalReferencePosition(
|
|
465
471
|
segment,
|
|
466
472
|
offset ?? 0,
|
|
@@ -509,7 +515,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
509
515
|
* Revert an op
|
|
510
516
|
*/
|
|
511
517
|
public rollback?(op: unknown, localOpMetadata: unknown): void {
|
|
512
|
-
// eslint-disable-next-line import/no-deprecated
|
|
513
518
|
this._mergeTree.rollback(op as IMergeTreeDeltaOp, localOpMetadata as SegmentGroup);
|
|
514
519
|
}
|
|
515
520
|
|
|
@@ -876,13 +881,16 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
876
881
|
0x032 /* "localSeq greater than collab window" */,
|
|
877
882
|
);
|
|
878
883
|
const { currentSeq, clientId } = this.getCollabWindow();
|
|
884
|
+
if (!isSegmentLeaf(segment)) {
|
|
885
|
+
throw new UsageError(UNBOUND_SEGMENT_ERROR);
|
|
886
|
+
}
|
|
879
887
|
return this._mergeTree.getPosition(segment, currentSeq, clientId, localSeq);
|
|
880
888
|
}
|
|
881
889
|
|
|
882
890
|
private resetPendingDeltaToOps(
|
|
883
891
|
resetOp: IMergeTreeDeltaOp,
|
|
884
|
-
|
|
885
|
-
segmentGroup: SegmentGroup
|
|
892
|
+
|
|
893
|
+
segmentGroup: SegmentGroup,
|
|
886
894
|
): IMergeTreeDeltaOp[] {
|
|
887
895
|
assert(!!segmentGroup, 0x033 /* "Segment group undefined" */);
|
|
888
896
|
const NACKedSegmentGroup = this.pendingRebase?.shift()?.data;
|
|
@@ -895,7 +903,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
895
903
|
}
|
|
896
904
|
|
|
897
905
|
// if this is an obliterate op, keep all segments in same segment group
|
|
898
|
-
|
|
906
|
+
|
|
899
907
|
const obliterateSegmentGroup: SegmentGroup = {
|
|
900
908
|
segments: [],
|
|
901
909
|
localSeq: segmentGroup.localSeq,
|
|
@@ -915,7 +923,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
915
923
|
a.ordinal < b.ordinal ? -1 : 1,
|
|
916
924
|
)) {
|
|
917
925
|
assert(
|
|
918
|
-
segment.segmentGroups?.remove
|
|
926
|
+
segment.segmentGroups?.remove(segmentGroup) === true,
|
|
919
927
|
0x035 /* "Segment group not in segment pending queue" */,
|
|
920
928
|
);
|
|
921
929
|
assert(
|
|
@@ -935,10 +943,10 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
935
943
|
// unless the remove was local, in which case the annotate must have come
|
|
936
944
|
// before the remove
|
|
937
945
|
if (
|
|
938
|
-
(segment
|
|
946
|
+
(!isRemoved(segment) ||
|
|
939
947
|
(segment.localRemovedSeq !== undefined &&
|
|
940
948
|
segment.removedSeq === UnassignedSequenceNumber)) &&
|
|
941
|
-
(segment
|
|
949
|
+
(!isMoved(segment) ||
|
|
942
950
|
(segment.localMovedSeq !== undefined &&
|
|
943
951
|
segment.movedSeq === UnassignedSequenceNumber))
|
|
944
952
|
) {
|
|
@@ -960,7 +968,7 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
960
968
|
|
|
961
969
|
case MergeTreeDeltaType.INSERT: {
|
|
962
970
|
assert(
|
|
963
|
-
segment.seq === UnassignedSequenceNumber,
|
|
971
|
+
isInserted(segment) && segment.seq === UnassignedSequenceNumber,
|
|
964
972
|
0x037 /* "Segment already has assigned sequence number" */,
|
|
965
973
|
);
|
|
966
974
|
const moveInfo = toMoveInfo(segment);
|
|
@@ -975,8 +983,11 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
975
983
|
// we set the seq to the universal seq and remove the local seq,
|
|
976
984
|
// so its length is not considered for subsequent local changes
|
|
977
985
|
// this allows us to not send the op as even the local client will ignore the segment
|
|
978
|
-
segment
|
|
979
|
-
|
|
986
|
+
overwriteInfo<IInsertionInfo>(segment, {
|
|
987
|
+
seq: UniversalSequenceNumber,
|
|
988
|
+
localSeq: undefined,
|
|
989
|
+
clientId: NonCollabClient,
|
|
990
|
+
});
|
|
980
991
|
break;
|
|
981
992
|
}
|
|
982
993
|
}
|
|
@@ -993,9 +1004,10 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
993
1004
|
|
|
994
1005
|
case MergeTreeDeltaType.REMOVE: {
|
|
995
1006
|
if (
|
|
1007
|
+
isRemoved(segment) &&
|
|
996
1008
|
segment.localRemovedSeq !== undefined &&
|
|
997
1009
|
segment.removedSeq === UnassignedSequenceNumber &&
|
|
998
|
-
(segment
|
|
1010
|
+
(!isMoved(segment) ||
|
|
999
1011
|
(segment.localMovedSeq !== undefined &&
|
|
1000
1012
|
segment.movedSeq === UnassignedSequenceNumber))
|
|
1001
1013
|
) {
|
|
@@ -1009,9 +1021,10 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1009
1021
|
case MergeTreeDeltaType.OBLITERATE: {
|
|
1010
1022
|
errorIfOptionNotTrue(this._mergeTree.options, "mergeTreeEnableObliterateReconnect");
|
|
1011
1023
|
if (
|
|
1024
|
+
isMoved(segment) &&
|
|
1012
1025
|
segment.localMovedSeq !== undefined &&
|
|
1013
1026
|
segment.movedSeq === UnassignedSequenceNumber &&
|
|
1014
|
-
(segment
|
|
1027
|
+
(!isRemoved(segment) ||
|
|
1015
1028
|
(segment.localRemovedSeq !== undefined &&
|
|
1016
1029
|
segment.removedSeq === UnassignedSequenceNumber))
|
|
1017
1030
|
) {
|
|
@@ -1191,7 +1204,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1191
1204
|
|
|
1192
1205
|
private lastNormalizationRefSeq = 0;
|
|
1193
1206
|
|
|
1194
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1195
1207
|
private pendingRebase: DoublyLinkedList<SegmentGroup> | undefined;
|
|
1196
1208
|
|
|
1197
1209
|
/**
|
|
@@ -1200,11 +1212,8 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1200
1212
|
* @param resetOp - The op to reset
|
|
1201
1213
|
* @param segmentGroup - The segment group associated with the op
|
|
1202
1214
|
*/
|
|
1203
|
-
public regeneratePendingOp(
|
|
1204
|
-
|
|
1205
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1206
|
-
segmentGroup: SegmentGroup | SegmentGroup[],
|
|
1207
|
-
): IMergeTreeOp {
|
|
1215
|
+
public regeneratePendingOp(resetOp: IMergeTreeOp, localOpMetadata: unknown): IMergeTreeOp {
|
|
1216
|
+
const segmentGroup = localOpMetadata as SegmentGroup | SegmentGroup[];
|
|
1208
1217
|
if (this.pendingRebase === undefined || this.pendingRebase.empty) {
|
|
1209
1218
|
let firstGroup: SegmentGroup;
|
|
1210
1219
|
if (Array.isArray(segmentGroup)) {
|
|
@@ -1269,7 +1278,6 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1269
1278
|
return opList.length === 1 ? opList[0] : createGroupOp(...opList);
|
|
1270
1279
|
}
|
|
1271
1280
|
|
|
1272
|
-
// eslint-disable-next-line import/no-deprecated
|
|
1273
1281
|
public createTextHelper(): IMergeTreeTextHelper {
|
|
1274
1282
|
return new MergeTreeTextHelper(this._mergeTree);
|
|
1275
1283
|
}
|
|
@@ -1376,12 +1384,15 @@ export class Client extends TypedEventEmitter<IClientEvents> {
|
|
|
1376
1384
|
} {
|
|
1377
1385
|
const { referenceSequenceNumber, clientId } =
|
|
1378
1386
|
this.getClientSequenceArgsForMessage(sequenceArgs);
|
|
1379
|
-
return this._mergeTree.getContainingSegment
|
|
1387
|
+
return this._mergeTree.getContainingSegment(
|
|
1380
1388
|
pos,
|
|
1381
1389
|
referenceSequenceNumber,
|
|
1382
1390
|
clientId,
|
|
1383
1391
|
localSeq,
|
|
1384
|
-
)
|
|
1392
|
+
) as {
|
|
1393
|
+
segment: T | undefined;
|
|
1394
|
+
offset: number | undefined;
|
|
1395
|
+
};
|
|
1385
1396
|
}
|
|
1386
1397
|
|
|
1387
1398
|
getPropertiesAtPosition(pos: number): PropertySet | undefined {
|
package/src/endOfTreeSegment.ts
CHANGED
|
@@ -10,8 +10,8 @@ import { LocalClientId } from "./constants.js";
|
|
|
10
10
|
import { LocalReferenceCollection } from "./localReference.js";
|
|
11
11
|
import { MergeTree } from "./mergeTree.js";
|
|
12
12
|
import { NodeAction, depthFirstNodeWalk } from "./mergeTreeNodeWalk.js";
|
|
13
|
-
|
|
14
|
-
import {
|
|
13
|
+
import { ISegment, type ISegmentLeaf, type MergeBlock } from "./mergeTreeNodes.js";
|
|
14
|
+
import { type IMergeNodeInfo } from "./segmentInfos.js";
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* This is a special segment that is not bound or known by the merge tree itself,
|
|
@@ -34,7 +34,7 @@ import { ISegment, ISegmentLeaf, type MergeBlock } from "./mergeTreeNodes.js";
|
|
|
34
34
|
* must be possible in some way to refer to a position before or after the tree
|
|
35
35
|
* respectively. The endpoint segments allow us to support such behavior.
|
|
36
36
|
*/
|
|
37
|
-
abstract class BaseEndpointSegment {
|
|
37
|
+
abstract class BaseEndpointSegment implements IMergeNodeInfo {
|
|
38
38
|
constructor(protected readonly mergeTree: MergeTree) {}
|
|
39
39
|
/*
|
|
40
40
|
* segments must be of at least length one, but
|
package/src/index.ts
CHANGED
|
@@ -58,20 +58,14 @@ export {
|
|
|
58
58
|
export {
|
|
59
59
|
BaseSegment,
|
|
60
60
|
CollaborationWindow,
|
|
61
|
-
debugMarkerToString,
|
|
62
61
|
IJSONMarkerSegment,
|
|
63
62
|
IMergeNodeCommon,
|
|
64
|
-
IMoveInfo,
|
|
65
|
-
IRemovalInfo,
|
|
66
63
|
segmentIsRemoved,
|
|
67
64
|
ISegment,
|
|
68
65
|
ISegmentAction,
|
|
69
66
|
Marker,
|
|
70
67
|
reservedMarkerIdKey,
|
|
71
68
|
reservedMarkerSimpleTypeKey,
|
|
72
|
-
SegmentGroup,
|
|
73
|
-
toRemovalInfo,
|
|
74
|
-
ObliterateInfo,
|
|
75
69
|
ISegmentInternal,
|
|
76
70
|
} from "./mergeTreeNodes.js";
|
|
77
71
|
export {
|
|
@@ -126,6 +120,10 @@ export {
|
|
|
126
120
|
reservedRangeLabelsKey,
|
|
127
121
|
reservedTileLabelsKey,
|
|
128
122
|
} from "./referencePositions.js";
|
|
123
|
+
export {
|
|
124
|
+
IMoveInfo,
|
|
125
|
+
IRemovalInfo,
|
|
126
|
+
} from "./segmentInfos.js";
|
|
129
127
|
export {
|
|
130
128
|
PropsOrAdjust,
|
|
131
129
|
copyPropertiesAndManager,
|