@fluidframework/merge-tree 2.23.0 → 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +407 -399
- package/api-report/merge-tree.legacy.alpha.api.md +1 -0
- package/dist/MergeTreeTextHelper.d.ts +9 -3
- package/dist/MergeTreeTextHelper.d.ts.map +1 -1
- package/dist/MergeTreeTextHelper.js +5 -5
- package/dist/MergeTreeTextHelper.js.map +1 -1
- package/dist/client.d.ts +7 -13
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +136 -110
- package/dist/client.js.map +1 -1
- package/dist/endOfTreeSegment.d.ts +12 -8
- package/dist/endOfTreeSegment.d.ts.map +1 -1
- package/dist/endOfTreeSegment.js +2 -4
- package/dist/endOfTreeSegment.js.map +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +38 -22
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +408 -486
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeDeltaCallback.d.ts +4 -8
- package/dist/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/dist/mergeTreeDeltaCallback.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +32 -10
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +43 -28
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts +2 -2
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +181 -109
- package/dist/partialLengths.js.map +1 -1
- package/dist/perspective.d.ts +84 -65
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +109 -108
- package/dist/perspective.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +2 -2
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentInfos.d.ts +20 -106
- package/dist/segmentInfos.d.ts.map +1 -1
- package/dist/segmentInfos.js +28 -42
- package/dist/segmentInfos.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts +1 -14
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +3 -17
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +62 -19
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +55 -24
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +6 -9
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/stamps.d.ts +90 -0
- package/dist/stamps.d.ts.map +1 -0
- package/dist/stamps.js +90 -0
- package/dist/stamps.js.map +1 -0
- package/dist/test/Insertion.perf.spec.js +6 -51
- package/dist/test/Insertion.perf.spec.js.map +1 -1
- package/dist/test/PartialLengths.perf.spec.js +18 -25
- package/dist/test/PartialLengths.perf.spec.js.map +1 -1
- package/dist/test/Removal.perf.spec.js +13 -41
- package/dist/test/Removal.perf.spec.js.map +1 -1
- package/dist/test/beastTest.spec.d.ts.map +1 -1
- package/dist/test/beastTest.spec.js +41 -66
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js +1 -11
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +14 -14
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +1 -1
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +1 -1
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +49 -58
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/client.rollbackFarm.spec.js +1 -1
- package/dist/test/client.rollbackFarm.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +4 -21
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/index.d.ts +2 -2
- package/dist/test/index.d.ts.map +1 -1
- package/dist/test/index.js +2 -6
- package/dist/test/index.js.map +1 -1
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js +14 -59
- package/dist/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +47 -63
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.insert.deltaCallback.spec.js +9 -62
- package/dist/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.insertingWalk.spec.js +59 -125
- package/dist/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +12 -93
- package/dist/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +10 -7
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/mergeTree.walk.spec.js +2 -14
- package/dist/test/mergeTree.walk.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +2 -2
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.concurrent.spec.js +18 -23
- package/dist/test/obliterate.concurrent.spec.js.map +1 -1
- package/dist/test/obliterate.partialLength.spec.js +166 -136
- package/dist/test/obliterate.partialLength.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +16 -126
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/partialLength.spec.js +28 -196
- package/dist/test/partialLength.spec.js.map +1 -1
- package/{prettier.config.cjs → dist/test/perspective.spec.d.ts} +2 -4
- package/dist/test/perspective.spec.d.ts.map +1 -0
- package/dist/test/perspective.spec.js +153 -0
- package/dist/test/perspective.spec.js.map +1 -0
- package/dist/test/propertyManager.spec.js +1 -1
- package/dist/test/propertyManager.spec.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +0 -2
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/segmentGroupCollection.spec.js +10 -4
- package/dist/test/segmentGroupCollection.spec.js.map +1 -1
- package/dist/test/stamps.spec.d.ts +6 -0
- package/dist/test/stamps.spec.d.ts.map +1 -0
- package/dist/test/stamps.spec.js +130 -0
- package/dist/test/stamps.spec.js.map +1 -0
- package/dist/test/testClient.d.ts +1 -0
- package/dist/test/testClient.d.ts.map +1 -1
- package/dist/test/testClient.js +16 -26
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/testClientLogger.d.ts +9 -0
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +59 -47
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/test/testServer.d.ts +2 -1
- package/dist/test/testServer.d.ts.map +1 -1
- package/dist/test/testServer.js +7 -5
- package/dist/test/testServer.js.map +1 -1
- package/dist/test/testUtils.d.ts +36 -56
- package/dist/test/testUtils.d.ts.map +1 -1
- package/dist/test/testUtils.js +68 -77
- package/dist/test/testUtils.js.map +1 -1
- package/dist/test/text.d.ts +2 -2
- package/dist/test/text.d.ts.map +1 -1
- package/dist/test/text.js +5 -2
- package/dist/test/text.js.map +1 -1
- package/dist/textSegment.d.ts +0 -6
- package/dist/textSegment.d.ts.map +1 -1
- package/dist/textSegment.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +53 -26
- package/dist/zamboni.js.map +1 -1
- package/lib/MergeTreeTextHelper.d.ts +9 -3
- package/lib/MergeTreeTextHelper.d.ts.map +1 -1
- package/lib/MergeTreeTextHelper.js +5 -5
- package/lib/MergeTreeTextHelper.js.map +1 -1
- package/lib/client.d.ts +7 -13
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +117 -116
- package/lib/client.js.map +1 -1
- package/lib/endOfTreeSegment.d.ts +12 -8
- package/lib/endOfTreeSegment.d.ts.map +1 -1
- package/lib/endOfTreeSegment.js +2 -4
- package/lib/endOfTreeSegment.js.map +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +38 -22
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +389 -491
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeDeltaCallback.d.ts +4 -8
- package/lib/mergeTreeDeltaCallback.d.ts.map +1 -1
- package/lib/mergeTreeDeltaCallback.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +32 -10
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +42 -29
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts +2 -2
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +160 -111
- package/lib/partialLengths.js.map +1 -1
- package/lib/perspective.d.ts +84 -65
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +82 -103
- package/lib/perspective.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +2 -2
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentInfos.d.ts +20 -106
- package/lib/segmentInfos.d.ts.map +1 -1
- package/lib/segmentInfos.js +26 -37
- package/lib/segmentInfos.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts +1 -14
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +2 -16
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +39 -19
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +34 -26
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +7 -10
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/stamps.d.ts +90 -0
- package/lib/stamps.d.ts.map +1 -0
- package/lib/stamps.js +77 -0
- package/lib/stamps.js.map +1 -0
- package/lib/test/Insertion.perf.spec.js +6 -51
- package/lib/test/Insertion.perf.spec.js.map +1 -1
- package/lib/test/PartialLengths.perf.spec.js +18 -25
- package/lib/test/PartialLengths.perf.spec.js.map +1 -1
- package/lib/test/Removal.perf.spec.js +13 -41
- package/lib/test/Removal.perf.spec.js.map +1 -1
- package/lib/test/beastTest.spec.d.ts.map +1 -1
- package/lib/test/beastTest.spec.js +42 -67
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js +1 -11
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +14 -14
- package/lib/test/client.applyMsg.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 +1 -1
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +50 -59
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/client.rollbackFarm.spec.js +1 -1
- package/lib/test/client.rollbackFarm.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +4 -21
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/index.d.ts +2 -2
- package/lib/test/index.d.ts.map +1 -1
- package/lib/test/index.js +1 -1
- package/lib/test/index.js.map +1 -1
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js +15 -60
- package/lib/test/mergeTree.annotate.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +48 -64
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.insert.deltaCallback.spec.js +10 -63
- package/lib/test/mergeTree.insert.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.insertingWalk.spec.js +61 -127
- package/lib/test/mergeTree.insertingWalk.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js +13 -94
- package/lib/test/mergeTree.markRangeRemoved.deltaCallback.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +10 -7
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/mergeTree.walk.spec.js +2 -14
- package/lib/test/mergeTree.walk.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +3 -3
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.concurrent.spec.js +18 -23
- package/lib/test/obliterate.concurrent.spec.js.map +1 -1
- package/lib/test/obliterate.partialLength.spec.js +167 -137
- package/lib/test/obliterate.partialLength.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +17 -127
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/partialLength.spec.js +29 -197
- package/lib/test/partialLength.spec.js.map +1 -1
- package/lib/test/perspective.spec.d.ts +6 -0
- package/lib/test/perspective.spec.d.ts.map +1 -0
- package/lib/test/perspective.spec.js +151 -0
- package/lib/test/perspective.spec.js.map +1 -0
- package/lib/test/propertyManager.spec.js +2 -2
- package/lib/test/propertyManager.spec.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +0 -2
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/segmentGroupCollection.spec.js +10 -4
- package/lib/test/segmentGroupCollection.spec.js.map +1 -1
- package/lib/test/stamps.spec.d.ts +6 -0
- package/lib/test/stamps.spec.d.ts.map +1 -0
- package/lib/test/stamps.spec.js +105 -0
- package/lib/test/stamps.spec.js.map +1 -0
- package/lib/test/testClient.d.ts +1 -0
- package/lib/test/testClient.d.ts.map +1 -1
- package/lib/test/testClient.js +18 -28
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/testClientLogger.d.ts +9 -0
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +60 -48
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/test/testServer.d.ts +2 -1
- package/lib/test/testServer.d.ts.map +1 -1
- package/lib/test/testServer.js +7 -5
- package/lib/test/testServer.js.map +1 -1
- package/lib/test/testUtils.d.ts +36 -56
- package/lib/test/testUtils.d.ts.map +1 -1
- package/lib/test/testUtils.js +66 -48
- package/lib/test/testUtils.js.map +1 -1
- package/lib/test/text.d.ts +2 -2
- package/lib/test/text.d.ts.map +1 -1
- package/lib/test/text.js +6 -3
- package/lib/test/text.js.map +1 -1
- package/lib/textSegment.d.ts +0 -6
- package/lib/textSegment.d.ts.map +1 -1
- package/lib/textSegment.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +32 -28
- package/lib/zamboni.js.map +1 -1
- package/package.json +18 -21
- package/src/MergeTreeTextHelper.ts +17 -12
- package/src/client.ts +141 -197
- package/src/endOfTreeSegment.ts +11 -8
- package/src/index.ts +4 -3
- package/src/mergeTree.ts +501 -631
- package/src/mergeTreeDeltaCallback.ts +4 -8
- package/src/mergeTreeNodes.ts +66 -45
- package/src/partialLengths.ts +181 -137
- package/src/perspective.ts +127 -129
- package/src/revertibles.ts +2 -7
- package/src/segmentInfos.ts +48 -141
- package/src/segmentPropertiesManager.ts +2 -16
- package/src/snapshotLoader.ts +62 -30
- package/src/snapshotV1.ts +36 -28
- package/src/snapshotlegacy.ts +7 -16
- package/src/stamps.ts +164 -0
- package/src/textSegment.ts +0 -13
- package/src/zamboni.ts +38 -32
- package/tsconfig.json +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamps.spec.js","sourceRoot":"","sources":["../../src/test/stamps.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 { UnassignedSequenceNumber } from \"../constants.js\";\nimport * as opstampUtils from \"../stamps.js\";\nimport type { OperationStamp } from \"../stamps.js\";\n\nfunction lessThan(a: OperationStamp, b: OperationStamp): boolean {\n\tconst result = opstampUtils.lessThan(a, b);\n\t// Validate that this gives a consistent result with some other ways to compute the same thing\n\tconst fromComparison = opstampUtils.compare(a, b) === -1;\n\tconst fromGte = !opstampUtils.gte(a, b);\n\tassert.strictEqual(result, fromComparison);\n\tassert.strictEqual(result, fromGte);\n\treturn result;\n}\n\nfunction greaterThan(a: OperationStamp, b: OperationStamp): boolean {\n\tconst result = opstampUtils.greaterThan(a, b);\n\t// Validate that this gives a consistent result with some other ways to compute the same thing\n\tconst fromComparison = opstampUtils.compare(a, b) === 1;\n\tconst fromLte = !opstampUtils.lte(a, b);\n\tassert.strictEqual(result, fromComparison);\n\tassert.strictEqual(result, fromLte);\n\treturn result;\n}\n\n/**\n * Validate that a list of operation stamps is in strictly increasing order in several different ways using the comparison\n * operation stamp utility methods.\n */\nfunction expectStrictlyIncreasing(list: OperationStamp[]): void {\n\tfor (let i = 0; i < list.length - 1; i++) {\n\t\tassert.ok(\n\t\t\tlessThan(list[i], list[i + 1]),\n\t\t\t`List not strictly increasing by lessThan: ${JSON.stringify(list[i])} >= ${JSON.stringify(list[i + 1])}`,\n\t\t);\n\t\tassert.ok(\n\t\t\tgreaterThan(list[i + 1], list[i]),\n\t\t\t`List not strictly increasing by greaterThan: ${JSON.stringify(list[i + 1])} <= ${JSON.stringify(list[i])}`,\n\t\t);\n\t}\n}\n\ndescribe(\"opstampUtils\", () => {\n\tconst acked1: OperationStamp = { clientId: 1, seq: 1 };\n\tconst acked2: OperationStamp = { clientId: 2, seq: 2 };\n\tconst acked3: OperationStamp = { clientId: 1, seq: 3 };\n\tconst local1: OperationStamp = { clientId: 1, seq: UnassignedSequenceNumber, localSeq: 1 };\n\tconst local2: OperationStamp = { clientId: 1, seq: UnassignedSequenceNumber, localSeq: 2 };\n\tdescribe(\"equality\", () => {\n\t\tit(\"returns true for reference equal stamps\", () => {\n\t\t\tfor (const stamp of [acked1, acked2, acked3, local1, local2]) {\n\t\t\t\tassert.ok(opstampUtils.equal(stamp, stamp));\n\t\t\t}\n\t\t});\n\n\t\tit(\"returns true for equal stamps\", () => {\n\t\t\tfor (const stamp of [acked1, acked2, acked3, local1, local2]) {\n\t\t\t\tassert.ok(opstampUtils.equal(stamp, { ...stamp }));\n\t\t\t}\n\t\t});\n\n\t\tit(\"returns false for different stamps\", () => {\n\t\t\tassert.ok(!opstampUtils.equal(acked1, acked2));\n\t\t\tassert.ok(!opstampUtils.equal(acked1, acked3));\n\t\t\tassert.ok(!opstampUtils.equal(acked1, local1));\n\t\t\tassert.ok(!opstampUtils.equal(acked1, local2));\n\t\t\tassert.ok(!opstampUtils.equal(local1, local2));\n\t\t});\n\t});\n\n\tdescribe(\"comparison\", () => {\n\t\tit(\"orders stamps correctly\", () => {\n\t\t\texpectStrictlyIncreasing([acked1, acked2, acked3, local1, local2]);\n\t\t});\n\n\t\tit(\"compare can sort lists\", () => {\n\t\t\tconst list = [acked3, local1, acked1, local2, acked2];\n\t\t\tlist.sort(opstampUtils.compare);\n\t\t\tassert.deepEqual(list, [acked1, acked2, acked3, local1, local2]);\n\t\t});\n\t});\n\n\tdescribe(\"spliceIntoList\", () => {\n\t\tit(\"inserts unacked into empty list\", () => {\n\t\t\tconst list: OperationStamp[] = [];\n\t\t\topstampUtils.spliceIntoList(list, local1);\n\t\t\tassert.deepStrictEqual(list, [local1]);\n\t\t});\n\n\t\tit(\"inserts acked into empty list\", () => {\n\t\t\tconst list: OperationStamp[] = [];\n\t\t\topstampUtils.spliceIntoList(list, acked1);\n\t\t\tassert.deepStrictEqual(list, [acked1]);\n\t\t});\n\n\t\tit(\"inserts unacked after acked\", () => {\n\t\t\tconst list: OperationStamp[] = [acked1];\n\t\t\topstampUtils.spliceIntoList(list, local1);\n\t\t\tassert.deepStrictEqual(list, [acked1, local1]);\n\t\t});\n\n\t\tit(\"inserts acked before unacked\", () => {\n\t\t\tconst list: OperationStamp[] = [acked1, acked2, local1];\n\t\t\topstampUtils.spliceIntoList(list, acked3);\n\t\t\tassert.deepStrictEqual(list, [acked1, acked2, acked3, local1]);\n\t\t});\n\n\t\tit(\"inserts acked before single unacked\", () => {\n\t\t\tconst list: OperationStamp[] = [local1];\n\t\t\topstampUtils.spliceIntoList(list, acked2);\n\t\t\tassert.deepStrictEqual(list, [acked2, local1]);\n\t\t});\n\n\t\tit(\"inserts local seqs at end\", () => {\n\t\t\tconst list: OperationStamp[] = [acked1, acked2];\n\t\t\topstampUtils.spliceIntoList(list, local1);\n\t\t\topstampUtils.spliceIntoList(list, local2);\n\t\t\tassert.deepStrictEqual(list, [acked1, acked2, local1, local2]);\n\t\t});\n\t});\n});\n"]}
|
package/lib/test/testClient.d.ts
CHANGED
|
@@ -47,6 +47,7 @@ export declare class TestClient extends Client {
|
|
|
47
47
|
insertTextLocal(pos: number, text: string, props?: PropertySet): IMergeTreeInsertMsg | undefined;
|
|
48
48
|
insertTextRemote(pos: number, text: string, props: PropertySet | undefined, seq: number, refSeq: number, longClientId: string): void;
|
|
49
49
|
removeRangeRemote(start: number, end: number, seq: number, refSeq: number, longClientId: string): void;
|
|
50
|
+
obliterateRangeRemote(start: number, end: number, seq: number, refSeq: number, longClientId: string): void;
|
|
50
51
|
annotateRangeRemote(start: number, end: number, props: PropertySet, seq: number, refSeq: number, longClientId: string): void;
|
|
51
52
|
insertMarkerLocal(pos: number, behaviors: ReferenceType, props?: PropertySet): IMergeTreeInsertMsg | undefined;
|
|
52
53
|
insertMarkerRemote(pos: number, markerDef: IMarkerDef, props: PropertySet, seq: number, refSeq: number, longClientId: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClient.d.ts","sourceRoot":"","sources":["../../src/test/testClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,OAAO,EACN,KAAK,EAEL,yBAAyB,EACzB,MAAM,6CAA6C,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,8CAA8C,CAAC;AAE9E,OAAO,EAAE,WAAW,EAAE,MAAM,6CAA6C,CAAC;AAG1E,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,EAAE,SAAS,EAAoB,MAAM,iBAAiB,CAAC;AAM9D,OAAO,EAEN,eAAe,EAGf,KAAK,YAAY,EAEjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"testClient.d.ts","sourceRoot":"","sources":["../../src/test/testClient.ts"],"names":[],"mappings":"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"}
|
package/lib/test/testClient.js
CHANGED
|
@@ -15,10 +15,11 @@ import { UnassignedSequenceNumber } from "../constants.js";
|
|
|
15
15
|
import { getSlideToSegoff } from "../mergeTree.js";
|
|
16
16
|
import { backwardExcursion, forwardExcursion, walkAllChildSegments, } from "../mergeTreeNodeWalk.js";
|
|
17
17
|
import { Marker, MaxNodesInBlock, assertSegmentLeaf, } from "../mergeTreeNodes.js";
|
|
18
|
-
import { createAnnotateRangeOp, createInsertSegmentOp, createRemoveRangeOp, } from "../opBuilder.js";
|
|
18
|
+
import { createAnnotateRangeOp, createInsertSegmentOp, createObliterateRangeOp, createRemoveRangeOp, } from "../opBuilder.js";
|
|
19
19
|
import { MergeTreeDeltaType, ReferenceType, } from "../ops.js";
|
|
20
|
+
import { LocalReconnectingPerspective, PriorPerspective } from "../perspective.js";
|
|
20
21
|
import { DetachedReferencePosition, refHasTileLabel } from "../referencePositions.js";
|
|
21
|
-
import { assertInserted, assertMergeNode,
|
|
22
|
+
import { assertInserted, assertMergeNode, isRemoved } from "../segmentInfos.js";
|
|
22
23
|
import { SnapshotLegacy } from "../snapshotlegacy.js";
|
|
23
24
|
import { TextSegment } from "../textSegment.js";
|
|
24
25
|
import { TestSerializer } from "./testSerializer.js";
|
|
@@ -35,6 +36,9 @@ export function specToSegment(spec) {
|
|
|
35
36
|
throw new Error(`Unrecognized IJSONSegment type: '${JSON.stringify(spec)}'`);
|
|
36
37
|
}
|
|
37
38
|
const random = makeRandom(0xdeadbeef, 0xfeedbed);
|
|
39
|
+
function opStampToString(stamp) {
|
|
40
|
+
return stamp.seq === UnassignedSequenceNumber ? `L${stamp.localSeq}` : `${stamp.seq}`;
|
|
41
|
+
}
|
|
38
42
|
export class TestClient extends Client {
|
|
39
43
|
static async createFromClientSnapshot(client1, newLongClientId) {
|
|
40
44
|
const snapshot = new SnapshotLegacy(client1.mergeTree, createChildLogger({ namespace: "fluid:snapshot" }));
|
|
@@ -81,7 +85,7 @@ export class TestClient extends Client {
|
|
|
81
85
|
});
|
|
82
86
|
}
|
|
83
87
|
getText(start, end) {
|
|
84
|
-
return this.textHelper.getText(this.
|
|
88
|
+
return this.textHelper.getText(this.mergeTree.localPerspective, "", start, end);
|
|
85
89
|
}
|
|
86
90
|
enqueueTestString() {
|
|
87
91
|
this.checkQ.push(this.getText());
|
|
@@ -120,6 +124,9 @@ export class TestClient extends Client {
|
|
|
120
124
|
removeRangeRemote(start, end, seq, refSeq, longClientId) {
|
|
121
125
|
this.applyMsg(this.makeOpMessage(createRemoveRangeOp(start, end), seq, refSeq, longClientId));
|
|
122
126
|
}
|
|
127
|
+
obliterateRangeRemote(start, end, seq, refSeq, longClientId) {
|
|
128
|
+
this.applyMsg(this.makeOpMessage(createObliterateRangeOp(start, end), seq, refSeq, longClientId));
|
|
129
|
+
}
|
|
123
130
|
annotateRangeRemote(start, end, props, seq, refSeq, longClientId) {
|
|
124
131
|
this.applyMsg(this.makeOpMessage(createAnnotateRangeOp(start, end, props), seq, refSeq, longClientId));
|
|
125
132
|
}
|
|
@@ -132,7 +139,7 @@ export class TestClient extends Client {
|
|
|
132
139
|
this.applyMsg(this.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId));
|
|
133
140
|
}
|
|
134
141
|
relText(clientId, refSeq) {
|
|
135
|
-
return `cli: ${this.getLongClientId(clientId)} refSeq: ${refSeq}: ${this.textHelper.getText(refSeq, clientId)}`;
|
|
142
|
+
return `cli: ${this.getLongClientId(clientId)} refSeq: ${refSeq}: ${this.textHelper.getText(new PriorPerspective(refSeq, clientId))}`;
|
|
136
143
|
}
|
|
137
144
|
makeOpMessage(op, seq = UnassignedSequenceNumber, refSeq = this.getCurrentSeq(), longClientId, minSeqNumber = 0) {
|
|
138
145
|
if (op === undefined) {
|
|
@@ -179,11 +186,9 @@ export class TestClient extends Client {
|
|
|
179
186
|
walkAllChildSegments(tree.root, (segment) => {
|
|
180
187
|
const prefixes = [];
|
|
181
188
|
assertInserted(segment);
|
|
182
|
-
prefixes.push(segment.
|
|
189
|
+
prefixes.push(opStampToString(segment.insert));
|
|
183
190
|
if (isRemoved(segment)) {
|
|
184
|
-
prefixes.push(segment.
|
|
185
|
-
? `L${segment.localRemovedSeq}`
|
|
186
|
-
: segment.removedSeq);
|
|
191
|
+
prefixes.push(opStampToString(segment.removes[0]));
|
|
187
192
|
}
|
|
188
193
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
189
194
|
test.push(`${prefixes.join(",")}:${segment.text}`);
|
|
@@ -199,16 +204,11 @@ export class TestClient extends Client {
|
|
|
199
204
|
let segment;
|
|
200
205
|
let posAccumulated = 0;
|
|
201
206
|
let offset = pos;
|
|
202
|
-
const
|
|
203
|
-
((seg.seq !== UnassignedSequenceNumber && seg.seq <= seqNumberFrom) ||
|
|
204
|
-
(seg.localSeq !== undefined && seg.localSeq <= localSeq));
|
|
205
|
-
const isRemovedFromView = (s) => isRemoved(s) &&
|
|
206
|
-
((s.removedSeq !== UnassignedSequenceNumber && s.removedSeq <= seqNumberFrom) ||
|
|
207
|
-
(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));
|
|
207
|
+
const perspective = new LocalReconnectingPerspective(seqNumberFrom, this.getCollabWindow().clientId, localSeq);
|
|
208
208
|
walkAllChildSegments(this.mergeTree.root, (seg) => {
|
|
209
209
|
assertInserted(seg);
|
|
210
210
|
segment = seg;
|
|
211
|
-
if (
|
|
211
|
+
if (perspective.isSegmentPresent(seg)) {
|
|
212
212
|
posAccumulated += seg.cachedLength;
|
|
213
213
|
if (offset >= seg.cachedLength) {
|
|
214
214
|
offset -= seg.cachedLength;
|
|
@@ -226,14 +226,8 @@ export class TestClient extends Client {
|
|
|
226
226
|
}
|
|
227
227
|
findReconnectionPosition(segment, localSeq) {
|
|
228
228
|
const fasterComputedPosition = super.findReconnectionPosition(segment, localSeq);
|
|
229
|
+
const perspective = new LocalReconnectingPerspective(Number.MAX_SAFE_INTEGER, this.getCollabWindow().clientId, localSeq);
|
|
229
230
|
let segmentPosition = 0;
|
|
230
|
-
const isInsertedInView = (seg) => isInserted(seg) && (seg.localSeq === undefined || seg.localSeq <= localSeq);
|
|
231
|
-
const isRemovedFromView = (s) => isRemoved(s) &&
|
|
232
|
-
(s.removedSeq !== UnassignedSequenceNumber ||
|
|
233
|
-
(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));
|
|
234
|
-
const isMovedFromView = (s) => isMoved(s) &&
|
|
235
|
-
(s.movedSeq !== UnassignedSequenceNumber ||
|
|
236
|
-
(s.localMovedSeq !== undefined && s.localMovedSeq <= localSeq));
|
|
237
231
|
/*
|
|
238
232
|
Walk the segments up to the current segment, and calculate its
|
|
239
233
|
position taking into account local segments that were modified,
|
|
@@ -244,12 +238,8 @@ export class TestClient extends Client {
|
|
|
244
238
|
if (seg === segment) {
|
|
245
239
|
return false;
|
|
246
240
|
}
|
|
247
|
-
// Otherwise, advance segmentPosition if the segment
|
|
248
|
-
|
|
249
|
-
//
|
|
250
|
-
// Note that all ACKed / remote ops are applied and we only need concern ourself with
|
|
251
|
-
// determining if locally pending ops fall before/after the given 'localSeq'.
|
|
252
|
-
if (isInsertedInView(seg) && !isRemovedFromView(seg) && !isMovedFromView(seg)) {
|
|
241
|
+
// Otherwise, advance segmentPosition if the segment is visible at the given perspective.
|
|
242
|
+
if (perspective.isSegmentPresent(seg)) {
|
|
253
243
|
segmentPosition += seg.cachedLength;
|
|
254
244
|
}
|
|
255
245
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClient.js","sourceRoot":"","sources":["../../src/test/testClient.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 { Trace } from \"@fluid-internal/client-utils\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions/internal\";\nimport { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport {\n\tITree,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { MockStorage } from \"@fluidframework/test-runtime-utils/internal\";\n\nimport { MergeTreeTextHelper } from \"../MergeTreeTextHelper.js\";\nimport { Client } from \"../client.js\";\nimport { DoublyLinkedList } from \"../collections/index.js\";\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions, ReferencePosition } from \"../index.js\";\nimport { MergeTree, getSlideToSegoff } from \"../mergeTree.js\";\nimport {\n\tbackwardExcursion,\n\tforwardExcursion,\n\twalkAllChildSegments,\n} from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMergeBlock,\n\tISegmentPrivate,\n\tMarker,\n\tMaxNodesInBlock,\n\ttype SegmentGroup,\n\tassertSegmentLeaf,\n} from \"../mergeTreeNodes.js\";\nimport {\n\tcreateAnnotateRangeOp,\n\tcreateInsertSegmentOp,\n\tcreateRemoveRangeOp,\n} from \"../opBuilder.js\";\nimport {\n\tIJSONSegment,\n\tIMarkerDef,\n\tIMergeTreeOp,\n\tMergeTreeDeltaType,\n\tReferenceType,\n\ttype IMergeTreeInsertMsg,\n} from \"../ops.js\";\nimport { PropertySet } from \"../properties.js\";\nimport { DetachedReferencePosition, refHasTileLabel } from \"../referencePositions.js\";\nimport { MergeTreeRevertibleDriver } from \"../revertibles.js\";\nimport {\n\tassertInserted,\n\tassertMergeNode,\n\tisInserted,\n\tisMoved,\n\tisRemoved,\n} from \"../segmentInfos.js\";\nimport { SnapshotLegacy } from \"../snapshotlegacy.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestSerializer } from \"./testSerializer.js\";\nimport { nodeOrdinalsHaveIntegrity } from \"./testUtils.js\";\n\nexport function specToSegment(spec: IJSONSegment): ISegmentPrivate {\n\tconst maybeText = TextSegment.fromJSONObject(spec);\n\tif (maybeText) {\n\t\treturn maybeText;\n\t}\n\n\tconst maybeMarker = Marker.fromJSONObject(spec);\n\tif (maybeMarker) {\n\t\treturn maybeMarker;\n\t}\n\n\tthrow new Error(`Unrecognized IJSONSegment type: '${JSON.stringify(spec)}'`);\n}\n\nconst random = makeRandom(0xdeadbeef, 0xfeedbed);\n\nexport class TestClient extends Client {\n\tpublic static searchChunkSize = 256;\n\tpublic static readonly serializer = new TestSerializer();\n\tpublic measureOps = false;\n\tpublic accumTime = 0;\n\tpublic accumWindowTime = 0;\n\tpublic accumWindow = 0;\n\tpublic accumOps = 0;\n\tpublic maxWindowTime = 0;\n\n\t/**\n\t * Used for in-memory testing. This will queue a reference string for each client message.\n\t */\n\tpublic static useCheckQ = false;\n\n\tpublic static async createFromClientSnapshot(\n\t\tclient1: TestClient,\n\t\tnewLongClientId: string,\n\t): Promise<TestClient> {\n\t\tconst snapshot = new SnapshotLegacy(\n\t\t\tclient1.mergeTree,\n\t\t\tcreateChildLogger({ namespace: \"fluid:snapshot\" }),\n\t\t);\n\t\tsnapshot.extractSync();\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summaryTree = snapshot.emit([], TestClient.serializer, undefined!).summary;\n\t\treturn TestClient.createFromSummary(\n\t\t\tsummaryTree,\n\t\t\tnewLongClientId,\n\t\t\tclient1.specToSegment,\n\t\t\tclient1.mergeTree.options,\n\t\t);\n\t}\n\n\tpublic static async createFromSnapshot(\n\t\tsnapshotTree: ITree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tnew MockStorage(snapshotTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromSummary(\n\t\tsummaryTree: ISummaryTree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tMockStorage.createFromSummary(summaryTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromStorage(\n\t\tstorage: MockStorage,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\tconst client2 = new TestClient(options, specToSeg);\n\t\tconst { catchupOpsP } = await client2.load(\n\t\t\t{\n\t\t\t\tlogger: client2.logger,\n\t\t\t\tclientId: newLongClientId,\n\t\t\t} as unknown as IFluidDataStoreRuntime,\n\t\t\tstorage,\n\t\t\tTestClient.serializer,\n\t\t);\n\t\tawait catchupOpsP;\n\t\treturn client2;\n\t}\n\n\tpublic readonly mergeTree: MergeTree;\n\n\tpublic readonly checkQ: DoublyLinkedList<string> = new DoublyLinkedList<string>();\n\tprotected readonly q: DoublyLinkedList<ISequencedDocumentMessage> =\n\t\tnew DoublyLinkedList<ISequencedDocumentMessage>();\n\n\tprivate readonly textHelper: MergeTreeTextHelper;\n\tconstructor(\n\t\toptions?: IMergeTreeOptions & PropertySet,\n\t\tspecToSeg = specToSegment,\n\t\tgetMinInFlightRefSeq: () => number | undefined = (): undefined => undefined,\n\t) {\n\t\tsuper(\n\t\t\tspecToSeg,\n\t\t\tcreateChildLogger({ namespace: \"fluid:testClient\" }),\n\t\t\toptions,\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\t\tthis.mergeTree = (this as Record<\"_mergeTree\", MergeTree>)._mergeTree;\n\t\tthis.textHelper = new MergeTreeTextHelper(this.mergeTree);\n\n\t\t// Validate by default\n\t\tthis.on(\"delta\", (o, d) => {\n\t\t\t// assert.notEqual(d.deltaSegments.length, 0);\n\t\t\tfor (const s of d.deltaSegments) {\n\t\t\t\tif (d.operation === MergeTreeDeltaType.INSERT) {\n\t\t\t\t\tassertMergeNode(s.segment);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic getText(start?: number, end?: number): string {\n\t\treturn this.textHelper.getText(this.getCurrentSeq(), this.getClientId(), \"\", start, end);\n\t}\n\n\tpublic enqueueTestString(): void {\n\t\tthis.checkQ.push(this.getText());\n\t}\n\tpublic getMessageCount(): number {\n\t\treturn this.q.length;\n\t}\n\tpublic enqueueMsg(msg: ISequencedDocumentMessage): void {\n\t\tthis.q.push(msg);\n\t}\n\tpublic dequeueMsg(): ISequencedDocumentMessage | undefined {\n\t\treturn this.q.shift()?.data;\n\t}\n\tpublic applyMessages(msgCount: number): boolean {\n\t\tlet currMsgCount = msgCount;\n\t\twhile (currMsgCount > 0) {\n\t\t\tconst msg = this.dequeueMsg();\n\t\t\tif (msg) {\n\t\t\t\tthis.applyMsg(msg);\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrMsgCount--;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tpublic insertTextLocal(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = TextSegment.make(text, props);\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertTextRemote(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops: PropertySet | undefined,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = TextSegment.make(text, props);\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic removeRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createRemoveRangeOp(start, end), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic annotateRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createAnnotateRangeOp(start, end, props), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic insertMarkerLocal(\n\t\tpos: number,\n\t\tbehaviors: ReferenceType,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = Marker.make(behaviors, props);\n\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertMarkerRemote(\n\t\tpos: number,\n\t\tmarkerDef: IMarkerDef,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = Marker.make(markerDef.refType ?? ReferenceType.Tile, props);\n\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic relText(clientId: number, refSeq: number): string {\n\t\treturn `cli: ${this.getLongClientId(\n\t\t\tclientId,\n\t\t)} refSeq: ${refSeq}: ${this.textHelper.getText(refSeq, clientId)}`;\n\t}\n\n\tpublic makeOpMessage(\n\t\top: IMergeTreeOp | undefined,\n\t\tseq: number = UnassignedSequenceNumber,\n\t\trefSeq: number = this.getCurrentSeq(),\n\t\tlongClientId?: string,\n\t\tminSeqNumber = 0,\n\t): ISequencedDocumentMessage {\n\t\tif (op === undefined) {\n\t\t\tthrow new Error(\"op cannot be undefined\");\n\t\t}\n\t\tconst msg: ISequencedDocumentMessage = {\n\t\t\tclientId: longClientId ?? this.longClientId ?? \"\",\n\t\t\tclientSequenceNumber: 1,\n\t\t\tcontents: op,\n\t\t\tmetadata: undefined,\n\t\t\tminimumSequenceNumber: minSeqNumber,\n\t\t\treferenceSequenceNumber: refSeq,\n\t\t\tsequenceNumber: seq,\n\t\t\ttimestamp: Date.now(),\n\t\t\ttraces: [],\n\t\t\ttype: MessageType.Operation,\n\t\t};\n\t\treturn msg;\n\t}\n\n\tpublic validate(): void {\n\t\tassert(nodeOrdinalsHaveIntegrity(this.mergeTree.root));\n\t}\n\n\tpublic searchFromPos(\n\t\tpos: number,\n\t\ttarget: RegExp,\n\t): { text: string; pos: number } | undefined {\n\t\tlet start = pos;\n\t\tlet chunk = \"\";\n\t\twhile (start < this.getLength()) {\n\t\t\tchunk = this.getText(start, start + TestClient.searchChunkSize);\n\n\t\t\tconst result = chunk.match(target);\n\t\t\tif (result?.index) {\n\t\t\t\treturn { text: result[0], pos: result.index + start };\n\t\t\t}\n\t\t\tstart += TestClient.searchChunkSize;\n\t\t}\n\t}\n\n\tpublic findRandomWord(): { text: string; pos: number } | undefined {\n\t\tconst len = this.getLength();\n\t\tconst pos = random.integer(0, len);\n\t\tconst nextWord = this.searchFromPos(pos, /\\s\\w+\\b/);\n\t\treturn nextWord;\n\t}\n\n\tpublic debugDumpTree(tree: MergeTree): string[] {\n\t\t// want the segment's content and the state of insert/remove\n\t\tconst test: string[] = [];\n\t\twalkAllChildSegments(tree.root, (segment: ISegmentPrivate) => {\n\t\t\tconst prefixes: (string | undefined | number)[] = [];\n\t\t\tassertInserted(segment);\n\t\t\tprefixes.push(\n\t\t\t\tsegment.seq === UnassignedSequenceNumber ? `L${segment.localSeq}` : segment.seq,\n\t\t\t);\n\t\t\tif (isRemoved(segment)) {\n\t\t\t\tprefixes.push(\n\t\t\t\t\tsegment.removedSeq === UnassignedSequenceNumber\n\t\t\t\t\t\t? `L${segment.localRemovedSeq}`\n\t\t\t\t\t\t: segment.removedSeq,\n\t\t\t\t);\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\ttest.push(`${prefixes.join(\",\")}:${(segment as any).text}`);\n\t\t});\n\t\treturn test;\n\t}\n\n\t/**\n\t * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective\n\t * of the current sequence number. This is desirable when rebasing operations for reconnection. Perform\n\t * slow-path computations in this function without leveraging the merge-tree's structure\n\t */\n\tpublic rebasePosition(pos: number, seqNumberFrom: number, localSeq: number): number {\n\t\tlet segment: ISegmentPrivate | undefined;\n\t\tlet posAccumulated = 0;\n\t\tlet offset = pos;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) &&\n\t\t\t((seg.seq !== UnassignedSequenceNumber && seg.seq <= seqNumberFrom) ||\n\t\t\t\t(seg.localSeq !== undefined && seg.localSeq <= localSeq));\n\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t((s.removedSeq !== UnassignedSequenceNumber && s.removedSeq <= seqNumberFrom) ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\tassertInserted(seg);\n\t\t\tsegment = seg;\n\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg)) {\n\t\t\t\tposAccumulated += seg.cachedLength;\n\t\t\t\tif (offset >= seg.cachedLength) {\n\t\t\t\t\toffset -= seg.cachedLength;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Keep going while we've yet to reach the segment at the desired position\n\t\t\treturn posAccumulated <= pos;\n\t\t});\n\n\t\tassert(segment !== undefined, \"No segment found\");\n\t\tconst segoff = getSlideToSegoff({ segment, offset }) ?? segment;\n\t\tif (segoff.segment === undefined || segoff.offset === undefined) {\n\t\t\treturn DetachedReferencePosition;\n\t\t}\n\n\t\treturn this.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;\n\t}\n\n\tpublic findReconnectionPosition(segment: ISegmentPrivate, localSeq: number): number {\n\t\tconst fasterComputedPosition = super.findReconnectionPosition(segment, localSeq);\n\n\t\tlet segmentPosition = 0;\n\t\tconst isInsertedInView = (seg: ISegmentPrivate): boolean =>\n\t\t\tisInserted(seg) && (seg.localSeq === undefined || seg.localSeq <= localSeq);\n\t\tconst isRemovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisRemoved(s) &&\n\t\t\t(s.removedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localRemovedSeq !== undefined && s.localRemovedSeq <= localSeq));\n\t\tconst isMovedFromView = (s: ISegmentPrivate): boolean =>\n\t\t\tisMoved(s) &&\n\t\t\t(s.movedSeq !== UnassignedSequenceNumber ||\n\t\t\t\t(s.localMovedSeq !== undefined && s.localMovedSeq <= localSeq));\n\t\t/*\n Walk the segments up to the current segment, and calculate its\n position taking into account local segments that were modified,\n after the current segment.\n */\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\t// If we've found the desired segment, terminate the walk and return 'segmentPosition'.\n\t\t\tif (seg === segment) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise, advance segmentPosition if the segment has been inserted and not removed\n\t\t\t// with respect to the given 'localSeq'.\n\t\t\t//\n\t\t\t// Note that all ACKed / remote ops are applied and we only need concern ourself with\n\t\t\t// determining if locally pending ops fall before/after the given 'localSeq'.\n\t\t\tif (isInsertedInView(seg) && !isRemovedFromView(seg) && !isMovedFromView(seg)) {\n\t\t\t\tsegmentPosition += seg.cachedLength;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\tassert.equal(\n\t\t\tfasterComputedPosition,\n\t\t\tsegmentPosition,\n\t\t\t\"Expected fast-path computation to match result from walk all segments\",\n\t\t);\n\t\treturn segmentPosition;\n\t}\n\n\t/**\n\t * Validates segments either all have attribution information or none of them.\n\t * If no segment has attribution information, returns undefined.\n\t *\n\t * @param channel - Attribution channel name to request information from.\n\t * @returns an array of all attribution seq#s from the current perspective.\n\t * The `i`th entry of the array is the attribution key for the character at position `i`.\n\t */\n\tpublic getAllAttributionSeqs(channel?: string): (number | AttributionKey | undefined)[] {\n\t\tconst seqs: (number | AttributionKey | undefined)[] = [];\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tfor (let i = 0; i < segment.cachedLength; i++) {\n\t\t\t\tconst key = segment.attribution?.getAtOffset(i, channel);\n\t\t\t\tseqs.push(key?.type === \"op\" ? key.seq : key);\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\treturn seqs;\n\t}\n\n\tpublic peekPendingSegmentGroups(): SegmentGroup | undefined;\n\tpublic peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;\n\tpublic peekPendingSegmentGroups(\n\t\tcount: number = 1,\n\t): SegmentGroup | SegmentGroup[] | undefined {\n\t\treturn super.peekPendingSegmentGroups(count) as SegmentGroup | SegmentGroup[] | undefined;\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tpublic applyMsg(msg: ISequencedDocumentMessage, local: boolean = false): void {\n\t\tlet traceStart: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttraceStart = Trace.start();\n\t\t}\n\n\t\tsuper.applyMsg(msg, local);\n\n\t\tif (traceStart) {\n\t\t\tthis.accumTime += elapsedMicroseconds(traceStart);\n\t\t\tthis.accumOps++;\n\t\t\tthis.accumWindow += this.getCurrentSeq() - this.getCollabWindow().minSeq;\n\t\t}\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tupdateMinSeq(minSeq: number): void {\n\t\tlet trace: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttrace = Trace.start();\n\t\t}\n\n\t\tsuper.updateMinSeq(minSeq);\n\t\tif (trace) {\n\t\t\tconst elapsed = elapsedMicroseconds(trace);\n\t\t\tthis.accumWindowTime += elapsed;\n\t\t\tif (elapsed > this.maxWindowTime) {\n\t\t\t\tthis.maxWindowTime = elapsed;\n\t\t\t}\n\t\t}\n\t}\n\n\tslowSearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): ReferencePosition | undefined {\n\t\tlet foundMarker: Marker | undefined;\n\n\t\tconst { segment } = this.getContainingSegment<ISegmentPrivate>(startPos);\n\t\tassertSegmentLeaf(segment);\n\t\tif (Marker.is(segment)) {\n\t\t\tif (refHasTileLabel(segment, markerLabel)) {\n\t\t\t\tfoundMarker = segment;\n\t\t\t}\n\t\t} else {\n\t\t\tif (forwards) {\n\t\t\t\tforwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tbackwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn foundMarker;\n\t}\n}\n\nfunction elapsedMicroseconds(trace: Trace): number {\n\treturn trace.trace().duration * 1000;\n}\n\n// the client doesn't submit ops, so this adds a callback to capture them\nexport type TestClientRevertibleDriver = MergeTreeRevertibleDriver &\n\tPartial<{ submitOpCallback?: (op: IMergeTreeOp | undefined) => void }>;\n\nexport const createRevertDriver = (client: TestClient): TestClientRevertibleDriver => {\n\treturn {\n\t\tremoveRange(start: number, end: number): void {\n\t\t\tconst op = client.removeRangeLocal(start, end);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tannotateRange(start: number, end: number, props: PropertySet): void {\n\t\t\tconst op = client.annotateRangeLocal(start, end, props);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tinsertFromSpec(pos: number, spec: IJSONSegment): void {\n\t\t\tconst op = client.insertSegmentLocal(pos, client.specToSegment(spec));\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t};\n};\n\nexport interface MergeTreeStats {\n\tmaxHeight: number;\n\tnodeCount: number;\n\tleafCount: number;\n\tremovedLeafCount: number;\n\tliveCount: number;\n\thisto: number[];\n\twindowTime?: number;\n\tpackTime?: number;\n\tordTime?: number;\n\tmaxOrdTime?: number;\n}\n\nexport function getStats(tree: MergeTree): MergeTreeStats {\n\tconst nodeGetStats = (block: MergeBlock): MergeTreeStats => {\n\t\tconst stats: MergeTreeStats = {\n\t\t\tmaxHeight: 0,\n\t\t\tnodeCount: 0,\n\t\t\tleafCount: 0,\n\t\t\tremovedLeafCount: 0,\n\t\t\tliveCount: 0,\n\t\t\thisto: [],\n\t\t};\n\t\tfor (let k = 0; k < MaxNodesInBlock; k++) {\n\t\t\tstats.histo[k] = 0;\n\t\t}\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tlet height = 1;\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tstats.leafCount++;\n\t\t\t\tconst segment = child;\n\t\t\t\tif (isRemoved(segment)) {\n\t\t\t\t\tstats.removedLeafCount++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst childStats = nodeGetStats(child);\n\t\t\t\theight = 1 + childStats.maxHeight;\n\t\t\t\tstats.nodeCount += childStats.nodeCount;\n\t\t\t\tstats.leafCount += childStats.leafCount;\n\t\t\t\tstats.removedLeafCount += childStats.removedLeafCount;\n\t\t\t\tstats.liveCount += childStats.liveCount;\n\t\t\t\tfor (let j = 0; j < MaxNodesInBlock; j++) {\n\t\t\t\t\tstats.histo[j] += childStats.histo[j];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (height > stats.maxHeight) {\n\t\t\t\tstats.maxHeight = height;\n\t\t\t}\n\t\t}\n\t\tstats.histo[block.childCount]++;\n\t\tstats.nodeCount++;\n\t\tstats.liveCount += block.childCount;\n\t\treturn stats;\n\t};\n\tconst rootStats = nodeGetStats(tree.root);\n\treturn rootStats;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testClient.js","sourceRoot":"","sources":["../../src/test/testClient.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 { Trace } from \"@fluid-internal/client-utils\";\nimport { makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { IFluidDataStoreRuntime } from \"@fluidframework/datastore-definitions/internal\";\nimport { ISummaryTree } from \"@fluidframework/driver-definitions\";\nimport {\n\tITree,\n\tMessageType,\n\tISequencedDocumentMessage,\n} from \"@fluidframework/driver-definitions/internal\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\nimport { createChildLogger } from \"@fluidframework/telemetry-utils/internal\";\nimport { MockStorage } from \"@fluidframework/test-runtime-utils/internal\";\n\nimport { MergeTreeTextHelper } from \"../MergeTreeTextHelper.js\";\nimport { Client } from \"../client.js\";\nimport { DoublyLinkedList } from \"../collections/index.js\";\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions, ReferencePosition } from \"../index.js\";\nimport { MergeTree, getSlideToSegoff } from \"../mergeTree.js\";\nimport {\n\tbackwardExcursion,\n\tforwardExcursion,\n\twalkAllChildSegments,\n} from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMergeBlock,\n\tISegmentPrivate,\n\tMarker,\n\tMaxNodesInBlock,\n\ttype SegmentGroup,\n\tassertSegmentLeaf,\n} from \"../mergeTreeNodes.js\";\nimport {\n\tcreateAnnotateRangeOp,\n\tcreateInsertSegmentOp,\n\tcreateObliterateRangeOp,\n\tcreateRemoveRangeOp,\n} from \"../opBuilder.js\";\nimport {\n\tIJSONSegment,\n\tIMarkerDef,\n\tIMergeTreeOp,\n\tMergeTreeDeltaType,\n\tReferenceType,\n\ttype IMergeTreeInsertMsg,\n} from \"../ops.js\";\nimport { LocalReconnectingPerspective, PriorPerspective } from \"../perspective.js\";\nimport { PropertySet } from \"../properties.js\";\nimport { DetachedReferencePosition, refHasTileLabel } from \"../referencePositions.js\";\nimport { MergeTreeRevertibleDriver } from \"../revertibles.js\";\nimport { assertInserted, assertMergeNode, isRemoved } from \"../segmentInfos.js\";\nimport { SnapshotLegacy } from \"../snapshotlegacy.js\";\nimport type { OperationStamp } from \"../stamps.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestSerializer } from \"./testSerializer.js\";\nimport { nodeOrdinalsHaveIntegrity } from \"./testUtils.js\";\n\nexport function specToSegment(spec: IJSONSegment): ISegmentPrivate {\n\tconst maybeText = TextSegment.fromJSONObject(spec);\n\tif (maybeText) {\n\t\treturn maybeText;\n\t}\n\n\tconst maybeMarker = Marker.fromJSONObject(spec);\n\tif (maybeMarker) {\n\t\treturn maybeMarker;\n\t}\n\n\tthrow new Error(`Unrecognized IJSONSegment type: '${JSON.stringify(spec)}'`);\n}\n\nconst random = makeRandom(0xdeadbeef, 0xfeedbed);\n\nfunction opStampToString(stamp: OperationStamp): string {\n\treturn stamp.seq === UnassignedSequenceNumber ? `L${stamp.localSeq}` : `${stamp.seq}`;\n}\n\nexport class TestClient extends Client {\n\tpublic static searchChunkSize = 256;\n\tpublic static readonly serializer = new TestSerializer();\n\tpublic measureOps = false;\n\tpublic accumTime = 0;\n\tpublic accumWindowTime = 0;\n\tpublic accumWindow = 0;\n\tpublic accumOps = 0;\n\tpublic maxWindowTime = 0;\n\n\t/**\n\t * Used for in-memory testing. This will queue a reference string for each client message.\n\t */\n\tpublic static useCheckQ = false;\n\n\tpublic static async createFromClientSnapshot(\n\t\tclient1: TestClient,\n\t\tnewLongClientId: string,\n\t): Promise<TestClient> {\n\t\tconst snapshot = new SnapshotLegacy(\n\t\t\tclient1.mergeTree,\n\t\t\tcreateChildLogger({ namespace: \"fluid:snapshot\" }),\n\t\t);\n\t\tsnapshot.extractSync();\n\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\tconst summaryTree = snapshot.emit([], TestClient.serializer, undefined!).summary;\n\t\treturn TestClient.createFromSummary(\n\t\t\tsummaryTree,\n\t\t\tnewLongClientId,\n\t\t\tclient1.specToSegment,\n\t\t\tclient1.mergeTree.options,\n\t\t);\n\t}\n\n\tpublic static async createFromSnapshot(\n\t\tsnapshotTree: ITree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tnew MockStorage(snapshotTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromSummary(\n\t\tsummaryTree: ISummaryTree,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\treturn TestClient.createFromStorage(\n\t\t\tMockStorage.createFromSummary(summaryTree),\n\t\t\tnewLongClientId,\n\t\t\tspecToSeg,\n\t\t\toptions,\n\t\t);\n\t}\n\n\tpublic static async createFromStorage(\n\t\tstorage: MockStorage,\n\t\tnewLongClientId: string,\n\t\tspecToSeg: (spec: IJSONSegment) => ISegmentPrivate,\n\t\toptions?: PropertySet,\n\t): Promise<TestClient> {\n\t\tconst client2 = new TestClient(options, specToSeg);\n\t\tconst { catchupOpsP } = await client2.load(\n\t\t\t{\n\t\t\t\tlogger: client2.logger,\n\t\t\t\tclientId: newLongClientId,\n\t\t\t} as unknown as IFluidDataStoreRuntime,\n\t\t\tstorage,\n\t\t\tTestClient.serializer,\n\t\t);\n\t\tawait catchupOpsP;\n\t\treturn client2;\n\t}\n\n\tpublic readonly mergeTree: MergeTree;\n\n\tpublic readonly checkQ: DoublyLinkedList<string> = new DoublyLinkedList<string>();\n\tprotected readonly q: DoublyLinkedList<ISequencedDocumentMessage> =\n\t\tnew DoublyLinkedList<ISequencedDocumentMessage>();\n\n\tprivate readonly textHelper: MergeTreeTextHelper;\n\tconstructor(\n\t\toptions?: IMergeTreeOptions & PropertySet,\n\t\tspecToSeg = specToSegment,\n\t\tgetMinInFlightRefSeq: () => number | undefined = (): undefined => undefined,\n\t) {\n\t\tsuper(\n\t\t\tspecToSeg,\n\t\t\tcreateChildLogger({ namespace: \"fluid:testClient\" }),\n\t\t\toptions,\n\t\t\tgetMinInFlightRefSeq,\n\t\t);\n\t\tthis.mergeTree = (this as Record<\"_mergeTree\", MergeTree>)._mergeTree;\n\t\tthis.textHelper = new MergeTreeTextHelper(this.mergeTree);\n\n\t\t// Validate by default\n\t\tthis.on(\"delta\", (o, d) => {\n\t\t\t// assert.notEqual(d.deltaSegments.length, 0);\n\t\t\tfor (const s of d.deltaSegments) {\n\t\t\t\tif (d.operation === MergeTreeDeltaType.INSERT) {\n\t\t\t\t\tassertMergeNode(s.segment);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\tpublic getText(start?: number, end?: number): string {\n\t\treturn this.textHelper.getText(this.mergeTree.localPerspective, \"\", start, end);\n\t}\n\n\tpublic enqueueTestString(): void {\n\t\tthis.checkQ.push(this.getText());\n\t}\n\tpublic getMessageCount(): number {\n\t\treturn this.q.length;\n\t}\n\tpublic enqueueMsg(msg: ISequencedDocumentMessage): void {\n\t\tthis.q.push(msg);\n\t}\n\tpublic dequeueMsg(): ISequencedDocumentMessage | undefined {\n\t\treturn this.q.shift()?.data;\n\t}\n\tpublic applyMessages(msgCount: number): boolean {\n\t\tlet currMsgCount = msgCount;\n\t\twhile (currMsgCount > 0) {\n\t\t\tconst msg = this.dequeueMsg();\n\t\t\tif (msg) {\n\t\t\t\tthis.applyMsg(msg);\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcurrMsgCount--;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tpublic insertTextLocal(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = TextSegment.make(text, props);\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertTextRemote(\n\t\tpos: number,\n\t\ttext: string,\n\t\tprops: PropertySet | undefined,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = TextSegment.make(text, props);\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic removeRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createRemoveRangeOp(start, end), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic obliterateRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createObliterateRangeOp(start, end), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic annotateRangeRemote(\n\t\tstart: number,\n\t\tend: number,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createAnnotateRangeOp(start, end, props), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic insertMarkerLocal(\n\t\tpos: number,\n\t\tbehaviors: ReferenceType,\n\t\tprops?: PropertySet,\n\t): IMergeTreeInsertMsg | undefined {\n\t\tconst segment = Marker.make(behaviors, props);\n\n\t\treturn this.insertSegmentLocal(pos, segment);\n\t}\n\n\tpublic insertMarkerRemote(\n\t\tpos: number,\n\t\tmarkerDef: IMarkerDef,\n\t\tprops: PropertySet,\n\t\tseq: number,\n\t\trefSeq: number,\n\t\tlongClientId: string,\n\t): void {\n\t\tconst segment = Marker.make(markerDef.refType ?? ReferenceType.Tile, props);\n\n\t\tthis.applyMsg(\n\t\t\tthis.makeOpMessage(createInsertSegmentOp(pos, segment), seq, refSeq, longClientId),\n\t\t);\n\t}\n\n\tpublic relText(clientId: number, refSeq: number): string {\n\t\treturn `cli: ${this.getLongClientId(\n\t\t\tclientId,\n\t\t)} refSeq: ${refSeq}: ${this.textHelper.getText(new PriorPerspective(refSeq, clientId))}`;\n\t}\n\n\tpublic makeOpMessage(\n\t\top: IMergeTreeOp | undefined,\n\t\tseq: number = UnassignedSequenceNumber,\n\t\trefSeq: number = this.getCurrentSeq(),\n\t\tlongClientId?: string,\n\t\tminSeqNumber = 0,\n\t): ISequencedDocumentMessage {\n\t\tif (op === undefined) {\n\t\t\tthrow new Error(\"op cannot be undefined\");\n\t\t}\n\t\tconst msg: ISequencedDocumentMessage = {\n\t\t\tclientId: longClientId ?? this.longClientId ?? \"\",\n\t\t\tclientSequenceNumber: 1,\n\t\t\tcontents: op,\n\t\t\tmetadata: undefined,\n\t\t\tminimumSequenceNumber: minSeqNumber,\n\t\t\treferenceSequenceNumber: refSeq,\n\t\t\tsequenceNumber: seq,\n\t\t\ttimestamp: Date.now(),\n\t\t\ttraces: [],\n\t\t\ttype: MessageType.Operation,\n\t\t};\n\t\treturn msg;\n\t}\n\n\tpublic validate(): void {\n\t\tassert(nodeOrdinalsHaveIntegrity(this.mergeTree.root));\n\t}\n\n\tpublic searchFromPos(\n\t\tpos: number,\n\t\ttarget: RegExp,\n\t): { text: string; pos: number } | undefined {\n\t\tlet start = pos;\n\t\tlet chunk = \"\";\n\t\twhile (start < this.getLength()) {\n\t\t\tchunk = this.getText(start, start + TestClient.searchChunkSize);\n\n\t\t\tconst result = chunk.match(target);\n\t\t\tif (result?.index) {\n\t\t\t\treturn { text: result[0], pos: result.index + start };\n\t\t\t}\n\t\t\tstart += TestClient.searchChunkSize;\n\t\t}\n\t}\n\n\tpublic findRandomWord(): { text: string; pos: number } | undefined {\n\t\tconst len = this.getLength();\n\t\tconst pos = random.integer(0, len);\n\t\tconst nextWord = this.searchFromPos(pos, /\\s\\w+\\b/);\n\t\treturn nextWord;\n\t}\n\n\tpublic debugDumpTree(tree: MergeTree): string[] {\n\t\t// want the segment's content and the state of insert/remove\n\t\tconst test: string[] = [];\n\t\twalkAllChildSegments(tree.root, (segment: ISegmentPrivate) => {\n\t\t\tconst prefixes: (string | undefined | number)[] = [];\n\t\t\tassertInserted(segment);\n\t\t\tprefixes.push(opStampToString(segment.insert));\n\t\t\tif (isRemoved(segment)) {\n\t\t\t\tprefixes.push(opStampToString(segment.removes[0]));\n\t\t\t}\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\ttest.push(`${prefixes.join(\",\")}:${(segment as any).text}`);\n\t\t});\n\t\treturn test;\n\t}\n\n\t/**\n\t * Rebases a (local) position from the perspective `{ seq: seqNumberFrom, localSeq }` to the perspective\n\t * of the current sequence number. This is desirable when rebasing operations for reconnection. Perform\n\t * slow-path computations in this function without leveraging the merge-tree's structure\n\t */\n\tpublic rebasePosition(pos: number, seqNumberFrom: number, localSeq: number): number {\n\t\tlet segment: ISegmentPrivate | undefined;\n\t\tlet posAccumulated = 0;\n\t\tlet offset = pos;\n\n\t\tconst perspective = new LocalReconnectingPerspective(\n\t\t\tseqNumberFrom,\n\t\t\tthis.getCollabWindow().clientId,\n\t\t\tlocalSeq,\n\t\t);\n\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\tassertInserted(seg);\n\t\t\tsegment = seg;\n\n\t\t\tif (perspective.isSegmentPresent(seg)) {\n\t\t\t\tposAccumulated += seg.cachedLength;\n\t\t\t\tif (offset >= seg.cachedLength) {\n\t\t\t\t\toffset -= seg.cachedLength;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Keep going while we've yet to reach the segment at the desired position\n\t\t\treturn posAccumulated <= pos;\n\t\t});\n\n\t\tassert(segment !== undefined, \"No segment found\");\n\t\tconst segoff = getSlideToSegoff({ segment, offset }) ?? segment;\n\t\tif (segoff.segment === undefined || segoff.offset === undefined) {\n\t\t\treturn DetachedReferencePosition;\n\t\t}\n\n\t\treturn this.findReconnectionPosition(segoff.segment, localSeq) + segoff.offset;\n\t}\n\n\tpublic findReconnectionPosition(segment: ISegmentPrivate, localSeq: number): number {\n\t\tconst fasterComputedPosition = super.findReconnectionPosition(segment, localSeq);\n\n\t\tconst perspective = new LocalReconnectingPerspective(\n\t\t\tNumber.MAX_SAFE_INTEGER,\n\t\t\tthis.getCollabWindow().clientId,\n\t\t\tlocalSeq,\n\t\t);\n\t\tlet segmentPosition = 0;\n\n\t\t/*\n Walk the segments up to the current segment, and calculate its\n position taking into account local segments that were modified,\n after the current segment.\n */\n\t\twalkAllChildSegments(this.mergeTree.root, (seg) => {\n\t\t\t// If we've found the desired segment, terminate the walk and return 'segmentPosition'.\n\t\t\tif (seg === segment) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Otherwise, advance segmentPosition if the segment is visible at the given perspective.\n\t\t\tif (perspective.isSegmentPresent(seg)) {\n\t\t\t\tsegmentPosition += seg.cachedLength;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t});\n\n\t\tassert.equal(\n\t\t\tfasterComputedPosition,\n\t\t\tsegmentPosition,\n\t\t\t\"Expected fast-path computation to match result from walk all segments\",\n\t\t);\n\t\treturn segmentPosition;\n\t}\n\n\t/**\n\t * Validates segments either all have attribution information or none of them.\n\t * If no segment has attribution information, returns undefined.\n\t *\n\t * @param channel - Attribution channel name to request information from.\n\t * @returns an array of all attribution seq#s from the current perspective.\n\t * The `i`th entry of the array is the attribution key for the character at position `i`.\n\t */\n\tpublic getAllAttributionSeqs(channel?: string): (number | AttributionKey | undefined)[] {\n\t\tconst seqs: (number | AttributionKey | undefined)[] = [];\n\t\tthis.walkAllSegments((segment) => {\n\t\t\tfor (let i = 0; i < segment.cachedLength; i++) {\n\t\t\t\tconst key = segment.attribution?.getAtOffset(i, channel);\n\t\t\t\tseqs.push(key?.type === \"op\" ? key.seq : key);\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\treturn seqs;\n\t}\n\n\tpublic peekPendingSegmentGroups(): SegmentGroup | undefined;\n\tpublic peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;\n\tpublic peekPendingSegmentGroups(\n\t\tcount: number = 1,\n\t): SegmentGroup | SegmentGroup[] | undefined {\n\t\treturn super.peekPendingSegmentGroups(count) as SegmentGroup | SegmentGroup[] | undefined;\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tpublic applyMsg(msg: ISequencedDocumentMessage, local: boolean = false): void {\n\t\tlet traceStart: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttraceStart = Trace.start();\n\t\t}\n\n\t\tsuper.applyMsg(msg, local);\n\n\t\tif (traceStart) {\n\t\t\tthis.accumTime += elapsedMicroseconds(traceStart);\n\t\t\tthis.accumOps++;\n\t\t\tthis.accumWindow += this.getCurrentSeq() - this.getCollabWindow().minSeq;\n\t\t}\n\t}\n\n\t/**\n\t * Override and add some test only metrics\n\t */\n\tupdateMinSeq(minSeq: number): void {\n\t\tlet trace: Trace | undefined;\n\t\tif (this.measureOps) {\n\t\t\ttrace = Trace.start();\n\t\t}\n\n\t\tsuper.updateMinSeq(minSeq);\n\t\tif (trace) {\n\t\t\tconst elapsed = elapsedMicroseconds(trace);\n\t\t\tthis.accumWindowTime += elapsed;\n\t\t\tif (elapsed > this.maxWindowTime) {\n\t\t\t\tthis.maxWindowTime = elapsed;\n\t\t\t}\n\t\t}\n\t}\n\n\tslowSearchForMarker(\n\t\tstartPos: number,\n\t\tmarkerLabel: string,\n\t\tforwards = true,\n\t): ReferencePosition | undefined {\n\t\tlet foundMarker: Marker | undefined;\n\n\t\tconst { segment } = this.getContainingSegment<ISegmentPrivate>(startPos);\n\t\tassertSegmentLeaf(segment);\n\t\tif (Marker.is(segment)) {\n\t\t\tif (refHasTileLabel(segment, markerLabel)) {\n\t\t\t\tfoundMarker = segment;\n\t\t\t}\n\t\t} else {\n\t\t\tif (forwards) {\n\t\t\t\tforwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tbackwardExcursion(segment, (seg) => {\n\t\t\t\t\tif (Marker.is(seg) && refHasTileLabel(seg, markerLabel)) {\n\t\t\t\t\t\tfoundMarker = seg;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn foundMarker;\n\t}\n}\n\nfunction elapsedMicroseconds(trace: Trace): number {\n\treturn trace.trace().duration * 1000;\n}\n\n// the client doesn't submit ops, so this adds a callback to capture them\nexport type TestClientRevertibleDriver = MergeTreeRevertibleDriver &\n\tPartial<{ submitOpCallback?: (op: IMergeTreeOp | undefined) => void }>;\n\nexport const createRevertDriver = (client: TestClient): TestClientRevertibleDriver => {\n\treturn {\n\t\tremoveRange(start: number, end: number): void {\n\t\t\tconst op = client.removeRangeLocal(start, end);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tannotateRange(start: number, end: number, props: PropertySet): void {\n\t\t\tconst op = client.annotateRangeLocal(start, end, props);\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t\tinsertFromSpec(pos: number, spec: IJSONSegment): void {\n\t\t\tconst op = client.insertSegmentLocal(pos, client.specToSegment(spec));\n\t\t\tthis.submitOpCallback?.(op);\n\t\t},\n\t};\n};\n\nexport interface MergeTreeStats {\n\tmaxHeight: number;\n\tnodeCount: number;\n\tleafCount: number;\n\tremovedLeafCount: number;\n\tliveCount: number;\n\thisto: number[];\n\twindowTime?: number;\n\tpackTime?: number;\n\tordTime?: number;\n\tmaxOrdTime?: number;\n}\n\nexport function getStats(tree: MergeTree): MergeTreeStats {\n\tconst nodeGetStats = (block: MergeBlock): MergeTreeStats => {\n\t\tconst stats: MergeTreeStats = {\n\t\t\tmaxHeight: 0,\n\t\t\tnodeCount: 0,\n\t\t\tleafCount: 0,\n\t\t\tremovedLeafCount: 0,\n\t\t\tliveCount: 0,\n\t\t\thisto: [],\n\t\t};\n\t\tfor (let k = 0; k < MaxNodesInBlock; k++) {\n\t\t\tstats.histo[k] = 0;\n\t\t}\n\t\tfor (let i = 0; i < block.childCount; i++) {\n\t\t\tconst child = block.children[i];\n\t\t\tlet height = 1;\n\t\t\tif (child.isLeaf()) {\n\t\t\t\tstats.leafCount++;\n\t\t\t\tconst segment = child;\n\t\t\t\tif (isRemoved(segment)) {\n\t\t\t\t\tstats.removedLeafCount++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst childStats = nodeGetStats(child);\n\t\t\t\theight = 1 + childStats.maxHeight;\n\t\t\t\tstats.nodeCount += childStats.nodeCount;\n\t\t\t\tstats.leafCount += childStats.leafCount;\n\t\t\t\tstats.removedLeafCount += childStats.removedLeafCount;\n\t\t\t\tstats.liveCount += childStats.liveCount;\n\t\t\t\tfor (let j = 0; j < MaxNodesInBlock; j++) {\n\t\t\t\t\tstats.histo[j] += childStats.histo[j];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (height > stats.maxHeight) {\n\t\t\t\tstats.maxHeight = height;\n\t\t\t}\n\t\t}\n\t\tstats.histo[block.childCount]++;\n\t\tstats.nodeCount++;\n\t\tstats.liveCount += block.childCount;\n\t\treturn stats;\n\t};\n\tconst rootStats = nodeGetStats(tree.root);\n\treturn rootStats;\n}\n"]}
|
|
@@ -38,6 +38,15 @@ export declare class TestClientLogger {
|
|
|
38
38
|
static validate(clients: readonly TestClient[], title?: string): string;
|
|
39
39
|
toString(excludeHeader?: boolean): string;
|
|
40
40
|
addLogsToError(e: unknown): Error;
|
|
41
|
+
/**
|
|
42
|
+
* Get a string representation of the merge-tree state.
|
|
43
|
+
*
|
|
44
|
+
* @privateRemarks
|
|
45
|
+
* This function is a dominating bottleneck in operation runner tests, as they log multiple client states per operation performed.
|
|
46
|
+
* This takes more than 50% of the overall test time, so some inner-loop elements of this favor performance over readability/safety
|
|
47
|
+
* (e.g. precomputing removed string representations, casting to the more internal segment interfaces to view insertion/removal info
|
|
48
|
+
* rather than import typeguards, etc.)
|
|
49
|
+
*/
|
|
41
50
|
private static getSegString;
|
|
42
51
|
}
|
|
43
52
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAShD,OAAO,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAKhE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA4C7C,KAAK,SAAS,CAAC,WAAW,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAEtF,wBAAgB,2BAA2B,CAC1C,QAAQ,SAAS,SAAS,CAAC,WAAW,CAAC,EACvC,WAAW,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,QAAQ,EAEpD,IAAI,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAC;CAC1C,EACD,GAAG,SAAS,EAAE,WAAW,EAAE,GACzB,MAAM,CAAC,MAAM,QAAQ,EAAE,UAAU,CAAC,GAAG;IAAE,GAAG,EAAE,UAAU,EAAE,CAAA;CAAE,CAuB5D;AACD,qBAAa,gBAAgB;IA0C3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;WA1CV,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM;IAiB9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEhD,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD;;;OAGG;IACI,OAAO,IAAI,IAAI;gBAQJ,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,CAAC,oBAAQ;IA4DhC,OAAO,CAAC,aAAa;IA+Bd,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,MAAM;IA+DV,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhE,QAAQ,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAyBhD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK;IASxC;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,YAAY;CAqD3B"}
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
6
|
import { LoggingError } from "@fluidframework/telemetry-utils/internal";
|
|
7
|
+
import { DoublyLinkedList } from "../collections/index.js";
|
|
7
8
|
import { UnassignedSequenceNumber } from "../constants.js";
|
|
8
9
|
import { MergeTreeMaintenanceType, } from "../mergeTreeDeltaCallback.js";
|
|
9
10
|
import { depthFirstNodeWalk } from "../mergeTreeNodeWalk.js";
|
|
10
11
|
import { Marker, seqLTE } from "../mergeTreeNodes.js";
|
|
11
12
|
import { MergeTreeDeltaType } from "../ops.js";
|
|
12
13
|
import { matchProperties } from "../properties.js";
|
|
13
|
-
import {
|
|
14
|
-
import { TextSegment } from "../textSegment.js";
|
|
14
|
+
import { TextSegment, TextSegmentGranularity } from "../textSegment.js";
|
|
15
15
|
import { TestClient } from "./testClient.js";
|
|
16
16
|
function getOpString(msg) {
|
|
17
17
|
if (msg === undefined) {
|
|
@@ -235,70 +235,82 @@ export class TestClientLogger {
|
|
|
235
235
|
}
|
|
236
236
|
return new LoggingError(`${e}\n${this.toString()}`);
|
|
237
237
|
}
|
|
238
|
+
/**
|
|
239
|
+
* Get a string representation of the merge-tree state.
|
|
240
|
+
*
|
|
241
|
+
* @privateRemarks
|
|
242
|
+
* This function is a dominating bottleneck in operation runner tests, as they log multiple client states per operation performed.
|
|
243
|
+
* This takes more than 50% of the overall test time, so some inner-loop elements of this favor performance over readability/safety
|
|
244
|
+
* (e.g. precomputing removed string representations, casting to the more internal segment interfaces to view insertion/removal info
|
|
245
|
+
* rather than import typeguards, etc.)
|
|
246
|
+
*/
|
|
238
247
|
static getSegString(client) {
|
|
239
248
|
let acked = "";
|
|
240
249
|
let local = "";
|
|
241
|
-
const nodes = [
|
|
242
|
-
let parent
|
|
250
|
+
const nodes = new DoublyLinkedList([client.mergeTree.root]);
|
|
251
|
+
let parent;
|
|
252
|
+
const { minSeq } = client.getCollabWindow();
|
|
243
253
|
while (nodes.length > 0) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
254
|
+
// Safe due to length check above
|
|
255
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
256
|
+
const node = nodes.shift().data;
|
|
257
|
+
if (node.isLeaf()) {
|
|
258
|
+
if (node.parent !== parent) {
|
|
259
|
+
if (acked.length > 0) {
|
|
260
|
+
acked += " ";
|
|
261
|
+
local += " ";
|
|
262
|
+
}
|
|
263
|
+
parent = node.parent;
|
|
264
|
+
}
|
|
265
|
+
const text = TextSegment.is(node) ? node.text : Marker.is(node) ? "¶" : undefined;
|
|
266
|
+
if (text !== undefined) {
|
|
267
|
+
const insertionSeq = node.insert.seq;
|
|
268
|
+
const removedNode = toMoveOrRemove(node);
|
|
269
|
+
if (removedNode === undefined) {
|
|
270
|
+
if (insertionSeq === UnassignedSequenceNumber) {
|
|
271
|
+
acked += underscores[text.length];
|
|
272
|
+
local += text;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
acked += text;
|
|
276
|
+
local += spaces[text.length];
|
|
251
277
|
}
|
|
252
|
-
parent = node.parent;
|
|
253
278
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
local += text;
|
|
262
|
-
}
|
|
263
|
-
else {
|
|
264
|
-
acked += text;
|
|
265
|
-
local += " ".repeat(text.length);
|
|
266
|
-
}
|
|
279
|
+
else {
|
|
280
|
+
if (removedNode.seq === UnassignedSequenceNumber) {
|
|
281
|
+
acked += underscores[text.length];
|
|
282
|
+
local +=
|
|
283
|
+
insertionSeq === UnassignedSequenceNumber
|
|
284
|
+
? asterisks[text.length]
|
|
285
|
+
: dashes[text.length];
|
|
267
286
|
}
|
|
268
287
|
else {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
? "*".repeat(text.length)
|
|
274
|
-
: "-".repeat(text.length);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
const removedSymbol = seqLTE(removedNode.seq, client.getCollabWindow().minSeq)
|
|
278
|
-
? "~"
|
|
279
|
-
: "-";
|
|
280
|
-
acked += removedSymbol.repeat(text.length);
|
|
281
|
-
local += " ".repeat(text.length);
|
|
282
|
-
}
|
|
288
|
+
acked += seqLTE(removedNode.seq, minSeq)
|
|
289
|
+
? tildes[text.length]
|
|
290
|
+
: dashes[text.length];
|
|
291
|
+
local += spaces[text.length];
|
|
283
292
|
}
|
|
284
293
|
}
|
|
285
294
|
}
|
|
286
|
-
|
|
287
|
-
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
for (let i = 0; i < node.childCount; i++) {
|
|
298
|
+
nodes.push(node.children[i]);
|
|
288
299
|
}
|
|
289
300
|
}
|
|
290
301
|
}
|
|
291
302
|
return { acked, local };
|
|
292
303
|
}
|
|
293
304
|
}
|
|
305
|
+
const maxSegmentLength = TextSegmentGranularity * 2;
|
|
306
|
+
const underscores = Array.from({ length: maxSegmentLength }, (_, i) => "_".repeat(i));
|
|
307
|
+
const spaces = Array.from({ length: maxSegmentLength }, (_, i) => " ".repeat(i));
|
|
308
|
+
const dashes = Array.from({ length: maxSegmentLength }, (_, i) => "-".repeat(i));
|
|
309
|
+
const asterisks = Array.from({ length: maxSegmentLength }, (_, i) => "*".repeat(i));
|
|
310
|
+
const tildes = Array.from({ length: maxSegmentLength }, (_, i) => "~".repeat(i));
|
|
294
311
|
function toMoveOrRemove(segment) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
if (mi !== undefined || ri !== undefined) {
|
|
298
|
-
return {
|
|
299
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
300
|
-
seq: mi?.movedSeq ?? ri?.removedSeq,
|
|
301
|
-
};
|
|
312
|
+
if (segment.removes !== undefined) {
|
|
313
|
+
return segment.removes[0];
|
|
302
314
|
}
|
|
303
315
|
}
|
|
304
316
|
//# sourceMappingURL=testClientLogger.js.map
|