@fluidframework/merge-tree 2.1.0-276985 → 2.1.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/.eslintrc.cjs +2 -4
- package/CHANGELOG.md +15 -0
- package/README.md +109 -1
- package/api-extractor/api-extractor.current.json +5 -0
- package/api-extractor/api-extractor.legacy.json +1 -1
- package/api-extractor.json +1 -1
- package/api-report/merge-tree.legacy.alpha.api.md +10 -22
- package/api-report/merge-tree.legacy.public.api.md +9 -0
- package/dist/MergeTreeTextHelper.d.ts.map +1 -1
- package/dist/MergeTreeTextHelper.js +1 -1
- package/dist/MergeTreeTextHelper.js.map +1 -1
- package/dist/attributionCollection.d.ts.map +1 -1
- package/dist/attributionCollection.js +65 -17
- package/dist/attributionCollection.js.map +1 -1
- package/dist/attributionPolicy.d.ts +2 -1
- package/dist/attributionPolicy.d.ts.map +1 -1
- package/dist/attributionPolicy.js +10 -3
- package/dist/attributionPolicy.js.map +1 -1
- package/dist/client.d.ts +3 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +65 -37
- package/dist/client.js.map +1 -1
- package/dist/collections/list.d.ts.map +1 -1
- package/dist/collections/list.js +5 -2
- package/dist/collections/list.js.map +1 -1
- package/dist/collections/rbTree.d.ts +2 -2
- package/dist/collections/rbTree.d.ts.map +1 -1
- package/dist/collections/rbTree.js +23 -35
- package/dist/collections/rbTree.js.map +1 -1
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js +4 -1
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/legacy.d.ts +1 -1
- package/dist/localReference.d.ts +16 -6
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +31 -20
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +0 -1
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +127 -112
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodeWalk.d.ts.map +1 -1
- package/dist/mergeTreeNodeWalk.js +1 -1
- package/dist/mergeTreeNodeWalk.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +6 -5
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +29 -20
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/mergeTreeTracking.js +3 -3
- package/dist/mergeTreeTracking.js.map +1 -1
- package/dist/opBuilder.d.ts +6 -1
- package/dist/opBuilder.d.ts.map +1 -1
- package/dist/opBuilder.js +5 -0
- package/dist/opBuilder.js.map +1 -1
- package/dist/ops.d.ts.map +1 -1
- package/dist/ops.js.map +1 -1
- package/dist/ordinal.d.ts.map +1 -1
- package/dist/ordinal.js +7 -0
- package/dist/ordinal.js.map +1 -1
- package/dist/partialLengths.d.ts +4 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +101 -53
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +4 -1
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +7 -6
- package/dist/perspective.js.map +1 -1
- package/dist/properties.d.ts +13 -10
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +22 -11
- package/dist/properties.js.map +1 -1
- package/dist/public.d.ts +1 -1
- package/dist/referencePositions.d.ts +7 -0
- package/dist/referencePositions.d.ts.map +1 -1
- package/dist/referencePositions.js +7 -0
- package/dist/referencePositions.js.map +1 -1
- package/dist/revertibles.d.ts +6 -0
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +50 -21
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +2 -0
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts +7 -3
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +20 -15
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotChunks.d.ts.map +1 -1
- package/dist/snapshotChunks.js +10 -5
- package/dist/snapshotChunks.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +14 -10
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +20 -8
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +4 -2
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +8 -1
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/sortedSet.d.ts.map +1 -1
- package/dist/sortedSet.js +4 -0
- package/dist/sortedSet.js.map +1 -1
- package/dist/test/Insertion.perf.spec.js.map +1 -1
- package/dist/test/Removal.perf.spec.js.map +1 -1
- package/dist/test/Snapshot.perf.spec.js +1 -0
- package/dist/test/Snapshot.perf.spec.js.map +1 -1
- package/dist/test/attributionCollection.perf.spec.js +3 -1
- package/dist/test/attributionCollection.perf.spec.js.map +1 -1
- package/dist/test/attributionCollection.spec.js +69 -68
- package/dist/test/attributionCollection.spec.js.map +1 -1
- package/dist/test/attributionPolicy.spec.js +29 -27
- package/dist/test/attributionPolicy.spec.js.map +1 -1
- package/dist/test/beastTest.spec.d.ts +1 -4
- package/dist/test/beastTest.spec.d.ts.map +1 -1
- package/dist/test/beastTest.spec.js +32 -30
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js +5 -5
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.apis.spec.d.ts.map +1 -1
- package/dist/test/client.apis.spec.js +5 -7
- package/dist/test/client.apis.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +125 -103
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +18 -10
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +13 -8
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.conflictFarm.spec.js +4 -2
- package/dist/test/client.conflictFarm.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +10 -10
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +111 -104
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.localReferenceFarm.spec.js +14 -10
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
- package/dist/test/client.rebasePosition.spec.js +12 -12
- package/dist/test/client.rebasePosition.spec.js.map +1 -1
- package/dist/test/client.reconnectFarm.spec.js +12 -9
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.replay.spec.js +11 -10
- package/dist/test/client.replay.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +87 -84
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/client.rollbackFarm.spec.js +3 -1
- package/dist/test/client.rollbackFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +122 -112
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/client.walkSegments.spec.js +7 -7
- package/dist/test/client.walkSegments.spec.js.map +1 -1
- package/dist/test/collections.list.spec.js +14 -14
- package/dist/test/collections.list.spec.js.map +1 -1
- package/dist/test/createInsertOnlyAttributionPolicy.spec.js +3 -3
- package/dist/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -1
- package/dist/test/dirname.cjs +1 -0
- package/dist/test/dirname.cjs.map +1 -1
- package/dist/test/dirname.d.cts.map +1 -1
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js +7 -7
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +87 -87
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.insert.deltaCallback.spec.js +6 -6
- package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js +24 -24
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +6 -6
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +23 -23
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/mergeTree.walk.spec.js +3 -3
- package/dist/test/mergeTree.walk.spec.js.map +1 -1
- package/dist/test/mergeTree.zamboni.spec.js +10 -10
- package/dist/test/mergeTree.zamboni.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +28 -16
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.spec.js +9 -5
- package/dist/test/mergeTreeOperationRunner.spec.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +165 -165
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.deltaCallback.spec.js +20 -21
- package/dist/test/obliterate.deltaCallback.spec.js.map +1 -1
- package/dist/test/obliterate.partialLength.spec.js +7 -7
- package/dist/test/obliterate.partialLength.spec.js.map +1 -1
- package/dist/test/obliterate.reconnect.spec.js +13 -13
- package/dist/test/obliterate.reconnect.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +9 -9
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/ordinal.spec.js +10 -4
- package/dist/test/ordinal.spec.js.map +1 -1
- package/dist/test/partialLength.spec.js.map +1 -1
- package/dist/test/properties.spec.js +15 -15
- package/dist/test/properties.spec.js.map +1 -1
- package/dist/test/reconnectHelper.d.ts +4 -4
- package/dist/test/reconnectHelper.d.ts.map +1 -1
- package/dist/test/reconnectHelper.js +28 -20
- package/dist/test/reconnectHelper.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +35 -29
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/revertibleFarm.spec.js +11 -10
- package/dist/test/revertibleFarm.spec.js.map +1 -1
- package/dist/test/revertibles.spec.d.ts.map +1 -1
- package/dist/test/revertibles.spec.js +96 -57
- package/dist/test/revertibles.spec.js.map +1 -1
- package/dist/test/segmentGroupCollection.spec.js +17 -17
- package/dist/test/segmentGroupCollection.spec.js.map +1 -1
- package/dist/test/snapshot.spec.js +5 -5
- package/dist/test/snapshot.spec.js.map +1 -1
- package/dist/test/snapshot.utils.d.ts.map +1 -1
- package/dist/test/snapshot.utils.js +6 -6
- package/dist/test/snapshot.utils.js.map +1 -1
- package/dist/test/snapshotlegacy.spec.js +18 -13
- package/dist/test/snapshotlegacy.spec.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +22 -18
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.d.ts +6 -5
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +30 -32
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +39 -38
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testSerializer.d.ts +5 -5
- package/dist/test/testSerializer.d.ts.map +1 -1
- package/dist/test/testSerializer.js +0 -1
- package/dist/test/testSerializer.js.map +1 -1
- package/dist/test/testServer.d.ts.map +1 -1
- package/dist/test/testServer.js.map +1 -1
- package/dist/test/testUtils.d.ts +1 -1
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +15 -17
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +1 -1
- package/dist/test/text.js.map +1 -1
- package/dist/test/tracking.spec.js +50 -46
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.d.ts.map +1 -1
- package/dist/test/wordUnitTests.spec.js +10 -10
- package/dist/test/wordUnitTests.spec.js.map +1 -1
- package/dist/textSegment.d.ts +1 -1
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js +3 -3
- package/dist/textSegment.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +7 -2
- package/dist/zamboni.js.map +1 -1
- package/internal.d.ts +1 -1
- package/legacy.d.ts +1 -1
- package/lib/MergeTreeTextHelper.d.ts.map +1 -1
- package/lib/MergeTreeTextHelper.js +1 -1
- package/lib/MergeTreeTextHelper.js.map +1 -1
- package/lib/attributionCollection.d.ts.map +1 -1
- package/lib/attributionCollection.js +65 -17
- package/lib/attributionCollection.js.map +1 -1
- package/lib/attributionPolicy.d.ts +2 -1
- package/lib/attributionPolicy.d.ts.map +1 -1
- package/lib/attributionPolicy.js +10 -3
- package/lib/attributionPolicy.js.map +1 -1
- package/lib/client.d.ts +3 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +65 -37
- package/lib/client.js.map +1 -1
- package/lib/collections/list.d.ts.map +1 -1
- package/lib/collections/list.js +5 -2
- package/lib/collections/list.js.map +1 -1
- package/lib/collections/rbTree.d.ts +2 -2
- package/lib/collections/rbTree.d.ts.map +1 -1
- package/lib/collections/rbTree.js +23 -35
- package/lib/collections/rbTree.js.map +1 -1
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.js +4 -1
- package/lib/endOfTreeSegment.js.map +1 -1
- package/lib/legacy.d.ts +1 -1
- package/lib/localReference.d.ts +16 -6
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +31 -20
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +0 -1
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +127 -112
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodeWalk.d.ts.map +1 -1
- package/lib/mergeTreeNodeWalk.js +1 -1
- package/lib/mergeTreeNodeWalk.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +6 -5
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +29 -20
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/mergeTreeTracking.js +3 -3
- package/lib/mergeTreeTracking.js.map +1 -1
- package/lib/opBuilder.d.ts +6 -1
- package/lib/opBuilder.d.ts.map +1 -1
- package/lib/opBuilder.js +5 -0
- package/lib/opBuilder.js.map +1 -1
- package/lib/ops.d.ts.map +1 -1
- package/lib/ops.js.map +1 -1
- package/lib/ordinal.d.ts.map +1 -1
- package/lib/ordinal.js +7 -0
- package/lib/ordinal.js.map +1 -1
- package/lib/partialLengths.d.ts +4 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +101 -53
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +4 -1
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +7 -6
- package/lib/perspective.js.map +1 -1
- package/lib/properties.d.ts +13 -10
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +22 -11
- package/lib/properties.js.map +1 -1
- package/lib/public.d.ts +1 -1
- package/lib/referencePositions.d.ts +7 -0
- package/lib/referencePositions.d.ts.map +1 -1
- package/lib/referencePositions.js +7 -0
- package/lib/referencePositions.js.map +1 -1
- package/lib/revertibles.d.ts +6 -0
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +50 -21
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +2 -0
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts +7 -3
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +20 -15
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotChunks.d.ts.map +1 -1
- package/lib/snapshotChunks.js +10 -5
- package/lib/snapshotChunks.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +14 -10
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +20 -8
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +4 -2
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +8 -1
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/sortedSet.d.ts.map +1 -1
- package/lib/sortedSet.js +4 -0
- package/lib/sortedSet.js.map +1 -1
- package/lib/test/Insertion.perf.spec.js.map +1 -1
- package/lib/test/Removal.perf.spec.js.map +1 -1
- package/lib/test/Snapshot.perf.spec.js +1 -0
- package/lib/test/Snapshot.perf.spec.js.map +1 -1
- package/lib/test/attributionCollection.perf.spec.js +3 -1
- package/lib/test/attributionCollection.perf.spec.js.map +1 -1
- package/lib/test/attributionCollection.spec.js +3 -2
- package/lib/test/attributionCollection.spec.js.map +1 -1
- package/lib/test/attributionPolicy.spec.js +3 -1
- package/lib/test/attributionPolicy.spec.js.map +1 -1
- package/lib/test/beastTest.spec.d.ts +1 -4
- package/lib/test/beastTest.spec.d.ts.map +1 -1
- package/lib/test/beastTest.spec.js +26 -24
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js +1 -1
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.apis.spec.d.ts.map +1 -1
- package/lib/test/client.apis.spec.js +4 -6
- package/lib/test/client.apis.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +72 -50
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +18 -10
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +12 -7
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.conflictFarm.spec.js +4 -2
- package/lib/test/client.conflictFarm.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +1 -1
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +14 -7
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.localReferenceFarm.spec.js +13 -9
- package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
- package/lib/test/client.rebasePosition.spec.js +1 -1
- package/lib/test/client.rebasePosition.spec.js.map +1 -1
- package/lib/test/client.reconnectFarm.spec.js +11 -8
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.replay.spec.js +8 -7
- package/lib/test/client.replay.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +14 -11
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/client.rollbackFarm.spec.js +3 -1
- package/lib/test/client.rollbackFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +29 -19
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/client.walkSegments.spec.js +1 -1
- package/lib/test/client.walkSegments.spec.js.map +1 -1
- package/lib/test/collections.list.spec.js +1 -1
- package/lib/test/collections.list.spec.js.map +1 -1
- package/lib/test/createInsertOnlyAttributionPolicy.spec.js +1 -1
- package/lib/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -1
- package/lib/test/dirname.cjs +1 -0
- package/lib/test/dirname.cjs.map +1 -1
- package/lib/test/dirname.d.cts.map +1 -1
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js +1 -1
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +1 -1
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.insert.deltaCallback.spec.js +1 -1
- package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.insertingWalk.spec.js +8 -8
- package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/mergeTree.walk.spec.js +1 -1
- package/lib/test/mergeTree.walk.spec.js.map +1 -1
- package/lib/test/mergeTree.zamboni.spec.js +1 -1
- package/lib/test/mergeTree.zamboni.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +27 -15
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.spec.js +5 -1
- package/lib/test/mergeTreeOperationRunner.spec.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +4 -4
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.deltaCallback.spec.js +2 -3
- package/lib/test/obliterate.deltaCallback.spec.js.map +1 -1
- package/lib/test/obliterate.partialLength.spec.js +1 -1
- package/lib/test/obliterate.partialLength.spec.js.map +1 -1
- package/lib/test/obliterate.reconnect.spec.js +1 -1
- package/lib/test/obliterate.reconnect.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +1 -1
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/ordinal.spec.js +7 -1
- package/lib/test/ordinal.spec.js.map +1 -1
- package/lib/test/partialLength.spec.js.map +1 -1
- package/lib/test/properties.spec.js +1 -1
- package/lib/test/properties.spec.js.map +1 -1
- package/lib/test/reconnectHelper.d.ts +4 -4
- package/lib/test/reconnectHelper.d.ts.map +1 -1
- package/lib/test/reconnectHelper.js +22 -14
- package/lib/test/reconnectHelper.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +8 -2
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/revertibleFarm.spec.js +8 -7
- package/lib/test/revertibleFarm.spec.js.map +1 -1
- package/lib/test/revertibles.spec.d.ts.map +1 -1
- package/lib/test/revertibles.spec.js +93 -54
- package/lib/test/revertibles.spec.js.map +1 -1
- package/lib/test/segmentGroupCollection.spec.js +1 -1
- package/lib/test/segmentGroupCollection.spec.js.map +1 -1
- package/lib/test/snapshot.spec.js +1 -1
- package/lib/test/snapshot.spec.js.map +1 -1
- package/lib/test/snapshot.utils.d.ts.map +1 -1
- package/lib/test/snapshot.utils.js +1 -1
- package/lib/test/snapshot.utils.js.map +1 -1
- package/lib/test/snapshotlegacy.spec.js +10 -5
- package/lib/test/snapshotlegacy.spec.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +6 -2
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.d.ts +6 -5
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +25 -27
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +37 -36
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testSerializer.d.ts +5 -5
- package/lib/test/testSerializer.d.ts.map +1 -1
- package/lib/test/testSerializer.js +0 -1
- package/lib/test/testSerializer.js.map +1 -1
- package/lib/test/testServer.d.ts.map +1 -1
- package/lib/test/testServer.js.map +1 -1
- package/lib/test/testUtils.d.ts +1 -1
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +6 -8
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +1 -1
- package/lib/test/text.js.map +1 -1
- package/lib/test/tracking.spec.js +9 -5
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.d.ts.map +1 -1
- package/lib/test/wordUnitTests.spec.js +9 -9
- package/lib/test/wordUnitTests.spec.js.map +1 -1
- package/lib/textSegment.d.ts +1 -1
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js +3 -3
- package/lib/textSegment.js.map +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +7 -2
- package/lib/zamboni.js.map +1 -1
- package/package.json +29 -27
- package/src/MergeTreeTextHelper.ts +2 -2
- package/src/attributionCollection.ts +71 -28
- package/src/attributionPolicy.ts +14 -9
- package/src/client.ts +120 -71
- package/src/collections/list.ts +9 -6
- package/src/collections/rbTree.ts +62 -71
- package/src/endOfTreeSegment.ts +21 -10
- package/src/localReference.ts +61 -43
- package/src/mergeTree.ts +229 -178
- package/src/mergeTreeNodeWalk.ts +2 -1
- package/src/mergeTreeNodes.ts +59 -46
- package/src/mergeTreeTracking.ts +3 -3
- package/src/opBuilder.ts +6 -1
- package/src/ops.ts +5 -0
- package/src/ordinal.ts +8 -1
- package/src/partialLengths.ts +143 -87
- package/src/perspective.ts +10 -7
- package/src/properties.ts +36 -18
- package/src/referencePositions.ts +7 -0
- package/src/revertibles.ts +71 -41
- package/src/segmentGroupCollection.ts +8 -6
- package/src/segmentPropertiesManager.ts +28 -24
- package/src/snapshotChunks.ts +12 -7
- package/src/snapshotLoader.ts +20 -17
- package/src/snapshotV1.ts +36 -18
- package/src/snapshotlegacy.ts +7 -5
- package/src/sortedSegmentSet.ts +9 -3
- package/src/sortedSet.ts +7 -3
- package/src/textSegment.ts +9 -9
- package/src/zamboni.ts +14 -10
- package/tsconfig.json +0 -1
package/src/mergeTree.ts
CHANGED
|
@@ -77,7 +77,6 @@ import {
|
|
|
77
77
|
} from "./ops.js";
|
|
78
78
|
import { PartialSequenceLengths } from "./partialLengths.js";
|
|
79
79
|
import { PerspectiveImpl, isSegmentPresent } from "./perspective.js";
|
|
80
|
-
// eslint-disable-next-line import/no-deprecated
|
|
81
80
|
import { PropertySet, createMap, extend, extendIfUndefined } from "./properties.js";
|
|
82
81
|
import {
|
|
83
82
|
DetachedReferencePosition,
|
|
@@ -98,7 +97,7 @@ function wasRemovedAfter(seg: ISegment, seq: number): boolean {
|
|
|
98
97
|
|
|
99
98
|
function markSegmentMoved(seg: ISegment, moveInfo: IMoveInfo): void {
|
|
100
99
|
seg.moveDst = moveInfo.moveDst;
|
|
101
|
-
seg.movedClientIds = moveInfo.movedClientIds
|
|
100
|
+
seg.movedClientIds = [...moveInfo.movedClientIds];
|
|
102
101
|
seg.movedSeqs = [moveInfo.movedSeq];
|
|
103
102
|
seg.movedSeq = moveInfo.movedSeq;
|
|
104
103
|
seg.localMovedSeq = moveInfo.localMovedSeq;
|
|
@@ -271,18 +270,19 @@ export function findRootMergeBlock(
|
|
|
271
270
|
maybeRoot = maybeRoot.parent;
|
|
272
271
|
}
|
|
273
272
|
|
|
274
|
-
return maybeRoot?.mergeTree
|
|
273
|
+
return maybeRoot?.mergeTree === undefined ? undefined : maybeRoot;
|
|
275
274
|
}
|
|
276
275
|
|
|
277
276
|
/**
|
|
277
|
+
* Find the segment to which a reference will slide if it needs to slide, or undefined if there
|
|
278
|
+
* is no valid segment (i.e. the tree is empty).
|
|
279
|
+
*
|
|
278
280
|
* @param segment - The segment to slide from.
|
|
279
281
|
* @param cache - Optional cache mapping segments to their sliding destinations.
|
|
280
282
|
* Excursions will be avoided for segments in the cache, and the cache will be populated with
|
|
281
283
|
* entries for all segments visited during excursion.
|
|
282
284
|
* This can reduce the number of times the tree needs to be scanned if a range containing many
|
|
283
285
|
* SlideOnRemove references is removed.
|
|
284
|
-
* @returns The segment a SlideOnRemove reference should slide to, or undefined if there is no
|
|
285
|
-
* valid segment (i.e. the tree is empty).
|
|
286
286
|
* @internal
|
|
287
287
|
*/
|
|
288
288
|
function getSlideToSegment(
|
|
@@ -305,7 +305,7 @@ function getSlideToSegment(
|
|
|
305
305
|
}
|
|
306
306
|
const result: { seg?: ISegment } = {};
|
|
307
307
|
cache?.set(segment, result);
|
|
308
|
-
const goFurtherToFindSlideToSegment = (seg: ISegment) => {
|
|
308
|
+
const goFurtherToFindSlideToSegment = (seg: ISegment): boolean => {
|
|
309
309
|
if (seg.seq !== UnassignedSequenceNumber && !isRemovedAndAckedOrMovedAndAcked(seg)) {
|
|
310
310
|
result.seg = seg;
|
|
311
311
|
return false;
|
|
@@ -366,7 +366,10 @@ export function getSlideToSegoff(
|
|
|
366
366
|
segoff: { segment: ISegment | undefined; offset: number | undefined },
|
|
367
367
|
slidingPreference: SlidingPreference = SlidingPreference.FORWARD,
|
|
368
368
|
useNewSlidingBehavior: boolean = false,
|
|
369
|
-
) {
|
|
369
|
+
): {
|
|
370
|
+
segment: ISegment | undefined;
|
|
371
|
+
offset: number | undefined;
|
|
372
|
+
} {
|
|
370
373
|
if (segoff.segment === undefined) {
|
|
371
374
|
return segoff;
|
|
372
375
|
}
|
|
@@ -387,6 +390,11 @@ export function getSlideToSegoff(
|
|
|
387
390
|
};
|
|
388
391
|
}
|
|
389
392
|
|
|
393
|
+
const forwardPred = (ref: LocalReferencePosition): boolean =>
|
|
394
|
+
ref.slidingPreference !== SlidingPreference.BACKWARD;
|
|
395
|
+
const backwardPred = (ref: LocalReferencePosition): boolean =>
|
|
396
|
+
ref.slidingPreference === SlidingPreference.BACKWARD;
|
|
397
|
+
|
|
390
398
|
/**
|
|
391
399
|
* @internal
|
|
392
400
|
*/
|
|
@@ -465,12 +473,12 @@ export class MergeTree {
|
|
|
465
473
|
return this._root;
|
|
466
474
|
}
|
|
467
475
|
|
|
468
|
-
public set root(value) {
|
|
476
|
+
public set root(value: IRootMergeBlock) {
|
|
469
477
|
this._root = value;
|
|
470
478
|
value.mergeTree = this;
|
|
471
479
|
}
|
|
472
480
|
|
|
473
|
-
public makeBlock(childCount: number) {
|
|
481
|
+
public makeBlock(childCount: number): MergeBlock {
|
|
474
482
|
const block = new MergeBlock(childCount);
|
|
475
483
|
block.ordinal = "";
|
|
476
484
|
return block;
|
|
@@ -513,7 +521,22 @@ export class MergeTree {
|
|
|
513
521
|
);
|
|
514
522
|
assert(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
|
|
515
523
|
const { seq, removedSeq, localRemovedSeq, movedSeq, localMovedSeq } = segment;
|
|
516
|
-
if (seq
|
|
524
|
+
if (seq === UnassignedSequenceNumber) {
|
|
525
|
+
assert(
|
|
526
|
+
segment.localSeq !== undefined,
|
|
527
|
+
0x39a /* unacked segment with undefined localSeq */,
|
|
528
|
+
);
|
|
529
|
+
// inserted locally, still un-acked
|
|
530
|
+
if (
|
|
531
|
+
segment.localSeq > localSeq ||
|
|
532
|
+
(localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
|
|
533
|
+
(localMovedSeq !== undefined && localMovedSeq <= localSeq)
|
|
534
|
+
) {
|
|
535
|
+
return 0;
|
|
536
|
+
}
|
|
537
|
+
const { cachedLength } = segment;
|
|
538
|
+
return cachedLength;
|
|
539
|
+
} else {
|
|
517
540
|
// inserted remotely
|
|
518
541
|
if (
|
|
519
542
|
seq > refSeq ||
|
|
@@ -529,37 +552,23 @@ export class MergeTree {
|
|
|
529
552
|
return 0;
|
|
530
553
|
}
|
|
531
554
|
return segment.cachedLength;
|
|
532
|
-
} else {
|
|
533
|
-
assert(
|
|
534
|
-
segment.localSeq !== undefined,
|
|
535
|
-
0x39a /* unacked segment with undefined localSeq */,
|
|
536
|
-
);
|
|
537
|
-
// inserted locally, still un-acked
|
|
538
|
-
if (
|
|
539
|
-
segment.localSeq > localSeq ||
|
|
540
|
-
(localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
|
|
541
|
-
(localMovedSeq !== undefined && localMovedSeq <= localSeq)
|
|
542
|
-
) {
|
|
543
|
-
return 0;
|
|
544
|
-
}
|
|
545
|
-
return segment.cachedLength;
|
|
546
555
|
}
|
|
547
556
|
}
|
|
548
557
|
|
|
549
|
-
public unlinkMarker(marker: Marker) {
|
|
558
|
+
public unlinkMarker(marker: Marker): void {
|
|
550
559
|
const id = marker.getId();
|
|
551
560
|
if (id) {
|
|
552
561
|
this.idToMarker.delete(id);
|
|
553
562
|
}
|
|
554
563
|
}
|
|
555
564
|
|
|
556
|
-
private addNode(block: MergeBlock, node: IMergeNode) {
|
|
565
|
+
private addNode(block: MergeBlock, node: IMergeNode): number {
|
|
557
566
|
const index = block.childCount++;
|
|
558
567
|
block.assignChild(node, index, false);
|
|
559
568
|
return index;
|
|
560
569
|
}
|
|
561
570
|
|
|
562
|
-
public reloadFromSegments(segments: ISegment[]) {
|
|
571
|
+
public reloadFromSegments(segments: ISegment[]): void {
|
|
563
572
|
// This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
|
|
564
573
|
assert(
|
|
565
574
|
!this.collabWindow.collaborating,
|
|
@@ -571,7 +580,7 @@ export class MergeTree {
|
|
|
571
580
|
// Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
|
|
572
581
|
const buildMergeBlock = (nodes: IMergeNode[]): IRootMergeBlock => {
|
|
573
582
|
const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
|
|
574
|
-
const blocks: MergeBlock[] =
|
|
583
|
+
const blocks: MergeBlock[] = Array.from({ length: blockCount }); // Pre-alloc array to collect nodes
|
|
575
584
|
|
|
576
585
|
// For each block in this level of the B-Tree...
|
|
577
586
|
for (
|
|
@@ -589,7 +598,8 @@ export class MergeTree {
|
|
|
589
598
|
childIndex++, nodeIndex++ // Advance to next child & node
|
|
590
599
|
) {
|
|
591
600
|
// Insert the next node into the current block
|
|
592
|
-
|
|
601
|
+
// TODO Non null asserting, why is this not null?
|
|
602
|
+
this.addNode(block, nodes[nodeIndex]!);
|
|
593
603
|
}
|
|
594
604
|
|
|
595
605
|
// Calculate this block's info. Previously this was inlined into the above loop as a micro-optimization,
|
|
@@ -599,7 +609,8 @@ export class MergeTree {
|
|
|
599
609
|
}
|
|
600
610
|
|
|
601
611
|
return blocks.length === 1 // If there is only one block at this layer...
|
|
602
|
-
?
|
|
612
|
+
? // Non null asserting here because of the length check above
|
|
613
|
+
blocks[0]! // ...then we're done. Return the root.
|
|
603
614
|
: buildMergeBlock(blocks); // ...otherwise recursively build the next layer above blocks.
|
|
604
615
|
};
|
|
605
616
|
if (segments.length > 0) {
|
|
@@ -611,7 +622,7 @@ export class MergeTree {
|
|
|
611
622
|
}
|
|
612
623
|
|
|
613
624
|
// For now assume min starts at zero
|
|
614
|
-
public startCollaboration(localClientId: number, minSeq: number, currentSeq: number) {
|
|
625
|
+
public startCollaboration(localClientId: number, minSeq: number, currentSeq: number): void {
|
|
615
626
|
this.collabWindow.clientId = localClientId;
|
|
616
627
|
this.collabWindow.minSeq = minSeq;
|
|
617
628
|
this.collabWindow.collaborating = true;
|
|
@@ -619,7 +630,7 @@ export class MergeTree {
|
|
|
619
630
|
this.nodeUpdateLengthNewStructure(this.root, true);
|
|
620
631
|
}
|
|
621
632
|
|
|
622
|
-
private addToLRUSet(leaf: ISegmentLeaf, seq: number) {
|
|
633
|
+
private addToLRUSet(leaf: ISegmentLeaf, seq: number): void {
|
|
623
634
|
// If the parent node has not yet been marked for scour (i.e., needsScour is not false or undefined),
|
|
624
635
|
// add the segment and mark the mark the node now.
|
|
625
636
|
|
|
@@ -638,7 +649,7 @@ export class MergeTree {
|
|
|
638
649
|
/**
|
|
639
650
|
* Returns the current length of the MergeTree for the local client.
|
|
640
651
|
*/
|
|
641
|
-
public get length() {
|
|
652
|
+
public get length(): number | undefined {
|
|
642
653
|
return this.root.cachedLength;
|
|
643
654
|
}
|
|
644
655
|
|
|
@@ -658,7 +669,8 @@ export class MergeTree {
|
|
|
658
669
|
while (parent) {
|
|
659
670
|
const children = parent.children;
|
|
660
671
|
for (let childIndex = 0; childIndex < parent.childCount; childIndex++) {
|
|
661
|
-
|
|
672
|
+
// TODO Non null asserting, why is this not null?
|
|
673
|
+
const child = children[childIndex]!;
|
|
662
674
|
if ((!!prevParent && child === prevParent) || child === node) {
|
|
663
675
|
break;
|
|
664
676
|
}
|
|
@@ -675,7 +687,10 @@ export class MergeTree {
|
|
|
675
687
|
refSeq: number,
|
|
676
688
|
clientId: number,
|
|
677
689
|
localSeq?: number,
|
|
678
|
-
) {
|
|
690
|
+
): {
|
|
691
|
+
segment: T | undefined;
|
|
692
|
+
offset: number | undefined;
|
|
693
|
+
} {
|
|
679
694
|
assert(
|
|
680
695
|
localSeq === undefined || clientId === this.collabWindow.clientId,
|
|
681
696
|
0x39b /* localSeq provided for non-local client */,
|
|
@@ -689,7 +704,7 @@ export class MergeTree {
|
|
|
689
704
|
_refSeq: number,
|
|
690
705
|
_clientId: number,
|
|
691
706
|
start: number,
|
|
692
|
-
) => {
|
|
707
|
+
): boolean => {
|
|
693
708
|
segment = leafSeg as T;
|
|
694
709
|
offset = start;
|
|
695
710
|
return false;
|
|
@@ -718,7 +733,7 @@ export class MergeTree {
|
|
|
718
733
|
*
|
|
719
734
|
* @param segments - An array of (not necessarily contiguous) segments with increasing ordinals.
|
|
720
735
|
*/
|
|
721
|
-
private slideAckedRemovedSegmentReferences(segments: ISegment[]) {
|
|
736
|
+
private slideAckedRemovedSegmentReferences(segments: ISegment[]): void {
|
|
722
737
|
// References are slid in groups to preserve their order.
|
|
723
738
|
let currentForwardSlideGroup: LocalReferenceCollection[] = [];
|
|
724
739
|
let currentBackwardSlideGroup: LocalReferenceCollection[] = [];
|
|
@@ -726,14 +741,10 @@ export class MergeTree {
|
|
|
726
741
|
let currentForwardMaybeEndpoint: "start" | "end" | undefined;
|
|
727
742
|
let currentForwardSlideDestination: ISegment | undefined;
|
|
728
743
|
let currentForwardSlideIsForward: boolean | undefined;
|
|
729
|
-
const forwardPred = (ref: LocalReferencePosition) =>
|
|
730
|
-
ref.slidingPreference !== SlidingPreference.BACKWARD;
|
|
731
744
|
|
|
732
745
|
let currentBackwardMaybeEndpoint: "start" | "end" | undefined;
|
|
733
746
|
let currentBackwardSlideDestination: ISegment | undefined;
|
|
734
747
|
let currentBackwardSlideIsForward: boolean | undefined;
|
|
735
|
-
const backwardPred = (ref: LocalReferencePosition) =>
|
|
736
|
-
ref.slidingPreference === SlidingPreference.BACKWARD;
|
|
737
748
|
|
|
738
749
|
const slideGroup = (
|
|
739
750
|
currentSlideDestination: ISegmentLeaf | undefined,
|
|
@@ -741,7 +752,7 @@ export class MergeTree {
|
|
|
741
752
|
currentSlideGroup: LocalReferenceCollection[],
|
|
742
753
|
pred: (ref: LocalReferencePosition) => boolean,
|
|
743
754
|
maybeEndpoint: "start" | "end" | undefined,
|
|
744
|
-
) => {
|
|
755
|
+
): void => {
|
|
745
756
|
if (currentSlideIsForward === undefined) {
|
|
746
757
|
return;
|
|
747
758
|
}
|
|
@@ -770,14 +781,7 @@ export class MergeTree {
|
|
|
770
781
|
}
|
|
771
782
|
}
|
|
772
783
|
|
|
773
|
-
if (currentSlideDestination
|
|
774
|
-
const localRefs = LocalReferenceCollection.setOrGet(currentSlideDestination);
|
|
775
|
-
if (currentSlideIsForward) {
|
|
776
|
-
localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
|
|
777
|
-
} else {
|
|
778
|
-
localRefs.addAfterTombstones(...nonEndpointRefsToAdd);
|
|
779
|
-
}
|
|
780
|
-
} else {
|
|
784
|
+
if (currentSlideDestination === undefined) {
|
|
781
785
|
for (const collection of currentSlideGroup) {
|
|
782
786
|
for (const ref of collection) {
|
|
783
787
|
if (pred(ref) && !refTypeIncludesFlag(ref, ReferenceType.StayOnRemove)) {
|
|
@@ -787,6 +791,13 @@ export class MergeTree {
|
|
|
787
791
|
}
|
|
788
792
|
}
|
|
789
793
|
}
|
|
794
|
+
} else {
|
|
795
|
+
const localRefs = LocalReferenceCollection.setOrGet(currentSlideDestination);
|
|
796
|
+
if (currentSlideIsForward) {
|
|
797
|
+
localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
|
|
798
|
+
} else {
|
|
799
|
+
localRefs.addAfterTombstones(...nonEndpointRefsToAdd);
|
|
800
|
+
}
|
|
790
801
|
}
|
|
791
802
|
};
|
|
792
803
|
|
|
@@ -804,7 +815,7 @@ export class MergeTree {
|
|
|
804
815
|
slideIsForward: boolean,
|
|
805
816
|
maybeEndpoint: "start" | "end" | undefined,
|
|
806
817
|
) => void,
|
|
807
|
-
) => {
|
|
818
|
+
): void => {
|
|
808
819
|
// avoid sliding logic if this segment doesn't have any references
|
|
809
820
|
// with the given sliding preference
|
|
810
821
|
if (!segment.localRefs || !anyLocalReferencePosition(segment.localRefs, pred)) {
|
|
@@ -916,7 +927,7 @@ export class MergeTree {
|
|
|
916
927
|
*
|
|
917
928
|
* Public only for use by internal tests
|
|
918
929
|
*/
|
|
919
|
-
public computeLocalPartials(refSeq: number) {
|
|
930
|
+
public computeLocalPartials(refSeq: number): void {
|
|
920
931
|
if (this.localPartialsComputed) {
|
|
921
932
|
return;
|
|
922
933
|
}
|
|
@@ -966,13 +977,7 @@ export class MergeTree {
|
|
|
966
977
|
}
|
|
967
978
|
} else {
|
|
968
979
|
// Sequence number within window
|
|
969
|
-
if (
|
|
970
|
-
const partialLen = node.partialLengths!.getPartialLength(refSeq, clientId);
|
|
971
|
-
|
|
972
|
-
PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId);
|
|
973
|
-
|
|
974
|
-
return partialLen;
|
|
975
|
-
} else {
|
|
980
|
+
if (node.isLeaf()) {
|
|
976
981
|
const segment = node;
|
|
977
982
|
const removalInfo = toRemovalInfo(segment);
|
|
978
983
|
const moveInfo = toMoveInfo(segment);
|
|
@@ -1004,11 +1009,17 @@ export class MergeTree {
|
|
|
1004
1009
|
return seqLTE(node.seq ?? 0, refSeq) || segment.clientId === clientId
|
|
1005
1010
|
? segment.cachedLength
|
|
1006
1011
|
: 0;
|
|
1012
|
+
} else {
|
|
1013
|
+
const partialLen = node.partialLengths!.getPartialLength(refSeq, clientId);
|
|
1014
|
+
|
|
1015
|
+
PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId);
|
|
1016
|
+
|
|
1017
|
+
return partialLen;
|
|
1007
1018
|
}
|
|
1008
1019
|
}
|
|
1009
1020
|
}
|
|
1010
1021
|
|
|
1011
|
-
public setMinSeq(minSeq: number) {
|
|
1022
|
+
public setMinSeq(minSeq: number): void {
|
|
1012
1023
|
assert(
|
|
1013
1024
|
minSeq <= this.collabWindow.currentSeq,
|
|
1014
1025
|
0x04e /* "Trying to set minSeq above currentSeq of collab window!" */,
|
|
@@ -1038,7 +1049,6 @@ export class MergeTree {
|
|
|
1038
1049
|
* Defaults to including all edits which have been applied.
|
|
1039
1050
|
* @param clientId - The ID of the client from whose perspective to resolve this reference. Defaults to the current client.
|
|
1040
1051
|
* @param localSeq - The local sequence number to consider. Defaults to including all local edits.
|
|
1041
|
-
* @returns the count of elements before the given reference position in the given perspective.
|
|
1042
1052
|
*/
|
|
1043
1053
|
public referencePositionToLocalPosition(
|
|
1044
1054
|
refPos: ReferencePosition,
|
|
@@ -1129,7 +1139,7 @@ export class MergeTree {
|
|
|
1129
1139
|
foundMarker = marker;
|
|
1130
1140
|
}
|
|
1131
1141
|
}
|
|
1132
|
-
return foundMarker
|
|
1142
|
+
return foundMarker === undefined ? NodeAction.Skip : NodeAction.Exit;
|
|
1133
1143
|
},
|
|
1134
1144
|
undefined,
|
|
1135
1145
|
undefined,
|
|
@@ -1139,7 +1149,7 @@ export class MergeTree {
|
|
|
1139
1149
|
return foundMarker;
|
|
1140
1150
|
}
|
|
1141
1151
|
|
|
1142
|
-
private updateRoot(splitNode: MergeBlock | undefined) {
|
|
1152
|
+
private updateRoot(splitNode: MergeBlock | undefined): void {
|
|
1143
1153
|
if (splitNode !== undefined) {
|
|
1144
1154
|
const newRoot = this.makeBlock(2);
|
|
1145
1155
|
newRoot.assignChild(this.root, 0, false);
|
|
@@ -1154,7 +1164,7 @@ export class MergeTree {
|
|
|
1154
1164
|
* Assign sequence number to existing segment; update partial lengths to reflect the change
|
|
1155
1165
|
* @param seq - sequence number given by server to pending segment
|
|
1156
1166
|
*/
|
|
1157
|
-
public ackPendingSegment(opArgs: IMergeTreeDeltaOpArgs) {
|
|
1167
|
+
public ackPendingSegment(opArgs: IMergeTreeDeltaOpArgs): void {
|
|
1158
1168
|
const seq = opArgs.sequencedMessage!.sequenceNumber;
|
|
1159
1169
|
const pendingSegmentGroup = this.pendingSegments.shift()?.data;
|
|
1160
1170
|
const nodesToUpdate: MergeBlock[] = [];
|
|
@@ -1170,6 +1180,8 @@ export class MergeTree {
|
|
|
1170
1180
|
const locallyMovedSegments = this.locallyMovedSegments.get(localMovedSeq);
|
|
1171
1181
|
|
|
1172
1182
|
if (locallyMovedSegments) {
|
|
1183
|
+
// Disabling because a for of loop causes the type of segment to be ISegment, which does not have parent information stored
|
|
1184
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
1173
1185
|
locallyMovedSegments.segments.forEach((segment: ISegmentLeaf) => {
|
|
1174
1186
|
segment.localMovedSeq = undefined;
|
|
1175
1187
|
|
|
@@ -1241,7 +1253,8 @@ export class MergeTree {
|
|
|
1241
1253
|
segmentGroup?: SegmentGroup,
|
|
1242
1254
|
localSeq?: number,
|
|
1243
1255
|
previousProps?: PropertySet,
|
|
1244
|
-
|
|
1256
|
+
// eslint-disable-next-line import/no-deprecated
|
|
1257
|
+
): SegmentGroup {
|
|
1245
1258
|
let _segmentGroup = segmentGroup;
|
|
1246
1259
|
if (_segmentGroup === undefined) {
|
|
1247
1260
|
_segmentGroup = {
|
|
@@ -1290,7 +1303,7 @@ export class MergeTree {
|
|
|
1290
1303
|
relativePos: IRelativePosition,
|
|
1291
1304
|
refseq = this.collabWindow.currentSeq,
|
|
1292
1305
|
clientId = this.collabWindow.clientId,
|
|
1293
|
-
) {
|
|
1306
|
+
): number {
|
|
1294
1307
|
let pos = -1;
|
|
1295
1308
|
let marker: Marker | undefined;
|
|
1296
1309
|
if (relativePos.id) {
|
|
@@ -1298,14 +1311,14 @@ export class MergeTree {
|
|
|
1298
1311
|
}
|
|
1299
1312
|
if (marker) {
|
|
1300
1313
|
pos = this.getPosition(marker, refseq, clientId);
|
|
1301
|
-
if (
|
|
1302
|
-
pos += marker.cachedLength;
|
|
1314
|
+
if (relativePos.before) {
|
|
1303
1315
|
if (relativePos.offset !== undefined) {
|
|
1304
|
-
pos
|
|
1316
|
+
pos -= relativePos.offset;
|
|
1305
1317
|
}
|
|
1306
1318
|
} else {
|
|
1319
|
+
pos += marker.cachedLength;
|
|
1307
1320
|
if (relativePos.offset !== undefined) {
|
|
1308
|
-
pos
|
|
1321
|
+
pos += relativePos.offset;
|
|
1309
1322
|
}
|
|
1310
1323
|
}
|
|
1311
1324
|
}
|
|
@@ -1319,7 +1332,7 @@ export class MergeTree {
|
|
|
1319
1332
|
clientId: number,
|
|
1320
1333
|
seq: number,
|
|
1321
1334
|
opArgs: IMergeTreeDeltaOpArgs | undefined,
|
|
1322
|
-
) {
|
|
1335
|
+
): void {
|
|
1323
1336
|
this.ensureIntervalBoundary(pos, refSeq, clientId);
|
|
1324
1337
|
|
|
1325
1338
|
const localSeq =
|
|
@@ -1398,8 +1411,10 @@ export class MergeTree {
|
|
|
1398
1411
|
seq: number,
|
|
1399
1412
|
localSeq: number | undefined,
|
|
1400
1413
|
newSegments: T[],
|
|
1401
|
-
) {
|
|
1402
|
-
|
|
1414
|
+
): void {
|
|
1415
|
+
// Keeping this function within the scope of blockInsert for readability.
|
|
1416
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
1417
|
+
const continueFrom = (node: MergeBlock): boolean => {
|
|
1403
1418
|
let siblingExists = false;
|
|
1404
1419
|
forwardExcursion(node, () => {
|
|
1405
1420
|
siblingExists = true;
|
|
@@ -1407,10 +1422,9 @@ export class MergeTree {
|
|
|
1407
1422
|
});
|
|
1408
1423
|
return siblingExists;
|
|
1409
1424
|
};
|
|
1410
|
-
|
|
1411
1425
|
// eslint-disable-next-line import/no-deprecated
|
|
1412
1426
|
let segmentGroup: SegmentGroup;
|
|
1413
|
-
const saveIfLocal = (locSegment: ISegment) => {
|
|
1427
|
+
const saveIfLocal = (locSegment: ISegment): void => {
|
|
1414
1428
|
// Save segment so we can assign sequence number when acked by server
|
|
1415
1429
|
if (this.collabWindow.collaborating) {
|
|
1416
1430
|
if (
|
|
@@ -1430,7 +1444,13 @@ export class MergeTree {
|
|
|
1430
1444
|
}
|
|
1431
1445
|
}
|
|
1432
1446
|
};
|
|
1433
|
-
const onLeaf = (
|
|
1447
|
+
const onLeaf = (
|
|
1448
|
+
segment: ISegment | undefined,
|
|
1449
|
+
_pos: number,
|
|
1450
|
+
context: InsertContext,
|
|
1451
|
+
// Keeping this function within the scope of blockInsert for readability.
|
|
1452
|
+
// eslint-disable-next-line unicorn/consistent-function-scoping
|
|
1453
|
+
): ISegmentChanges => {
|
|
1434
1454
|
const segmentChanges: ISegmentChanges = {};
|
|
1435
1455
|
if (segment) {
|
|
1436
1456
|
// Insert before segment
|
|
@@ -1464,7 +1484,7 @@ export class MergeTree {
|
|
|
1464
1484
|
|
|
1465
1485
|
if (newSegment.parent === undefined) {
|
|
1466
1486
|
// Indicates an attempt to insert past the end of the merge-tree's content.
|
|
1467
|
-
const errorConstructor = localSeq
|
|
1487
|
+
const errorConstructor = localSeq === undefined ? DataProcessingError : UsageError;
|
|
1468
1488
|
throw new errorConstructor("MergeTree insert failed", {
|
|
1469
1489
|
currentSeq: this.collabWindow.currentSeq,
|
|
1470
1490
|
minSeq: this.collabWindow.minSeq,
|
|
@@ -1495,7 +1515,7 @@ export class MergeTree {
|
|
|
1495
1515
|
let _movedSeq: number | undefined;
|
|
1496
1516
|
let movedClientIds: number[] | undefined;
|
|
1497
1517
|
|
|
1498
|
-
const findLeftMovedSegment = (seg: ISegment) => {
|
|
1518
|
+
const findLeftMovedSegment = (seg: ISegment): boolean => {
|
|
1499
1519
|
const movedSeqs = seg.movedSeqs?.filter((movedSeq) => movedSeq >= refSeq) ?? [];
|
|
1500
1520
|
const localMovedSeqs = seg.localMovedSeq ? [seg.localMovedSeq] : [];
|
|
1501
1521
|
for (const movedSeq of movedSeqs) {
|
|
@@ -1518,7 +1538,7 @@ export class MergeTree {
|
|
|
1518
1538
|
return moveUpperBound >= smallestSeqMoveOp;
|
|
1519
1539
|
};
|
|
1520
1540
|
|
|
1521
|
-
const findRightMovedSegment = (seg: ISegment) => {
|
|
1541
|
+
const findRightMovedSegment = (seg: ISegment): boolean => {
|
|
1522
1542
|
const movedSeqs = seg.movedSeqs?.filter((movedSeq) => movedSeq >= refSeq) ?? [];
|
|
1523
1543
|
const localMovedSeqs = seg.localMovedSeq ? [seg.localMovedSeq] : [];
|
|
1524
1544
|
|
|
@@ -1616,7 +1636,7 @@ export class MergeTree {
|
|
|
1616
1636
|
return { next };
|
|
1617
1637
|
};
|
|
1618
1638
|
|
|
1619
|
-
private ensureIntervalBoundary(pos: number, refSeq: number, clientId: number) {
|
|
1639
|
+
private ensureIntervalBoundary(pos: number, refSeq: number, clientId: number): void {
|
|
1620
1640
|
const splitNode = this.insertingWalk(
|
|
1621
1641
|
this.root,
|
|
1622
1642
|
pos,
|
|
@@ -1629,7 +1649,7 @@ export class MergeTree {
|
|
|
1629
1649
|
}
|
|
1630
1650
|
|
|
1631
1651
|
// Assume called only when pos == len
|
|
1632
|
-
private breakTie(pos: number, node: IMergeNode, seq: number) {
|
|
1652
|
+
private breakTie(pos: number, node: IMergeNode, seq: number): boolean {
|
|
1633
1653
|
if (node.isLeaf()) {
|
|
1634
1654
|
if (pos !== 0) {
|
|
1635
1655
|
return false;
|
|
@@ -1670,7 +1690,7 @@ export class MergeTree {
|
|
|
1670
1690
|
seq: number,
|
|
1671
1691
|
context: InsertContext,
|
|
1672
1692
|
isLastChildBlock: boolean = true,
|
|
1673
|
-
) {
|
|
1693
|
+
): MergeBlock | undefined {
|
|
1674
1694
|
let _pos = pos;
|
|
1675
1695
|
const children = block.children;
|
|
1676
1696
|
let childIndex: number;
|
|
@@ -1678,7 +1698,8 @@ export class MergeTree {
|
|
|
1678
1698
|
let newNode: IMergeNode | undefined;
|
|
1679
1699
|
let fromSplit: MergeBlock | undefined;
|
|
1680
1700
|
for (childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
1681
|
-
|
|
1701
|
+
// TODO Non null asserting, why is this not null?
|
|
1702
|
+
child = children[childIndex]!;
|
|
1682
1703
|
// ensure we walk down the far edge of the tree, even if all sub-tree is eligible for zamboni
|
|
1683
1704
|
const isLastNonLeafBlock =
|
|
1684
1705
|
isLastChildBlock && !child.isLeaf() && childIndex === block.childCount - 1;
|
|
@@ -1695,7 +1716,21 @@ export class MergeTree {
|
|
|
1695
1716
|
|
|
1696
1717
|
if (_pos < len || (_pos === len && this.breakTie(_pos, child, seq))) {
|
|
1697
1718
|
// Found entry containing pos
|
|
1698
|
-
if (
|
|
1719
|
+
if (child.isLeaf()) {
|
|
1720
|
+
const segment = child;
|
|
1721
|
+
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1722
|
+
if (segmentChanges.replaceCurrent) {
|
|
1723
|
+
block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
|
|
1724
|
+
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1725
|
+
}
|
|
1726
|
+
if (segmentChanges.next) {
|
|
1727
|
+
newNode = segmentChanges.next;
|
|
1728
|
+
childIndex++; // Insert after
|
|
1729
|
+
} else {
|
|
1730
|
+
// No change
|
|
1731
|
+
return undefined;
|
|
1732
|
+
}
|
|
1733
|
+
} else {
|
|
1699
1734
|
const childBlock = child;
|
|
1700
1735
|
// Internal node
|
|
1701
1736
|
const splitNode = this.insertingWalk(
|
|
@@ -1718,41 +1753,27 @@ export class MergeTree {
|
|
|
1718
1753
|
fromSplit = splitNode;
|
|
1719
1754
|
childIndex++; // Insert after
|
|
1720
1755
|
}
|
|
1721
|
-
} else {
|
|
1722
|
-
const segment = child;
|
|
1723
|
-
const segmentChanges = context.leaf(segment, _pos, context);
|
|
1724
|
-
if (segmentChanges.replaceCurrent) {
|
|
1725
|
-
block.assignChild(segmentChanges.replaceCurrent, childIndex, false);
|
|
1726
|
-
segmentChanges.replaceCurrent.ordinal = child.ordinal;
|
|
1727
|
-
}
|
|
1728
|
-
if (segmentChanges.next) {
|
|
1729
|
-
newNode = segmentChanges.next;
|
|
1730
|
-
childIndex++; // Insert after
|
|
1731
|
-
} else {
|
|
1732
|
-
// No change
|
|
1733
|
-
return undefined;
|
|
1734
|
-
}
|
|
1735
1756
|
}
|
|
1736
1757
|
break;
|
|
1737
1758
|
} else {
|
|
1738
1759
|
_pos -= len;
|
|
1739
1760
|
}
|
|
1740
1761
|
}
|
|
1741
|
-
if (!newNode) {
|
|
1742
|
-
if (
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
// Assert segmentChanges.replaceCurrent === undefined
|
|
1749
|
-
}
|
|
1762
|
+
if (!newNode && _pos === 0) {
|
|
1763
|
+
if (context.continuePredicate?.(block)) {
|
|
1764
|
+
return MergeTree.theUnfinishedNode;
|
|
1765
|
+
} else {
|
|
1766
|
+
const segmentChanges = context.leaf(undefined, _pos, context);
|
|
1767
|
+
newNode = segmentChanges.next;
|
|
1768
|
+
// Assert segmentChanges.replaceCurrent === undefined
|
|
1750
1769
|
}
|
|
1751
1770
|
}
|
|
1752
1771
|
if (newNode) {
|
|
1753
1772
|
for (let i = block.childCount; i > childIndex; i--) {
|
|
1754
|
-
|
|
1755
|
-
block.children[i]
|
|
1773
|
+
// TODO Non null asserting, why is this not null?
|
|
1774
|
+
block.children[i] = block.children[i - 1]!;
|
|
1775
|
+
// TODO Non null asserting, why is this not null?
|
|
1776
|
+
block.children[i]!.index = i;
|
|
1756
1777
|
}
|
|
1757
1778
|
block.assignChild(newNode, childIndex, false);
|
|
1758
1779
|
block.childCount++;
|
|
@@ -1782,14 +1803,15 @@ export class MergeTree {
|
|
|
1782
1803
|
}
|
|
1783
1804
|
}
|
|
1784
1805
|
|
|
1785
|
-
private split(node: MergeBlock) {
|
|
1806
|
+
private split(node: MergeBlock): MergeBlock {
|
|
1786
1807
|
const halfCount = MaxNodesInBlock / 2;
|
|
1787
1808
|
const newNode = this.makeBlock(halfCount);
|
|
1788
1809
|
node.childCount = halfCount;
|
|
1789
1810
|
// Update ordinals to reflect lowered child count
|
|
1790
1811
|
this.nodeUpdateOrdinals(node);
|
|
1791
1812
|
for (let i = 0; i < halfCount; i++) {
|
|
1792
|
-
|
|
1813
|
+
// TODO Non null asserting, why is this not null?
|
|
1814
|
+
newNode.assignChild(node.children[halfCount + i]!, i, false);
|
|
1793
1815
|
node.children[halfCount + i] = undefined!;
|
|
1794
1816
|
}
|
|
1795
1817
|
this.nodeUpdateLengthNewStructure(node);
|
|
@@ -1797,9 +1819,10 @@ export class MergeTree {
|
|
|
1797
1819
|
return newNode;
|
|
1798
1820
|
}
|
|
1799
1821
|
|
|
1800
|
-
public nodeUpdateOrdinals(block: MergeBlock) {
|
|
1822
|
+
public nodeUpdateOrdinals(block: MergeBlock): void {
|
|
1801
1823
|
for (let i = 0; i < block.childCount; i++) {
|
|
1802
|
-
|
|
1824
|
+
// TODO Non null asserting, why is this not null?
|
|
1825
|
+
const child = block.children[i]!;
|
|
1803
1826
|
block.setOrdinal(child, i);
|
|
1804
1827
|
if (!child.isLeaf()) {
|
|
1805
1828
|
this.nodeUpdateOrdinals(child);
|
|
@@ -1827,7 +1850,7 @@ export class MergeTree {
|
|
|
1827
1850
|
seq: number,
|
|
1828
1851
|
opArgs: IMergeTreeDeltaOpArgs,
|
|
1829
1852
|
rollback: PropertiesRollback = PropertiesRollback.None,
|
|
1830
|
-
) {
|
|
1853
|
+
): void {
|
|
1831
1854
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1832
1855
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1833
1856
|
const deltaSegments: IMergeTreeSegmentDelta[] = [];
|
|
@@ -1835,7 +1858,7 @@ export class MergeTree {
|
|
|
1835
1858
|
seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1836
1859
|
// eslint-disable-next-line import/no-deprecated
|
|
1837
1860
|
let segmentGroup: SegmentGroup | undefined;
|
|
1838
|
-
const annotateSegment = (segment: ISegment) => {
|
|
1861
|
+
const annotateSegment = (segment: ISegment): boolean => {
|
|
1839
1862
|
assert(
|
|
1840
1863
|
!Marker.is(segment) ||
|
|
1841
1864
|
!(reservedMarkerIdKey in props) ||
|
|
@@ -1877,10 +1900,12 @@ export class MergeTree {
|
|
|
1877
1900
|
deltaSegments,
|
|
1878
1901
|
});
|
|
1879
1902
|
}
|
|
1880
|
-
if (
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1903
|
+
if (
|
|
1904
|
+
this.collabWindow.collaborating &&
|
|
1905
|
+
seq !== UnassignedSequenceNumber &&
|
|
1906
|
+
MergeTree.options.zamboniSegments
|
|
1907
|
+
) {
|
|
1908
|
+
zamboniSegments(this);
|
|
1884
1909
|
}
|
|
1885
1910
|
}
|
|
1886
1911
|
|
|
@@ -1912,7 +1937,12 @@ export class MergeTree {
|
|
|
1912
1937
|
}
|
|
1913
1938
|
// eslint-disable-next-line import/no-deprecated
|
|
1914
1939
|
let segmentGroup: SegmentGroup;
|
|
1915
|
-
const markMoved = (
|
|
1940
|
+
const markMoved = (
|
|
1941
|
+
segment: ISegment,
|
|
1942
|
+
pos: number,
|
|
1943
|
+
_start: number,
|
|
1944
|
+
_end: number,
|
|
1945
|
+
): boolean => {
|
|
1916
1946
|
const existingMoveInfo = toMoveInfo(segment);
|
|
1917
1947
|
|
|
1918
1948
|
if (
|
|
@@ -1924,7 +1954,16 @@ export class MergeTree {
|
|
|
1924
1954
|
segment.wasMovedOnInsert = true;
|
|
1925
1955
|
}
|
|
1926
1956
|
|
|
1927
|
-
if (existingMoveInfo
|
|
1957
|
+
if (existingMoveInfo === undefined) {
|
|
1958
|
+
segment.movedClientIds = [clientId];
|
|
1959
|
+
segment.movedSeq = seq;
|
|
1960
|
+
segment.localMovedSeq = localSeq;
|
|
1961
|
+
segment.movedSeqs = [seq];
|
|
1962
|
+
|
|
1963
|
+
if (!toRemovalInfo(segment)) {
|
|
1964
|
+
movedSegments.push({ segment });
|
|
1965
|
+
}
|
|
1966
|
+
} else {
|
|
1928
1967
|
_overwrite = true;
|
|
1929
1968
|
if (existingMoveInfo.movedSeq === UnassignedSequenceNumber) {
|
|
1930
1969
|
// we moved this locally, but someone else moved it first
|
|
@@ -1943,15 +1982,6 @@ export class MergeTree {
|
|
|
1943
1982
|
existingMoveInfo.movedClientIds.push(clientId);
|
|
1944
1983
|
existingMoveInfo.movedSeqs.push(seq);
|
|
1945
1984
|
}
|
|
1946
|
-
} else {
|
|
1947
|
-
segment.movedClientIds = [clientId];
|
|
1948
|
-
segment.movedSeq = seq;
|
|
1949
|
-
segment.localMovedSeq = localSeq;
|
|
1950
|
-
segment.movedSeqs = [seq];
|
|
1951
|
-
|
|
1952
|
-
if (!toRemovalInfo(segment)) {
|
|
1953
|
-
movedSegments.push({ segment });
|
|
1954
|
-
}
|
|
1955
1985
|
}
|
|
1956
1986
|
|
|
1957
1987
|
// Save segment so can assign moved sequence number when acked by server
|
|
@@ -1970,7 +2000,12 @@ export class MergeTree {
|
|
|
1970
2000
|
return true;
|
|
1971
2001
|
};
|
|
1972
2002
|
|
|
1973
|
-
const afterMarkMoved = (
|
|
2003
|
+
const afterMarkMoved = (
|
|
2004
|
+
node: MergeBlock,
|
|
2005
|
+
pos: number,
|
|
2006
|
+
_start: number,
|
|
2007
|
+
_end: number,
|
|
2008
|
+
): boolean => {
|
|
1974
2009
|
if (_overwrite) {
|
|
1975
2010
|
this.nodeUpdateLengthNewStructure(node);
|
|
1976
2011
|
} else {
|
|
@@ -1988,7 +2023,7 @@ export class MergeTree {
|
|
|
1988
2023
|
start,
|
|
1989
2024
|
end,
|
|
1990
2025
|
undefined,
|
|
1991
|
-
seq
|
|
2026
|
+
seq === UnassignedSequenceNumber ? undefined : seq,
|
|
1992
2027
|
);
|
|
1993
2028
|
|
|
1994
2029
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
@@ -2011,10 +2046,12 @@ export class MergeTree {
|
|
|
2011
2046
|
this.slideAckedRemovedSegmentReferences(movedSegments.map(({ segment }) => segment));
|
|
2012
2047
|
}
|
|
2013
2048
|
|
|
2014
|
-
if (
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2049
|
+
if (
|
|
2050
|
+
this.collabWindow.collaborating &&
|
|
2051
|
+
seq !== UnassignedSequenceNumber &&
|
|
2052
|
+
MergeTree.options.zamboniSegments
|
|
2053
|
+
) {
|
|
2054
|
+
zamboniSegments(this);
|
|
2018
2055
|
}
|
|
2019
2056
|
}
|
|
2020
2057
|
|
|
@@ -2036,10 +2073,23 @@ export class MergeTree {
|
|
|
2036
2073
|
const localOverlapWithRefs: ISegment[] = [];
|
|
2037
2074
|
const localSeq =
|
|
2038
2075
|
seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
2039
|
-
const markRemoved = (
|
|
2076
|
+
const markRemoved = (
|
|
2077
|
+
segment: ISegment,
|
|
2078
|
+
pos: number,
|
|
2079
|
+
_start: number,
|
|
2080
|
+
_end: number,
|
|
2081
|
+
): boolean => {
|
|
2040
2082
|
const existingRemovalInfo = toRemovalInfo(segment);
|
|
2041
2083
|
|
|
2042
|
-
if (existingRemovalInfo
|
|
2084
|
+
if (existingRemovalInfo === undefined) {
|
|
2085
|
+
segment.removedClientIds = [clientId];
|
|
2086
|
+
segment.removedSeq = seq;
|
|
2087
|
+
segment.localRemovedSeq = localSeq;
|
|
2088
|
+
|
|
2089
|
+
if (!toMoveInfo(segment)) {
|
|
2090
|
+
removedSegments.push({ segment });
|
|
2091
|
+
}
|
|
2092
|
+
} else {
|
|
2043
2093
|
_overwrite = true;
|
|
2044
2094
|
if (existingRemovalInfo.removedSeq === UnassignedSequenceNumber) {
|
|
2045
2095
|
// we removed this locally, but someone else removed it first
|
|
@@ -2056,14 +2106,6 @@ export class MergeTree {
|
|
|
2056
2106
|
// Do not replace earlier sequence number for remove
|
|
2057
2107
|
existingRemovalInfo.removedClientIds.push(clientId);
|
|
2058
2108
|
}
|
|
2059
|
-
} else {
|
|
2060
|
-
segment.removedClientIds = [clientId];
|
|
2061
|
-
segment.removedSeq = seq;
|
|
2062
|
-
segment.localRemovedSeq = localSeq;
|
|
2063
|
-
|
|
2064
|
-
if (!toMoveInfo(segment)) {
|
|
2065
|
-
removedSegments.push({ segment });
|
|
2066
|
-
}
|
|
2067
2109
|
}
|
|
2068
2110
|
|
|
2069
2111
|
// Save segment so we can assign removed sequence number when acked by server
|
|
@@ -2081,7 +2123,12 @@ export class MergeTree {
|
|
|
2081
2123
|
}
|
|
2082
2124
|
return true;
|
|
2083
2125
|
};
|
|
2084
|
-
const afterMarkRemoved = (
|
|
2126
|
+
const afterMarkRemoved = (
|
|
2127
|
+
node: MergeBlock,
|
|
2128
|
+
pos: number,
|
|
2129
|
+
_start: number,
|
|
2130
|
+
_end: number,
|
|
2131
|
+
): boolean => {
|
|
2085
2132
|
if (_overwrite) {
|
|
2086
2133
|
this.nodeUpdateLengthNewStructure(node);
|
|
2087
2134
|
} else {
|
|
@@ -2107,10 +2154,12 @@ export class MergeTree {
|
|
|
2107
2154
|
this.slideAckedRemovedSegmentReferences(removedSegments.map(({ segment }) => segment));
|
|
2108
2155
|
}
|
|
2109
2156
|
|
|
2110
|
-
if (
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2157
|
+
if (
|
|
2158
|
+
this.collabWindow.collaborating &&
|
|
2159
|
+
seq !== UnassignedSequenceNumber &&
|
|
2160
|
+
MergeTree.options.zamboniSegments
|
|
2161
|
+
) {
|
|
2162
|
+
zamboniSegments(this);
|
|
2114
2163
|
}
|
|
2115
2164
|
}
|
|
2116
2165
|
|
|
@@ -2118,12 +2167,14 @@ export class MergeTree {
|
|
|
2118
2167
|
* Revert an unacked local op
|
|
2119
2168
|
*/
|
|
2120
2169
|
// eslint-disable-next-line import/no-deprecated
|
|
2121
|
-
public rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup) {
|
|
2170
|
+
public rollback(op: IMergeTreeDeltaOp, localOpMetadata: SegmentGroup): void {
|
|
2122
2171
|
if (op.type === MergeTreeDeltaType.REMOVE) {
|
|
2123
2172
|
const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
|
|
2124
2173
|
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
|
|
2125
2174
|
throw new Error("Rollback op doesn't match last edit");
|
|
2126
2175
|
}
|
|
2176
|
+
// Disabling because a for of loop causes the type of segment to be ISegment, which does not have parent information stored
|
|
2177
|
+
// eslint-disable-next-line unicorn/no-array-for-each
|
|
2127
2178
|
pendingSegmentGroup.segments.forEach((segment: ISegmentLeaf) => {
|
|
2128
2179
|
const segmentSegmentGroup = segment.segmentGroups?.pop?.();
|
|
2129
2180
|
assert(
|
|
@@ -2197,7 +2248,8 @@ export class MergeTree {
|
|
|
2197
2248
|
{ op: removeOp },
|
|
2198
2249
|
);
|
|
2199
2250
|
} /* op.type === MergeTreeDeltaType.ANNOTATE */ else {
|
|
2200
|
-
|
|
2251
|
+
// TODO Non null asserting, why is this not null?
|
|
2252
|
+
const props = pendingSegmentGroup.previousProps![i]!;
|
|
2201
2253
|
const annotateOp = createAnnotateRangeOp(start, start + segment.cachedLength, props);
|
|
2202
2254
|
this.annotateRange(
|
|
2203
2255
|
start,
|
|
@@ -2220,7 +2272,7 @@ export class MergeTree {
|
|
|
2220
2272
|
/**
|
|
2221
2273
|
* Walk the segments up to the current segment and calculate its position
|
|
2222
2274
|
*/
|
|
2223
|
-
private findRollbackPosition(segment: ISegment) {
|
|
2275
|
+
private findRollbackPosition(segment: ISegment): number {
|
|
2224
2276
|
let segmentPosition = 0;
|
|
2225
2277
|
walkAllChildSegments(this.root, (seg) => {
|
|
2226
2278
|
// If we've found the desired segment, terminate the walk and return 'segmentPosition'.
|
|
@@ -2239,7 +2291,7 @@ export class MergeTree {
|
|
|
2239
2291
|
return segmentPosition;
|
|
2240
2292
|
}
|
|
2241
2293
|
|
|
2242
|
-
public nodeUpdateLengthNewStructure(node: MergeBlock, recur = false) {
|
|
2294
|
+
public nodeUpdateLengthNewStructure(node: MergeBlock, recur = false): void {
|
|
2243
2295
|
this.blockUpdate(node);
|
|
2244
2296
|
if (this.collabWindow.collaborating) {
|
|
2245
2297
|
this.localPartialsComputed = false;
|
|
@@ -2355,14 +2407,13 @@ export class MergeTree {
|
|
|
2355
2407
|
}
|
|
2356
2408
|
}
|
|
2357
2409
|
|
|
2358
|
-
const newOrder = Array.from(affectedSegments
|
|
2359
|
-
|
|
2360
|
-
seg.localRefs?.walkReferences((lref) => lref.callbacks?.beforeSlide?.(lref))
|
|
2361
|
-
);
|
|
2410
|
+
const newOrder = Array.from(affectedSegments, ({ data }) => data);
|
|
2411
|
+
for (const seg of newOrder)
|
|
2412
|
+
seg.localRefs?.walkReferences((lref) => lref.callbacks?.beforeSlide?.(lref));
|
|
2362
2413
|
const perSegmentTrackingGroups = new Map<ISegment, TrackingGroup[]>();
|
|
2363
2414
|
for (const segment of newOrder) {
|
|
2364
2415
|
const { trackingCollection } = segment;
|
|
2365
|
-
const trackingGroups =
|
|
2416
|
+
const trackingGroups = [...trackingCollection.trackingGroups];
|
|
2366
2417
|
perSegmentTrackingGroups.set(segment, trackingGroups);
|
|
2367
2418
|
for (const group of trackingCollection.trackingGroups) {
|
|
2368
2419
|
trackingCollection.unlink(group);
|
|
@@ -2370,8 +2421,9 @@ export class MergeTree {
|
|
|
2370
2421
|
}
|
|
2371
2422
|
|
|
2372
2423
|
for (let i = 0; i < newOrder.length; i++) {
|
|
2373
|
-
|
|
2374
|
-
const
|
|
2424
|
+
// TODO Non null asserting, why is this not null?
|
|
2425
|
+
const seg = newOrder[i]!;
|
|
2426
|
+
const { parent, index, ordinal } = currentOrder[i]!;
|
|
2375
2427
|
parent?.assignChild(seg, index, false);
|
|
2376
2428
|
seg.ordinal = ordinal;
|
|
2377
2429
|
}
|
|
@@ -2391,15 +2443,16 @@ export class MergeTree {
|
|
|
2391
2443
|
}
|
|
2392
2444
|
return depths.get(block)!;
|
|
2393
2445
|
};
|
|
2394
|
-
newOrder
|
|
2395
|
-
|
|
2446
|
+
for (const element of newOrder) {
|
|
2447
|
+
computeDepth(element);
|
|
2448
|
+
}
|
|
2449
|
+
for (const [node] of [...depths.entries()].sort((a, b) => b[1] - a[1])) {
|
|
2396
2450
|
if (!node.isLeaf()) {
|
|
2397
2451
|
this.nodeUpdateLengthNewStructure(node);
|
|
2398
2452
|
}
|
|
2399
2453
|
}
|
|
2400
|
-
|
|
2401
|
-
seg.localRefs?.walkReferences((lref) => lref.callbacks?.afterSlide?.(lref))
|
|
2402
|
-
);
|
|
2454
|
+
for (const seg of newOrder)
|
|
2455
|
+
seg.localRefs?.walkReferences((lref) => lref.callbacks?.afterSlide?.(lref));
|
|
2403
2456
|
}
|
|
2404
2457
|
|
|
2405
2458
|
/**
|
|
@@ -2426,7 +2479,7 @@ export class MergeTree {
|
|
|
2426
2479
|
let currentRangeToNormalize = new DoublyLinkedList<ISegment>();
|
|
2427
2480
|
let rangeContainsLocalSegs = false;
|
|
2428
2481
|
let rangeContainsRemoteRemovedSegs = false;
|
|
2429
|
-
const normalize = () => {
|
|
2482
|
+
const normalize = (): void => {
|
|
2430
2483
|
if (
|
|
2431
2484
|
rangeContainsLocalSegs &&
|
|
2432
2485
|
rangeContainsRemoteRemovedSegs &&
|
|
@@ -2456,16 +2509,15 @@ export class MergeTree {
|
|
|
2456
2509
|
|
|
2457
2510
|
normalize();
|
|
2458
2511
|
}
|
|
2459
|
-
private blockUpdate(block: MergeBlock) {
|
|
2512
|
+
private blockUpdate(block: MergeBlock): void {
|
|
2460
2513
|
let len: number | undefined;
|
|
2461
2514
|
|
|
2462
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2463
2515
|
const rightmostTiles = createMap<Marker>();
|
|
2464
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2465
2516
|
const leftmostTiles = createMap<Marker>();
|
|
2466
2517
|
|
|
2467
2518
|
for (let i = 0; i < block.childCount; i++) {
|
|
2468
|
-
|
|
2519
|
+
// TODO Non null asserting, why is this not null?
|
|
2520
|
+
const node = block.children[i]!;
|
|
2469
2521
|
const nodeLength = nodeTotalLength(this, node);
|
|
2470
2522
|
if (nodeLength !== undefined) {
|
|
2471
2523
|
len ??= 0;
|
|
@@ -2495,9 +2547,7 @@ export class MergeTree {
|
|
|
2495
2547
|
}
|
|
2496
2548
|
}
|
|
2497
2549
|
} else {
|
|
2498
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2499
2550
|
extend(rightmostTiles, node.rightmostTiles);
|
|
2500
|
-
// eslint-disable-next-line import/no-deprecated
|
|
2501
2551
|
extendIfUndefined(leftmostTiles, node.leftmostTiles);
|
|
2502
2552
|
}
|
|
2503
2553
|
}
|
|
@@ -2511,7 +2561,7 @@ export class MergeTree {
|
|
|
2511
2561
|
seq: number,
|
|
2512
2562
|
clientId: number,
|
|
2513
2563
|
newStructure = false,
|
|
2514
|
-
) {
|
|
2564
|
+
): void {
|
|
2515
2565
|
let block: MergeBlock | undefined = startBlock;
|
|
2516
2566
|
while (block !== undefined) {
|
|
2517
2567
|
if (newStructure) {
|
|
@@ -2523,7 +2573,7 @@ export class MergeTree {
|
|
|
2523
2573
|
}
|
|
2524
2574
|
}
|
|
2525
2575
|
|
|
2526
|
-
private blockUpdateLength(node: MergeBlock, seq: number, clientId: number) {
|
|
2576
|
+
private blockUpdateLength(node: MergeBlock, seq: number, clientId: number): void {
|
|
2527
2577
|
this.blockUpdate(node);
|
|
2528
2578
|
this.localPartialsComputed = false;
|
|
2529
2579
|
if (
|
|
@@ -2561,7 +2611,7 @@ export class MergeTree {
|
|
|
2561
2611
|
end?: number,
|
|
2562
2612
|
splitRange: boolean = false,
|
|
2563
2613
|
visibilitySeq: number = refSeq,
|
|
2564
|
-
) {
|
|
2614
|
+
): void {
|
|
2565
2615
|
if (splitRange) {
|
|
2566
2616
|
if (start) {
|
|
2567
2617
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
@@ -2666,7 +2716,8 @@ export class MergeTree {
|
|
|
2666
2716
|
undefined,
|
|
2667
2717
|
post === undefined
|
|
2668
2718
|
? undefined
|
|
2669
|
-
: (block) =>
|
|
2719
|
+
: (block): boolean =>
|
|
2720
|
+
post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum),
|
|
2670
2721
|
);
|
|
2671
2722
|
}
|
|
2672
2723
|
}
|