@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
|
@@ -44,7 +44,8 @@ function applyMessagesWithReconnect(startingSeq, messageDatas, clients, stashCli
|
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
46
46
|
message.sequenceNumber = ++seq;
|
|
47
|
-
|
|
47
|
+
for (const c of clients)
|
|
48
|
+
c.applyMsg(message);
|
|
48
49
|
minSeq = message.minimumSequenceNumber;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
@@ -54,18 +55,19 @@ function applyMessagesWithReconnect(startingSeq, messageDatas, clients, stashCli
|
|
|
54
55
|
let stashedOpSeq = startingSeq;
|
|
55
56
|
for (const msg of regeneratedStashedOps) {
|
|
56
57
|
msg.sequenceNumber = ++stashedOpSeq;
|
|
57
|
-
|
|
58
|
+
for (const c of stashClients)
|
|
59
|
+
c.applyMsg(msg);
|
|
58
60
|
}
|
|
59
61
|
// all stash and normal clients should now be in the same state,
|
|
60
62
|
// except #1 (normal) which still has local changes
|
|
61
63
|
TestClientLogger.validate([...clients.filter((_, i) => i !== 1), ...stashClients]);
|
|
62
64
|
// regenerate ops for client #1
|
|
63
65
|
const reconnectMsgs = [];
|
|
64
|
-
|
|
66
|
+
for (const opData of reconnectClientMsgs) {
|
|
65
67
|
const newMsg = clients[1].makeOpMessage(clients[1].regeneratePendingOp(opData[0], opData[1]));
|
|
66
68
|
newMsg.minimumSequenceNumber = minSeq;
|
|
67
69
|
reconnectMsgs.push(newMsg);
|
|
68
|
-
}
|
|
70
|
+
}
|
|
69
71
|
// apply regenerated ops as stashed ops for client #1
|
|
70
72
|
const stashedRegeneratedOps = reconnectMsgs.map((message) => {
|
|
71
73
|
const op = message.contents;
|
|
@@ -81,13 +83,15 @@ function applyMessagesWithReconnect(startingSeq, messageDatas, clients, stashCli
|
|
|
81
83
|
// apply the regenerated ops from client #1
|
|
82
84
|
for (const message of reconnectMsgs) {
|
|
83
85
|
message.sequenceNumber = ++seq;
|
|
84
|
-
|
|
86
|
+
for (const c of clients)
|
|
87
|
+
c.applyMsg(message);
|
|
85
88
|
}
|
|
86
89
|
// resubmit regenerated stashed ops
|
|
87
90
|
const reRegeneratedStashedMessages = stashedRegeneratedOps.map((stashedOp) => stashClients[1].makeOpMessage(stashClients[1].regeneratePendingOp(stashedOp[0], stashedOp[1])));
|
|
88
91
|
for (const reRegeneratedStashedOp of reRegeneratedStashedMessages) {
|
|
89
92
|
reRegeneratedStashedOp.sequenceNumber = ++stashedOpSeq;
|
|
90
|
-
|
|
93
|
+
for (const c of stashClients)
|
|
94
|
+
c.applyMsg(reRegeneratedStashedOp);
|
|
91
95
|
}
|
|
92
96
|
// all clients should now be the same
|
|
93
97
|
TestClientLogger.validate([...clients, ...stashClients]);
|
|
@@ -118,12 +122,16 @@ function runApplyStashedOpFarmTests(opts, extraSeed) {
|
|
|
118
122
|
// them to simulate resubmit(), then apply them. In the end, they should arrive
|
|
119
123
|
// at the same state as the "normal" set of clients
|
|
120
124
|
let stashClients = [];
|
|
121
|
-
|
|
125
|
+
for (const [i, c] of clients.entries())
|
|
126
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
122
127
|
stashClients = [new TestClient()];
|
|
123
|
-
|
|
128
|
+
for (const [i, c] of stashClients.entries())
|
|
129
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
124
130
|
let seq = 0;
|
|
125
|
-
|
|
126
|
-
|
|
131
|
+
for (const c of clients)
|
|
132
|
+
c.updateMinSeq(seq);
|
|
133
|
+
for (const c of stashClients)
|
|
134
|
+
c.updateMinSeq(seq);
|
|
127
135
|
// Add double the number of clients each iteration
|
|
128
136
|
const targetClients = Math.max(opts.clients.min, clientCount);
|
|
129
137
|
for (let cc = clients.length; cc < targetClients; cc++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.applyStashedOpFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.applyStashedOpFarm.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 { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tannotateRange,\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\tstashClients: readonly TestClient[],\n) {\n\tlet seq = startingSeq;\n\tconst reconnectClientMsgs: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] = [];\n\tlet minSeq = 0;\n\n\t// apply ops as stashed ops except for client #1\n\tconst stashedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[], number][] = [];\n\tfor (const messageData of messageDatas) {\n\t\tif (messageData[0].clientId !== clients[1].longClientId) {\n\t\t\tconst index = clients\n\t\t\t\t.map((c) => c.longClientId)\n\t\t\t\t.indexOf(messageData[0].clientId as string);\n\t\t\tconst op = messageData[0].contents as IMergeTreeOp;\n\t\t\tstashClients[index].applyStashedOp(op);\n\t\t\tstashedOps.push([\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[index].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t\tindex,\n\t\t\t]);\n\t\t}\n\t}\n\t// this should put all stash clients (except #1) in the same state as the\n\t// respective normal clients, having local changes only.\n\tfor (let i = 0; i < clients.length; ++i) {\n\t\tif (i !== 1) {\n\t\t\tTestClientLogger.validate([clients[i], stashClients[i]]);\n\t\t}\n\t}\n\tTestClientLogger.validate([clients[0], stashClients[1]]);\n\n\t// apply the ops to the normal clients. they will all be the same now,\n\t// except #1 which has local changes other clients haven't seen yet\n\tfor (const [message, sg] of messageDatas) {\n\t\tif (message.clientId === clients[1].longClientId) {\n\t\t\treconnectClientMsgs.push([message.contents as IMergeTreeOp, sg]);\n\t\t} else {\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tclients.forEach((c) => c.applyMsg(message));\n\t\t\tminSeq = message.minimumSequenceNumber;\n\t\t}\n\t}\n\n\t// regenerate the ops that were applied as stashed ops. this simulates resubmit()\n\tconst regeneratedStashedOps = stashedOps.map((op) =>\n\t\tstashClients[op[2]].makeOpMessage(stashClients[op[2]].regeneratePendingOp(op[0], op[1])),\n\t);\n\n\t// apply the regenerated stashed ops\n\tlet stashedOpSeq = startingSeq;\n\tfor (const msg of regeneratedStashedOps) {\n\t\tmsg.sequenceNumber = ++stashedOpSeq;\n\t\tstashClients.forEach((c) => c.applyMsg(msg));\n\t}\n\t// all stash and normal clients should now be in the same state,\n\t// except #1 (normal) which still has local changes\n\tTestClientLogger.validate([...clients.filter((_, i) => i !== 1), ...stashClients]);\n\n\t// regenerate ops for client #1\n\tconst reconnectMsgs: ISequencedDocumentMessage[] = [];\n\treconnectClientMsgs.forEach((opData) => {\n\t\tconst newMsg = clients[1].makeOpMessage(\n\t\t\tclients[1].regeneratePendingOp(opData[0], opData[1]),\n\t\t);\n\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\treconnectMsgs.push(newMsg);\n\t});\n\n\t// apply regenerated ops as stashed ops for client #1\n\tconst stashedRegeneratedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] =\n\t\treconnectMsgs.map((message) => {\n\t\t\tconst op = message.contents as IMergeTreeOp;\n\t\t\tstashClients[1].applyStashedOp(op);\n\t\t\treturn [\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[1].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t];\n\t\t});\n\t// now both clients at index 1 should be the same\n\tTestClientLogger.validate([clients[1], stashClients[1]]);\n\n\t// apply the regenerated ops from client #1\n\tfor (const message of reconnectMsgs) {\n\t\tmessage.sequenceNumber = ++seq;\n\t\tclients.forEach((c) => c.applyMsg(message));\n\t}\n\n\t// resubmit regenerated stashed ops\n\tconst reRegeneratedStashedMessages = stashedRegeneratedOps.map((stashedOp) =>\n\t\tstashClients[1].makeOpMessage(\n\t\t\tstashClients[1].regeneratePendingOp(stashedOp[0], stashedOp[1]),\n\t\t),\n\t);\n\n\tfor (const reRegeneratedStashedOp of reRegeneratedStashedMessages) {\n\t\treRegeneratedStashedOp.sequenceNumber = ++stashedOpSeq;\n\t\tstashClients.forEach((c) => c.applyMsg(reRegeneratedStashedOp));\n\t}\n\n\t// all clients should now be the same\n\tTestClientLogger.validate([...clients, ...stashClients]);\n\n\treturn seq;\n}\n\ninterface IApplyStashedOpFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IApplyStashedOpFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 3, max: 12 },\n\topsPerRoundRange: { min: 40, max: 120 },\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 runApplyStashedOpFarmTests(\n\topts: IApplyStashedOpFarmConfig,\n\textraSeed?: number,\n): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`applyStashedOpFarm_${clientCount}`, 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\t// This test is based on reconnectFarm, but we keep a second set of clients. For\n\t\t\t// these clients, we apply the generated ops as stashed ops, then regenerate\n\t\t\t// them to simulate resubmit(), then apply them. In the end, they should arrive\n\t\t\t// at the same state as the \"normal\" set of clients\n\t\t\tlet stashClients: TestClient[] = [];\n\n\t\t\tclients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));\n\t\t\tstashClients = [new TestClient()];\n\t\t\tstashClients.forEach((c, i) => c.startOrUpdateCollaboration(clientNames[i]));\n\n\t\t\tlet seq = 0;\n\t\t\tclients.forEach((c) => c.updateMinSeq(seq));\n\t\t\tstashClients.forEach((c) => 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\t// add 1 stash client per normal client\n\t\t\t\tconst anotherNewClient = 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\tstashClients.push(anotherNewClient);\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\topts.minLength,\n\t\t\t\topts,\n\t\t\t\t(s, m, c) => applyMessagesWithReconnect(s, m, c, stashClients),\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\trunApplyStashedOpFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunApplyStashedOpFarmTests(opts);\n\t}\n});\n"]}
|
|
1
|
+
{"version":3,"file":"client.applyStashedOpFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.applyStashedOpFarm.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 { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tannotateRange,\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\tstashClients: readonly TestClient[],\n): number {\n\tlet seq = startingSeq;\n\tconst reconnectClientMsgs: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] = [];\n\tlet minSeq = 0;\n\n\t// apply ops as stashed ops except for client #1\n\tconst stashedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[], number][] = [];\n\tfor (const messageData of messageDatas) {\n\t\tif (messageData[0].clientId !== clients[1].longClientId) {\n\t\t\tconst index = clients\n\t\t\t\t.map((c) => c.longClientId)\n\t\t\t\t.indexOf(messageData[0].clientId as string);\n\t\t\tconst op = messageData[0].contents as IMergeTreeOp;\n\t\t\tstashClients[index].applyStashedOp(op);\n\t\t\tstashedOps.push([\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[index].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t\tindex,\n\t\t\t]);\n\t\t}\n\t}\n\t// this should put all stash clients (except #1) in the same state as the\n\t// respective normal clients, having local changes only.\n\tfor (let i = 0; i < clients.length; ++i) {\n\t\tif (i !== 1) {\n\t\t\tTestClientLogger.validate([clients[i], stashClients[i]]);\n\t\t}\n\t}\n\tTestClientLogger.validate([clients[0], stashClients[1]]);\n\n\t// apply the ops to the normal clients. they will all be the same now,\n\t// except #1 which has local changes other clients haven't seen yet\n\tfor (const [message, sg] of messageDatas) {\n\t\tif (message.clientId === clients[1].longClientId) {\n\t\t\treconnectClientMsgs.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\t// regenerate the ops that were applied as stashed ops. this simulates resubmit()\n\tconst regeneratedStashedOps = stashedOps.map((op) =>\n\t\tstashClients[op[2]].makeOpMessage(stashClients[op[2]].regeneratePendingOp(op[0], op[1])),\n\t);\n\n\t// apply the regenerated stashed ops\n\tlet stashedOpSeq = startingSeq;\n\tfor (const msg of regeneratedStashedOps) {\n\t\tmsg.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(msg);\n\t}\n\t// all stash and normal clients should now be in the same state,\n\t// except #1 (normal) which still has local changes\n\tTestClientLogger.validate([...clients.filter((_, i) => i !== 1), ...stashClients]);\n\n\t// regenerate ops for client #1\n\tconst reconnectMsgs: ISequencedDocumentMessage[] = [];\n\tfor (const opData of reconnectClientMsgs) {\n\t\tconst newMsg = clients[1].makeOpMessage(\n\t\t\tclients[1].regeneratePendingOp(opData[0], opData[1]),\n\t\t);\n\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\treconnectMsgs.push(newMsg);\n\t}\n\n\t// apply regenerated ops as stashed ops for client #1\n\tconst stashedRegeneratedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] =\n\t\treconnectMsgs.map((message) => {\n\t\t\tconst op = message.contents as IMergeTreeOp;\n\t\t\tstashClients[1].applyStashedOp(op);\n\t\t\treturn [\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[1].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t];\n\t\t});\n\t// now both clients at index 1 should be the same\n\tTestClientLogger.validate([clients[1], stashClients[1]]);\n\n\t// apply the regenerated ops from client #1\n\tfor (const message of reconnectMsgs) {\n\t\tmessage.sequenceNumber = ++seq;\n\t\tfor (const c of clients) c.applyMsg(message);\n\t}\n\n\t// resubmit regenerated stashed ops\n\tconst reRegeneratedStashedMessages = stashedRegeneratedOps.map((stashedOp) =>\n\t\tstashClients[1].makeOpMessage(\n\t\t\tstashClients[1].regeneratePendingOp(stashedOp[0], stashedOp[1]),\n\t\t),\n\t);\n\n\tfor (const reRegeneratedStashedOp of reRegeneratedStashedMessages) {\n\t\treRegeneratedStashedOp.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(reRegeneratedStashedOp);\n\t}\n\n\t// all clients should now be the same\n\tTestClientLogger.validate([...clients, ...stashClients]);\n\n\treturn seq;\n}\n\ninterface IApplyStashedOpFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IApplyStashedOpFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 3, max: 12 },\n\topsPerRoundRange: { min: 40, max: 120 },\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 runApplyStashedOpFarmTests(\n\topts: IApplyStashedOpFarmConfig,\n\textraSeed?: number,\n): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`applyStashedOpFarm_${clientCount}`, 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\t// This test is based on reconnectFarm, but we keep a second set of clients. For\n\t\t\t// these clients, we apply the generated ops as stashed ops, then regenerate\n\t\t\t// them to simulate resubmit(), then apply them. In the end, they should arrive\n\t\t\t// at the same state as the \"normal\" set of clients\n\t\t\tlet stashClients: TestClient[] = [];\n\n\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\t\t\tstashClients = [new TestClient()];\n\t\t\tfor (const [i, c] of stashClients.entries())\n\t\t\t\tc.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\tlet seq = 0;\n\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\t\t\tfor (const c of stashClients) 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\t// add 1 stash client per normal client\n\t\t\t\tconst anotherNewClient = 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\tstashClients.push(anotherNewClient);\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\topts.minLength,\n\t\t\t\topts,\n\t\t\t\t(s, m, c) => applyMessagesWithReconnect(s, m, c, stashClients),\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\trunApplyStashedOpFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunApplyStashedOpFarmTests(opts);\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 { describeFuzz, makeRandom } from "@fluid-private/stochastic-test-utils";
|
|
7
7
|
import { generatePairwiseOptions } from "@fluid-private/test-pairwise-generator";
|
|
8
8
|
import { createPropertyTrackingAndInsertionAttributionPolicyFactory } from "../attributionPolicy.js";
|
|
@@ -23,16 +23,19 @@ describeFuzz("MergeTree.Attribution", ({ testCount }) => {
|
|
|
23
23
|
const clientNames = generateClientNames();
|
|
24
24
|
const rangeOptions = resolveRanges(defaultOptions, defaultOptions.growthFunc);
|
|
25
25
|
for (let extraSeed = 0; extraSeed < testCount; extraSeed++) {
|
|
26
|
-
|
|
26
|
+
for (const { initLen, modLen, opsPerRoundRange } of generatePairwiseOptions(rangeOptions)) {
|
|
27
27
|
it(`AttributionFarm_${initLen}_${modLen}_${opsPerRoundRange}`, async () => {
|
|
28
28
|
const random = makeRandom(0xdeadbeef, initLen, modLen, extraSeed ?? 0);
|
|
29
|
-
const clients =
|
|
29
|
+
const clients = Array.from({ length: 3 })
|
|
30
|
+
.fill(0)
|
|
31
|
+
.map(() => new TestClient({
|
|
30
32
|
attribution: {
|
|
31
33
|
track: true,
|
|
32
34
|
policyFactory: createPropertyTrackingAndInsertionAttributionPolicyFactory("trackedProp"),
|
|
33
35
|
},
|
|
34
36
|
}));
|
|
35
|
-
|
|
37
|
+
for (const [i, c] of clients.entries())
|
|
38
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
36
39
|
const getAttributionAtPosition = (client, pos) => {
|
|
37
40
|
const { segment, offset } = client.getContainingSegment(pos);
|
|
38
41
|
if (segment?.attribution === undefined || offset === undefined) {
|
|
@@ -73,7 +76,8 @@ describeFuzz("MergeTree.Attribution", ({ testCount }) => {
|
|
|
73
76
|
validateAnnotation("After Init Zamboni", () => {
|
|
74
77
|
// trigger zamboni multiple times as it is incremental
|
|
75
78
|
for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
|
|
76
|
-
|
|
79
|
+
for (const c of clients)
|
|
80
|
+
c.updateMinSeq(i);
|
|
77
81
|
}
|
|
78
82
|
});
|
|
79
83
|
validateAnnotation("After More Ops", () => {
|
|
@@ -82,11 +86,12 @@ describeFuzz("MergeTree.Attribution", ({ testCount }) => {
|
|
|
82
86
|
validateAnnotation("After Final Zamboni", () => {
|
|
83
87
|
// trigger zamboni multiple times as it is incremental
|
|
84
88
|
for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
|
|
85
|
-
|
|
89
|
+
for (const c of clients)
|
|
90
|
+
c.updateMinSeq(i);
|
|
86
91
|
}
|
|
87
92
|
});
|
|
88
93
|
});
|
|
89
|
-
}
|
|
94
|
+
}
|
|
90
95
|
}
|
|
91
96
|
});
|
|
92
97
|
//# sourceMappingURL=client.attributionFarm.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.attributionFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.attributionFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.attributionFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.attributionFarm.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 { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { generatePairwiseOptions } from \"@fluid-private/test-pairwise-generator\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport { createPropertyTrackingAndInsertionAttributionPolicyFactory } from \"../attributionPolicy.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tTestOperation,\n\tgenerateClientNames,\n\tinsert,\n\tremoveRange,\n\tresolveRanges,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.annotateRangeLocal(opStart, opEnd, { trackedProp: client.longClientId });\n\nconst defaultOptions: Record<\"initLen\" | \"modLen\", IConfigRange> &\n\tIMergeTreeOperationRunnerConfig = {\n\tinitLen: { min: 2, max: 4 },\n\tmodLen: { min: 1, max: 8 },\n\topsPerRoundRange: { min: 10, max: 40 },\n\trounds: 10,\n\toperations: [removeRange, annotateRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\ndescribeFuzz(\"MergeTree.Attribution\", ({ testCount }) => {\n\t// Generate a list of single character client names, support up to 69 clients\n\tconst clientNames = generateClientNames();\n\tconst rangeOptions = resolveRanges(defaultOptions, defaultOptions.growthFunc);\n\tfor (let extraSeed = 0; extraSeed < testCount; extraSeed++) {\n\t\tfor (const { initLen, modLen, opsPerRoundRange } of generatePairwiseOptions(\n\t\t\trangeOptions,\n\t\t)) {\n\t\t\tit(`AttributionFarm_${initLen}_${modLen}_${opsPerRoundRange}`, async () => {\n\t\t\t\tconst random = makeRandom(0xdeadbeef, initLen, modLen, extraSeed ?? 0);\n\n\t\t\t\tconst clients: TestClient[] = Array.from({ length: 3 })\n\t\t\t\t\t.fill(0)\n\t\t\t\t\t.map(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tnew TestClient({\n\t\t\t\t\t\t\t\tattribution: {\n\t\t\t\t\t\t\t\t\ttrack: true,\n\t\t\t\t\t\t\t\t\tpolicyFactory:\n\t\t\t\t\t\t\t\t\t\tcreatePropertyTrackingAndInsertionAttributionPolicyFactory(\"trackedProp\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\t\tconst getAttributionAtPosition = (\n\t\t\t\t\tclient: TestClient,\n\t\t\t\t\tpos: number,\n\t\t\t\t):\n\t\t\t\t\t| {\n\t\t\t\t\t\t\t[name: string]: AttributionKey | undefined;\n\t\t\t\t\t }\n\t\t\t\t\t| undefined => {\n\t\t\t\t\tconst { segment, offset } = client.getContainingSegment(pos);\n\t\t\t\t\tif (segment?.attribution === undefined || offset === undefined) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst { attribution } = segment;\n\t\t\t\t\tlet channels: { [name: string]: AttributionKey | undefined } | undefined;\n\t\t\t\t\tconst result: {\n\t\t\t\t\t\troot: AttributionKey | undefined;\n\t\t\t\t\t\tchannels?: { [name: string]: AttributionKey | undefined };\n\t\t\t\t\t} = {\n\t\t\t\t\t\troot: attribution.getAtOffset(offset),\n\t\t\t\t\t};\n\t\t\t\t\tfor (const name of attribution.channelNames) {\n\t\t\t\t\t\t(channels ??= {})[name] = attribution.getAtOffset(offset, name);\n\t\t\t\t\t\tresult.channels = channels;\n\t\t\t\t\t}\n\t\t\t\t\treturn channels;\n\t\t\t\t};\n\n\t\t\t\tconst validateAnnotation = (reason: string, workload: () => void): void => {\n\t\t\t\t\tconst preWorkload = TestClientLogger.toString(clients);\n\t\t\t\t\tworkload();\n\t\t\t\t\tconst attributions = Array.from({ length: clients[0].getLength() }).map((_, i) =>\n\t\t\t\t\t\tgetAttributionAtPosition(clients[0], i),\n\t\t\t\t\t);\n\t\t\t\t\tfor (let c = 1; c < clients.length; c++) {\n\t\t\t\t\t\tfor (let i = 0; i < clients[c].getLength(); i++) {\n\t\t\t\t\t\t\tconst attribution0 = attributions[i];\n\t\t\t\t\t\t\tconst attributionC = getAttributionAtPosition(clients[c], i);\n\t\t\t\t\t\t\tif (attribution0 !== attributionC) {\n\t\t\t\t\t\t\t\tassert.deepEqual(\n\t\t\t\t\t\t\t\t\tattribution0,\n\t\t\t\t\t\t\t\t\tattributionC,\n\t\t\t\t\t\t\t\t\t`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString([\n\t\t\t\t\t\t\t\t\t\tclients[0],\n\t\t\t\t\t\t\t\t\t\tclients[c],\n\t\t\t\t\t\t\t\t\t])}`,\n\t\t\t\t\t\t\t\t);\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\n\t\t\t\tlet seq = 0;\n\n\t\t\t\tvalidateAnnotation(\"Initialize\", () => {\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, initLen, defaultOptions);\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After Init Zamboni\", () => {\n\t\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After More Ops\", () => {\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, modLen, defaultOptions);\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After Final Zamboni\", () => {\n\t\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t}\n});\n"]}
|
|
@@ -51,10 +51,12 @@ function runConflictFarmTests(opts, extraSeed) {
|
|
|
51
51
|
testOpts.resultsFilePostfix += extraSeed;
|
|
52
52
|
}
|
|
53
53
|
const clients = [new TestClient()];
|
|
54
|
-
|
|
54
|
+
for (const [i, c] of clients.entries())
|
|
55
|
+
c.startOrUpdateCollaboration(clientNames[i]);
|
|
55
56
|
let seq = 0;
|
|
56
57
|
while (clients.length < opts.clients.max) {
|
|
57
|
-
|
|
58
|
+
for (const c of clients)
|
|
59
|
+
c.updateMinSeq(seq);
|
|
58
60
|
// Add double the number of clients each iteration
|
|
59
61
|
const targetClients = Math.max(opts.clients.min, opts.growthFunc(clients.length));
|
|
60
62
|
for (let cc = clients.length; cc < targetClients; cc++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.conflictFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.conflictFarm.spec.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"client.conflictFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.conflictFarm.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 { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tTestOperation,\n\tannotateRange,\n\tdoOverRange,\n\tgenerateClientNames,\n\tinsertAtRefPos,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\n\ninterface IConflictFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: IConfigRange;\n\tclients: IConfigRange;\n}\n\nconst allOperations: TestOperation[] = [removeRange, annotateRange, insertAtRefPos];\n\nexport const debugOptions: IConflictFarmConfig = {\n\tminLength: { min: 1, max: 1 },\n\tclients: { min: 3, max: 3 },\n\topsPerRoundRange: { min: 1, max: 100 },\n\trounds: 1000,\n\toperations: allOperations,\n\tincrementalLog: true,\n\tgrowthFunc: (input: number) => input + 1,\n};\n\nexport const defaultOptions: IConflictFarmConfig = {\n\tminLength: { min: 1, max: 512 },\n\tclients: { min: 1, max: 8 },\n\topsPerRoundRange: { min: 1, max: 128 },\n\trounds: 8,\n\toperations: allOperations,\n\tgrowthFunc: (input: number) => input * 2,\n};\n\nexport const longOptions: IConflictFarmConfig = {\n\tminLength: { min: 1, max: 512 },\n\tclients: { min: 1, max: 32 },\n\topsPerRoundRange: { min: 1, max: 512 },\n\trounds: 32,\n\toperations: allOperations,\n\tgrowthFunc: (input: number) => input * 2,\n};\n\nexport const stressOptions: IConflictFarmConfig = {\n\tminLength: { min: 1, max: 512 },\n\tclients: { min: 1, max: 32 },\n\topsPerRoundRange: { min: 1, max: 128 },\n\trounds: 32,\n\toperations: allOperations,\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 runConflictFarmTests(opts: IConflictFarmConfig, extraSeed?: number): void {\n\tdoOverRange(opts.minLength, opts.growthFunc, (minLength) => {\n\t\tit(`ConflictFarm_${minLength}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, minLength, 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\twhile (clients.length < opts.clients.max) {\n\t\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\n\t\t\t\t// Add double the number of clients each iteration\n\t\t\t\tconst targetClients = Math.max(opts.clients.min, opts.growthFunc(clients.length));\n\t\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\t\tclients[0],\n\t\t\t\t\t\tclientNames[cc],\n\t\t\t\t\t);\n\t\t\t\t\tclients.push(newClient);\n\t\t\t\t}\n\n\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, minLength, opts);\n\t\t\t}\n\t\t}).timeout(30 * 10000);\n\t});\n}\n\ndescribeFuzz(\"MergeTree.Client\", ({ testCount, isStress }) => {\n\tconst opts = isStress ? stressOptions : defaultOptions;\n\t// defaultOptions;\n\t// debugOptions;\n\t// longOptions;\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\trunConflictFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunConflictFarmTests(opts);\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 { TextSegment } from "../textSegment.js";
|
|
8
8
|
import { TestClient } from "./testClient.js";
|
|
9
9
|
describe("client.getPosition", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.getPosition.spec.js","sourceRoot":"","sources":["../../src/test/client.getPosition.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6DAA6D;AAE7D,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"client.getPosition.spec.js","sourceRoot":"","sources":["../../src/test/client.getPosition.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 { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\ndescribe(\"client.getPosition\", () => {\n\tconst localUserLongId = \"localUser\";\n\tlet client: TestClient;\n\tlet segment: TextSegment;\n\tconst segPos = 4;\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tfor (const c of \"hello world\") {\n\t\t\tclient.insertTextLocal(client.getLength(), c);\n\t\t}\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\n\t\tconst segOff = client.getContainingSegment(segPos);\n\t\tassert(TextSegment.is(segOff.segment!));\n\t\tassert.strictEqual(segOff.offset, 0);\n\t\tassert.strictEqual(segOff.segment.text, \"o\");\n\t\tsegment = segOff.segment;\n\t});\n\n\tit(\"Existing Segment\", () => {\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos);\n\t});\n\n\tit(\"Deleted Segment\", () => {\n\t\tclient.removeRangeLocal(segPos, segPos + 1);\n\t\tassert.notStrictEqual(segment.removedSeq, undefined);\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos);\n\t});\n\n\tit(\"Detached Segment\", () => {\n\t\tclient.applyMsg(client.makeOpMessage(client.removeRangeLocal(segPos, segPos + 1), 1));\n\t\t// do some work and move the client's min seq forward, so zamboni runs\n\t\tfor (const c of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), c),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t\tclient.getCurrentSeq(),\n\t\t\t\t\tundefined,\n\t\t\t\t\tclient.getCurrentSeq(),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.notStrictEqual(segment.removedSeq, undefined);\n\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, -1);\n\t});\n\n\tit(\"Moved Segment\", () => {\n\t\tclient.removeRangeLocal(segPos - 1, segPos);\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos - 1);\n\t});\n});\n"]}
|
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
|
5
6
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
6
|
-
import { strict as assert } from "assert";
|
|
7
|
+
import { strict as assert } from "node:assert";
|
|
7
8
|
import { SlidingPreference, setValidateRefCount, } from "../localReference.js";
|
|
8
9
|
import { getSlideToSegoff } from "../mergeTree.js";
|
|
9
10
|
import { toRemovalInfo } from "../mergeTreeNodes.js";
|
|
@@ -316,10 +317,12 @@ describe("MergeTree.Client", () => {
|
|
|
316
317
|
// apply all the ops
|
|
317
318
|
while (messages.length > 0) {
|
|
318
319
|
const msg = messages.shift();
|
|
319
|
-
|
|
320
|
+
for (const c of clients.all)
|
|
321
|
+
c.applyMsg(msg);
|
|
320
322
|
}
|
|
321
323
|
// regression: would fire 0x2be on zamboni during segment append
|
|
322
|
-
|
|
324
|
+
for (const c of clients.all)
|
|
325
|
+
c.updateMinSeq(seq);
|
|
323
326
|
});
|
|
324
327
|
describe("avoids removing StayOnRemove references on local + remote concurrent delete", () => {
|
|
325
328
|
let client;
|
|
@@ -407,7 +410,7 @@ describe("MergeTree.Client", () => {
|
|
|
407
410
|
},
|
|
408
411
|
];
|
|
409
412
|
describe("doesn't crash for remove ref then link to undefined", () => {
|
|
410
|
-
|
|
413
|
+
for (const { name, addRef } of tgCases) {
|
|
411
414
|
it(name, () => {
|
|
412
415
|
const client1 = new TestClient();
|
|
413
416
|
const client2 = new TestClient();
|
|
@@ -426,6 +429,8 @@ describe("MergeTree.Client", () => {
|
|
|
426
429
|
assert(!segInfo.segment.localRefs.empty);
|
|
427
430
|
segInfo.segment.localRefs.removeLocalRef(localRef);
|
|
428
431
|
assert(segInfo.segment.localRefs.empty);
|
|
432
|
+
// Cast is necessary because LocalReference is not exported, so we can't directly call link.
|
|
433
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
429
434
|
localRef.link(undefined, 0, undefined);
|
|
430
435
|
assert(segInfo.segment.localRefs.empty);
|
|
431
436
|
assert.equal(segInfo.segment.localRefs.empty, true);
|
|
@@ -433,10 +438,10 @@ describe("MergeTree.Client", () => {
|
|
|
433
438
|
assert.equal(localRef.getSegment(), undefined);
|
|
434
439
|
assert.equal(localRef.getOffset(), 0);
|
|
435
440
|
});
|
|
436
|
-
}
|
|
441
|
+
}
|
|
437
442
|
});
|
|
438
443
|
describe("doesn't crash for link to undefined then remove ref", () => {
|
|
439
|
-
|
|
444
|
+
for (const { name, addRef } of tgCases) {
|
|
440
445
|
it(name, () => {
|
|
441
446
|
const client1 = new TestClient();
|
|
442
447
|
const client2 = new TestClient();
|
|
@@ -453,6 +458,8 @@ describe("MergeTree.Client", () => {
|
|
|
453
458
|
assert.equal(localRef.getSegment(), segInfo.segment);
|
|
454
459
|
assert(segInfo.segment.localRefs);
|
|
455
460
|
assert(!segInfo.segment.localRefs.empty);
|
|
461
|
+
// Cast is necessary because LocalReference is not exported, so we can't directly call link
|
|
462
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
456
463
|
localRef.link(undefined, 0, undefined);
|
|
457
464
|
assert(segInfo.segment.localRefs.empty);
|
|
458
465
|
segInfo.segment.localRefs.removeLocalRef(localRef);
|
|
@@ -462,7 +469,7 @@ describe("MergeTree.Client", () => {
|
|
|
462
469
|
assert.equal(localRef.getSegment(), undefined);
|
|
463
470
|
assert.equal(localRef.getOffset(), 0);
|
|
464
471
|
});
|
|
465
|
-
}
|
|
472
|
+
}
|
|
466
473
|
});
|
|
467
474
|
});
|
|
468
475
|
//# sourceMappingURL=client.localReference.spec.js.map
|