@fluidframework/merge-tree 2.0.0-internal.8.0.0 → 2.0.0-rc.1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +0 -6
- package/api-extractor-esm.json +17 -0
- package/api-extractor-lint.json +1 -10
- package/api-extractor.json +0 -4
- package/api-report/merge-tree.api.md +4 -9
- package/dist/client.d.ts +0 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +0 -7
- package/dist/client.js.map +1 -1
- package/dist/merge-tree-alpha.d.ts +27 -12
- package/dist/merge-tree-beta.d.ts +0 -16
- package/dist/merge-tree-public.d.ts +0 -16
- package/dist/merge-tree-untrimmed.d.ts +5 -29
- package/dist/mergeTree.d.ts +0 -17
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +0 -130
- package/dist/mergeTree.js.map +1 -1
- package/dist/ops.d.ts +1 -1
- package/dist/ops.js +1 -1
- package/dist/ops.js.map +1 -1
- package/dist/revertibles.d.ts +4 -4
- package/dist/revertibles.js +3 -3
- package/dist/revertibles.js.map +1 -1
- package/dist/test/Insertion.perf.spec.d.ts +6 -0
- package/dist/test/Insertion.perf.spec.d.ts.map +1 -0
- package/dist/test/Insertion.perf.spec.js +113 -0
- package/dist/test/Insertion.perf.spec.js.map +1 -0
- package/dist/test/PartialLengths.perf.spec.d.ts +6 -0
- package/dist/test/PartialLengths.perf.spec.d.ts.map +1 -0
- package/dist/test/PartialLengths.perf.spec.js +67 -0
- package/dist/test/PartialLengths.perf.spec.js.map +1 -0
- package/dist/test/Removal.perf.spec.d.ts +6 -0
- package/dist/test/Removal.perf.spec.d.ts.map +1 -0
- package/dist/test/Removal.perf.spec.js +166 -0
- package/dist/test/Removal.perf.spec.js.map +1 -0
- package/dist/test/Snapshot.perf.spec.d.ts +6 -0
- package/dist/test/Snapshot.perf.spec.d.ts.map +1 -0
- package/dist/test/Snapshot.perf.spec.js +33 -0
- package/dist/test/Snapshot.perf.spec.js.map +1 -0
- package/dist/test/attributionCollection.perf.spec.d.ts +6 -0
- package/dist/test/attributionCollection.perf.spec.d.ts.map +1 -0
- package/dist/test/attributionCollection.perf.spec.js +231 -0
- package/dist/test/attributionCollection.perf.spec.js.map +1 -0
- package/dist/test/attributionCollection.spec.d.ts +6 -0
- package/dist/test/attributionCollection.spec.d.ts.map +1 -0
- package/dist/test/attributionCollection.spec.js +486 -0
- package/dist/test/attributionCollection.spec.js.map +1 -0
- package/dist/test/attributionPolicy.spec.d.ts +6 -0
- package/dist/test/attributionPolicy.spec.d.ts.map +1 -0
- package/dist/test/attributionPolicy.spec.js +189 -0
- package/dist/test/attributionPolicy.spec.js.map +1 -0
- package/dist/test/beastTest.d.ts +54 -0
- package/dist/test/beastTest.d.ts.map +1 -0
- package/dist/test/beastTest.js +1333 -0
- package/dist/test/beastTest.js.map +1 -0
- package/dist/test/client.annotateMarker.spec.d.ts +6 -0
- package/dist/test/client.annotateMarker.spec.d.ts.map +1 -0
- package/dist/test/client.annotateMarker.spec.js +45 -0
- package/dist/test/client.annotateMarker.spec.js.map +1 -0
- package/dist/test/client.apis.d.ts +7 -0
- package/dist/test/client.apis.d.ts.map +1 -0
- package/dist/test/client.apis.js +72 -0
- package/dist/test/client.apis.js.map +1 -0
- package/dist/test/client.applyMsg.spec.d.ts +6 -0
- package/dist/test/client.applyMsg.spec.d.ts.map +1 -0
- package/dist/test/client.applyMsg.spec.js +500 -0
- package/dist/test/client.applyMsg.spec.js.map +1 -0
- package/dist/test/client.applyStashedOpFarm.spec.d.ts +12 -0
- package/dist/test/client.applyStashedOpFarm.spec.d.ts.map +1 -0
- package/dist/test/client.applyStashedOpFarm.spec.js +144 -0
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -0
- package/dist/test/client.attributionFarm.spec.d.ts +7 -0
- package/dist/test/client.attributionFarm.spec.d.ts.map +1 -0
- package/dist/test/client.attributionFarm.spec.js +96 -0
- package/dist/test/client.attributionFarm.spec.js.map +1 -0
- package/dist/test/client.conflictFarm.spec.d.ts +15 -0
- package/dist/test/client.conflictFarm.spec.d.ts.map +1 -0
- package/dist/test/client.conflictFarm.spec.js +88 -0
- package/dist/test/client.conflictFarm.spec.js.map +1 -0
- package/dist/test/client.getPosition.spec.d.ts +6 -0
- package/dist/test/client.getPosition.spec.d.ts.map +1 -0
- package/dist/test/client.getPosition.spec.js +54 -0
- package/dist/test/client.getPosition.spec.js.map +1 -0
- package/dist/test/client.localReference.spec.d.ts +6 -0
- package/dist/test/client.localReference.spec.d.ts.map +1 -0
- package/dist/test/client.localReference.spec.js +439 -0
- package/dist/test/client.localReference.spec.js.map +1 -0
- package/dist/test/client.localReferenceFarm.spec.d.ts +6 -0
- package/dist/test/client.localReferenceFarm.spec.d.ts.map +1 -0
- package/dist/test/client.localReferenceFarm.spec.js +88 -0
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -0
- package/dist/test/client.rebasePosition.spec.d.ts +6 -0
- package/dist/test/client.rebasePosition.spec.d.ts.map +1 -0
- package/dist/test/client.rebasePosition.spec.js +102 -0
- package/dist/test/client.rebasePosition.spec.js.map +1 -0
- package/dist/test/client.reconnectFarm.spec.d.ts +12 -0
- package/dist/test/client.reconnectFarm.spec.d.ts.map +1 -0
- package/dist/test/client.reconnectFarm.spec.js +91 -0
- package/dist/test/client.reconnectFarm.spec.js.map +1 -0
- package/dist/test/client.replay.spec.d.ts +6 -0
- package/dist/test/client.replay.spec.d.ts.map +1 -0
- package/dist/test/client.replay.spec.js +85 -0
- package/dist/test/client.replay.spec.js.map +1 -0
- package/dist/test/client.rollback.spec.d.ts +6 -0
- package/dist/test/client.rollback.spec.d.ts.map +1 -0
- package/dist/test/client.rollback.spec.js +453 -0
- package/dist/test/client.rollback.spec.js.map +1 -0
- package/dist/test/client.rollbackFarm.spec.d.ts +6 -0
- package/dist/test/client.rollbackFarm.spec.d.ts.map +1 -0
- package/dist/test/client.rollbackFarm.spec.js +48 -0
- package/dist/test/client.rollbackFarm.spec.js.map +1 -0
- package/dist/test/client.searchForMarker.spec.d.ts +6 -0
- package/dist/test/client.searchForMarker.spec.d.ts.map +1 -0
- package/dist/test/client.searchForMarker.spec.js +446 -0
- package/dist/test/client.searchForMarker.spec.js.map +1 -0
- package/dist/test/client.walkSegments.spec.d.ts +6 -0
- package/dist/test/client.walkSegments.spec.d.ts.map +1 -0
- package/dist/test/client.walkSegments.spec.js +54 -0
- package/dist/test/client.walkSegments.spec.js.map +1 -0
- package/dist/test/collections.list.spec.d.ts +6 -0
- package/dist/test/collections.list.spec.d.ts.map +1 -0
- package/dist/test/collections.list.spec.js +84 -0
- package/dist/test/collections.list.spec.js.map +1 -0
- package/dist/test/createInsertOnlyAttributionPolicy.spec.d.ts +6 -0
- package/dist/test/createInsertOnlyAttributionPolicy.spec.d.ts.map +1 -0
- package/dist/test/createInsertOnlyAttributionPolicy.spec.js +35 -0
- package/dist/test/createInsertOnlyAttributionPolicy.spec.js.map +1 -0
- package/dist/test/index.d.ts +13 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +88 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/mergeTree.annotate.deltaCallback.spec.d.ts +6 -0
- package/dist/test/mergeTree.annotate.deltaCallback.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js +142 -0
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -0
- package/dist/test/mergeTree.annotate.spec.d.ts +6 -0
- package/dist/test/mergeTree.annotate.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.annotate.spec.js +448 -0
- package/dist/test/mergeTree.annotate.spec.js.map +1 -0
- package/dist/test/mergeTree.insert.deltaCallback.spec.d.ts +6 -0
- package/dist/test/mergeTree.insert.deltaCallback.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.insert.deltaCallback.spec.js +126 -0
- package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -0
- package/dist/test/mergeTree.insertingWalk.spec.d.ts +6 -0
- package/dist/test/mergeTree.insertingWalk.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.insertingWalk.spec.js +279 -0
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -0
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.d.ts +6 -0
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +178 -0
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.d.ts +6 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.js +130 -0
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -0
- package/dist/test/mergeTree.walk.spec.d.ts +6 -0
- package/dist/test/mergeTree.walk.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.walk.spec.js +63 -0
- package/dist/test/mergeTree.walk.spec.js.map +1 -0
- package/dist/test/mergeTree.zamboni.spec.d.ts +6 -0
- package/dist/test/mergeTree.zamboni.spec.d.ts.map +1 -0
- package/dist/test/mergeTree.zamboni.spec.js +52 -0
- package/dist/test/mergeTree.zamboni.spec.js.map +1 -0
- package/dist/test/mergeTreeOperationRunner.d.ts +63 -0
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -0
- package/dist/test/mergeTreeOperationRunner.js +245 -0
- package/dist/test/mergeTreeOperationRunner.js.map +1 -0
- package/dist/test/mergeTreeOperationRunner.spec.d.ts +6 -0
- package/dist/test/mergeTreeOperationRunner.spec.d.ts.map +1 -0
- package/dist/test/mergeTreeOperationRunner.spec.js +156 -0
- package/dist/test/mergeTreeOperationRunner.spec.js.map +1 -0
- package/dist/test/obliterate.concurrent.spec.d.ts +6 -0
- package/dist/test/obliterate.concurrent.spec.d.ts.map +1 -0
- package/dist/test/obliterate.concurrent.spec.js +1446 -0
- package/dist/test/obliterate.concurrent.spec.js.map +1 -0
- package/dist/test/obliterate.partialLength.spec.d.ts +6 -0
- package/dist/test/obliterate.partialLength.spec.d.ts.map +1 -0
- package/dist/test/obliterate.partialLength.spec.js +279 -0
- package/dist/test/obliterate.partialLength.spec.js.map +1 -0
- package/dist/test/obliterate.reconnect.spec.d.ts +6 -0
- package/dist/test/obliterate.reconnect.spec.d.ts.map +1 -0
- package/dist/test/obliterate.reconnect.spec.js +164 -0
- package/dist/test/obliterate.reconnect.spec.js.map +1 -0
- package/dist/test/obliterate.spec.d.ts +6 -0
- package/dist/test/obliterate.spec.d.ts.map +1 -0
- package/dist/test/obliterate.spec.js +162 -0
- package/dist/test/obliterate.spec.js.map +1 -0
- package/dist/test/ordinal.spec.d.ts +2 -0
- package/dist/test/ordinal.spec.d.ts.map +1 -0
- package/dist/test/ordinal.spec.js +43 -0
- package/dist/test/ordinal.spec.js.map +1 -0
- package/dist/test/partialLength.spec.d.ts +6 -0
- package/dist/test/partialLength.spec.d.ts.map +1 -0
- package/dist/test/partialLength.spec.js +282 -0
- package/dist/test/partialLength.spec.js.map +1 -0
- package/dist/test/properties.spec.d.ts +6 -0
- package/dist/test/properties.spec.d.ts.map +1 -0
- package/dist/test/properties.spec.js +55 -0
- package/dist/test/properties.spec.js.map +1 -0
- package/dist/test/reconnectHelper.d.ts +48 -0
- package/dist/test/reconnectHelper.d.ts.map +1 -0
- package/dist/test/reconnectHelper.js +86 -0
- package/dist/test/reconnectHelper.js.map +1 -0
- package/dist/test/resetPendingSegmentsToOp.spec.d.ts +6 -0
- package/dist/test/resetPendingSegmentsToOp.spec.d.ts.map +1 -0
- package/dist/test/resetPendingSegmentsToOp.spec.js +218 -0
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -0
- package/dist/test/revertibleFarm.spec.d.ts +6 -0
- package/dist/test/revertibleFarm.spec.d.ts.map +1 -0
- package/dist/test/revertibleFarm.spec.js +124 -0
- package/dist/test/revertibleFarm.spec.js.map +1 -0
- package/dist/test/revertibles.spec.d.ts +17 -0
- package/dist/test/revertibles.spec.d.ts.map +1 -0
- package/dist/test/revertibles.spec.js +385 -0
- package/dist/test/revertibles.spec.js.map +1 -0
- package/dist/test/segmentGroupCollection.spec.d.ts +6 -0
- package/dist/test/segmentGroupCollection.spec.d.ts.map +1 -0
- package/dist/test/segmentGroupCollection.spec.js +60 -0
- package/dist/test/segmentGroupCollection.spec.js.map +1 -0
- package/dist/test/snapshot.spec.d.ts +6 -0
- package/dist/test/snapshot.spec.d.ts.map +1 -0
- package/dist/test/snapshot.spec.js +178 -0
- package/dist/test/snapshot.spec.js.map +1 -0
- package/dist/test/snapshot.utils.d.ts +33 -0
- package/dist/test/snapshot.utils.d.ts.map +1 -0
- package/dist/test/snapshot.utils.js +109 -0
- package/dist/test/snapshot.utils.js.map +1 -0
- package/dist/test/snapshotlegacy.spec.d.ts +6 -0
- package/dist/test/snapshotlegacy.spec.d.ts.map +1 -0
- package/dist/test/snapshotlegacy.spec.js +139 -0
- package/dist/test/snapshotlegacy.spec.js.map +1 -0
- package/dist/test/sortedSegmentSet.spec.d.ts +6 -0
- package/dist/test/sortedSegmentSet.spec.d.ts.map +1 -0
- package/dist/test/sortedSegmentSet.spec.js +95 -0
- package/dist/test/sortedSegmentSet.spec.js.map +1 -0
- package/dist/test/testClient.d.ts +119 -0
- package/dist/test/testClient.d.ts.map +1 -0
- package/dist/test/testClient.js +439 -0
- package/dist/test/testClient.js.map +1 -0
- package/dist/test/testClientLogger.d.ts +44 -0
- package/dist/test/testClientLogger.d.ts.map +1 -0
- package/dist/test/testClientLogger.js +287 -0
- package/dist/test/testClientLogger.js.map +1 -0
- package/dist/test/testSerializer.d.ts +18 -0
- package/dist/test/testSerializer.d.ts.map +1 -0
- package/dist/test/testSerializer.js +33 -0
- package/dist/test/testSerializer.js.map +1 -0
- package/dist/test/testServer.d.ts +36 -0
- package/dist/test/testServer.d.ts.map +1 -0
- package/dist/test/testServer.js +138 -0
- package/dist/test/testServer.js.map +1 -0
- package/dist/test/testUtils.d.ts +69 -0
- package/dist/test/testUtils.d.ts.map +1 -0
- package/dist/test/testUtils.js +149 -0
- package/dist/test/testUtils.js.map +1 -0
- package/dist/test/text.d.ts +9 -0
- package/dist/test/text.d.ts.map +1 -0
- package/dist/test/text.js +76 -0
- package/dist/test/text.js.map +1 -0
- package/dist/test/tracking.spec.d.ts +6 -0
- package/dist/test/tracking.spec.d.ts.map +1 -0
- package/dist/test/tracking.spec.js +120 -0
- package/dist/test/tracking.spec.js.map +1 -0
- package/dist/test/wordUnitTests.d.ts +6 -0
- package/dist/test/wordUnitTests.d.ts.map +1 -0
- package/dist/test/wordUnitTests.js +172 -0
- package/dist/test/wordUnitTests.js.map +1 -0
- package/lib/{MergeTreeTextHelper.d.ts → MergeTreeTextHelper.d.mts} +3 -3
- package/lib/MergeTreeTextHelper.d.mts.map +1 -0
- package/lib/{MergeTreeTextHelper.js → MergeTreeTextHelper.mjs} +5 -10
- package/lib/MergeTreeTextHelper.mjs.map +1 -0
- package/lib/{attributionCollection.d.ts → attributionCollection.d.mts} +2 -2
- package/lib/attributionCollection.d.mts.map +1 -0
- package/lib/{attributionCollection.js → attributionCollection.mjs} +9 -14
- package/lib/attributionCollection.mjs.map +1 -0
- package/lib/{attributionPolicy.d.ts → attributionPolicy.d.mts} +2 -2
- package/lib/attributionPolicy.d.mts.map +1 -0
- package/lib/{attributionPolicy.js → attributionPolicy.mjs} +21 -27
- package/lib/attributionPolicy.mjs.map +1 -0
- package/lib/{client.d.ts → client.d.mts} +9 -16
- package/lib/client.d.mts.map +1 -0
- package/lib/{client.js → client.mjs} +101 -110
- package/lib/client.mjs.map +1 -0
- package/lib/collections/{index.d.ts → index.d.mts} +3 -3
- package/lib/collections/index.d.mts.map +1 -0
- package/lib/collections/index.mjs +7 -0
- package/lib/collections/index.mjs.map +1 -0
- package/lib/collections/{list.d.ts → list.d.mts} +1 -1
- package/lib/collections/list.d.mts.map +1 -0
- package/lib/collections/{list.js → list.mjs} +6 -11
- package/lib/collections/list.mjs.map +1 -0
- package/lib/collections/{rbTree.d.ts → rbTree.d.mts} +1 -1
- package/lib/collections/rbTree.d.mts.map +1 -0
- package/lib/collections/{rbTree.js → rbTree.mjs} +16 -20
- package/lib/collections/rbTree.mjs.map +1 -0
- package/lib/{constants.d.ts → constants.d.mts} +1 -1
- package/lib/constants.d.mts.map +1 -0
- package/lib/constants.mjs +32 -0
- package/lib/constants.mjs.map +1 -0
- package/lib/{endOfTreeSegment.d.ts → endOfTreeSegment.d.mts} +4 -4
- package/lib/endOfTreeSegment.d.mts.map +1 -0
- package/lib/{endOfTreeSegment.js → endOfTreeSegment.mjs} +13 -18
- package/lib/endOfTreeSegment.mjs.map +1 -0
- package/lib/{index.d.ts → index.d.mts} +21 -21
- package/lib/index.d.mts.map +1 -0
- package/lib/index.mjs +24 -0
- package/lib/index.mjs.map +1 -0
- package/lib/{localReference.d.ts → localReference.d.mts} +7 -7
- package/lib/localReference.d.mts.map +1 -0
- package/lib/{localReference.js → localReference.mjs} +38 -47
- package/lib/localReference.mjs.map +1 -0
- package/lib/{merge-tree-alpha.d.ts → merge-tree-alpha.d.mts} +27 -12
- package/lib/{merge-tree-beta.d.ts → merge-tree-beta.d.mts} +0 -16
- package/lib/{merge-tree-public.d.ts → merge-tree-public.d.mts} +0 -16
- package/lib/{merge-tree-untrimmed.d.ts → merge-tree-untrimmed.d.mts} +5 -29
- package/lib/{mergeTree.d.ts → mergeTree.d.mts} +12 -29
- package/lib/mergeTree.d.mts.map +1 -0
- package/lib/{mergeTree.js → mergeTree.mjs} +203 -340
- package/lib/mergeTree.mjs.map +1 -0
- package/lib/{mergeTreeDeltaCallback.d.ts → mergeTreeDeltaCallback.d.mts} +4 -8
- package/lib/mergeTreeDeltaCallback.d.mts.map +1 -0
- package/lib/{mergeTreeDeltaCallback.js → mergeTreeDeltaCallback.mjs} +2 -5
- package/lib/mergeTreeDeltaCallback.mjs.map +1 -0
- package/lib/{mergeTreeNodeWalk.d.ts → mergeTreeNodeWalk.d.mts} +2 -2
- package/lib/mergeTreeNodeWalk.d.mts.map +1 -0
- package/lib/{mergeTreeNodeWalk.js → mergeTreeNodeWalk.mjs} +14 -21
- package/lib/mergeTreeNodeWalk.mjs.map +1 -0
- package/lib/{mergeTreeNodes.d.ts → mergeTreeNodes.d.mts} +12 -12
- package/lib/mergeTreeNodes.d.mts.map +1 -0
- package/lib/{mergeTreeNodes.js → mergeTreeNodes.mjs} +60 -76
- package/lib/mergeTreeNodes.mjs.map +1 -0
- package/lib/{mergeTreeTracking.d.ts → mergeTreeTracking.d.mts} +3 -3
- package/lib/mergeTreeTracking.d.mts.map +1 -0
- package/lib/{mergeTreeTracking.js → mergeTreeTracking.mjs} +6 -13
- package/lib/mergeTreeTracking.mjs.map +1 -0
- package/lib/{opBuilder.d.ts → opBuilder.d.mts} +4 -4
- package/lib/opBuilder.d.mts.map +1 -0
- package/lib/{opBuilder.js → opBuilder.mjs} +15 -25
- package/lib/opBuilder.mjs.map +1 -0
- package/lib/{ops.d.ts → ops.d.mts} +2 -2
- package/lib/ops.d.mts.map +1 -0
- package/lib/{ops.js → ops.mjs} +5 -8
- package/lib/ops.mjs.map +1 -0
- package/lib/{ordinal.d.ts → ordinal.d.mts} +1 -1
- package/lib/ordinal.d.mts.map +1 -0
- package/lib/{ordinal.js → ordinal.mjs} +4 -9
- package/lib/ordinal.mjs.map +1 -0
- package/lib/{partialLengths.d.ts → partialLengths.d.mts} +4 -4
- package/lib/partialLengths.d.mts.map +1 -0
- package/lib/{partialLengths.js → partialLengths.mjs} +38 -46
- package/lib/partialLengths.mjs.map +1 -0
- package/lib/{properties.d.ts → properties.d.mts} +1 -1
- package/lib/properties.d.mts.map +1 -0
- package/lib/{properties.js → properties.mjs} +7 -16
- package/lib/properties.mjs.map +1 -0
- package/lib/{referencePositions.d.ts → referencePositions.d.mts} +5 -5
- package/lib/referencePositions.d.mts.map +1 -0
- package/lib/referencePositions.mjs +70 -0
- package/lib/referencePositions.mjs.map +1 -0
- package/lib/{revertibles.d.ts → revertibles.d.mts} +12 -12
- package/lib/revertibles.d.mts.map +1 -0
- package/lib/{revertibles.js → revertibles.mjs} +60 -67
- package/lib/revertibles.mjs.map +1 -0
- package/lib/{segmentGroupCollection.d.ts → segmentGroupCollection.d.mts} +2 -2
- package/lib/segmentGroupCollection.d.mts.map +1 -0
- package/lib/{segmentGroupCollection.js → segmentGroupCollection.mjs} +5 -9
- package/lib/segmentGroupCollection.mjs.map +1 -0
- package/lib/{segmentPropertiesManager.d.ts → segmentPropertiesManager.d.mts} +3 -3
- package/lib/segmentPropertiesManager.d.mts.map +1 -0
- package/lib/{segmentPropertiesManager.js → segmentPropertiesManager.mjs} +14 -20
- package/lib/{segmentPropertiesManager.js.map → segmentPropertiesManager.mjs.map} +1 -1
- package/lib/{snapshotChunks.d.ts → snapshotChunks.d.mts} +4 -4
- package/lib/snapshotChunks.d.mts.map +1 -0
- package/lib/{snapshotChunks.js → snapshotChunks.mjs} +10 -17
- package/lib/snapshotChunks.mjs.map +1 -0
- package/lib/{snapshotLoader.d.ts → snapshotLoader.d.mts} +3 -3
- package/lib/snapshotLoader.d.mts.map +1 -0
- package/lib/{snapshotLoader.js → snapshotLoader.mjs} +33 -38
- package/lib/snapshotLoader.mjs.map +1 -0
- package/lib/{snapshotV1.d.ts → snapshotV1.d.mts} +4 -4
- package/lib/snapshotV1.d.mts.map +1 -0
- package/lib/{snapshotV1.js → snapshotV1.mjs} +28 -32
- package/lib/snapshotV1.mjs.map +1 -0
- package/lib/{snapshotlegacy.d.ts → snapshotlegacy.d.mts} +3 -3
- package/lib/snapshotlegacy.d.mts.map +1 -0
- package/lib/{snapshotlegacy.js → snapshotlegacy.mjs} +21 -26
- package/lib/snapshotlegacy.mjs.map +1 -0
- package/lib/{sortedSegmentSet.d.ts → sortedSegmentSet.d.mts} +4 -4
- package/lib/sortedSegmentSet.d.mts.map +1 -0
- package/lib/{sortedSegmentSet.js → sortedSegmentSet.mjs} +3 -8
- package/lib/sortedSegmentSet.mjs.map +1 -0
- package/lib/{sortedSet.d.ts → sortedSet.d.mts} +1 -1
- package/lib/sortedSet.d.mts.map +1 -0
- package/lib/{sortedSet.js → sortedSet.mjs} +2 -6
- package/lib/sortedSet.mjs.map +1 -0
- package/lib/{textSegment.d.ts → textSegment.d.mts} +4 -4
- package/lib/textSegment.d.mts.map +1 -0
- package/lib/{textSegment.js → textSegment.mjs} +8 -12
- package/lib/textSegment.mjs.map +1 -0
- package/lib/{zamboni.d.ts → zamboni.d.mts} +3 -3
- package/lib/zamboni.d.mts.map +1 -0
- package/lib/{zamboni.js → zamboni.mjs} +22 -28
- package/lib/zamboni.mjs.map +1 -0
- package/package.json +95 -164
- package/src/client.ts +0 -8
- package/src/mergeTree.ts +0 -226
- package/src/ops.ts +1 -1
- package/src/revertibles.ts +4 -4
- package/lib/MergeTreeTextHelper.d.ts.map +0 -1
- package/lib/MergeTreeTextHelper.js.map +0 -1
- package/lib/attributionCollection.d.ts.map +0 -1
- package/lib/attributionCollection.js.map +0 -1
- package/lib/attributionPolicy.d.ts.map +0 -1
- package/lib/attributionPolicy.js.map +0 -1
- package/lib/client.d.ts.map +0 -1
- package/lib/client.js.map +0 -1
- package/lib/collections/index.d.ts.map +0 -1
- package/lib/collections/index.js +0 -14
- package/lib/collections/index.js.map +0 -1
- package/lib/collections/list.d.ts.map +0 -1
- package/lib/collections/list.js.map +0 -1
- package/lib/collections/rbTree.d.ts.map +0 -1
- package/lib/collections/rbTree.js.map +0 -1
- package/lib/constants.d.ts.map +0 -1
- package/lib/constants.js +0 -35
- package/lib/constants.js.map +0 -1
- package/lib/endOfTreeSegment.d.ts.map +0 -1
- package/lib/endOfTreeSegment.js.map +0 -1
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -80
- package/lib/index.js.map +0 -1
- package/lib/localReference.d.ts.map +0 -1
- package/lib/localReference.js.map +0 -1
- package/lib/mergeTree.d.ts.map +0 -1
- package/lib/mergeTree.js.map +0 -1
- package/lib/mergeTreeDeltaCallback.d.ts.map +0 -1
- package/lib/mergeTreeDeltaCallback.js.map +0 -1
- package/lib/mergeTreeNodeWalk.d.ts.map +0 -1
- package/lib/mergeTreeNodeWalk.js.map +0 -1
- package/lib/mergeTreeNodes.d.ts.map +0 -1
- package/lib/mergeTreeNodes.js.map +0 -1
- package/lib/mergeTreeTracking.d.ts.map +0 -1
- package/lib/mergeTreeTracking.js.map +0 -1
- package/lib/opBuilder.d.ts.map +0 -1
- package/lib/opBuilder.js.map +0 -1
- package/lib/ops.d.ts.map +0 -1
- package/lib/ops.js.map +0 -1
- package/lib/ordinal.d.ts.map +0 -1
- package/lib/ordinal.js.map +0 -1
- package/lib/partialLengths.d.ts.map +0 -1
- package/lib/partialLengths.js.map +0 -1
- package/lib/properties.d.ts.map +0 -1
- package/lib/properties.js.map +0 -1
- package/lib/referencePositions.d.ts.map +0 -1
- package/lib/referencePositions.js +0 -80
- package/lib/referencePositions.js.map +0 -1
- package/lib/revertibles.d.ts.map +0 -1
- package/lib/revertibles.js.map +0 -1
- package/lib/segmentGroupCollection.d.ts.map +0 -1
- package/lib/segmentGroupCollection.js.map +0 -1
- package/lib/segmentPropertiesManager.d.ts.map +0 -1
- package/lib/snapshotChunks.d.ts.map +0 -1
- package/lib/snapshotChunks.js.map +0 -1
- package/lib/snapshotLoader.d.ts.map +0 -1
- package/lib/snapshotLoader.js.map +0 -1
- package/lib/snapshotV1.d.ts.map +0 -1
- package/lib/snapshotV1.js.map +0 -1
- package/lib/snapshotlegacy.d.ts.map +0 -1
- package/lib/snapshotlegacy.js.map +0 -1
- package/lib/sortedSegmentSet.d.ts.map +0 -1
- package/lib/sortedSegmentSet.js.map +0 -1
- package/lib/sortedSet.d.ts.map +0 -1
- package/lib/sortedSet.js.map +0 -1
- package/lib/textSegment.d.ts.map +0 -1
- package/lib/textSegment.js.map +0 -1
- package/lib/zamboni.d.ts.map +0 -1
- package/lib/zamboni.js.map +0 -1
- package/merge-tree.test-files.tar +0 -0
- package/src/mergeTreeExample1.pdf +0 -0
- package/tsconfig.esnext.json +0 -6
|
@@ -1,31 +1,27 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/*!
|
|
3
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
3
|
* Licensed under the MIT License.
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const collections_1 = require("./collections");
|
|
13
|
-
const constants_1 = require("./constants");
|
|
14
|
-
const localReference_1 = require("./localReference");
|
|
15
|
-
const mergeTreeNodes_1 = require("./mergeTreeNodes");
|
|
16
|
-
const mergeTreeDeltaCallback_1 = require("./mergeTreeDeltaCallback");
|
|
17
|
-
const opBuilder_1 = require("./opBuilder");
|
|
18
|
-
const ops_1 = require("./ops");
|
|
19
|
-
const partialLengths_1 = require("./partialLengths");
|
|
5
|
+
import { assert, Heap } from "@fluidframework/core-utils";
|
|
6
|
+
import { DataProcessingError, UsageError } from "@fluidframework/telemetry-utils";
|
|
7
|
+
import { DoublyLinkedList } from "./collections/index.mjs";
|
|
8
|
+
import { NonCollabClient, TreeMaintenanceSequenceNumber, UnassignedSequenceNumber, UniversalSequenceNumber, } from "./constants.mjs";
|
|
9
|
+
import { anyLocalReferencePosition, filterLocalReferencePositions, LocalReferenceCollection, SlidingPreference, } from "./localReference.mjs";
|
|
10
|
+
import {
|
|
20
11
|
// eslint-disable-next-line import/no-deprecated
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
12
|
+
CollaborationWindow, Marker, MaxNodesInBlock, MergeBlock, reservedMarkerIdKey, toMoveInfo, seqLTE, toRemovalInfo, } from "./mergeTreeNodes.mjs";
|
|
13
|
+
import { MergeTreeMaintenanceType, } from "./mergeTreeDeltaCallback.mjs";
|
|
14
|
+
import { createAnnotateRangeOp, createInsertSegmentOp, createRemoveRangeOp } from "./opBuilder.mjs";
|
|
15
|
+
import { MergeTreeDeltaType, ReferenceType } from "./ops.mjs";
|
|
16
|
+
import { PartialSequenceLengths } from "./partialLengths.mjs";
|
|
17
|
+
import { createMap, extend, extendIfUndefined } from "./properties.mjs";
|
|
18
|
+
import { refTypeIncludesFlag, DetachedReferencePosition, refGetTileLabels, refHasTileLabel, } from "./referencePositions.mjs";
|
|
19
|
+
import { PropertiesRollback } from "./segmentPropertiesManager.mjs";
|
|
20
|
+
import { backwardExcursion, depthFirstNodeWalk, forwardExcursion, NodeAction, walkAllChildSegments, } from "./mergeTreeNodeWalk.mjs";
|
|
21
|
+
import { zamboniSegments } from "./zamboni.mjs";
|
|
22
|
+
import { EndOfTreeSegment, StartOfTreeSegment } from "./endOfTreeSegment.mjs";
|
|
27
23
|
function wasRemovedAfter(seg, seq) {
|
|
28
|
-
return (seg.removedSeq !==
|
|
24
|
+
return (seg.removedSeq !== UnassignedSequenceNumber &&
|
|
29
25
|
(seg.removedSeq === undefined || seg.removedSeq > seq));
|
|
30
26
|
}
|
|
31
27
|
function markSegmentMoved(seg, moveInfo) {
|
|
@@ -37,18 +33,18 @@ function markSegmentMoved(seg, moveInfo) {
|
|
|
37
33
|
seg.wasMovedOnInsert = moveInfo.wasMovedOnInsert;
|
|
38
34
|
}
|
|
39
35
|
function isMoved(segment) {
|
|
40
|
-
return
|
|
36
|
+
return toMoveInfo(segment) !== undefined;
|
|
41
37
|
}
|
|
42
38
|
function isRemoved(segment) {
|
|
43
|
-
return
|
|
39
|
+
return toRemovalInfo(segment) !== undefined;
|
|
44
40
|
}
|
|
45
41
|
function isRemovedAndAcked(segment) {
|
|
46
|
-
const removalInfo =
|
|
47
|
-
return removalInfo !== undefined && removalInfo.removedSeq !==
|
|
42
|
+
const removalInfo = toRemovalInfo(segment);
|
|
43
|
+
return removalInfo !== undefined && removalInfo.removedSeq !== UnassignedSequenceNumber;
|
|
48
44
|
}
|
|
49
45
|
function isMovedAndAcked(segment) {
|
|
50
|
-
const moveInfo =
|
|
51
|
-
return moveInfo !== undefined && moveInfo.movedSeq !==
|
|
46
|
+
const moveInfo = toMoveInfo(segment);
|
|
47
|
+
return moveInfo !== undefined && moveInfo.movedSeq !== UnassignedSequenceNumber;
|
|
52
48
|
}
|
|
53
49
|
function isRemovedAndAckedOrMovedAndAcked(segment) {
|
|
54
50
|
return isRemovedAndAcked(segment) || isMovedAndAcked(segment);
|
|
@@ -63,37 +59,8 @@ const LRUSegmentComparer = {
|
|
|
63
59
|
min: { maxSeq: -2 },
|
|
64
60
|
compare: (a, b) => a.maxSeq - b.maxSeq,
|
|
65
61
|
};
|
|
66
|
-
function recordTileStart(segment, segpos, refSeq, clientId, start, end, searchInfo) {
|
|
67
|
-
if (mergeTreeNodes_1.Marker.is(segment)) {
|
|
68
|
-
if ((0, referencePositions_1.refHasTileLabel)(segment, searchInfo.tileLabel)) {
|
|
69
|
-
searchInfo.tile = segment;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return false;
|
|
73
|
-
}
|
|
74
|
-
function tileShift(node, segpos, refSeq, clientId, offset, end, searchInfo) {
|
|
75
|
-
if (node.isLeaf()) {
|
|
76
|
-
const seg = node;
|
|
77
|
-
if ((searchInfo.mergeTree.localNetLength(seg) ?? 0) > 0 && mergeTreeNodes_1.Marker.is(seg)) {
|
|
78
|
-
if ((0, referencePositions_1.refHasTileLabel)(seg, searchInfo.tileLabel)) {
|
|
79
|
-
searchInfo.tile = seg;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
const block = node;
|
|
85
|
-
const marker = searchInfo.tilePrecedesPos
|
|
86
|
-
? block.rightmostTiles[searchInfo.tileLabel]
|
|
87
|
-
: block.leftmostTiles[searchInfo.tileLabel];
|
|
88
|
-
if (marker !== undefined) {
|
|
89
|
-
(0, core_utils_1.assert)(marker.isLeaf() && mergeTreeNodes_1.Marker.is(marker), 0x868 /* Object returned is not a valid marker */);
|
|
90
|
-
searchInfo.tile = marker;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
62
|
function addTile(tile, tiles) {
|
|
96
|
-
const tileLabels =
|
|
63
|
+
const tileLabels = refGetTileLabels(tile);
|
|
97
64
|
if (tileLabels) {
|
|
98
65
|
for (const tileLabel of tileLabels) {
|
|
99
66
|
tiles[tileLabel] = tile;
|
|
@@ -101,7 +68,7 @@ function addTile(tile, tiles) {
|
|
|
101
68
|
}
|
|
102
69
|
}
|
|
103
70
|
function addTileIfNotPresent(tile, tiles) {
|
|
104
|
-
const tileLabels =
|
|
71
|
+
const tileLabels = refGetTileLabels(tile);
|
|
105
72
|
if (tileLabels) {
|
|
106
73
|
for (const tileLabel of tileLabels) {
|
|
107
74
|
if (tiles[tileLabel] === undefined) {
|
|
@@ -110,19 +77,19 @@ function addTileIfNotPresent(tile, tiles) {
|
|
|
110
77
|
}
|
|
111
78
|
}
|
|
112
79
|
}
|
|
113
|
-
class HierMergeBlock extends
|
|
80
|
+
class HierMergeBlock extends MergeBlock {
|
|
114
81
|
constructor(childCount) {
|
|
115
82
|
super(childCount);
|
|
116
83
|
// eslint-disable-next-line import/no-deprecated
|
|
117
|
-
this.rightmostTiles =
|
|
84
|
+
this.rightmostTiles = createMap();
|
|
118
85
|
// eslint-disable-next-line import/no-deprecated
|
|
119
|
-
this.leftmostTiles =
|
|
86
|
+
this.leftmostTiles = createMap();
|
|
120
87
|
}
|
|
121
88
|
hierBlock() {
|
|
122
89
|
return this;
|
|
123
90
|
}
|
|
124
91
|
}
|
|
125
|
-
function findRootMergeBlock(segmentOrNode) {
|
|
92
|
+
export function findRootMergeBlock(segmentOrNode) {
|
|
126
93
|
if (segmentOrNode === undefined) {
|
|
127
94
|
return undefined;
|
|
128
95
|
}
|
|
@@ -134,7 +101,6 @@ function findRootMergeBlock(segmentOrNode) {
|
|
|
134
101
|
}
|
|
135
102
|
return maybeRoot?.mergeTree !== undefined ? maybeRoot : undefined;
|
|
136
103
|
}
|
|
137
|
-
exports.findRootMergeBlock = findRootMergeBlock;
|
|
138
104
|
/**
|
|
139
105
|
* @param segment - The segment to slide from.
|
|
140
106
|
* @param cache - Optional cache mapping segments to their sliding destinations.
|
|
@@ -146,7 +112,7 @@ exports.findRootMergeBlock = findRootMergeBlock;
|
|
|
146
112
|
* valid segment (i.e. the tree is empty).
|
|
147
113
|
* @internal
|
|
148
114
|
*/
|
|
149
|
-
function getSlideToSegment(segment, slidingPreference =
|
|
115
|
+
function getSlideToSegment(segment, slidingPreference = SlidingPreference.FORWARD, cache, useNewSlidingBehavior = false) {
|
|
150
116
|
if (!segment ||
|
|
151
117
|
!isRemovedAndAckedOrMovedAndAcked(segment) ||
|
|
152
118
|
segment.endpointType !== undefined) {
|
|
@@ -159,7 +125,7 @@ function getSlideToSegment(segment, slidingPreference = localReference_1.Sliding
|
|
|
159
125
|
const result = {};
|
|
160
126
|
cache?.set(segment, result);
|
|
161
127
|
const goFurtherToFindSlideToSegment = (seg) => {
|
|
162
|
-
if (seg.seq !==
|
|
128
|
+
if (seg.seq !== UnassignedSequenceNumber && !isRemovedAndAckedOrMovedAndAcked(seg)) {
|
|
163
129
|
result.seg = seg;
|
|
164
130
|
return false;
|
|
165
131
|
}
|
|
@@ -169,11 +135,11 @@ function getSlideToSegment(segment, slidingPreference = localReference_1.Sliding
|
|
|
169
135
|
}
|
|
170
136
|
return true;
|
|
171
137
|
};
|
|
172
|
-
if (slidingPreference ===
|
|
173
|
-
|
|
138
|
+
if (slidingPreference === SlidingPreference.BACKWARD) {
|
|
139
|
+
backwardExcursion(segment, goFurtherToFindSlideToSegment);
|
|
174
140
|
}
|
|
175
141
|
else {
|
|
176
|
-
|
|
142
|
+
forwardExcursion(segment, goFurtherToFindSlideToSegment);
|
|
177
143
|
}
|
|
178
144
|
if (result.seg !== undefined) {
|
|
179
145
|
return [result.seg, undefined];
|
|
@@ -188,18 +154,18 @@ function getSlideToSegment(segment, slidingPreference = localReference_1.Sliding
|
|
|
188
154
|
// in both of these cases detached may be substituted for one of the special
|
|
189
155
|
// endpoint segments, if such behavior is enabled
|
|
190
156
|
if (!useNewSlidingBehavior) {
|
|
191
|
-
if (slidingPreference ===
|
|
192
|
-
|
|
157
|
+
if (slidingPreference === SlidingPreference.BACKWARD) {
|
|
158
|
+
forwardExcursion(segment, goFurtherToFindSlideToSegment);
|
|
193
159
|
}
|
|
194
160
|
else {
|
|
195
|
-
|
|
161
|
+
backwardExcursion(segment, goFurtherToFindSlideToSegment);
|
|
196
162
|
}
|
|
197
163
|
}
|
|
198
164
|
let maybeEndpoint;
|
|
199
|
-
if (slidingPreference ===
|
|
165
|
+
if (slidingPreference === SlidingPreference.BACKWARD) {
|
|
200
166
|
maybeEndpoint = "start";
|
|
201
167
|
}
|
|
202
|
-
else if (slidingPreference ===
|
|
168
|
+
else if (slidingPreference === SlidingPreference.FORWARD) {
|
|
203
169
|
maybeEndpoint = "end";
|
|
204
170
|
}
|
|
205
171
|
return [result.seg, maybeEndpoint];
|
|
@@ -210,7 +176,7 @@ function getSlideToSegment(segment, slidingPreference = localReference_1.Sliding
|
|
|
210
176
|
* @returns segment and offset to slide the reference to
|
|
211
177
|
* @internal
|
|
212
178
|
*/
|
|
213
|
-
function getSlideToSegoff(segoff, slidingPreference =
|
|
179
|
+
export function getSlideToSegoff(segoff, slidingPreference = SlidingPreference.FORWARD, useNewSlidingBehavior = false) {
|
|
214
180
|
if (segoff.segment === undefined) {
|
|
215
181
|
return segoff;
|
|
216
182
|
}
|
|
@@ -224,18 +190,17 @@ function getSlideToSegoff(segoff, slidingPreference = localReference_1.SlidingPr
|
|
|
224
190
|
offset,
|
|
225
191
|
};
|
|
226
192
|
}
|
|
227
|
-
exports.getSlideToSegoff = getSlideToSegoff;
|
|
228
193
|
/**
|
|
229
194
|
* @internal
|
|
230
195
|
*/
|
|
231
|
-
class MergeTree {
|
|
196
|
+
export class MergeTree {
|
|
232
197
|
constructor(options) {
|
|
233
198
|
this.options = options;
|
|
234
199
|
// eslint-disable-next-line import/no-deprecated
|
|
235
|
-
this.collabWindow = new
|
|
200
|
+
this.collabWindow = new CollaborationWindow();
|
|
236
201
|
// eslint-disable-next-line import/no-deprecated
|
|
237
|
-
this.pendingSegments = new
|
|
238
|
-
this.segmentsToScour = new
|
|
202
|
+
this.pendingSegments = new DoublyLinkedList();
|
|
203
|
+
this.segmentsToScour = new Heap(LRUSegmentComparer);
|
|
239
204
|
/**
|
|
240
205
|
* Whether or not all blocks in the mergeTree currently have information about local partial lengths computed.
|
|
241
206
|
* This information is only necessary on reconnect, and otherwise costly to bookkeep.
|
|
@@ -281,13 +246,13 @@ class MergeTree {
|
|
|
281
246
|
}
|
|
282
247
|
const next = segment.splitAt(pos);
|
|
283
248
|
this.mergeTreeMaintenanceCallback?.({
|
|
284
|
-
operation:
|
|
249
|
+
operation: MergeTreeMaintenanceType.SPLIT,
|
|
285
250
|
deltaSegments: [{ segment }, { segment: next }],
|
|
286
251
|
}, undefined);
|
|
287
252
|
return { next };
|
|
288
253
|
};
|
|
289
|
-
this.startOfTree = new
|
|
290
|
-
this.endOfTree = new
|
|
254
|
+
this.startOfTree = new StartOfTreeSegment(this);
|
|
255
|
+
this.endOfTree = new EndOfTreeSegment(this);
|
|
291
256
|
this._root = this.makeBlock(0);
|
|
292
257
|
this._root.mergeTree = this;
|
|
293
258
|
this.attributionPolicy = options?.attribution?.policyFactory?.();
|
|
@@ -312,12 +277,12 @@ class MergeTree {
|
|
|
312
277
|
* numbers corresponding to un-acked operations give valid results.
|
|
313
278
|
*/
|
|
314
279
|
localNetLength(segment, refSeq, localSeq) {
|
|
315
|
-
const removalInfo =
|
|
316
|
-
const moveInfo =
|
|
280
|
+
const removalInfo = toRemovalInfo(segment);
|
|
281
|
+
const moveInfo = toMoveInfo(segment);
|
|
317
282
|
if (localSeq === undefined) {
|
|
318
283
|
if (removalInfo !== undefined || moveInfo !== undefined) {
|
|
319
|
-
if ((!!removalInfo && !
|
|
320
|
-
(!!moveInfo && !
|
|
284
|
+
if ((!!removalInfo && !seqLTE(removalInfo.removedSeq, this.collabWindow.minSeq)) ||
|
|
285
|
+
(!!moveInfo && !seqLTE(moveInfo.movedSeq, this.collabWindow.minSeq))) {
|
|
321
286
|
return 0;
|
|
322
287
|
}
|
|
323
288
|
// this segment removed and outside the collab window which means it is zamboni eligible
|
|
@@ -329,17 +294,17 @@ class MergeTree {
|
|
|
329
294
|
return segment.cachedLength;
|
|
330
295
|
}
|
|
331
296
|
}
|
|
332
|
-
|
|
333
|
-
|
|
297
|
+
assert(refSeq !== undefined, 0x398 /* localSeq provided for local length without refSeq */);
|
|
298
|
+
assert(segment.seq !== undefined, 0x399 /* segment with no seq in mergeTree */);
|
|
334
299
|
const { seq, removedSeq, localRemovedSeq, movedSeq, localMovedSeq } = segment;
|
|
335
|
-
if (seq !==
|
|
300
|
+
if (seq !== UnassignedSequenceNumber) {
|
|
336
301
|
// inserted remotely
|
|
337
302
|
if (seq > refSeq ||
|
|
338
303
|
(removedSeq !== undefined &&
|
|
339
|
-
removedSeq !==
|
|
304
|
+
removedSeq !== UnassignedSequenceNumber &&
|
|
340
305
|
removedSeq <= refSeq) ||
|
|
341
306
|
(movedSeq !== undefined &&
|
|
342
|
-
movedSeq !==
|
|
307
|
+
movedSeq !== UnassignedSequenceNumber &&
|
|
343
308
|
movedSeq <= refSeq) ||
|
|
344
309
|
(localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
|
|
345
310
|
(localMovedSeq !== undefined && localMovedSeq <= localSeq)) {
|
|
@@ -348,7 +313,7 @@ class MergeTree {
|
|
|
348
313
|
return segment.cachedLength;
|
|
349
314
|
}
|
|
350
315
|
else {
|
|
351
|
-
|
|
316
|
+
assert(segment.localSeq !== undefined, 0x39a /* unacked segment with undefined localSeq */);
|
|
352
317
|
// inserted locally, still un-acked
|
|
353
318
|
if (segment.localSeq > localSeq ||
|
|
354
319
|
(localRemovedSeq !== undefined && localRemovedSeq <= localSeq) ||
|
|
@@ -371,8 +336,8 @@ class MergeTree {
|
|
|
371
336
|
}
|
|
372
337
|
reloadFromSegments(segments) {
|
|
373
338
|
// This code assumes that a later call to `startCollaboration()` will initialize partial lengths.
|
|
374
|
-
|
|
375
|
-
const maxChildren =
|
|
339
|
+
assert(!this.collabWindow.collaborating, 0x049 /* "Trying to reload from segments while collaborating!" */);
|
|
340
|
+
const maxChildren = MaxNodesInBlock - 1;
|
|
376
341
|
// Starting with the leaf segments, recursively builds the B-Tree layer by layer from the bottom up.
|
|
377
342
|
const buildMergeBlock = (nodes) => {
|
|
378
343
|
const blockCount = Math.ceil(nodes.length / maxChildren); // Compute # blocks require for this level of B-Tree
|
|
@@ -457,7 +422,7 @@ class MergeTree {
|
|
|
457
422
|
return totalOffset;
|
|
458
423
|
}
|
|
459
424
|
getContainingSegment(pos, refSeq, clientId, localSeq) {
|
|
460
|
-
|
|
425
|
+
assert(localSeq === undefined || clientId === this.collabWindow.clientId, 0x39b /* localSeq provided for non-local client */);
|
|
461
426
|
let segment;
|
|
462
427
|
let offset;
|
|
463
428
|
const leaf = (leafSeg, segpos, _refSeq, _clientId, start) => {
|
|
@@ -495,20 +460,20 @@ class MergeTree {
|
|
|
495
460
|
let currentForwardMaybeEndpoint;
|
|
496
461
|
let currentForwardSlideDestination;
|
|
497
462
|
let currentForwardSlideIsForward;
|
|
498
|
-
const forwardPred = (ref) => ref.slidingPreference !==
|
|
463
|
+
const forwardPred = (ref) => ref.slidingPreference !== SlidingPreference.BACKWARD;
|
|
499
464
|
let currentBackwardMaybeEndpoint;
|
|
500
465
|
let currentBackwardSlideDestination;
|
|
501
466
|
let currentBackwardSlideIsForward;
|
|
502
|
-
const backwardPred = (ref) => ref.slidingPreference ===
|
|
467
|
+
const backwardPred = (ref) => ref.slidingPreference === SlidingPreference.BACKWARD;
|
|
503
468
|
const slideGroup = (currentSlideDestination, currentSlideIsForward, currentSlideGroup, pred, maybeEndpoint) => {
|
|
504
469
|
if (currentSlideIsForward === undefined) {
|
|
505
470
|
return;
|
|
506
471
|
}
|
|
507
|
-
const nonEndpointRefsToAdd = currentSlideGroup.map((collection) =>
|
|
508
|
-
const endpointRefsToAdd = currentSlideGroup.map((collection) =>
|
|
472
|
+
const nonEndpointRefsToAdd = currentSlideGroup.map((collection) => filterLocalReferencePositions(collection, (ref) => pred(ref) && (maybeEndpoint ? !ref.canSlideToEndpoint : true)));
|
|
473
|
+
const endpointRefsToAdd = currentSlideGroup.map((collection) => filterLocalReferencePositions(collection, (ref) => pred(ref) && !!ref.canSlideToEndpoint));
|
|
509
474
|
if (maybeEndpoint) {
|
|
510
475
|
const endpoint = maybeEndpoint === "start" ? this.startOfTree : this.endOfTree;
|
|
511
|
-
const localRefs = (endpoint.localRefs ?? (endpoint.localRefs = new
|
|
476
|
+
const localRefs = (endpoint.localRefs ?? (endpoint.localRefs = new LocalReferenceCollection(endpoint)));
|
|
512
477
|
if (currentSlideIsForward) {
|
|
513
478
|
localRefs.addBeforeTombstones(...endpointRefsToAdd);
|
|
514
479
|
}
|
|
@@ -517,7 +482,7 @@ class MergeTree {
|
|
|
517
482
|
}
|
|
518
483
|
}
|
|
519
484
|
if (currentSlideDestination !== undefined) {
|
|
520
|
-
const localRefs = (currentSlideDestination.localRefs ?? (currentSlideDestination.localRefs = new
|
|
485
|
+
const localRefs = (currentSlideDestination.localRefs ?? (currentSlideDestination.localRefs = new LocalReferenceCollection(currentSlideDestination)));
|
|
521
486
|
if (currentSlideIsForward) {
|
|
522
487
|
localRefs.addBeforeTombstones(...nonEndpointRefsToAdd);
|
|
523
488
|
}
|
|
@@ -528,7 +493,7 @@ class MergeTree {
|
|
|
528
493
|
else {
|
|
529
494
|
for (const collection of currentSlideGroup) {
|
|
530
495
|
for (const ref of collection) {
|
|
531
|
-
if (pred(ref) && !
|
|
496
|
+
if (pred(ref) && !refTypeIncludesFlag(ref, ReferenceType.StayOnRemove)) {
|
|
532
497
|
ref.callbacks?.beforeSlide?.(ref);
|
|
533
498
|
collection.removeLocalRef(ref);
|
|
534
499
|
ref.callbacks?.afterSlide?.(ref);
|
|
@@ -540,10 +505,10 @@ class MergeTree {
|
|
|
540
505
|
const trySlideSegment = (segment, currentSlideDestination, currentSlideIsForward, currentSlideGroup, pred, slidingPreference, currentMaybeEndpoint, reassign) => {
|
|
541
506
|
// avoid sliding logic if this segment doesn't have any references
|
|
542
507
|
// with the given sliding preference
|
|
543
|
-
if (!segment.localRefs || !
|
|
508
|
+
if (!segment.localRefs || !anyLocalReferencePosition(segment.localRefs, pred)) {
|
|
544
509
|
return;
|
|
545
510
|
}
|
|
546
|
-
const [slideToSegment, maybeEndpoint] = getSlideToSegment(segment, slidingPreference, slidingPreference ===
|
|
511
|
+
const [slideToSegment, maybeEndpoint] = getSlideToSegment(segment, slidingPreference, slidingPreference === SlidingPreference.FORWARD
|
|
547
512
|
? forwardSegmentCache
|
|
548
513
|
: backwardSegmentCache, this.options?.mergeTreeReferencesCanSlideToEndpoint);
|
|
549
514
|
const slideIsForward = slideToSegment === undefined ? false : slideToSegment.ordinal > segment.ordinal;
|
|
@@ -560,17 +525,17 @@ class MergeTree {
|
|
|
560
525
|
const forwardSegmentCache = new Map();
|
|
561
526
|
const backwardSegmentCache = new Map();
|
|
562
527
|
for (const segment of segments) {
|
|
563
|
-
|
|
528
|
+
assert(isRemovedAndAckedOrMovedAndAcked(segment), 0x2f1 /* slideReferences from a segment which has not been removed and acked */);
|
|
564
529
|
if (segment.localRefs === undefined || segment.localRefs.empty) {
|
|
565
530
|
continue;
|
|
566
531
|
}
|
|
567
|
-
trySlideSegment(segment, currentForwardSlideDestination, currentForwardSlideIsForward, currentForwardSlideGroup, forwardPred,
|
|
532
|
+
trySlideSegment(segment, currentForwardSlideDestination, currentForwardSlideIsForward, currentForwardSlideGroup, forwardPred, SlidingPreference.FORWARD, currentForwardMaybeEndpoint, (localRefs, slideToSegment, slideIsForward, maybeEndpoint) => {
|
|
568
533
|
currentForwardSlideGroup = [localRefs];
|
|
569
534
|
currentForwardSlideDestination = slideToSegment;
|
|
570
535
|
currentForwardSlideIsForward = slideIsForward;
|
|
571
536
|
currentForwardMaybeEndpoint = maybeEndpoint;
|
|
572
537
|
});
|
|
573
|
-
trySlideSegment(segment, currentBackwardSlideDestination, currentBackwardSlideIsForward, currentBackwardSlideGroup, backwardPred,
|
|
538
|
+
trySlideSegment(segment, currentBackwardSlideDestination, currentBackwardSlideIsForward, currentBackwardSlideGroup, backwardPred, SlidingPreference.BACKWARD, currentBackwardMaybeEndpoint, (localRefs, slideToSegment, slideIsForward, maybeEndpoint) => {
|
|
574
539
|
currentBackwardSlideGroup = [localRefs];
|
|
575
540
|
currentBackwardSlideDestination = slideToSegment;
|
|
576
541
|
currentBackwardSlideIsForward = slideIsForward;
|
|
@@ -595,12 +560,12 @@ class MergeTree {
|
|
|
595
560
|
return;
|
|
596
561
|
}
|
|
597
562
|
// eslint-disable-next-line import/no-deprecated
|
|
598
|
-
const rebaseCollabWindow = new
|
|
563
|
+
const rebaseCollabWindow = new CollaborationWindow();
|
|
599
564
|
rebaseCollabWindow.loadFrom(this.collabWindow);
|
|
600
565
|
if (refSeq < this.collabWindow.minSeq) {
|
|
601
566
|
rebaseCollabWindow.minSeq = refSeq;
|
|
602
567
|
}
|
|
603
|
-
this.root.partialLengths =
|
|
568
|
+
this.root.partialLengths = PartialSequenceLengths.combine(this.root, rebaseCollabWindow, true, true);
|
|
604
569
|
this.localPartialsComputed = true;
|
|
605
570
|
}
|
|
606
571
|
nodeLength(node, refSeq, clientId, localSeq) {
|
|
@@ -616,7 +581,7 @@ class MergeTree {
|
|
|
616
581
|
this.computeLocalPartials(refSeq);
|
|
617
582
|
// Local client should see all segments except those after localSeq.
|
|
618
583
|
const partialLen = node.partialLengths.getPartialLength(refSeq, clientId, localSeq);
|
|
619
|
-
|
|
584
|
+
PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId, localSeq);
|
|
620
585
|
return partialLen;
|
|
621
586
|
}
|
|
622
587
|
}
|
|
@@ -624,99 +589,63 @@ class MergeTree {
|
|
|
624
589
|
// Sequence number within window
|
|
625
590
|
if (!node.isLeaf()) {
|
|
626
591
|
const partialLen = node.partialLengths.getPartialLength(refSeq, clientId);
|
|
627
|
-
|
|
592
|
+
PartialSequenceLengths.options.verifyExpected?.(this, node, refSeq, clientId);
|
|
628
593
|
return partialLen;
|
|
629
594
|
}
|
|
630
595
|
else {
|
|
631
596
|
const segment = node;
|
|
632
|
-
const removalInfo =
|
|
633
|
-
const moveInfo =
|
|
597
|
+
const removalInfo = toRemovalInfo(segment);
|
|
598
|
+
const moveInfo = toMoveInfo(segment);
|
|
634
599
|
if (removalInfo !== undefined) {
|
|
635
|
-
if (
|
|
600
|
+
if (seqLTE(removalInfo.removedSeq, this.collabWindow.minSeq)) {
|
|
636
601
|
return undefined;
|
|
637
602
|
}
|
|
638
|
-
if (
|
|
603
|
+
if (seqLTE(removalInfo.removedSeq, refSeq) ||
|
|
639
604
|
removalInfo.removedClientIds.includes(clientId)) {
|
|
640
605
|
return 0;
|
|
641
606
|
}
|
|
642
607
|
}
|
|
643
608
|
if (moveInfo !== undefined) {
|
|
644
|
-
if (
|
|
609
|
+
if (seqLTE(moveInfo.movedSeq, this.collabWindow.minSeq)) {
|
|
645
610
|
return undefined;
|
|
646
611
|
}
|
|
647
|
-
if (
|
|
612
|
+
if (seqLTE(moveInfo.movedSeq, refSeq) ||
|
|
648
613
|
moveInfo.movedClientIds.includes(clientId)) {
|
|
649
614
|
return 0;
|
|
650
615
|
}
|
|
651
616
|
}
|
|
652
|
-
return
|
|
617
|
+
return seqLTE(node.seq ?? 0, refSeq) || segment.clientId === clientId
|
|
653
618
|
? segment.cachedLength
|
|
654
619
|
: 0;
|
|
655
620
|
}
|
|
656
621
|
}
|
|
657
622
|
}
|
|
658
623
|
setMinSeq(minSeq) {
|
|
659
|
-
|
|
624
|
+
assert(minSeq <= this.collabWindow.currentSeq, 0x04e /* "Trying to set minSeq above currentSeq of collab window!" */);
|
|
660
625
|
// Only move forward
|
|
661
|
-
|
|
626
|
+
assert(this.collabWindow.minSeq <= minSeq, 0x04f /* "minSeq of collab window > target minSeq!" */);
|
|
662
627
|
if (minSeq > this.collabWindow.minSeq) {
|
|
663
628
|
this.collabWindow.minSeq = minSeq;
|
|
664
629
|
const firstMoveSeqIdx = this.moveSeqs.findIndex((seq) => seq >= minSeq);
|
|
665
630
|
this.moveSeqs = firstMoveSeqIdx === -1 ? [] : this.moveSeqs.slice(firstMoveSeqIdx);
|
|
666
631
|
if (MergeTree.options.zamboniSegments) {
|
|
667
|
-
|
|
632
|
+
zamboniSegments(this);
|
|
668
633
|
}
|
|
669
634
|
}
|
|
670
635
|
}
|
|
671
636
|
referencePositionToLocalPosition(refPos, refSeq = this.collabWindow.currentSeq, clientId = this.collabWindow.clientId) {
|
|
672
637
|
const seg = refPos.getSegment();
|
|
673
638
|
if (seg?.parent === undefined) {
|
|
674
|
-
return
|
|
639
|
+
return DetachedReferencePosition;
|
|
675
640
|
}
|
|
676
641
|
if (refPos.isLeaf()) {
|
|
677
642
|
return this.getPosition(refPos, refSeq, clientId);
|
|
678
643
|
}
|
|
679
|
-
if (
|
|
644
|
+
if (refTypeIncludesFlag(refPos, ReferenceType.Transient) || seg.localRefs?.has(refPos)) {
|
|
680
645
|
const offset = isRemoved(seg) || isMoved(seg) ? 0 : refPos.getOffset();
|
|
681
646
|
return offset + this.getPosition(seg, refSeq, clientId);
|
|
682
647
|
}
|
|
683
|
-
return
|
|
684
|
-
}
|
|
685
|
-
// TODO: filter function
|
|
686
|
-
/**
|
|
687
|
-
* Finds the nearest reference with ReferenceType.Tile to `startPos` in the direction dictated by `tilePrecedesPos`.
|
|
688
|
-
* @deprecated Use searchForMarker instead.
|
|
689
|
-
*
|
|
690
|
-
* @param startPos - Position at which to start the search
|
|
691
|
-
* @param clientId - clientId dictating the perspective to search from
|
|
692
|
-
* @param tileLabel - Label of the tile to search for
|
|
693
|
-
* @param tilePrecedesPos - Whether the desired tile comes before (true) or after (false) `startPos`
|
|
694
|
-
*/
|
|
695
|
-
findTile(startPos, clientId, tileLabel, tilePrecedesPos = true) {
|
|
696
|
-
const searchInfo = {
|
|
697
|
-
mergeTree: this,
|
|
698
|
-
tilePrecedesPos,
|
|
699
|
-
tileLabel,
|
|
700
|
-
};
|
|
701
|
-
if (tilePrecedesPos) {
|
|
702
|
-
this.search(startPos, constants_1.UniversalSequenceNumber, clientId, { leaf: recordTileStart, shift: tileShift }, searchInfo);
|
|
703
|
-
}
|
|
704
|
-
else {
|
|
705
|
-
this.backwardSearch(startPos, constants_1.UniversalSequenceNumber, clientId, { leaf: recordTileStart, shift: tileShift }, searchInfo);
|
|
706
|
-
}
|
|
707
|
-
if (searchInfo.tile) {
|
|
708
|
-
let pos;
|
|
709
|
-
if (searchInfo.tile.isLeaf()) {
|
|
710
|
-
const marker = searchInfo.tile;
|
|
711
|
-
pos = this.getPosition(marker, constants_1.UniversalSequenceNumber, clientId);
|
|
712
|
-
}
|
|
713
|
-
else {
|
|
714
|
-
const localRef = searchInfo.tile;
|
|
715
|
-
pos = this.referencePositionToLocalPosition(localRef, constants_1.UniversalSequenceNumber, clientId);
|
|
716
|
-
}
|
|
717
|
-
return { tile: searchInfo.tile, pos };
|
|
718
|
-
}
|
|
719
|
-
return undefined;
|
|
648
|
+
return DetachedReferencePosition;
|
|
720
649
|
}
|
|
721
650
|
/**
|
|
722
651
|
* Finds the nearest reference with ReferenceType.Tile to `startPos` in the direction dictated by `forwards`.
|
|
@@ -732,14 +661,14 @@ class MergeTree {
|
|
|
732
661
|
*/
|
|
733
662
|
searchForMarker(startPos, clientId, markerLabel, forwards = true) {
|
|
734
663
|
let foundMarker;
|
|
735
|
-
const { segment } = this.getContainingSegment(startPos,
|
|
664
|
+
const { segment } = this.getContainingSegment(startPos, UniversalSequenceNumber, clientId);
|
|
736
665
|
const segWithParent = segment;
|
|
737
666
|
if (segWithParent?.parent === undefined) {
|
|
738
667
|
return undefined;
|
|
739
668
|
}
|
|
740
|
-
|
|
669
|
+
depthFirstNodeWalk(segWithParent.parent, segWithParent, (seg) => {
|
|
741
670
|
if (seg.isLeaf()) {
|
|
742
|
-
if (
|
|
671
|
+
if (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {
|
|
743
672
|
foundMarker = seg;
|
|
744
673
|
}
|
|
745
674
|
}
|
|
@@ -749,79 +678,14 @@ class MergeTree {
|
|
|
749
678
|
? block.leftmostTiles[markerLabel]
|
|
750
679
|
: block.rightmostTiles[markerLabel];
|
|
751
680
|
if (marker !== undefined) {
|
|
752
|
-
|
|
681
|
+
assert(marker.isLeaf() && Marker.is(marker), 0x751 /* Object returned is not a valid marker */);
|
|
753
682
|
foundMarker = marker;
|
|
754
683
|
}
|
|
755
684
|
}
|
|
756
|
-
return foundMarker !== undefined ?
|
|
685
|
+
return foundMarker !== undefined ? NodeAction.Exit : NodeAction.Skip;
|
|
757
686
|
}, undefined, undefined, forwards);
|
|
758
687
|
return foundMarker;
|
|
759
688
|
}
|
|
760
|
-
search(pos, refSeq, clientId, actions, clientData) {
|
|
761
|
-
return this.searchBlock(this.root, pos, 0, refSeq, clientId, actions, clientData);
|
|
762
|
-
}
|
|
763
|
-
searchBlock(block, pos, segpos, refSeq, clientId, actions, clientData, localSeq) {
|
|
764
|
-
const { pre, post, contains, leaf, shift } = actions ?? {};
|
|
765
|
-
let _pos = pos;
|
|
766
|
-
let _segpos = segpos;
|
|
767
|
-
const children = block.children;
|
|
768
|
-
pre?.(block, _segpos, refSeq, clientId, undefined, undefined, clientData);
|
|
769
|
-
for (let childIndex = 0; childIndex < block.childCount; childIndex++) {
|
|
770
|
-
const child = children[childIndex];
|
|
771
|
-
const len = this.nodeLength(child, refSeq, clientId, localSeq) ?? 0;
|
|
772
|
-
if ((!contains && _pos < len) ||
|
|
773
|
-
contains?.(child, _pos, refSeq, clientId, undefined, undefined, clientData)) {
|
|
774
|
-
// Found entry containing pos
|
|
775
|
-
if (!child.isLeaf()) {
|
|
776
|
-
return this.searchBlock(child, _pos, _segpos, refSeq, clientId, actions, clientData, localSeq);
|
|
777
|
-
}
|
|
778
|
-
else {
|
|
779
|
-
leaf?.(child, _segpos, refSeq, clientId, _pos, -1, clientData);
|
|
780
|
-
return child;
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
else {
|
|
784
|
-
shift?.(child, _segpos, refSeq, clientId, _pos, undefined, clientData);
|
|
785
|
-
_pos -= len;
|
|
786
|
-
_segpos += len;
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
post?.(block, _segpos, refSeq, clientId, undefined, undefined, clientData);
|
|
790
|
-
}
|
|
791
|
-
backwardSearch(pos, refSeq, clientId, actions, clientData) {
|
|
792
|
-
const len = this.getLength(refSeq, clientId);
|
|
793
|
-
if (pos > len) {
|
|
794
|
-
return undefined;
|
|
795
|
-
}
|
|
796
|
-
return this.backwardSearchBlock(this.root, pos, len, refSeq, clientId, actions, clientData);
|
|
797
|
-
}
|
|
798
|
-
backwardSearchBlock(block, pos, segEnd, refSeq, clientId, actions, clientData) {
|
|
799
|
-
const { pre, post, contains, leaf, shift } = actions ?? {};
|
|
800
|
-
let _segEnd = segEnd;
|
|
801
|
-
const children = block.children;
|
|
802
|
-
pre?.(block, _segEnd, refSeq, clientId, undefined, undefined, clientData);
|
|
803
|
-
for (let childIndex = block.childCount - 1; childIndex >= 0; childIndex--) {
|
|
804
|
-
const child = children[childIndex];
|
|
805
|
-
const len = this.nodeLength(child, refSeq, clientId) ?? 0;
|
|
806
|
-
const segpos = _segEnd - len;
|
|
807
|
-
if ((!contains && pos >= segpos) ||
|
|
808
|
-
contains?.(child, pos, refSeq, clientId, undefined, undefined, clientData)) {
|
|
809
|
-
// Found entry containing pos
|
|
810
|
-
if (!child.isLeaf()) {
|
|
811
|
-
return this.backwardSearchBlock(child, pos, _segEnd, refSeq, clientId, actions, clientData);
|
|
812
|
-
}
|
|
813
|
-
else {
|
|
814
|
-
leaf?.(child, segpos, refSeq, clientId, pos, -1, clientData);
|
|
815
|
-
return child;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
else {
|
|
819
|
-
shift?.(child, segpos, refSeq, clientId, pos, undefined, clientData);
|
|
820
|
-
_segEnd = segpos;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
post?.(block, _segEnd, refSeq, clientId, undefined, undefined, clientData);
|
|
824
|
-
}
|
|
825
689
|
updateRoot(splitNode) {
|
|
826
690
|
if (splitNode !== undefined) {
|
|
827
691
|
const newRoot = this.makeBlock(2);
|
|
@@ -847,7 +711,7 @@ class MergeTree {
|
|
|
847
711
|
pendingSegmentGroup.segments.map((pendingSegment) => {
|
|
848
712
|
const localMovedSeq = pendingSegment.localMovedSeq;
|
|
849
713
|
const overlappingRemove = !pendingSegment.ack(pendingSegmentGroup, opArgs);
|
|
850
|
-
if (opArgs.op.type ===
|
|
714
|
+
if (opArgs.op.type === MergeTreeDeltaType.OBLITERATE &&
|
|
851
715
|
localMovedSeq !== undefined) {
|
|
852
716
|
const locallyMovedSegments = this.locallyMovedSegments.get(localMovedSeq);
|
|
853
717
|
if (locallyMovedSegments) {
|
|
@@ -856,7 +720,7 @@ class MergeTree {
|
|
|
856
720
|
if (!nodesToUpdate.includes(segment.parent)) {
|
|
857
721
|
nodesToUpdate.push(segment.parent);
|
|
858
722
|
}
|
|
859
|
-
if (segment.movedSeq ===
|
|
723
|
+
if (segment.movedSeq === UnassignedSequenceNumber) {
|
|
860
724
|
segment.movedSeq = seq;
|
|
861
725
|
}
|
|
862
726
|
}
|
|
@@ -864,7 +728,7 @@ class MergeTree {
|
|
|
864
728
|
}
|
|
865
729
|
}
|
|
866
730
|
overwrite = overlappingRemove || overwrite;
|
|
867
|
-
if (opArgs.op.type ===
|
|
731
|
+
if (opArgs.op.type === MergeTreeDeltaType.OBLITERATE) {
|
|
868
732
|
if (seq !== this.moveSeqs[this.moveSeqs.length - 1]) {
|
|
869
733
|
this.moveSeqs.push(seq);
|
|
870
734
|
}
|
|
@@ -885,13 +749,13 @@ class MergeTree {
|
|
|
885
749
|
});
|
|
886
750
|
// Perform slides after all segments have been acked, so that
|
|
887
751
|
// positions after slide are final
|
|
888
|
-
if (opArgs.op.type ===
|
|
889
|
-
opArgs.op.type ===
|
|
752
|
+
if (opArgs.op.type === MergeTreeDeltaType.REMOVE ||
|
|
753
|
+
opArgs.op.type === MergeTreeDeltaType.OBLITERATE) {
|
|
890
754
|
this.slideAckedRemovedSegmentReferences(pendingSegmentGroup.segments);
|
|
891
755
|
}
|
|
892
756
|
this.mergeTreeMaintenanceCallback?.({
|
|
893
757
|
deltaSegments,
|
|
894
|
-
operation:
|
|
758
|
+
operation: MergeTreeMaintenanceType.ACKNOWLEDGED,
|
|
895
759
|
}, opArgs);
|
|
896
760
|
const clientId = this.collabWindow.clientId;
|
|
897
761
|
for (const node of nodesToUpdate) {
|
|
@@ -899,7 +763,7 @@ class MergeTree {
|
|
|
899
763
|
}
|
|
900
764
|
}
|
|
901
765
|
if (MergeTree.options.zamboniSegments) {
|
|
902
|
-
|
|
766
|
+
zamboniSegments(this);
|
|
903
767
|
}
|
|
904
768
|
}
|
|
905
769
|
addToPendingList(segment,
|
|
@@ -962,19 +826,19 @@ class MergeTree {
|
|
|
962
826
|
}
|
|
963
827
|
insertSegments(pos, segments, refSeq, clientId, seq, opArgs) {
|
|
964
828
|
this.ensureIntervalBoundary(pos, refSeq, clientId);
|
|
965
|
-
const localSeq = seq ===
|
|
829
|
+
const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
966
830
|
this.blockInsert(pos, refSeq, clientId, seq, localSeq, segments);
|
|
967
831
|
// opArgs == undefined => loading snapshot or test code
|
|
968
832
|
if (opArgs !== undefined) {
|
|
969
833
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
970
|
-
operation:
|
|
834
|
+
operation: MergeTreeDeltaType.INSERT,
|
|
971
835
|
deltaSegments: segments.map((segment) => ({ segment })),
|
|
972
836
|
});
|
|
973
837
|
}
|
|
974
838
|
if (this.collabWindow.collaborating &&
|
|
975
839
|
MergeTree.options.zamboniSegments &&
|
|
976
|
-
seq !==
|
|
977
|
-
|
|
840
|
+
seq !== UnassignedSequenceNumber) {
|
|
841
|
+
zamboniSegments(this);
|
|
978
842
|
}
|
|
979
843
|
}
|
|
980
844
|
/**
|
|
@@ -1010,7 +874,7 @@ class MergeTree {
|
|
|
1010
874
|
blockInsert(pos, refSeq, clientId, seq, localSeq, newSegments) {
|
|
1011
875
|
const continueFrom = (node) => {
|
|
1012
876
|
let siblingExists = false;
|
|
1013
|
-
|
|
877
|
+
forwardExcursion(node, () => {
|
|
1014
878
|
siblingExists = true;
|
|
1015
879
|
return false;
|
|
1016
880
|
});
|
|
@@ -1021,7 +885,7 @@ class MergeTree {
|
|
|
1021
885
|
const saveIfLocal = (locSegment) => {
|
|
1022
886
|
// Save segment so we can assign sequence number when acked by server
|
|
1023
887
|
if (this.collabWindow.collaborating) {
|
|
1024
|
-
if (locSegment.seq ===
|
|
888
|
+
if (locSegment.seq === UnassignedSequenceNumber &&
|
|
1025
889
|
clientId === this.collabWindow.clientId) {
|
|
1026
890
|
segmentGroup = this.addToPendingList(locSegment, segmentGroup, localSeq);
|
|
1027
891
|
}
|
|
@@ -1053,7 +917,7 @@ class MergeTree {
|
|
|
1053
917
|
newSegment.seq = seq;
|
|
1054
918
|
newSegment.localSeq = localSeq;
|
|
1055
919
|
newSegment.clientId = clientId;
|
|
1056
|
-
if (
|
|
920
|
+
if (Marker.is(newSegment)) {
|
|
1057
921
|
const markerId = newSegment.getId();
|
|
1058
922
|
if (markerId) {
|
|
1059
923
|
this.idToMarker.set(markerId, newSegment);
|
|
@@ -1066,7 +930,7 @@ class MergeTree {
|
|
|
1066
930
|
});
|
|
1067
931
|
if (newSegment.parent === undefined) {
|
|
1068
932
|
// Indicates an attempt to insert past the end of the merge-tree's content.
|
|
1069
|
-
const errorConstructor = localSeq !== undefined ?
|
|
933
|
+
const errorConstructor = localSeq !== undefined ? UsageError : DataProcessingError;
|
|
1070
934
|
throw new errorConstructor("MergeTree insert failed", {
|
|
1071
935
|
currentSeq: this.collabWindow.currentSeq,
|
|
1072
936
|
minSeq: this.collabWindow.minSeq,
|
|
@@ -1117,7 +981,7 @@ class MergeTree {
|
|
|
1117
981
|
_movedSeq = movedSeq;
|
|
1118
982
|
const clientIdIdx = left.movedSeqs?.indexOf(movedSeq) ?? -1;
|
|
1119
983
|
const movedClientId = left.movedClientIds?.[clientIdIdx];
|
|
1120
|
-
|
|
984
|
+
assert(movedClientId !== undefined, 0x869 /* expected client id to exist */);
|
|
1121
985
|
movedClientIds = [movedClientId];
|
|
1122
986
|
return false;
|
|
1123
987
|
}
|
|
@@ -1126,9 +990,9 @@ class MergeTree {
|
|
|
1126
990
|
const left = leftLocalSegments[localMovedSeq];
|
|
1127
991
|
if (left) {
|
|
1128
992
|
_localMovedSeq = localMovedSeq;
|
|
1129
|
-
const clientIdIdx = left.movedSeqs?.indexOf(
|
|
993
|
+
const clientIdIdx = left.movedSeqs?.indexOf(UnassignedSequenceNumber) ?? -1;
|
|
1130
994
|
const movedClientId = left.movedClientIds?.[clientIdIdx];
|
|
1131
|
-
|
|
995
|
+
assert(movedClientId !== undefined, 0x86a /* expected client id to exist */);
|
|
1132
996
|
movedClientIds = [movedClientId];
|
|
1133
997
|
return false;
|
|
1134
998
|
}
|
|
@@ -1143,22 +1007,22 @@ class MergeTree {
|
|
|
1143
1007
|
// happened, no need to continue.
|
|
1144
1008
|
return moveUpperBound >= smallestSeqMoveOp;
|
|
1145
1009
|
};
|
|
1146
|
-
|
|
1010
|
+
backwardExcursion(newSegment, findLeftMovedSegment);
|
|
1147
1011
|
moveUpperBound = Number.POSITIVE_INFINITY;
|
|
1148
|
-
|
|
1012
|
+
forwardExcursion(newSegment, findRightMovedSegment);
|
|
1149
1013
|
if (_localMovedSeq !== undefined || _movedSeq !== undefined) {
|
|
1150
|
-
|
|
1014
|
+
assert(movedClientIds !== undefined, 0x86b /* movedClientIds should be set if local/moved seq is set */);
|
|
1151
1015
|
const moveInfo = {
|
|
1152
1016
|
movedClientIds,
|
|
1153
|
-
movedSeq: _movedSeq ??
|
|
1154
|
-
movedSeqs: _movedSeq === undefined ? [
|
|
1017
|
+
movedSeq: _movedSeq ?? UnassignedSequenceNumber,
|
|
1018
|
+
movedSeqs: _movedSeq === undefined ? [UnassignedSequenceNumber] : [_movedSeq],
|
|
1155
1019
|
localMovedSeq: _localMovedSeq,
|
|
1156
|
-
wasMovedOnInsert: (_movedSeq ?? -1) !==
|
|
1020
|
+
wasMovedOnInsert: (_movedSeq ?? -1) !== UnassignedSequenceNumber,
|
|
1157
1021
|
};
|
|
1158
1022
|
markSegmentMoved(newSegment, moveInfo);
|
|
1159
1023
|
if (moveInfo.localMovedSeq !== undefined) {
|
|
1160
1024
|
const movedSegmentGroup = this.locallyMovedSegments.get(moveInfo.localMovedSeq);
|
|
1161
|
-
|
|
1025
|
+
assert(movedSegmentGroup !== undefined, 0x86c /* expected segment group to exist */);
|
|
1162
1026
|
this.addToPendingList(newSegment, movedSegmentGroup, localSeq);
|
|
1163
1027
|
}
|
|
1164
1028
|
if (newSegment.parent) {
|
|
@@ -1169,7 +1033,7 @@ class MergeTree {
|
|
|
1169
1033
|
}
|
|
1170
1034
|
}
|
|
1171
1035
|
ensureIntervalBoundary(pos, refSeq, clientId) {
|
|
1172
|
-
const splitNode = this.insertingWalk(this.root, pos, refSeq, clientId,
|
|
1036
|
+
const splitNode = this.insertingWalk(this.root, pos, refSeq, clientId, TreeMaintenanceSequenceNumber, { leaf: this.splitLeafSegment });
|
|
1173
1037
|
this.updateRoot(splitNode);
|
|
1174
1038
|
}
|
|
1175
1039
|
// Assume called only when pos == len
|
|
@@ -1183,14 +1047,14 @@ class MergeTree {
|
|
|
1183
1047
|
// seq for comparison, as it will get a seq higher than any other seq once sequences
|
|
1184
1048
|
// if the current seg is local (UnassignedSequenceNumber) give it the second highest
|
|
1185
1049
|
// possible seq, as the highest is reserved for the previous.
|
|
1186
|
-
const newSeq = seq ===
|
|
1187
|
-
const segSeq = node.seq ===
|
|
1050
|
+
const newSeq = seq === UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER : seq;
|
|
1051
|
+
const segSeq = node.seq === UnassignedSequenceNumber ? Number.MAX_SAFE_INTEGER - 1 : node.seq ?? 0;
|
|
1188
1052
|
return (newSeq > segSeq ||
|
|
1189
1053
|
(node.movedSeq !== undefined &&
|
|
1190
|
-
node.movedSeq !==
|
|
1054
|
+
node.movedSeq !== UnassignedSequenceNumber &&
|
|
1191
1055
|
node.movedSeq > seq) ||
|
|
1192
1056
|
(node.removedSeq !== undefined &&
|
|
1193
|
-
node.removedSeq !==
|
|
1057
|
+
node.removedSeq !== UnassignedSequenceNumber &&
|
|
1194
1058
|
node.removedSeq > seq));
|
|
1195
1059
|
}
|
|
1196
1060
|
else {
|
|
@@ -1217,7 +1081,7 @@ class MergeTree {
|
|
|
1217
1081
|
// will be removed, so should just be skipped for now
|
|
1218
1082
|
continue;
|
|
1219
1083
|
}
|
|
1220
|
-
|
|
1084
|
+
assert(len >= 0, 0x4bc /* Length should not be negative */);
|
|
1221
1085
|
if (_pos < len || (_pos === len && this.breakTie(_pos, child, seq))) {
|
|
1222
1086
|
// Found entry containing pos
|
|
1223
1087
|
if (!child.isLeaf()) {
|
|
@@ -1280,7 +1144,7 @@ class MergeTree {
|
|
|
1280
1144
|
block.assignChild(newNode, childIndex, false);
|
|
1281
1145
|
block.childCount++;
|
|
1282
1146
|
block.setOrdinal(newNode, childIndex);
|
|
1283
|
-
if (block.childCount <
|
|
1147
|
+
if (block.childCount < MaxNodesInBlock) {
|
|
1284
1148
|
if (fromSplit) {
|
|
1285
1149
|
this.nodeUpdateOrdinals(fromSplit);
|
|
1286
1150
|
}
|
|
@@ -1290,8 +1154,8 @@ class MergeTree {
|
|
|
1290
1154
|
else {
|
|
1291
1155
|
// Don't update ordinals because higher block will do it
|
|
1292
1156
|
const newNodeFromSplit = this.split(block);
|
|
1293
|
-
|
|
1294
|
-
|
|
1157
|
+
PartialSequenceLengths.options.verifyExpected?.(this, block, refSeq, clientId);
|
|
1158
|
+
PartialSequenceLengths.options.verifyExpected?.(this, newNodeFromSplit, refSeq, clientId);
|
|
1295
1159
|
return newNodeFromSplit;
|
|
1296
1160
|
}
|
|
1297
1161
|
}
|
|
@@ -1300,7 +1164,7 @@ class MergeTree {
|
|
|
1300
1164
|
}
|
|
1301
1165
|
}
|
|
1302
1166
|
split(node) {
|
|
1303
|
-
const halfCount =
|
|
1167
|
+
const halfCount = MaxNodesInBlock / 2;
|
|
1304
1168
|
const newNode = this.makeBlock(halfCount);
|
|
1305
1169
|
node.childCount = halfCount;
|
|
1306
1170
|
// Update ordinals to reflect lowered child count
|
|
@@ -1333,21 +1197,21 @@ class MergeTree {
|
|
|
1333
1197
|
* @param opArgs - The op args for the annotate op. this is passed to the merge tree callback if there is one
|
|
1334
1198
|
* @param rollback - Whether this is for a local rollback and what kind
|
|
1335
1199
|
*/
|
|
1336
|
-
annotateRange(start, end, props, refSeq, clientId, seq, opArgs, rollback =
|
|
1200
|
+
annotateRange(start, end, props, refSeq, clientId, seq, opArgs, rollback = PropertiesRollback.None) {
|
|
1337
1201
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1338
1202
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1339
1203
|
const deltaSegments = [];
|
|
1340
|
-
const localSeq = seq ===
|
|
1204
|
+
const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1341
1205
|
// eslint-disable-next-line import/no-deprecated
|
|
1342
1206
|
let segmentGroup;
|
|
1343
1207
|
const annotateSegment = (segment) => {
|
|
1344
|
-
|
|
1345
|
-
!(
|
|
1208
|
+
assert(!Marker.is(segment) ||
|
|
1209
|
+
!(reservedMarkerIdKey in props) ||
|
|
1346
1210
|
props.markerId === segment.properties?.markerId, 0x5ad /* Cannot change the markerId of an existing marker */);
|
|
1347
1211
|
const propertyDeltas = segment.addProperties(props, seq, this.collabWindow.collaborating, rollback);
|
|
1348
1212
|
deltaSegments.push({ segment, propertyDeltas });
|
|
1349
1213
|
if (this.collabWindow.collaborating) {
|
|
1350
|
-
if (seq ===
|
|
1214
|
+
if (seq === UnassignedSequenceNumber) {
|
|
1351
1215
|
segmentGroup = this.addToPendingList(segment, segmentGroup, localSeq, propertyDeltas);
|
|
1352
1216
|
}
|
|
1353
1217
|
else {
|
|
@@ -1362,13 +1226,13 @@ class MergeTree {
|
|
|
1362
1226
|
// OpArgs == undefined => test code
|
|
1363
1227
|
if (deltaSegments.length > 0) {
|
|
1364
1228
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1365
|
-
operation:
|
|
1229
|
+
operation: MergeTreeDeltaType.ANNOTATE,
|
|
1366
1230
|
deltaSegments,
|
|
1367
1231
|
});
|
|
1368
1232
|
}
|
|
1369
|
-
if (this.collabWindow.collaborating && seq !==
|
|
1233
|
+
if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
|
|
1370
1234
|
if (MergeTree.options.zamboniSegments) {
|
|
1371
|
-
|
|
1235
|
+
zamboniSegments(this);
|
|
1372
1236
|
}
|
|
1373
1237
|
}
|
|
1374
1238
|
}
|
|
@@ -1377,33 +1241,33 @@ class MergeTree {
|
|
|
1377
1241
|
*/
|
|
1378
1242
|
obliterateRange(start, end, refSeq, clientId, seq, overwrite = false, opArgs) {
|
|
1379
1243
|
if (!this.options?.mergeTreeEnableObliterate) {
|
|
1380
|
-
throw new
|
|
1244
|
+
throw new UsageError("Attempted to send obliterate op without enabling feature flag.");
|
|
1381
1245
|
}
|
|
1382
1246
|
this.ensureIntervalBoundary(start, refSeq, clientId);
|
|
1383
1247
|
this.ensureIntervalBoundary(end, refSeq, clientId);
|
|
1384
1248
|
let _overwrite = overwrite;
|
|
1385
1249
|
const localOverlapWithRefs = [];
|
|
1386
1250
|
const movedSegments = [];
|
|
1387
|
-
const localSeq = seq ===
|
|
1388
|
-
if (seq !==
|
|
1251
|
+
const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1252
|
+
if (seq !== UnassignedSequenceNumber && seq !== this.moveSeqs[this.moveSeqs.length - 1]) {
|
|
1389
1253
|
this.moveSeqs.push(seq);
|
|
1390
1254
|
}
|
|
1391
|
-
else if (seq ===
|
|
1255
|
+
else if (seq === UnassignedSequenceNumber && localSeq !== undefined) {
|
|
1392
1256
|
this.localMoveSeqs.add(localSeq);
|
|
1393
1257
|
}
|
|
1394
1258
|
// eslint-disable-next-line import/no-deprecated
|
|
1395
1259
|
let segmentGroup;
|
|
1396
1260
|
const markMoved = (segment, pos, _start, _end) => {
|
|
1397
|
-
const existingMoveInfo =
|
|
1261
|
+
const existingMoveInfo = toMoveInfo(segment);
|
|
1398
1262
|
if (clientId !== segment.clientId &&
|
|
1399
1263
|
segment.seq !== undefined &&
|
|
1400
|
-
seq !==
|
|
1401
|
-
(refSeq < segment.seq || segment.seq ===
|
|
1264
|
+
seq !== UnassignedSequenceNumber &&
|
|
1265
|
+
(refSeq < segment.seq || segment.seq === UnassignedSequenceNumber)) {
|
|
1402
1266
|
segment.wasMovedOnInsert = true;
|
|
1403
1267
|
}
|
|
1404
1268
|
if (existingMoveInfo !== undefined) {
|
|
1405
1269
|
_overwrite = true;
|
|
1406
|
-
if (existingMoveInfo.movedSeq ===
|
|
1270
|
+
if (existingMoveInfo.movedSeq === UnassignedSequenceNumber) {
|
|
1407
1271
|
// we moved this locally, but someone else moved it first
|
|
1408
1272
|
// so put them at the head of the list
|
|
1409
1273
|
// The list isn't ordered, but we keep the first move at the head
|
|
@@ -1430,7 +1294,7 @@ class MergeTree {
|
|
|
1430
1294
|
}
|
|
1431
1295
|
// Save segment so can assign moved sequence number when acked by server
|
|
1432
1296
|
if (this.collabWindow.collaborating) {
|
|
1433
|
-
if (segment.movedSeq ===
|
|
1297
|
+
if (segment.movedSeq === UnassignedSequenceNumber &&
|
|
1434
1298
|
clientId === this.collabWindow.clientId) {
|
|
1435
1299
|
segmentGroup = this.addToPendingList(segment, segmentGroup, localSeq);
|
|
1436
1300
|
}
|
|
@@ -1451,12 +1315,12 @@ class MergeTree {
|
|
|
1451
1315
|
}
|
|
1452
1316
|
return true;
|
|
1453
1317
|
};
|
|
1454
|
-
this.nodeMap(refSeq, clientId, markMoved, undefined, afterMarkMoved, start, end, undefined, seq !==
|
|
1318
|
+
this.nodeMap(refSeq, clientId, markMoved, undefined, afterMarkMoved, start, end, undefined, seq !== UnassignedSequenceNumber ? seq : undefined);
|
|
1455
1319
|
this.slideAckedRemovedSegmentReferences(localOverlapWithRefs);
|
|
1456
1320
|
// opArgs == undefined => test code
|
|
1457
1321
|
if (movedSegments.length > 0) {
|
|
1458
1322
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1459
|
-
operation:
|
|
1323
|
+
operation: MergeTreeDeltaType.OBLITERATE,
|
|
1460
1324
|
deltaSegments: movedSegments,
|
|
1461
1325
|
});
|
|
1462
1326
|
}
|
|
@@ -1469,9 +1333,9 @@ class MergeTree {
|
|
|
1469
1333
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1470
1334
|
this.slideAckedRemovedSegmentReferences(movedSegments.map(({ segment }) => segment));
|
|
1471
1335
|
}
|
|
1472
|
-
if (this.collabWindow.collaborating && seq !==
|
|
1336
|
+
if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
|
|
1473
1337
|
if (MergeTree.options.zamboniSegments) {
|
|
1474
|
-
|
|
1338
|
+
zamboniSegments(this);
|
|
1475
1339
|
}
|
|
1476
1340
|
}
|
|
1477
1341
|
}
|
|
@@ -1483,12 +1347,12 @@ class MergeTree {
|
|
|
1483
1347
|
let segmentGroup;
|
|
1484
1348
|
const removedSegments = [];
|
|
1485
1349
|
const localOverlapWithRefs = [];
|
|
1486
|
-
const localSeq = seq ===
|
|
1350
|
+
const localSeq = seq === UnassignedSequenceNumber ? ++this.collabWindow.localSeq : undefined;
|
|
1487
1351
|
const markRemoved = (segment, pos, _start, _end) => {
|
|
1488
|
-
const existingRemovalInfo =
|
|
1352
|
+
const existingRemovalInfo = toRemovalInfo(segment);
|
|
1489
1353
|
if (existingRemovalInfo !== undefined) {
|
|
1490
1354
|
_overwrite = true;
|
|
1491
|
-
if (existingRemovalInfo.removedSeq ===
|
|
1355
|
+
if (existingRemovalInfo.removedSeq === UnassignedSequenceNumber) {
|
|
1492
1356
|
// we removed this locally, but someone else removed it first
|
|
1493
1357
|
// so put them at the head of the list
|
|
1494
1358
|
// The list isn't ordered, but we keep the first removal at the head
|
|
@@ -1512,7 +1376,7 @@ class MergeTree {
|
|
|
1512
1376
|
}
|
|
1513
1377
|
// Save segment so we can assign removed sequence number when acked by server
|
|
1514
1378
|
if (this.collabWindow.collaborating) {
|
|
1515
|
-
if (segment.removedSeq ===
|
|
1379
|
+
if (segment.removedSeq === UnassignedSequenceNumber &&
|
|
1516
1380
|
clientId === this.collabWindow.clientId) {
|
|
1517
1381
|
segmentGroup = this.addToPendingList(segment, segmentGroup, localSeq);
|
|
1518
1382
|
}
|
|
@@ -1540,7 +1404,7 @@ class MergeTree {
|
|
|
1540
1404
|
// opArgs == undefined => test code
|
|
1541
1405
|
if (removedSegments.length > 0) {
|
|
1542
1406
|
this.mergeTreeDeltaCallback?.(opArgs, {
|
|
1543
|
-
operation:
|
|
1407
|
+
operation: MergeTreeDeltaType.REMOVE,
|
|
1544
1408
|
deltaSegments: removedSegments,
|
|
1545
1409
|
});
|
|
1546
1410
|
}
|
|
@@ -1550,9 +1414,9 @@ class MergeTree {
|
|
|
1550
1414
|
if (!this.collabWindow.collaborating || clientId !== this.collabWindow.clientId) {
|
|
1551
1415
|
this.slideAckedRemovedSegmentReferences(removedSegments.map(({ segment }) => segment));
|
|
1552
1416
|
}
|
|
1553
|
-
if (this.collabWindow.collaborating && seq !==
|
|
1417
|
+
if (this.collabWindow.collaborating && seq !== UnassignedSequenceNumber) {
|
|
1554
1418
|
if (MergeTree.options.zamboniSegments) {
|
|
1555
|
-
|
|
1419
|
+
zamboniSegments(this);
|
|
1556
1420
|
}
|
|
1557
1421
|
}
|
|
1558
1422
|
}
|
|
@@ -1561,53 +1425,53 @@ class MergeTree {
|
|
|
1561
1425
|
*/
|
|
1562
1426
|
// eslint-disable-next-line import/no-deprecated
|
|
1563
1427
|
rollback(op, localOpMetadata) {
|
|
1564
|
-
if (op.type ===
|
|
1428
|
+
if (op.type === MergeTreeDeltaType.REMOVE) {
|
|
1565
1429
|
const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
|
|
1566
1430
|
if (pendingSegmentGroup === undefined || pendingSegmentGroup !== localOpMetadata) {
|
|
1567
1431
|
throw new Error("Rollback op doesn't match last edit");
|
|
1568
1432
|
}
|
|
1569
1433
|
pendingSegmentGroup.segments.forEach((segment) => {
|
|
1570
1434
|
const segmentSegmentGroup = segment.segmentGroups?.pop?.();
|
|
1571
|
-
|
|
1572
|
-
|
|
1435
|
+
assert(segmentSegmentGroup === pendingSegmentGroup, 0x3ee /* Unexpected segmentGroup in segment */);
|
|
1436
|
+
assert(segment.removedClientIds !== undefined &&
|
|
1573
1437
|
segment.removedClientIds[0] === this.collabWindow.clientId, 0x39d /* Rollback segment removedClientId does not match local client */);
|
|
1574
1438
|
segment.removedClientIds = undefined;
|
|
1575
1439
|
segment.removedSeq = undefined;
|
|
1576
1440
|
segment.localRemovedSeq = undefined;
|
|
1577
1441
|
// Note: optional chaining short-circuits:
|
|
1578
1442
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#short-circuiting
|
|
1579
|
-
this.mergeTreeDeltaCallback?.({ op:
|
|
1580
|
-
operation:
|
|
1443
|
+
this.mergeTreeDeltaCallback?.({ op: createInsertSegmentOp(this.findRollbackPosition(segment), segment) }, {
|
|
1444
|
+
operation: MergeTreeDeltaType.INSERT,
|
|
1581
1445
|
deltaSegments: [{ segment }],
|
|
1582
1446
|
});
|
|
1583
1447
|
for (let updateNode = segment.parent; updateNode !== undefined; updateNode = updateNode.parent) {
|
|
1584
|
-
this.blockUpdateLength(updateNode,
|
|
1448
|
+
this.blockUpdateLength(updateNode, UnassignedSequenceNumber, this.collabWindow.clientId);
|
|
1585
1449
|
}
|
|
1586
1450
|
});
|
|
1587
1451
|
}
|
|
1588
|
-
else if (op.type ===
|
|
1589
|
-
op.type ===
|
|
1452
|
+
else if (op.type === MergeTreeDeltaType.INSERT ||
|
|
1453
|
+
op.type === MergeTreeDeltaType.ANNOTATE) {
|
|
1590
1454
|
const pendingSegmentGroup = this.pendingSegments.pop?.()?.data;
|
|
1591
1455
|
if (pendingSegmentGroup === undefined ||
|
|
1592
1456
|
pendingSegmentGroup !== localOpMetadata ||
|
|
1593
|
-
(op.type ===
|
|
1457
|
+
(op.type === MergeTreeDeltaType.ANNOTATE && !pendingSegmentGroup.previousProps)) {
|
|
1594
1458
|
throw new Error("Rollback op doesn't match last edit");
|
|
1595
1459
|
}
|
|
1596
1460
|
let i = 0;
|
|
1597
1461
|
for (const segment of pendingSegmentGroup.segments) {
|
|
1598
1462
|
const segmentSegmentGroup = segment.segmentGroups.pop?.();
|
|
1599
|
-
|
|
1463
|
+
assert(segmentSegmentGroup === pendingSegmentGroup, 0x3ef /* Unexpected segmentGroup in segment */);
|
|
1600
1464
|
const start = this.findRollbackPosition(segment);
|
|
1601
|
-
if (op.type ===
|
|
1602
|
-
segment.seq =
|
|
1465
|
+
if (op.type === MergeTreeDeltaType.INSERT) {
|
|
1466
|
+
segment.seq = UniversalSequenceNumber;
|
|
1603
1467
|
segment.localSeq = undefined;
|
|
1604
|
-
const removeOp =
|
|
1605
|
-
this.markRangeRemoved(start, start + segment.cachedLength,
|
|
1468
|
+
const removeOp = createRemoveRangeOp(start, start + segment.cachedLength);
|
|
1469
|
+
this.markRangeRemoved(start, start + segment.cachedLength, UniversalSequenceNumber, this.collabWindow.clientId, UniversalSequenceNumber, false, { op: removeOp });
|
|
1606
1470
|
} /* op.type === MergeTreeDeltaType.ANNOTATE */
|
|
1607
1471
|
else {
|
|
1608
1472
|
const props = pendingSegmentGroup.previousProps[i];
|
|
1609
|
-
const annotateOp =
|
|
1610
|
-
this.annotateRange(start, start + segment.cachedLength, props,
|
|
1473
|
+
const annotateOp = createAnnotateRangeOp(start, start + segment.cachedLength, props);
|
|
1474
|
+
this.annotateRange(start, start + segment.cachedLength, props, UniversalSequenceNumber, this.collabWindow.clientId, UniversalSequenceNumber, { op: annotateOp }, PropertiesRollback.Rollback);
|
|
1611
1475
|
i++;
|
|
1612
1476
|
}
|
|
1613
1477
|
}
|
|
@@ -1621,7 +1485,7 @@ class MergeTree {
|
|
|
1621
1485
|
*/
|
|
1622
1486
|
findRollbackPosition(segment) {
|
|
1623
1487
|
let segmentPosition = 0;
|
|
1624
|
-
|
|
1488
|
+
walkAllChildSegments(this.root, (seg) => {
|
|
1625
1489
|
// If we've found the desired segment, terminate the walk and return 'segmentPosition'.
|
|
1626
1490
|
if (seg === segment) {
|
|
1627
1491
|
return false;
|
|
@@ -1638,7 +1502,7 @@ class MergeTree {
|
|
|
1638
1502
|
this.blockUpdate(node);
|
|
1639
1503
|
if (this.collabWindow.collaborating) {
|
|
1640
1504
|
this.localPartialsComputed = false;
|
|
1641
|
-
node.partialLengths =
|
|
1505
|
+
node.partialLengths = PartialSequenceLengths.combine(node, this.collabWindow, recur);
|
|
1642
1506
|
}
|
|
1643
1507
|
}
|
|
1644
1508
|
removeLocalReferencePosition(lref) {
|
|
@@ -1649,9 +1513,9 @@ class MergeTree {
|
|
|
1649
1513
|
if (_segment !== "start" &&
|
|
1650
1514
|
_segment !== "end" &&
|
|
1651
1515
|
isRemovedAndAckedOrMovedAndAcked(_segment) &&
|
|
1652
|
-
!
|
|
1516
|
+
!refTypeIncludesFlag(refType, ReferenceType.SlideOnRemove | ReferenceType.Transient) &&
|
|
1653
1517
|
_segment.endpointType === undefined) {
|
|
1654
|
-
throw new
|
|
1518
|
+
throw new UsageError("Can only create SlideOnRemove or Transient local reference position on a removed or obliterated segment");
|
|
1655
1519
|
}
|
|
1656
1520
|
let segment;
|
|
1657
1521
|
if (_segment === "start") {
|
|
@@ -1663,7 +1527,7 @@ class MergeTree {
|
|
|
1663
1527
|
else {
|
|
1664
1528
|
segment = _segment;
|
|
1665
1529
|
}
|
|
1666
|
-
const localRefs = segment.localRefs ?? new
|
|
1530
|
+
const localRefs = segment.localRefs ?? new LocalReferenceCollection(segment);
|
|
1667
1531
|
segment.localRefs = localRefs;
|
|
1668
1532
|
const segRef = localRefs.createLocalRef(offset, refType, properties, slidingPreference, canSlideToEndpoint);
|
|
1669
1533
|
return segRef;
|
|
@@ -1692,7 +1556,7 @@ class MergeTree {
|
|
|
1692
1556
|
affectedSegments.insertAfter(lastLocalSegment, segmentToSlide.data);
|
|
1693
1557
|
}
|
|
1694
1558
|
else if (isRemoved(segmentToSlide.data)) {
|
|
1695
|
-
|
|
1559
|
+
assert(segmentToSlide.data.localRemovedSeq !== undefined, 0x54d /* Removed segment that hasnt had its removal acked should be locally removed */);
|
|
1696
1560
|
// Slide each locally removed item past all segments that have localSeq > lremoveItem.localSeq
|
|
1697
1561
|
// but not past remotely removed segments;
|
|
1698
1562
|
let cur = segmentToSlide;
|
|
@@ -1770,7 +1634,7 @@ class MergeTree {
|
|
|
1770
1634
|
* it can fix up its local state to align with what would be expected of the op it resubmits.
|
|
1771
1635
|
*/
|
|
1772
1636
|
normalizeSegmentsOnRebase() {
|
|
1773
|
-
let currentRangeToNormalize = new
|
|
1637
|
+
let currentRangeToNormalize = new DoublyLinkedList();
|
|
1774
1638
|
let rangeContainsLocalSegs = false;
|
|
1775
1639
|
let rangeContainsRemoteRemovedSegs = false;
|
|
1776
1640
|
const normalize = () => {
|
|
@@ -1780,19 +1644,19 @@ class MergeTree {
|
|
|
1780
1644
|
this.normalizeAdjacentSegments(currentRangeToNormalize);
|
|
1781
1645
|
}
|
|
1782
1646
|
};
|
|
1783
|
-
|
|
1784
|
-
if (isRemoved(seg) || seg.seq ===
|
|
1647
|
+
walkAllChildSegments(this.root, (seg) => {
|
|
1648
|
+
if (isRemoved(seg) || seg.seq === UnassignedSequenceNumber) {
|
|
1785
1649
|
if (isRemovedAndAcked(seg)) {
|
|
1786
1650
|
rangeContainsRemoteRemovedSegs = true;
|
|
1787
1651
|
}
|
|
1788
|
-
if (seg.seq ===
|
|
1652
|
+
if (seg.seq === UnassignedSequenceNumber) {
|
|
1789
1653
|
rangeContainsLocalSegs = true;
|
|
1790
1654
|
}
|
|
1791
1655
|
currentRangeToNormalize.push(seg);
|
|
1792
1656
|
}
|
|
1793
1657
|
else {
|
|
1794
1658
|
normalize();
|
|
1795
|
-
currentRangeToNormalize = new
|
|
1659
|
+
currentRangeToNormalize = new DoublyLinkedList();
|
|
1796
1660
|
rangeContainsLocalSegs = false;
|
|
1797
1661
|
rangeContainsRemoteRemovedSegs = false;
|
|
1798
1662
|
}
|
|
@@ -1803,14 +1667,14 @@ class MergeTree {
|
|
|
1803
1667
|
addNodeReferences(node, rightmostTiles, leftmostTiles) {
|
|
1804
1668
|
if (node.isLeaf()) {
|
|
1805
1669
|
const segment = node;
|
|
1806
|
-
if ((this.localNetLength(segment) ?? 0) > 0 &&
|
|
1670
|
+
if ((this.localNetLength(segment) ?? 0) > 0 && Marker.is(segment)) {
|
|
1807
1671
|
const markerId = segment.getId();
|
|
1808
1672
|
// Also in insertMarker but need for reload segs case
|
|
1809
1673
|
// can add option for this only from reload segs
|
|
1810
1674
|
if (markerId) {
|
|
1811
1675
|
this.idToMarker.set(markerId, segment);
|
|
1812
1676
|
}
|
|
1813
|
-
if (
|
|
1677
|
+
if (refTypeIncludesFlag(segment, ReferenceType.Tile)) {
|
|
1814
1678
|
addTile(segment, rightmostTiles);
|
|
1815
1679
|
addTileIfNotPresent(segment, leftmostTiles);
|
|
1816
1680
|
}
|
|
@@ -1819,9 +1683,9 @@ class MergeTree {
|
|
|
1819
1683
|
else {
|
|
1820
1684
|
const block = node;
|
|
1821
1685
|
// eslint-disable-next-line import/no-deprecated
|
|
1822
|
-
|
|
1686
|
+
extend(rightmostTiles, block.rightmostTiles);
|
|
1823
1687
|
// eslint-disable-next-line import/no-deprecated
|
|
1824
|
-
|
|
1688
|
+
extendIfUndefined(leftmostTiles, block.leftmostTiles);
|
|
1825
1689
|
}
|
|
1826
1690
|
}
|
|
1827
1691
|
blockUpdate(block) {
|
|
@@ -1829,9 +1693,9 @@ class MergeTree {
|
|
|
1829
1693
|
const hierBlock = block.hierBlock();
|
|
1830
1694
|
if (hierBlock) {
|
|
1831
1695
|
// eslint-disable-next-line import/no-deprecated
|
|
1832
|
-
hierBlock.rightmostTiles =
|
|
1696
|
+
hierBlock.rightmostTiles = createMap();
|
|
1833
1697
|
// eslint-disable-next-line import/no-deprecated
|
|
1834
|
-
hierBlock.leftmostTiles =
|
|
1698
|
+
hierBlock.leftmostTiles = createMap();
|
|
1835
1699
|
}
|
|
1836
1700
|
for (let i = 0; i < block.childCount; i++) {
|
|
1837
1701
|
const child = block.children[i];
|
|
@@ -1862,17 +1726,17 @@ class MergeTree {
|
|
|
1862
1726
|
this.blockUpdate(node);
|
|
1863
1727
|
this.localPartialsComputed = false;
|
|
1864
1728
|
if (this.collabWindow.collaborating &&
|
|
1865
|
-
seq !==
|
|
1866
|
-
seq !==
|
|
1729
|
+
seq !== UnassignedSequenceNumber &&
|
|
1730
|
+
seq !== TreeMaintenanceSequenceNumber) {
|
|
1867
1731
|
if (node.partialLengths !== undefined &&
|
|
1868
1732
|
MergeTree.options.incrementalUpdate &&
|
|
1869
|
-
clientId !==
|
|
1733
|
+
clientId !== NonCollabClient) {
|
|
1870
1734
|
node.partialLengths.update(node, seq, clientId, this.collabWindow);
|
|
1871
1735
|
}
|
|
1872
1736
|
else {
|
|
1873
|
-
node.partialLengths =
|
|
1737
|
+
node.partialLengths = PartialSequenceLengths.combine(node, this.collabWindow);
|
|
1874
1738
|
}
|
|
1875
|
-
|
|
1739
|
+
PartialSequenceLengths.options.verifyExpected?.(this, node, seq, clientId);
|
|
1876
1740
|
}
|
|
1877
1741
|
}
|
|
1878
1742
|
/**
|
|
@@ -1922,30 +1786,30 @@ class MergeTree {
|
|
|
1922
1786
|
return;
|
|
1923
1787
|
}
|
|
1924
1788
|
let pos = 0;
|
|
1925
|
-
|
|
1789
|
+
depthFirstNodeWalk(this.root, this.root.children[0], (node) => {
|
|
1926
1790
|
if (endPos <= pos) {
|
|
1927
|
-
return
|
|
1791
|
+
return NodeAction.Exit;
|
|
1928
1792
|
}
|
|
1929
1793
|
const len = this.nodeLength(node, visibilitySeq, clientId, localSeq);
|
|
1930
1794
|
const lenAtRefSeq = (visibilitySeq === refSeq
|
|
1931
1795
|
? len
|
|
1932
1796
|
: this.nodeLength(node, refSeq, clientId, localSeq)) ?? 0;
|
|
1933
1797
|
const isUnackedAndInObliterate = visibilitySeq !== refSeq &&
|
|
1934
|
-
(!node.isLeaf() || node.seq ===
|
|
1798
|
+
(!node.isLeaf() || node.seq === UnassignedSequenceNumber);
|
|
1935
1799
|
if ((len === undefined && lenAtRefSeq === 0) ||
|
|
1936
1800
|
(len === 0 && !isUnackedAndInObliterate && lenAtRefSeq === 0)) {
|
|
1937
|
-
return
|
|
1801
|
+
return NodeAction.Skip;
|
|
1938
1802
|
}
|
|
1939
1803
|
const nextPos = pos + lenAtRefSeq;
|
|
1940
1804
|
// start is beyond the current node, so we can skip it
|
|
1941
1805
|
if (start >= nextPos) {
|
|
1942
1806
|
pos = nextPos;
|
|
1943
|
-
return
|
|
1807
|
+
return NodeAction.Skip;
|
|
1944
1808
|
}
|
|
1945
1809
|
if (node.isLeaf()) {
|
|
1946
1810
|
if (leaf(node, pos, refSeq, clientId, start - pos, endPos - pos, accum) ===
|
|
1947
1811
|
false) {
|
|
1948
|
-
return
|
|
1812
|
+
return NodeAction.Exit;
|
|
1949
1813
|
}
|
|
1950
1814
|
pos = nextPos;
|
|
1951
1815
|
}
|
|
@@ -1954,11 +1818,10 @@ class MergeTree {
|
|
|
1954
1818
|
: (block) => post(block, pos, refSeq, clientId, start - pos, endPos - pos, accum));
|
|
1955
1819
|
}
|
|
1956
1820
|
}
|
|
1957
|
-
exports.MergeTree = MergeTree;
|
|
1958
1821
|
MergeTree.options = {
|
|
1959
1822
|
incrementalUpdate: true,
|
|
1960
1823
|
insertAfterRemovedSegs: true,
|
|
1961
1824
|
zamboniSegments: true,
|
|
1962
1825
|
};
|
|
1963
1826
|
MergeTree.theUnfinishedNode = { childCount: -1 };
|
|
1964
|
-
//# sourceMappingURL=mergeTree.
|
|
1827
|
+
//# sourceMappingURL=mergeTree.mjs.map
|