@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.localReference.spec.js","sourceRoot":"","sources":["../../src/test/client.localReference.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { Client } from \"../client.js\";\nimport {\n\tLocalReferencePosition,\n\tSlidingPreference,\n\tsetValidateRefCount,\n} from \"../localReference.js\";\nimport { getSlideToSegoff } from \"../mergeTree.js\";\nimport { toRemovalInfo } from \"../mergeTreeNodes.js\";\nimport { TrackingGroup, UnorderedTrackingGroup } from \"../mergeTreeTracking.js\";\nimport { MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { DetachedReferencePosition } from \"../referencePositions.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { createClientsAtInitialState } from \"./testClientLogger.js\";\nimport { validateRefCount } from \"./testUtils.js\";\n\nfunction getSlideOnRemoveReferencePosition(\n\tclient: Client,\n\tpos: number,\n\top: ISequencedDocumentMessage,\n) {\n\tlet segoff = client.getContainingSegment(pos, {\n\t\treferenceSequenceNumber: op.referenceSequenceNumber,\n\t\tclientId: op.clientId,\n\t});\n\tsegoff = getSlideToSegoff(segoff);\n\treturn segoff;\n}\n\ndescribe(\"MergeTree.Client\", () => {\n\tbeforeEach(() => {\n\t\tsetValidateRefCount(validateRefCount);\n\t});\n\n\tafterEach(() => {\n\t\tsetValidateRefCount(undefined);\n\t});\n\n\tit(\"Remove segment of non-sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.Simple,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2, \"create position\");\n\n\t\tconst remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\t// this only works because zamboni hasn't run yet\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t\t\"after remove\",\n\t\t);\n\n\t\t// this will force Zamboni to run\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t\t\"after zamboni\",\n\t\t);\n\t});\n\n\tit(\"Remove segment of sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\t});\n\n\tit(\"Remove segments to end with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(2, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tclient2.getLength() - 1,\n\t\t);\n\t});\n\n\tit(\"Remove segments from end with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tlet seq = 0;\n\t\tconst insert = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(insert);\n\n\t\tconst segInfo = client1.getContainingSegment(3);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 3, \"ref created\");\n\n\t\tconst remove1 = client1.makeOpMessage(client1.removeRangeLocal(3, 4), ++seq);\n\t\tremove1.minimumSequenceNumber = seq - 1;\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 3, \"after remove\");\n\n\t\tconst remove2 = client1.makeOpMessage(client1.removeRangeLocal(1, 3), ++seq);\n\t\tremove2.minimumSequenceNumber = seq - 1;\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\t1,\n\t\t\t\"after second remove\",\n\t\t);\n\n\t\tclient1.applyMsg(remove1);\n\t\tclient1.applyMsg(remove2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 0, \"ops applied\");\n\t});\n\n\tit(\"getSlideOnRemoveReferencePosition\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"XYZ\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABC\"), ++seq);\n\t\tclient1.applyMsg(insert2);\n\n\t\t// Position depends on op\n\t\tconst createReference1 = client2.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert1.sequenceNumber,\n\t\t);\n\t\tlet segoff = getSlideOnRemoveReferencePosition(client1, 1, createReference1);\n\t\tassert(segoff.segment);\n\t\tassert.equal(client1.getPosition(segoff.segment), 3);\n\t\tassert.equal(segoff.offset, 1);\n\n\t\tconst createReference2 = client2.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert2.sequenceNumber,\n\t\t);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 2, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(client1.getPosition(segoff.segment), 0);\n\t\tassert.equal(segoff.offset, 2);\n\n\t\t// On a removed, unacked segment\n\t\tlet remove = client1.makeOpMessage(client1.removeRangeLocal(2, 5), ++seq);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.notEqual(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// Slid from a removed, acked segment\n\t\tclient1.applyMsg(remove);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// On a removed, unacked segment, end of string\n\t\tremove = client1.makeOpMessage(client1.removeRangeLocal(2, 3), ++seq);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.notEqual(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// Slid from a removed, acked segment, end of string\n\t\tclient1.applyMsg(remove);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 0);\n\t\tassert.equal(segoff.offset, 1);\n\t});\n\n\tit(\"Remove all segments with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(0, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t);\n\t\tassert.equal(c1LocalRef.getSegment(), undefined);\n\t});\n\n\tit(\"References can have offsets on removed segment\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo1 = client1.getContainingSegment(1);\n\t\tconst LocalRef1 = client1.createLocalReferencePosition(\n\t\t\tsegInfo1.segment!,\n\t\t\tsegInfo1.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst segInfo3 = client1.getContainingSegment(3);\n\t\tconst LocalRef2 = client1.createLocalReferencePosition(\n\t\t\tsegInfo3.segment!,\n\t\t\tsegInfo3.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(2, \"XY\"), ++seq);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 1);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 5);\n\n\t\tconst c2SegInfo1 = client2.getContainingSegment(1);\n\t\tconst c2SegInfo3 = client2.getContainingSegment(3);\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(0, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\n\t\tconst c2LocalRef1 = client2.createLocalReferencePosition(\n\t\t\tc2SegInfo1.segment!,\n\t\t\tc2SegInfo1.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst c2LocalRef2 = client2.createLocalReferencePosition(\n\t\t\tc2SegInfo3.segment!,\n\t\t\tc2SegInfo3.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 0);\n\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 1);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 5);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 2);\n\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 0);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 1);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 1);\n\t});\n\n\tit(\"Transient references can be created on removed segments\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tconst insertOp = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tclient1.applyMsg(insertOp);\n\t\tclient2.applyMsg(insertOp);\n\t\tclient1.removeRangeLocal(0, 2);\n\n\t\tconst opFromBeforeRemovePerspective = client2.makeOpMessage(\n\t\t\tclient2.insertTextLocal(3, \"X\"),\n\t\t);\n\t\tconst { segment, offset } = client1.getContainingSegment(0, {\n\t\t\treferenceSequenceNumber: opFromBeforeRemovePerspective.referenceSequenceNumber,\n\t\t\tclientId: opFromBeforeRemovePerspective.clientId,\n\t\t});\n\t\tassert(segment && toRemovalInfo(segment) !== undefined);\n\t\tconst transientRef = client1.createLocalReferencePosition(\n\t\t\tsegment,\n\t\t\toffset,\n\t\t\tReferenceType.Transient,\n\t\t\t{},\n\t\t);\n\t\tassert.equal(transientRef.getSegment(), segment);\n\t\tassert.equal(transientRef.getOffset(), 0);\n\t});\n\n\tit(\"References can have offsets when slid to locally removed segment\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCDE\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo = client1.getContainingSegment(4);\n\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst createReference1 = client1.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert1.sequenceNumber,\n\t\t);\n\n\t\tconst remove1 = client2.makeOpMessage(client2.removeRangeLocal(4, 5), ++seq);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(2, \"XY\"), ++seq);\n\n\t\tconst remove2 = client2.makeOpMessage(client2.removeRangeLocal(1, 4), ++seq);\n\n\t\tconst segoff = getSlideOnRemoveReferencePosition(client2, 4, createReference1);\n\t\tconst c2LocalRef = client2.createLocalReferencePosition(\n\t\t\tsegoff.segment!,\n\t\t\tsegoff.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 6);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 1);\n\n\t\tclient1.applyMsg(remove1);\n\t\tclient2.applyMsg(remove1);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 5);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 1);\n\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 5);\n\t\tassert.equal(client2.getText(), \"AXY\");\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 3);\n\n\t\tclient1.applyMsg(remove2);\n\t\tclient2.applyMsg(remove2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 2);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 2);\n\t});\n\n\tit(\"Split segment with no references and append to segment with references\", () => {\n\t\tconst clients = createClientsAtInitialState({ initialState: \"\" }, \"A\", \"B\");\n\n\t\tconst messages: ISequencedDocumentMessage[] = [];\n\t\tlet seq = 0;\n\t\tmessages.push(clients.A.makeOpMessage(clients.A.insertTextLocal(0, \"0123456789\"), ++seq));\n\t\t// initialize the local reference collection on the segment, but keep it empty\n\t\t{\n\t\t\tconst segInfo = clients.A.getContainingSegment(9);\n\t\t\tconst segment = segInfo.segment;\n\t\t\tassert(segment !== undefined && TextSegment.is(segment));\n\t\t\tassert.strictEqual(segment.text[segInfo.offset!], \"9\");\n\t\t\tconst localRef = clients.A.createLocalReferencePosition(\n\t\t\t\tsegment,\n\t\t\t\tsegInfo.offset,\n\t\t\t\tReferenceType.Simple,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tclients.A.removeLocalReferencePosition(localRef);\n\t\t}\n\t\t// split the segment\n\t\tmessages.push(clients.A.makeOpMessage(clients.A.insertTextLocal(5, \"ABCD\"), ++seq));\n\n\t\t// add a local reference to the newly inserted segment that caused the split\n\t\t{\n\t\t\tconst segInfo = clients.A.getContainingSegment(6);\n\t\t\tconst segment = segInfo.segment;\n\t\t\tassert(segment !== undefined && TextSegment.is(segment));\n\t\t\tassert.strictEqual(segment.text[segInfo.offset!], \"B\");\n\t\t\tclients.A.createLocalReferencePosition(\n\t\t\t\tsegment,\n\t\t\t\tsegInfo.offset,\n\t\t\t\tReferenceType.Simple,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t}\n\t\t// apply all the ops\n\t\twhile (messages.length > 0) {\n\t\t\tconst msg = messages.shift()!;\n\t\t\tclients.all.forEach((c) => c.applyMsg(msg));\n\t\t}\n\n\t\t// regression: would fire 0x2be on zamboni during segment append\n\t\tclients.all.forEach((c) => c.updateMinSeq(seq));\n\t});\n\n\tdescribe(\"avoids removing StayOnRemove references on local + remote concurrent delete\", () => {\n\t\tlet client: TestClient;\n\t\tlet localRefA: LocalReferencePosition;\n\t\tlet localRefB: LocalReferencePosition;\n\t\tlet seq: number;\n\t\tbeforeEach(() => {\n\t\t\tseq = 0;\n\t\t\tclient = new TestClient();\n\t\t\tclient.startOrUpdateCollaboration(\"1\");\n\t\t\tclient.enqueueMsg(client.makeOpMessage(client.insertTextLocal(0, \"B\"), ++seq));\n\t\t\tclient.enqueueMsg(client.makeOpMessage(client.insertTextLocal(0, \"A\"), ++seq));\n\t\t\tclient.applyMessages(2);\n\t\t\tassert.equal(client.getText(), \"AB\");\n\t\t\tlocalRefA = client.createLocalReferencePosition(\n\t\t\t\tclient.getContainingSegment(0).segment!,\n\t\t\t\t0,\n\t\t\t\tReferenceType.StayOnRemove,\n\t\t\t\t{},\n\t\t\t);\n\t\t\tlocalRefB = client.createLocalReferencePosition(\n\t\t\t\tclient.getContainingSegment(1).segment!,\n\t\t\t\t0,\n\t\t\t\tReferenceType.StayOnRemove,\n\t\t\t\t{},\n\t\t\t);\n\t\t\tfor (const ref of [localRefA, localRefB]) {\n\t\t\t\tref.callbacks = {\n\t\t\t\t\tbeforeSlide: () => assert.fail(\"Unexpected slide\"),\n\t\t\t\t\tafterSlide: () => assert.fail(\"Unexpected slide\"),\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\tit(\"when references would slide forward\", () => {\n\t\t\tconst originalSegment = localRefA.getSegment();\n\t\t\tclient.removeRangeLocal(0, 1);\n\t\t\tclient.removeRangeRemote(0, 1, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefA.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\n\t\tit(\"when references would slide backward\", () => {\n\t\t\tconst originalSegment = localRefB.getSegment();\n\t\t\tclient.removeRangeLocal(1, 2);\n\t\t\tclient.removeRangeRemote(1, 2, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefB.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\n\t\tit(\"when references would slide off the string\", () => {\n\t\t\tconst originalSegment = localRefA.getSegment();\n\t\t\tclient.removeRangeLocal(0, 2);\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefA.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\t});\n\n\tit(\"slides to correct position with backward sliding preference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcXdef\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t\tSlidingPreference.BACKWARD,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 3);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(4, \"ghi\"), ++seq);\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 3);\n\n\t\tconst remove1 = client1.makeOpMessage(client1.removeRangeLocal(1, 4), ++seq);\n\t\tclient1.applyMsg(remove1);\n\t\tclient2.applyMsg(remove1);\n\n\t\tassert.equal(client1.getText(), \"aghidef\");\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 0);\n\t\tassert.equal(client2.getText(), \"aghidef\");\n\t\tassert.equal(client2.localReferencePositionToPosition(localRef), 0);\n\t});\n\n\tconst tgCases = [\n\t\t{\n\t\t\tname: \"when the ref is not in a tracking group\",\n\t\t\taddRef: () => {},\n\t\t},\n\t\t{\n\t\t\tname: \"when the ref is in a TrackingGroup\",\n\t\t\taddRef: (ref: LocalReferencePosition) => {\n\t\t\t\tconst tg = new TrackingGroup();\n\t\t\t\ttg.link(ref);\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"when the ref is in an UnorderedTrackingGroup\",\n\t\t\taddRef: (ref: LocalReferencePosition) => {\n\t\t\t\tconst tg = new UnorderedTrackingGroup();\n\t\t\t\ttg.link(ref);\n\t\t\t},\n\t\t},\n\t];\n\n\tdescribe(\"doesn't crash for remove ref then link to undefined\", () => {\n\t\ttgCases.forEach(({ name, addRef }) => {\n\t\t\tit(name, () => {\n\t\t\t\tconst client1 = new TestClient();\n\t\t\t\tconst client2 = new TestClient();\n\n\t\t\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\t\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcdef\"), ++seq);\n\t\t\t\tclient1.applyMsg(insert1);\n\t\t\t\tclient2.applyMsg(insert1);\n\n\t\t\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\t\t\tassert(segInfo.segment);\n\n\t\t\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\t\t\tsegInfo.segment,\n\t\t\t\t\tsegInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\taddRef(localRef);\n\n\t\t\t\tassert.equal(localRef.getSegment(), segInfo.segment);\n\n\t\t\t\tassert(segInfo.segment.localRefs);\n\t\t\t\tassert(!segInfo.segment.localRefs.empty);\n\n\t\t\t\tsegInfo.segment.localRefs.removeLocalRef(localRef);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\t\t\t\t(localRef as any).link(undefined, 0, undefined);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\n\t\t\t\tassert.equal(segInfo.segment.localRefs.empty, true);\n\t\t\t\tassert.equal(segInfo.segment.localRefs.has(localRef), false);\n\t\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe(\"doesn't crash for link to undefined then remove ref\", () => {\n\t\ttgCases.forEach(({ name, addRef }) => {\n\t\t\tit(name, () => {\n\t\t\t\tconst client1 = new TestClient();\n\t\t\t\tconst client2 = new TestClient();\n\n\t\t\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\t\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcdef\"), ++seq);\n\t\t\t\tclient1.applyMsg(insert1);\n\t\t\t\tclient2.applyMsg(insert1);\n\n\t\t\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\t\t\tassert(segInfo.segment);\n\n\t\t\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\t\t\tsegInfo.segment,\n\t\t\t\t\tsegInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\taddRef(localRef);\n\n\t\t\t\tassert.equal(localRef.getSegment(), segInfo.segment);\n\n\t\t\t\tassert(segInfo.segment.localRefs);\n\t\t\t\tassert(!segInfo.segment.localRefs.empty);\n\n\t\t\t\t(localRef as any).link(undefined, 0, undefined);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\t\t\t\tsegInfo.segment.localRefs.removeLocalRef(localRef);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\n\t\t\t\tassert.equal(segInfo.segment.localRefs.empty, true);\n\t\t\t\tassert.equal(segInfo.segment.localRefs.has(localRef), false);\n\t\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"client.localReference.spec.js","sourceRoot":"","sources":["../../src/test/client.localReference.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { Client } from \"../client.js\";\nimport {\n\tLocalReferencePosition,\n\tSlidingPreference,\n\tsetValidateRefCount,\n} from \"../localReference.js\";\nimport { getSlideToSegoff } from \"../mergeTree.js\";\nimport { toRemovalInfo, type ISegment } from \"../mergeTreeNodes.js\";\nimport { TrackingGroup, UnorderedTrackingGroup } from \"../mergeTreeTracking.js\";\nimport { MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { DetachedReferencePosition } from \"../referencePositions.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { createClientsAtInitialState } from \"./testClientLogger.js\";\nimport { validateRefCount } from \"./testUtils.js\";\n\nfunction getSlideOnRemoveReferencePosition(\n\tclient: Client,\n\tpos: number,\n\top: ISequencedDocumentMessage,\n): {\n\tsegment: ISegment | undefined;\n\toffset: number | undefined;\n} {\n\tlet segoff = client.getContainingSegment(pos, {\n\t\treferenceSequenceNumber: op.referenceSequenceNumber,\n\t\tclientId: op.clientId,\n\t});\n\tsegoff = getSlideToSegoff(segoff);\n\treturn segoff;\n}\n\ndescribe(\"MergeTree.Client\", () => {\n\tbeforeEach(() => {\n\t\tsetValidateRefCount(validateRefCount);\n\t});\n\n\tafterEach(() => {\n\t\tsetValidateRefCount(undefined);\n\t});\n\n\tit(\"Remove segment of non-sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.Simple,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2, \"create position\");\n\n\t\tconst remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\t// this only works because zamboni hasn't run yet\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t\t\"after remove\",\n\t\t);\n\n\t\t// this will force Zamboni to run\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t\t\"after zamboni\",\n\t\t);\n\t});\n\n\tit(\"Remove segment of sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\t});\n\n\tit(\"Remove segments to end with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(2, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tclient2.getLength() - 1,\n\t\t);\n\t});\n\n\tit(\"Remove segments from end with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tlet seq = 0;\n\t\tconst insert = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(insert);\n\n\t\tconst segInfo = client1.getContainingSegment(3);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 3, \"ref created\");\n\n\t\tconst remove1 = client1.makeOpMessage(client1.removeRangeLocal(3, 4), ++seq);\n\t\tremove1.minimumSequenceNumber = seq - 1;\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 3, \"after remove\");\n\n\t\tconst remove2 = client1.makeOpMessage(client1.removeRangeLocal(1, 3), ++seq);\n\t\tremove2.minimumSequenceNumber = seq - 1;\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\t1,\n\t\t\t\"after second remove\",\n\t\t);\n\n\t\tclient1.applyMsg(remove1);\n\t\tclient1.applyMsg(remove2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 0, \"ops applied\");\n\t});\n\n\tit(\"getSlideOnRemoveReferencePosition\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"XYZ\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABC\"), ++seq);\n\t\tclient1.applyMsg(insert2);\n\n\t\t// Position depends on op\n\t\tconst createReference1 = client2.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert1.sequenceNumber,\n\t\t);\n\t\tlet segoff = getSlideOnRemoveReferencePosition(client1, 1, createReference1);\n\t\tassert(segoff.segment);\n\t\tassert.equal(client1.getPosition(segoff.segment), 3);\n\t\tassert.equal(segoff.offset, 1);\n\n\t\tconst createReference2 = client2.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert2.sequenceNumber,\n\t\t);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 2, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(client1.getPosition(segoff.segment), 0);\n\t\tassert.equal(segoff.offset, 2);\n\n\t\t// On a removed, unacked segment\n\t\tlet remove = client1.makeOpMessage(client1.removeRangeLocal(2, 5), ++seq);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.notEqual(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// Slid from a removed, acked segment\n\t\tclient1.applyMsg(remove);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// On a removed, unacked segment, end of string\n\t\tremove = client1.makeOpMessage(client1.removeRangeLocal(2, 3), ++seq);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.notEqual(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 2);\n\t\tassert.equal(segoff.offset, 0);\n\n\t\t// Slid from a removed, acked segment, end of string\n\t\tclient1.applyMsg(remove);\n\t\tsegoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);\n\t\tassert(segoff.segment);\n\t\tassert.equal(toRemovalInfo(segoff.segment), undefined);\n\t\tassert.equal(client1.getPosition(segoff.segment), 0);\n\t\tassert.equal(segoff.offset, 1);\n\t});\n\n\tit(\"Remove all segments with sliding local reference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tfor (let i = 0; i < 5; i++) {\n\t\t\tconst insert = client1.makeOpMessage(\n\t\t\t\tclient1.insertTextLocal(client1.getLength(), i.toString()),\n\t\t\t\t++seq,\n\t\t\t);\n\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\tclient1.applyMsg(insert);\n\t\t\tclient2.applyMsg(insert);\n\t\t}\n\n\t\tconst segInfo = client1.getContainingSegment(2);\n\t\tconst c1LocalRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);\n\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(0, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\t\tremove.minimumSequenceNumber = seq - 1;\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(\n\t\t\tclient1.localReferencePositionToPosition(c1LocalRef),\n\t\t\tDetachedReferencePosition,\n\t\t);\n\t\tassert.equal(c1LocalRef.getSegment(), undefined);\n\t});\n\n\tit(\"References can have offsets on removed segment\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo1 = client1.getContainingSegment(1);\n\t\tconst LocalRef1 = client1.createLocalReferencePosition(\n\t\t\tsegInfo1.segment!,\n\t\t\tsegInfo1.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst segInfo3 = client1.getContainingSegment(3);\n\t\tconst LocalRef2 = client1.createLocalReferencePosition(\n\t\t\tsegInfo3.segment!,\n\t\t\tsegInfo3.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(2, \"XY\"), ++seq);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 1);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 5);\n\n\t\tconst c2SegInfo1 = client2.getContainingSegment(1);\n\t\tconst c2SegInfo3 = client2.getContainingSegment(3);\n\t\tconst remove = client2.makeOpMessage(\n\t\t\tclient2.removeRangeLocal(0, client2.getLength()),\n\t\t\t++seq,\n\t\t);\n\n\t\tconst c2LocalRef1 = client2.createLocalReferencePosition(\n\t\t\tc2SegInfo1.segment!,\n\t\t\tc2SegInfo1.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst c2LocalRef2 = client2.createLocalReferencePosition(\n\t\t\tc2SegInfo3.segment!,\n\t\t\tc2SegInfo3.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 0);\n\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 1);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 5);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 2);\n\n\t\tclient1.applyMsg(remove);\n\t\tclient2.applyMsg(remove);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef1), 0);\n\t\tassert.equal(client1.localReferencePositionToPosition(LocalRef2), 1);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef1), 0);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef2), 1);\n\t});\n\n\tit(\"Transient references can be created on removed segments\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\t\tlet seq = 0;\n\t\tconst insertOp = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCD\"), ++seq);\n\t\tclient1.applyMsg(insertOp);\n\t\tclient2.applyMsg(insertOp);\n\t\tclient1.removeRangeLocal(0, 2);\n\n\t\tconst opFromBeforeRemovePerspective = client2.makeOpMessage(\n\t\t\tclient2.insertTextLocal(3, \"X\"),\n\t\t);\n\t\tconst { segment, offset } = client1.getContainingSegment(0, {\n\t\t\treferenceSequenceNumber: opFromBeforeRemovePerspective.referenceSequenceNumber,\n\t\t\tclientId: opFromBeforeRemovePerspective.clientId,\n\t\t});\n\t\tassert(segment && toRemovalInfo(segment) !== undefined);\n\t\tconst transientRef = client1.createLocalReferencePosition(\n\t\t\tsegment,\n\t\t\toffset,\n\t\t\tReferenceType.Transient,\n\t\t\t{},\n\t\t);\n\t\tassert.equal(transientRef.getSegment(), segment);\n\t\tassert.equal(transientRef.getOffset(), 0);\n\t});\n\n\tit(\"References can have offsets when slid to locally removed segment\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"ABCDE\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo = client1.getContainingSegment(4);\n\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tconst createReference1 = client1.makeOpMessage(\n\t\t\t{ type: MergeTreeDeltaType.INSERT },\n\t\t\t++seq,\n\t\t\tinsert1.sequenceNumber,\n\t\t);\n\n\t\tconst remove1 = client2.makeOpMessage(client2.removeRangeLocal(4, 5), ++seq);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(2, \"XY\"), ++seq);\n\n\t\tconst remove2 = client2.makeOpMessage(client2.removeRangeLocal(1, 4), ++seq);\n\n\t\tconst segoff = getSlideOnRemoveReferencePosition(client2, 4, createReference1);\n\t\tconst c2LocalRef = client2.createLocalReferencePosition(\n\t\t\tsegoff.segment!,\n\t\t\tsegoff.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t);\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 6);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 1);\n\n\t\tclient1.applyMsg(remove1);\n\t\tclient2.applyMsg(remove1);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 5);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 1);\n\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 5);\n\t\tassert.equal(client2.getText(), \"AXY\");\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 3);\n\n\t\tclient1.applyMsg(remove2);\n\t\tclient2.applyMsg(remove2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 2);\n\t\tassert.equal(client2.localReferencePositionToPosition(c2LocalRef), 2);\n\t});\n\n\tit(\"Split segment with no references and append to segment with references\", () => {\n\t\tconst clients = createClientsAtInitialState({ initialState: \"\" }, \"A\", \"B\");\n\n\t\tconst messages: ISequencedDocumentMessage[] = [];\n\t\tlet seq = 0;\n\t\tmessages.push(clients.A.makeOpMessage(clients.A.insertTextLocal(0, \"0123456789\"), ++seq));\n\t\t// initialize the local reference collection on the segment, but keep it empty\n\t\t{\n\t\t\tconst segInfo = clients.A.getContainingSegment(9);\n\t\t\tconst segment = segInfo.segment;\n\t\t\tassert(segment !== undefined && TextSegment.is(segment));\n\t\t\tassert.strictEqual(segment.text[segInfo.offset!], \"9\");\n\t\t\tconst localRef = clients.A.createLocalReferencePosition(\n\t\t\t\tsegment,\n\t\t\t\tsegInfo.offset,\n\t\t\t\tReferenceType.Simple,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tclients.A.removeLocalReferencePosition(localRef);\n\t\t}\n\t\t// split the segment\n\t\tmessages.push(clients.A.makeOpMessage(clients.A.insertTextLocal(5, \"ABCD\"), ++seq));\n\n\t\t// add a local reference to the newly inserted segment that caused the split\n\t\t{\n\t\t\tconst segInfo = clients.A.getContainingSegment(6);\n\t\t\tconst segment = segInfo.segment;\n\t\t\tassert(segment !== undefined && TextSegment.is(segment));\n\t\t\tassert.strictEqual(segment.text[segInfo.offset!], \"B\");\n\t\t\tclients.A.createLocalReferencePosition(\n\t\t\t\tsegment,\n\t\t\t\tsegInfo.offset,\n\t\t\t\tReferenceType.Simple,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t}\n\t\t// apply all the ops\n\t\twhile (messages.length > 0) {\n\t\t\tconst msg = messages.shift()!;\n\t\t\tfor (const c of clients.all) c.applyMsg(msg);\n\t\t}\n\n\t\t// regression: would fire 0x2be on zamboni during segment append\n\t\tfor (const c of clients.all) c.updateMinSeq(seq);\n\t});\n\n\tdescribe(\"avoids removing StayOnRemove references on local + remote concurrent delete\", () => {\n\t\tlet client: TestClient;\n\t\tlet localRefA: LocalReferencePosition;\n\t\tlet localRefB: LocalReferencePosition;\n\t\tlet seq: number;\n\t\tbeforeEach(() => {\n\t\t\tseq = 0;\n\t\t\tclient = new TestClient();\n\t\t\tclient.startOrUpdateCollaboration(\"1\");\n\t\t\tclient.enqueueMsg(client.makeOpMessage(client.insertTextLocal(0, \"B\"), ++seq));\n\t\t\tclient.enqueueMsg(client.makeOpMessage(client.insertTextLocal(0, \"A\"), ++seq));\n\t\t\tclient.applyMessages(2);\n\t\t\tassert.equal(client.getText(), \"AB\");\n\t\t\tlocalRefA = client.createLocalReferencePosition(\n\t\t\t\tclient.getContainingSegment(0).segment!,\n\t\t\t\t0,\n\t\t\t\tReferenceType.StayOnRemove,\n\t\t\t\t{},\n\t\t\t);\n\t\t\tlocalRefB = client.createLocalReferencePosition(\n\t\t\t\tclient.getContainingSegment(1).segment!,\n\t\t\t\t0,\n\t\t\t\tReferenceType.StayOnRemove,\n\t\t\t\t{},\n\t\t\t);\n\t\t\tfor (const ref of [localRefA, localRefB]) {\n\t\t\t\tref.callbacks = {\n\t\t\t\t\tbeforeSlide: (): void => assert.fail(\"Unexpected slide\"),\n\t\t\t\t\tafterSlide: (): void => assert.fail(\"Unexpected slide\"),\n\t\t\t\t};\n\t\t\t}\n\t\t});\n\n\t\tit(\"when references would slide forward\", () => {\n\t\t\tconst originalSegment = localRefA.getSegment();\n\t\t\tclient.removeRangeLocal(0, 1);\n\t\t\tclient.removeRangeRemote(0, 1, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefA.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\n\t\tit(\"when references would slide backward\", () => {\n\t\t\tconst originalSegment = localRefB.getSegment();\n\t\t\tclient.removeRangeLocal(1, 2);\n\t\t\tclient.removeRangeRemote(1, 2, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefB.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\n\t\tit(\"when references would slide off the string\", () => {\n\t\t\tconst originalSegment = localRefA.getSegment();\n\t\t\tclient.removeRangeLocal(0, 2);\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, seq - 1, \"2\");\n\t\t\tassert(localRefA.getSegment() === originalSegment, \"ref was removed\");\n\t\t});\n\t});\n\n\tit(\"slides to correct position with backward sliding preference\", () => {\n\t\tconst client1 = new TestClient();\n\t\tconst client2 = new TestClient();\n\n\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\tlet seq = 0;\n\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcXdef\"), ++seq);\n\t\tclient1.applyMsg(insert1);\n\t\tclient2.applyMsg(insert1);\n\n\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\tsegInfo.segment!,\n\t\t\tsegInfo.offset,\n\t\t\tReferenceType.SlideOnRemove,\n\t\t\tundefined,\n\t\t\tSlidingPreference.BACKWARD,\n\t\t);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 3);\n\n\t\tconst insert2 = client1.makeOpMessage(client1.insertTextLocal(4, \"ghi\"), ++seq);\n\t\tclient1.applyMsg(insert2);\n\t\tclient2.applyMsg(insert2);\n\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 3);\n\n\t\tconst remove1 = client1.makeOpMessage(client1.removeRangeLocal(1, 4), ++seq);\n\t\tclient1.applyMsg(remove1);\n\t\tclient2.applyMsg(remove1);\n\n\t\tassert.equal(client1.getText(), \"aghidef\");\n\t\tassert.equal(client1.localReferencePositionToPosition(localRef), 0);\n\t\tassert.equal(client2.getText(), \"aghidef\");\n\t\tassert.equal(client2.localReferencePositionToPosition(localRef), 0);\n\t});\n\n\tconst tgCases = [\n\t\t{\n\t\t\tname: \"when the ref is not in a tracking group\",\n\t\t\taddRef: (): void => {},\n\t\t},\n\t\t{\n\t\t\tname: \"when the ref is in a TrackingGroup\",\n\t\t\taddRef: (ref: LocalReferencePosition): void => {\n\t\t\t\tconst tg = new TrackingGroup();\n\t\t\t\ttg.link(ref);\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"when the ref is in an UnorderedTrackingGroup\",\n\t\t\taddRef: (ref: LocalReferencePosition): void => {\n\t\t\t\tconst tg = new UnorderedTrackingGroup();\n\t\t\t\ttg.link(ref);\n\t\t\t},\n\t\t},\n\t];\n\n\tdescribe(\"doesn't crash for remove ref then link to undefined\", () => {\n\t\tfor (const { name, addRef } of tgCases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst client1 = new TestClient();\n\t\t\t\tconst client2 = new TestClient();\n\n\t\t\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\t\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcdef\"), ++seq);\n\t\t\t\tclient1.applyMsg(insert1);\n\t\t\t\tclient2.applyMsg(insert1);\n\n\t\t\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\t\t\tassert(segInfo.segment);\n\n\t\t\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\t\t\tsegInfo.segment,\n\t\t\t\t\tsegInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\taddRef(localRef);\n\n\t\t\t\tassert.equal(localRef.getSegment(), segInfo.segment);\n\n\t\t\t\tassert(segInfo.segment.localRefs);\n\t\t\t\tassert(!segInfo.segment.localRefs.empty);\n\n\t\t\t\tsegInfo.segment.localRefs.removeLocalRef(localRef);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\t\t\t\t// Cast is necessary because LocalReference is not exported, so we can't directly call link.\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\t(localRef as any).link(undefined, 0, undefined);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\n\t\t\t\tassert.equal(segInfo.segment.localRefs.empty, true);\n\t\t\t\tassert.equal(segInfo.segment.localRefs.has(localRef), false);\n\t\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t\t});\n\t\t}\n\t});\n\n\tdescribe(\"doesn't crash for link to undefined then remove ref\", () => {\n\t\tfor (const { name, addRef } of tgCases) {\n\t\t\tit(name, () => {\n\t\t\t\tconst client1 = new TestClient();\n\t\t\t\tconst client2 = new TestClient();\n\n\t\t\t\tclient1.startOrUpdateCollaboration(\"1\");\n\t\t\t\tclient2.startOrUpdateCollaboration(\"2\");\n\n\t\t\t\tlet seq = 0;\n\t\t\t\tconst insert1 = client1.makeOpMessage(client1.insertTextLocal(0, \"abcdef\"), ++seq);\n\t\t\t\tclient1.applyMsg(insert1);\n\t\t\t\tclient2.applyMsg(insert1);\n\n\t\t\t\tconst segInfo = client1.getContainingSegment(3);\n\n\t\t\t\tassert(segInfo.segment);\n\n\t\t\t\tconst localRef = client1.createLocalReferencePosition(\n\t\t\t\t\tsegInfo.segment,\n\t\t\t\t\tsegInfo.offset,\n\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\taddRef(localRef);\n\n\t\t\t\tassert.equal(localRef.getSegment(), segInfo.segment);\n\n\t\t\t\tassert(segInfo.segment.localRefs);\n\t\t\t\tassert(!segInfo.segment.localRefs.empty);\n\t\t\t\t// Cast is necessary because LocalReference is not exported, so we can't directly call link\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\t(localRef as any).link(undefined, 0, undefined);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\t\t\t\tsegInfo.segment.localRefs.removeLocalRef(localRef);\n\t\t\t\tassert(segInfo.segment.localRefs.empty);\n\n\t\t\t\tassert.equal(segInfo.segment.localRefs.empty, true);\n\t\t\t\tassert.equal(segInfo.segment.localRefs.has(localRef), false);\n\t\t\t\tassert.equal(localRef.getSegment(), undefined);\n\t\t\t\tassert.equal(localRef.getOffset(), 0);\n\t\t\t});\n\t\t}\n\t});\n});\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
|
-
import { strict as assert } from "assert";
|
|
6
|
+
import { strict as assert } from "node:assert";
|
|
7
7
|
import { makeRandom } from "@fluid-private/stochastic-test-utils";
|
|
8
8
|
import { SlidingPreference, setValidateRefCount } from "../localReference.js";
|
|
9
9
|
import { ReferenceType } from "../ops.js";
|
|
@@ -31,8 +31,11 @@ describe("MergeTree.Client", () => {
|
|
|
31
31
|
doOverRanges(defaultOptions, ({ initLen, modLen }) => {
|
|
32
32
|
it(`LocalReferenceFarm_${initLen}_${modLen}`, async () => {
|
|
33
33
|
const random = makeRandom(0xdeadbeef, 0xfeedbed, initLen, modLen);
|
|
34
|
-
const clients =
|
|
35
|
-
|
|
34
|
+
const clients = Array.from({ length: 3 })
|
|
35
|
+
.fill(0)
|
|
36
|
+
.map(() => new TestClient());
|
|
37
|
+
for (const [i, c] of clients.entries())
|
|
38
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
36
39
|
let seq = 0;
|
|
37
40
|
// init with random values
|
|
38
41
|
seq = runMergeTreeOperationRunner(random, seq, clients, initLen, defaultOptions);
|
|
@@ -53,21 +56,21 @@ describe("MergeTree.Client", () => {
|
|
|
53
56
|
// console.log(`${reason}:\n${preWorkload}\n${TestClientLogger.toString(clients)}`)
|
|
54
57
|
};
|
|
55
58
|
validateRefs("Initialize", () => {
|
|
56
|
-
clients.
|
|
59
|
+
for (const [i, c] of clients.entries()) {
|
|
57
60
|
refs.push([]);
|
|
58
61
|
for (let t = 0; t < c.getLength(); t++) {
|
|
59
62
|
const seg = c.getContainingSegment(t);
|
|
60
63
|
const forwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ReferenceType.SlideOnRemove, { t }, SlidingPreference.FORWARD);
|
|
61
64
|
const backwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ReferenceType.SlideOnRemove, { t }, SlidingPreference.BACKWARD);
|
|
62
|
-
refs[i].push(forwardLref);
|
|
63
|
-
refs[i].push(backwardLref);
|
|
65
|
+
refs[i].push(forwardLref, backwardLref);
|
|
64
66
|
}
|
|
65
|
-
}
|
|
67
|
+
}
|
|
66
68
|
});
|
|
67
69
|
validateRefs("After Init Zamboni", () => {
|
|
68
70
|
// trigger zamboni multiple times as it is incremental
|
|
69
71
|
for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
|
|
70
|
-
|
|
72
|
+
for (const c of clients)
|
|
73
|
+
c.updateMinSeq(i);
|
|
71
74
|
}
|
|
72
75
|
});
|
|
73
76
|
validateRefs("After More Ops", () => {
|
|
@@ -77,7 +80,8 @@ describe("MergeTree.Client", () => {
|
|
|
77
80
|
validateRefs("After Final Zamboni", () => {
|
|
78
81
|
// trigger zamboni multiple times as it is incremental
|
|
79
82
|
for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
|
|
80
|
-
|
|
83
|
+
for (const c of clients)
|
|
84
|
+
c.updateMinSeq(i);
|
|
81
85
|
}
|
|
82
86
|
});
|
|
83
87
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.localReferenceFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.localReferenceFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.localReferenceFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.localReferenceFarm.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport { SlidingPreference, setValidateRefCount } from \"../localReference.js\";\nimport { ReferenceType } from \"../ops.js\";\nimport { ReferencePosition } from \"../referencePositions.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tdoOverRanges,\n\tgenerateClientNames,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\nimport { validateRefCount } from \"./testUtils.js\";\n\nconst defaultOptions: Record<\"initLen\" | \"modLen\", IConfigRange> &\n\tIMergeTreeOperationRunnerConfig = {\n\tinitLen: { min: 2, max: 256 },\n\tmodLen: { min: 1, max: 256 },\n\topsPerRoundRange: { min: 10, max: 10 },\n\trounds: 10,\n\toperations: [removeRange],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\ndescribe(\"MergeTree.Client\", () => {\n\tbeforeEach(() => {\n\t\tsetValidateRefCount(validateRefCount);\n\t});\n\n\tafterEach(() => {\n\t\tsetValidateRefCount(undefined);\n\t});\n\n\t// Generate a list of single character client names, support up to 69 clients\n\tconst clientNames = generateClientNames();\n\n\tdoOverRanges(defaultOptions, ({ initLen, modLen }) => {\n\t\tit(`LocalReferenceFarm_${initLen}_${modLen}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, initLen, modLen);\n\n\t\t\tconst clients: TestClient[] = Array.from({ length: 3 })\n\t\t\t\t.fill(0)\n\t\t\t\t.map(() => new TestClient());\n\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\tlet seq = 0;\n\t\t\t// init with random values\n\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, initLen, defaultOptions);\n\t\t\t// add local references\n\t\t\tconst refs: ReferencePosition[][] = [];\n\n\t\t\tconst validateRefs = (reason: string, workload: () => void): void => {\n\t\t\t\tconst preWorkload = TestClientLogger.toString(clients);\n\t\t\t\tworkload();\n\t\t\t\tfor (let c = 1; c < clients.length; c++) {\n\t\t\t\t\tfor (let r = 0; r < refs[c].length; r++) {\n\t\t\t\t\t\tconst pos0 = clients[0].localReferencePositionToPosition(refs[0][r]);\n\t\t\t\t\t\tconst posC = clients[c].localReferencePositionToPosition(refs[c][r]);\n\t\t\t\t\t\tif (pos0 !== posC) {\n\t\t\t\t\t\t\tassert.equal(\n\t\t\t\t\t\t\t\tpos0,\n\t\t\t\t\t\t\t\tposC,\n\t\t\t\t\t\t\t\t`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString(clients)}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// console.log(`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString(clients)}`)\n\t\t\t};\n\n\t\t\tvalidateRefs(\"Initialize\", () => {\n\t\t\t\tfor (const [i, c] of clients.entries()) {\n\t\t\t\t\trefs.push([]);\n\t\t\t\t\tfor (let t = 0; t < c.getLength(); t++) {\n\t\t\t\t\t\tconst seg = c.getContainingSegment(t);\n\t\t\t\t\t\tconst forwardLref = c.createLocalReferencePosition(\n\t\t\t\t\t\t\tseg.segment!,\n\t\t\t\t\t\t\tseg.offset,\n\t\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\t\t{ t },\n\t\t\t\t\t\t\tSlidingPreference.FORWARD,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst backwardLref = c.createLocalReferencePosition(\n\t\t\t\t\t\t\tseg.segment!,\n\t\t\t\t\t\t\tseg.offset,\n\t\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\t\t{ t },\n\t\t\t\t\t\t\tSlidingPreference.BACKWARD,\n\t\t\t\t\t\t);\n\t\t\t\t\t\trefs[i].push(forwardLref, backwardLref);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After Init Zamboni\", () => {\n\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After More Ops\", () => {\n\t\t\t\t// init with random values\n\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, modLen, defaultOptions);\n\t\t\t});\n\n\t\t\tvalidateRefs(\"After Final Zamboni\", () => {\n\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { strict as assert } from "assert";
|
|
5
|
+
import { strict as assert } from "node:assert";
|
|
6
6
|
import { TestClient } from "./testClient.js";
|
|
7
7
|
describe("client.rebasePosition", () => {
|
|
8
8
|
const localUserLongId = "localUser";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.rebasePosition.spec.js","sourceRoot":"","sources":["../../src/test/client.rebasePosition.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"assert\";\n\nimport { IMergeTreeOp } from \"../ops.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\ndescribe(\"client.rebasePosition\", () => {\n\tconst localUserLongId = \"localUser\";\n\tconst remoteUserLongId = \"remoteUser\";\n\tlet client: TestClient;\n\tlet seq: number;\n\n\tconst getTextAt = (pos: number): string => client.getText(pos, pos + 1);\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tclient.insertTextLocal(0, \"hello world\");\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\t\tseq = 0;\n\t});\n\n\tit(\"rebase past remote insert\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* \"w\" */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase past remote delete\", () => {\n\t\tclient.removeRangeRemote(0, 3, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* w */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase on a variety of seqNumberFrom values\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tclient.removeRangeRemote(0, 1, ++seq, seq - 1, remoteUserLongId);\n\t\tclient.insertTextRemote(1, \"XYZ@\", undefined, ++seq, seq - 1, remoteUserLongId);\n\n\t\tconst rebasedPos0 = client.rebasePosition(6 /* into \"hello world\" */, 0, 0);\n\t\tconst rebasedPos1 = client.rebasePosition(6 /* into \"abchello world\" */, 1, 0);\n\t\tconst rebasedPos2 = client.rebasePosition(6 /* into \"bchello world\" */, 2, 0);\n\t\tconst rebasedPos3 = client.rebasePosition(6 /* into \"bXYZ@chello world\" */, 3, 0);\n\n\t\tassert.equal(getTextAt(rebasedPos0), \"w\");\n\t\tassert.equal(getTextAt(rebasedPos1), \"l\");\n\t\tassert.equal(getTextAt(rebasedPos2), \"o\");\n\t\tassert.equal(getTextAt(rebasedPos3), \"h\");\n\t});\n\n\tdescribe(\"with subsequent local changes\", () => {\n\t\t// Rebasing is made more complicated from the client perspective when there are local changes applied\n\t\t// meanwhile, since the local state of the string contains segments that should not be considered\n\t\t// when computing the position to rebase to (since they wouldn't be visible remotely)\n\n\t\tlet op1: IMergeTreeOp | undefined;\n\t\tlet op2: IMergeTreeOp | undefined;\n\t\tbeforeEach(() => {\n\t\t\top1 = client.insertTextLocal(5, \"123456\");\n\t\t\top2 = client.removeRangeLocal(3, 5);\n\t\t});\n\n\t\t// For these tests, rebasedPos conceptually refers to a position that a *remote* client should use in order\n\t\t// to get an equivalent position to the one that was applied locally with a different refSeq.\n\t\t// Since this suite doesn't actually spin up a remote client, we verify this equivalence by asking\n\t\t// the local client to resolve that remote position and confirm the text matches what's expected.\n\t\tconst expectTextAtRebasedPosMatches = (\n\t\t\tpos: number,\n\t\t\texpected: string,\n\t\t\tmessage?: string,\n\t\t) => {\n\t\t\tconst localViewOfRebasedPos = client.resolveRemoteClientPosition(\n\t\t\t\tpos,\n\t\t\t\tseq,\n\t\t\t\tremoteUserLongId,\n\t\t\t);\n\t\t\tassert(localViewOfRebasedPos !== undefined, \"pos should be defined\");\n\t\t\tconst text = getTextAt(localViewOfRebasedPos);\n\t\t\tassert.equal(text, expected, message);\n\t\t};\n\n\t\tit(\"rebase past remote insert\", () => {\n\t\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\tit(\"rebase past remote delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\t// Mid-remote delete with meanwhile local edits isn't particularly more interesting than the cases\n\t\t// handled above. Instead we include some rebased positions amid the local delete (removal of \"lo\")\n\t\t// as this caught a bug with the original implementation.\n\t\tit(\"rebase mid local delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(4 /* index 4 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t4 /* index 4 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(4 /* index 4 into \"hel123456 world\" */, 0, 2);\n\n\t\t\tassert.equal(rebasedPos, 2);\n\t\t\tassert.equal(rebasedPos1, 2);\n\t\t\tassert.equal(rebasedPos2, 2);\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"client.rebasePosition.spec.js","sourceRoot":"","sources":["../../src/test/client.rebasePosition.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { IMergeTreeOp } from \"../ops.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\ndescribe(\"client.rebasePosition\", () => {\n\tconst localUserLongId = \"localUser\";\n\tconst remoteUserLongId = \"remoteUser\";\n\tlet client: TestClient;\n\tlet seq: number;\n\n\tconst getTextAt = (pos: number): string => client.getText(pos, pos + 1);\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tclient.insertTextLocal(0, \"hello world\");\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\t\tseq = 0;\n\t});\n\n\tit(\"rebase past remote insert\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* \"w\" */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase past remote delete\", () => {\n\t\tclient.removeRangeRemote(0, 3, ++seq, 0, remoteUserLongId);\n\t\tconst rebasedPos = client.rebasePosition(6 /* w */, 0, 0);\n\t\tconst text = getTextAt(rebasedPos);\n\t\tassert.equal(text, \"w\", \"rebased pos should still refer to 'w'\");\n\t});\n\n\tit(\"rebase on a variety of seqNumberFrom values\", () => {\n\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\tclient.removeRangeRemote(0, 1, ++seq, seq - 1, remoteUserLongId);\n\t\tclient.insertTextRemote(1, \"XYZ@\", undefined, ++seq, seq - 1, remoteUserLongId);\n\n\t\tconst rebasedPos0 = client.rebasePosition(6 /* into \"hello world\" */, 0, 0);\n\t\tconst rebasedPos1 = client.rebasePosition(6 /* into \"abchello world\" */, 1, 0);\n\t\tconst rebasedPos2 = client.rebasePosition(6 /* into \"bchello world\" */, 2, 0);\n\t\tconst rebasedPos3 = client.rebasePosition(6 /* into \"bXYZ@chello world\" */, 3, 0);\n\n\t\tassert.equal(getTextAt(rebasedPos0), \"w\");\n\t\tassert.equal(getTextAt(rebasedPos1), \"l\");\n\t\tassert.equal(getTextAt(rebasedPos2), \"o\");\n\t\tassert.equal(getTextAt(rebasedPos3), \"h\");\n\t});\n\n\tdescribe(\"with subsequent local changes\", () => {\n\t\t// Rebasing is made more complicated from the client perspective when there are local changes applied\n\t\t// meanwhile, since the local state of the string contains segments that should not be considered\n\t\t// when computing the position to rebase to (since they wouldn't be visible remotely)\n\n\t\tlet op1: IMergeTreeOp | undefined;\n\t\tlet op2: IMergeTreeOp | undefined;\n\t\tbeforeEach(() => {\n\t\t\top1 = client.insertTextLocal(5, \"123456\");\n\t\t\top2 = client.removeRangeLocal(3, 5);\n\t\t});\n\n\t\t// For these tests, rebasedPos conceptually refers to a position that a *remote* client should use in order\n\t\t// to get an equivalent position to the one that was applied locally with a different refSeq.\n\t\t// Since this suite doesn't actually spin up a remote client, we verify this equivalence by asking\n\t\t// the local client to resolve that remote position and confirm the text matches what's expected.\n\t\tconst expectTextAtRebasedPosMatches = (\n\t\t\tpos: number,\n\t\t\texpected: string,\n\t\t\tmessage?: string,\n\t\t): void => {\n\t\t\tconst localViewOfRebasedPos = client.resolveRemoteClientPosition(\n\t\t\t\tpos,\n\t\t\t\tseq,\n\t\t\t\tremoteUserLongId,\n\t\t\t);\n\t\t\tassert(localViewOfRebasedPos !== undefined, \"pos should be defined\");\n\t\t\tconst text = getTextAt(localViewOfRebasedPos);\n\t\t\tassert.equal(text, expected, message);\n\t\t};\n\n\t\tit(\"rebase past remote insert\", () => {\n\t\t\tclient.insertTextRemote(0, \"abc\", undefined, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\tit(\"rebase past remote delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(6 /* index 6 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t6 /* index 6 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(6 /* index 6 into \"hel123456 world\" */, 0, 2);\n\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos, \"w\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op1, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos1, \"2\");\n\n\t\t\tclient.applyMsg(client.makeOpMessage(op2, ++seq, 0, localUserLongId), true);\n\t\t\texpectTextAtRebasedPosMatches(rebasedPos2, \"4\");\n\t\t});\n\n\t\t// Mid-remote delete with meanwhile local edits isn't particularly more interesting than the cases\n\t\t// handled above. Instead we include some rebased positions amid the local delete (removal of \"lo\")\n\t\t// as this caught a bug with the original implementation.\n\t\tit(\"rebase mid local delete\", () => {\n\t\t\tclient.removeRangeRemote(0, 2, ++seq, 0, remoteUserLongId);\n\t\t\tconst rebasedPos = client.rebasePosition(4 /* index 4 into \"hello world\" */, 0, 0);\n\t\t\tconst rebasedPos1 = client.rebasePosition(\n\t\t\t\t4 /* index 4 into \"hello123456 world\" */,\n\t\t\t\t0,\n\t\t\t\t1,\n\t\t\t);\n\t\t\tconst rebasedPos2 = client.rebasePosition(4 /* index 4 into \"hel123456 world\" */, 0, 2);\n\n\t\t\tassert.equal(rebasedPos, 2);\n\t\t\tassert.equal(rebasedPos1, 2);\n\t\t\tassert.equal(rebasedPos2, 2);\n\t\t});\n\t});\n});\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
|
-
import { strict as assert } from "assert";
|
|
6
|
+
import { strict as assert } from "node:assert";
|
|
7
7
|
import { describeFuzz, makeRandom } from "@fluid-private/stochastic-test-utils";
|
|
8
8
|
import { annotateRange, applyMessages, doOverRange, generateClientNames, insert, removeRange, runMergeTreeOperationRunner, } from "./mergeTreeOperationRunner.js";
|
|
9
9
|
import { TestClient } from "./testClient.js";
|
|
@@ -23,20 +23,21 @@ function applyMessagesWithReconnect(startingSeq, messageDatas, clients, logger,
|
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
25
|
message.sequenceNumber = ++seq;
|
|
26
|
-
|
|
26
|
+
for (const c of clients)
|
|
27
|
+
c.applyMsg(message);
|
|
27
28
|
minSeq = message.minimumSequenceNumber;
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
const reconnectMsgs = [];
|
|
31
|
-
reconnectClientMsgs.
|
|
32
|
+
for (const [clientId, messageData] of reconnectClientMsgs.entries()) {
|
|
32
33
|
const client = clients.find(({ longClientId }) => longClientId === clientId);
|
|
33
|
-
|
|
34
|
+
for (const [op, segmentGroup] of messageData) {
|
|
34
35
|
const newMsg = client.makeOpMessage(client.regeneratePendingOp(op, segmentGroup));
|
|
35
36
|
newMsg.minimumSequenceNumber = minSeq;
|
|
36
37
|
// apply message doesn't use the segment group, so just pass undefined
|
|
37
38
|
reconnectMsgs.push([newMsg, undefined]);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
40
41
|
return applyMessages(seq, reconnectMsgs, clients, logger);
|
|
41
42
|
}
|
|
42
43
|
export const defaultOptions = {
|
|
@@ -59,9 +60,11 @@ function runReconnectFarmTests(opts, extraSeed) {
|
|
|
59
60
|
testOpts.resultsFilePostfix += extraSeed;
|
|
60
61
|
}
|
|
61
62
|
const clients = [new TestClient()];
|
|
62
|
-
|
|
63
|
+
for (const [i, c] of clients.entries())
|
|
64
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
63
65
|
let seq = 0;
|
|
64
|
-
|
|
66
|
+
for (const c of clients)
|
|
67
|
+
c.updateMinSeq(seq);
|
|
65
68
|
// Add double the number of clients each iteration
|
|
66
69
|
const targetClients = Math.max(opts.clients.min, clientCount);
|
|
67
70
|
for (let cc = clients.length; cc < targetClients; cc++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.reconnectFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.reconnectFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.reconnectFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.reconnectFarm.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { IRandom, describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp } from \"../ops.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tannotateRange,\n\tapplyMessages,\n\tdoOverRange,\n\tgenerateClientNames,\n\tinsert,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nfunction applyMessagesWithReconnect(\n\tstartingSeq: number,\n\tmessageDatas: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n): number {\n\tlet seq = startingSeq;\n\tconst reconnectingClientIds =\n\t\tclients.length > 2 && random.bool()\n\t\t\t? [clients[1].longClientId!, clients[2].longClientId!]\n\t\t\t: [clients[1].longClientId!];\n\tconst reconnectClientMsgs: Map<string, [IMergeTreeOp, SegmentGroup | SegmentGroup[]][]> =\n\t\tnew Map(reconnectingClientIds.map((id) => [id, []]));\n\tlet minSeq = 0;\n\t// log and apply all the ops created in the round\n\twhile (messageDatas.length > 0) {\n\t\tconst [message, sg] = messageDatas.shift()!;\n\t\tassert(message.clientId, \"expected clientId to be defined\");\n\t\tif (reconnectingClientIds.includes(message.clientId)) {\n\t\t\treconnectClientMsgs.get(message.clientId)!.push([message.contents as IMergeTreeOp, sg]);\n\t\t} else {\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) c.applyMsg(message);\n\t\t\tminSeq = message.minimumSequenceNumber;\n\t\t}\n\t}\n\n\tconst reconnectMsgs: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\tfor (const [clientId, messageData] of reconnectClientMsgs.entries()) {\n\t\tconst client = clients.find(({ longClientId }) => longClientId === clientId)!;\n\t\tfor (const [op, segmentGroup] of messageData) {\n\t\t\tconst newMsg = client.makeOpMessage(client.regeneratePendingOp(op, segmentGroup));\n\t\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\t\t// apply message doesn't use the segment group, so just pass undefined\n\t\t\treconnectMsgs.push([newMsg, undefined as never]);\n\t\t}\n\t}\n\n\treturn applyMessages(seq, reconnectMsgs, clients, logger);\n}\n\ninterface IReconnectFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IReconnectFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 2, max: 8 },\n\topsPerRoundRange: { min: 40, max: 320 },\n\trounds: 3,\n\toperations: [annotateRange, removeRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runReconnectFarmTests(opts: IReconnectFarmConfig, extraSeed?: number): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`ReconnectFarm_${clientCount}_${extraSeed ?? 0}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, clientCount, extraSeed ?? 0);\n\t\t\tconst testOpts = { ...opts };\n\t\t\tif (extraSeed) {\n\t\t\t\ttestOpts.resultsFilePostfix ??= \"\";\n\t\t\t\ttestOpts.resultsFilePostfix += extraSeed;\n\t\t\t}\n\n\t\t\tconst clients: TestClient[] = [new TestClient()];\n\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\tlet seq = 0;\n\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\n\t\t\t// Add double the number of clients each iteration\n\t\t\tconst targetClients = Math.max(opts.clients.min, clientCount);\n\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tclients.push(newClient);\n\t\t\t}\n\n\t\t\tseq = runMergeTreeOperationRunner(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\ttestOpts.minLength,\n\t\t\t\ttestOpts,\n\t\t\t\tapplyMessagesWithReconnect,\n\t\t\t);\n\t\t}).timeout(30 * 1000);\n\t});\n}\n\ndescribeFuzz(\"MergeTree.Client\", ({ testCount }) => {\n\tconst opts = defaultOptions;\n\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunReconnectFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunReconnectFarmTests(opts);\n\t}\n});\n"]}
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
|
-
import assert from "assert";
|
|
7
|
-
import * as fs from "fs";
|
|
6
|
+
import assert from "node:assert";
|
|
7
|
+
import * as fs from "node:fs";
|
|
8
8
|
import { createGroupOp } from "../opBuilder.js";
|
|
9
9
|
import { MergeTreeDeltaType } from "../ops.js";
|
|
10
10
|
import { replayResultsPath } from "./mergeTreeOperationRunner.js";
|
|
@@ -40,13 +40,14 @@ describe("MergeTree.Client", () => {
|
|
|
40
40
|
}
|
|
41
41
|
const op = msg.contents;
|
|
42
42
|
msgClient.client.localTransaction(op.type === MergeTreeDeltaType.GROUP ? op : createGroupOp(op));
|
|
43
|
-
|
|
43
|
+
for (const mc of msgClients)
|
|
44
|
+
mc[1].msgs.push(msg);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
while (mc.msgs.length > 0) {
|
|
47
|
-
mc.client.applyMsg(mc.msgs.shift());
|
|
46
|
+
for (const mc of msgClients) {
|
|
47
|
+
while (mc[1].msgs.length > 0) {
|
|
48
|
+
mc[1].client.applyMsg(mc[1].msgs.shift());
|
|
48
49
|
}
|
|
49
|
-
}
|
|
50
|
+
}
|
|
50
51
|
const result = logger.validate();
|
|
51
52
|
assert.strictEqual(result, group.resultText, "Result text not as expected");
|
|
52
53
|
logger.dispose();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.replay.spec.js","sourceRoot":"","sources":["../../src/test/client.replay.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"client.replay.spec.js","sourceRoot":"","sources":["../../src/test/client.replay.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport assert from \"node:assert\";\nimport * as fs from \"node:fs\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { createGroupOp } from \"../opBuilder.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\n\nimport { ReplayGroup, replayResultsPath } from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\ndescribe(\"MergeTree.Client\", () => {\n\tfor (const filePath of fs.readdirSync(replayResultsPath)) {\n\t\tit(`Replay ${filePath}`, async () => {\n\t\t\tconst file: ReplayGroup[] = JSON.parse(\n\t\t\t\tfs.readFileSync(`${replayResultsPath}/${filePath}`).toString(),\n\t\t\t) as ReplayGroup[];\n\t\t\tconst msgClients = new Map<\n\t\t\t\tstring,\n\t\t\t\t{ client: TestClient; msgs: ISequencedDocumentMessage[] }\n\t\t\t>();\n\t\t\tconst originalClient = new TestClient();\n\t\t\tmsgClients.set(\"A\", { client: originalClient, msgs: [] });\n\t\t\toriginalClient.insertTextLocal(0, file[0].initialText);\n\t\t\toriginalClient.startOrUpdateCollaboration(\"A\");\n\t\t\tfor (const group of file) {\n\t\t\t\tfor (const msg of group.msgs) {\n\t\t\t\t\tassert(msg.clientId, \"expected clientId to be defined\");\n\t\t\t\t\tif (!msgClients.has(msg.clientId)) {\n\t\t\t\t\t\tconst client = await TestClient.createFromClientSnapshot(\n\t\t\t\t\t\t\toriginalClient,\n\t\t\t\t\t\t\tmsg.clientId,\n\t\t\t\t\t\t);\n\t\t\t\t\t\tmsgClients.set(msg.clientId, { client, msgs: [] });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const group of file) {\n\t\t\t\tconst logger = new TestClientLogger([...msgClients.values()].map((mc) => mc.client));\n\t\t\t\tconst initialText = logger.validate();\n\t\t\t\tassert.strictEqual(initialText, group.initialText, \"Initial text not as expected\");\n\t\t\t\tfor (const msg of group.msgs) {\n\t\t\t\t\tconst msgClient = msgClients.get(msg.clientId!)!;\n\t\t\t\t\twhile (\n\t\t\t\t\t\tmsgClient.msgs.length > 0 &&\n\t\t\t\t\t\tmsg.referenceSequenceNumber > msgClient.client.getCurrentSeq()\n\t\t\t\t\t) {\n\t\t\t\t\t\tmsgClient.client.applyMsg(msgClient.msgs.shift()!);\n\t\t\t\t\t}\n\t\t\t\t\tconst op = msg.contents as IMergeTreeOp;\n\t\t\t\t\tmsgClient.client.localTransaction(\n\t\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op : createGroupOp(op),\n\t\t\t\t\t);\n\t\t\t\t\tfor (const mc of msgClients) mc[1].msgs.push(msg);\n\t\t\t\t}\n\n\t\t\t\tfor (const mc of msgClients) {\n\t\t\t\t\twhile (mc[1].msgs.length > 0) {\n\t\t\t\t\t\tmc[1].client.applyMsg(mc[1].msgs.shift()!);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst result = logger.validate();\n\t\t\t\tassert.strictEqual(result, group.resultText, \"Result text not as expected\");\n\t\t\t\tlogger.dispose();\n\t\t\t}\n\t\t}).timeout(30 * 10000);\n\t}\n});\n"]}
|