@fluid-experimental/tree 0.59.2001 → 0.59.3000
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.js +2 -0
- package/.vscode/SharedTree.code-workspace +15 -0
- package/.vscode/settings.json +6 -0
- package/dist/ChangeCompression.js +9 -9
- package/dist/ChangeCompression.js.map +1 -1
- package/dist/ChangeTypes.d.ts +1 -6
- package/dist/ChangeTypes.d.ts.map +1 -1
- package/dist/ChangeTypes.js +5 -5
- package/dist/ChangeTypes.js.map +1 -1
- package/dist/Checkout.js +14 -14
- package/dist/Checkout.js.map +1 -1
- package/dist/Common.d.ts +21 -3
- package/dist/Common.d.ts.map +1 -1
- package/dist/Common.js +29 -4
- package/dist/Common.js.map +1 -1
- package/dist/EditLog.js +26 -25
- package/dist/EditLog.js.map +1 -1
- package/dist/EditUtilities.js +17 -17
- package/dist/EditUtilities.js.map +1 -1
- package/dist/Forest.js +31 -31
- package/dist/Forest.js.map +1 -1
- package/dist/HistoryEditFactory.js +9 -9
- package/dist/HistoryEditFactory.js.map +1 -1
- package/dist/IdConversion.js +9 -9
- package/dist/IdConversion.js.map +1 -1
- package/dist/Identifiers.d.ts +4 -0
- package/dist/Identifiers.d.ts.map +1 -1
- package/dist/Identifiers.js.map +1 -1
- package/dist/LogViewer.d.ts +1 -5
- package/dist/LogViewer.d.ts.map +1 -1
- package/dist/LogViewer.js +11 -19
- package/dist/LogViewer.js.map +1 -1
- package/dist/MergeHealth.js +2 -2
- package/dist/MergeHealth.js.map +1 -1
- package/dist/NodeIdUtilities.js +2 -2
- package/dist/NodeIdUtilities.js.map +1 -1
- package/dist/PayloadUtilities.js +1 -1
- package/dist/PayloadUtilities.js.map +1 -1
- package/dist/RevisionValueCache.d.ts +13 -10
- package/dist/RevisionValueCache.d.ts.map +1 -1
- package/dist/RevisionValueCache.js +14 -11
- package/dist/RevisionValueCache.js.map +1 -1
- package/dist/RevisionView.js +4 -4
- package/dist/RevisionView.js.map +1 -1
- package/dist/SerializationUtilities.js +4 -4
- package/dist/SerializationUtilities.js.map +1 -1
- package/dist/SharedTree.d.ts +93 -31
- package/dist/SharedTree.d.ts.map +1 -1
- package/dist/SharedTree.js +160 -131
- package/dist/SharedTree.js.map +1 -1
- package/dist/SharedTreeEncoder.d.ts +3 -3
- package/dist/SharedTreeEncoder.d.ts.map +1 -1
- package/dist/SharedTreeEncoder.js +36 -36
- package/dist/SharedTreeEncoder.js.map +1 -1
- package/dist/StringInterner.js +1 -1
- package/dist/StringInterner.js.map +1 -1
- package/dist/Summary.js +1 -1
- package/dist/Summary.js.map +1 -1
- package/dist/SummaryBackCompatibility.js +8 -8
- package/dist/SummaryBackCompatibility.js.map +1 -1
- package/dist/Transaction.js +1 -1
- package/dist/Transaction.js.map +1 -1
- package/dist/TransactionInternal.js +17 -17
- package/dist/TransactionInternal.js.map +1 -1
- package/dist/TreeCompressor.d.ts.map +1 -1
- package/dist/TreeCompressor.js +6 -8
- package/dist/TreeCompressor.js.map +1 -1
- package/dist/TreeNodeHandle.js +4 -4
- package/dist/TreeNodeHandle.js.map +1 -1
- package/dist/TreeView.js +7 -7
- package/dist/TreeView.js.map +1 -1
- package/dist/TreeViewUtilities.js +2 -2
- package/dist/TreeViewUtilities.js.map +1 -1
- package/dist/UndoRedoHandler.js +1 -1
- package/dist/UndoRedoHandler.js.map +1 -1
- package/dist/UuidUtilities.d.ts +30 -0
- package/dist/UuidUtilities.d.ts.map +1 -0
- package/dist/UuidUtilities.js +106 -0
- package/dist/UuidUtilities.js.map +1 -0
- package/dist/id-compressor/AppendOnlySortedMap.d.ts +52 -28
- package/dist/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/AppendOnlySortedMap.js +167 -90
- package/dist/id-compressor/AppendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/IdCompressor.d.ts +43 -42
- package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
- package/dist/id-compressor/IdCompressor.js +179 -177
- package/dist/id-compressor/IdCompressor.js.map +1 -1
- package/dist/id-compressor/IdRange.js +1 -1
- package/dist/id-compressor/IdRange.js.map +1 -1
- package/dist/id-compressor/NumericUuid.d.ts +6 -14
- package/dist/id-compressor/NumericUuid.d.ts.map +1 -1
- package/dist/id-compressor/NumericUuid.js +15 -76
- package/dist/id-compressor/NumericUuid.js.map +1 -1
- package/dist/id-compressor/SessionIdNormalizer.d.ts +122 -0
- package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
- package/dist/id-compressor/SessionIdNormalizer.js +418 -0
- package/dist/id-compressor/SessionIdNormalizer.js.map +1 -0
- package/dist/id-compressor/persisted-types/0.0.1.d.ts +6 -13
- package/dist/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
- package/dist/id-compressor/persisted-types/0.0.1.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/persisted-types/0.1.1.d.ts +1 -6
- package/dist/persisted-types/0.1.1.d.ts.map +1 -1
- package/dist/persisted-types/0.1.1.js +3 -3
- package/dist/persisted-types/0.1.1.js.map +1 -1
- package/lib/ChangeTypes.d.ts +1 -6
- package/lib/ChangeTypes.d.ts.map +1 -1
- package/lib/Checkout.js.map +1 -1
- package/lib/Common.d.ts +21 -3
- package/lib/Common.d.ts.map +1 -1
- package/lib/Common.js +25 -3
- package/lib/Common.js.map +1 -1
- package/lib/EditLog.js +2 -1
- package/lib/EditLog.js.map +1 -1
- package/lib/EditUtilities.js.map +1 -1
- package/lib/Forest.js.map +1 -1
- package/lib/HistoryEditFactory.js.map +1 -1
- package/lib/Identifiers.d.ts +4 -0
- package/lib/Identifiers.d.ts.map +1 -1
- package/lib/Identifiers.js.map +1 -1
- package/lib/LogViewer.d.ts +1 -5
- package/lib/LogViewer.d.ts.map +1 -1
- package/lib/LogViewer.js +5 -13
- package/lib/LogViewer.js.map +1 -1
- package/lib/MergeHealth.js.map +1 -1
- package/lib/NodeIdUtilities.js.map +1 -1
- package/lib/RevisionValueCache.d.ts +13 -10
- package/lib/RevisionValueCache.d.ts.map +1 -1
- package/lib/RevisionValueCache.js +10 -7
- package/lib/RevisionValueCache.js.map +1 -1
- package/lib/RevisionView.js.map +1 -1
- package/lib/SharedTree.d.ts +93 -31
- package/lib/SharedTree.d.ts.map +1 -1
- package/lib/SharedTree.js +107 -78
- package/lib/SharedTree.js.map +1 -1
- package/lib/SharedTreeEncoder.d.ts +3 -3
- package/lib/SharedTreeEncoder.d.ts.map +1 -1
- package/lib/SharedTreeEncoder.js +4 -4
- package/lib/SharedTreeEncoder.js.map +1 -1
- package/lib/StringInterner.js.map +1 -1
- package/lib/Summary.js.map +1 -1
- package/lib/TreeCompressor.d.ts.map +1 -1
- package/lib/TreeCompressor.js +1 -3
- package/lib/TreeCompressor.js.map +1 -1
- package/lib/TreeNodeHandle.js.map +1 -1
- package/lib/TreeView.js.map +1 -1
- package/lib/TreeViewUtilities.js.map +1 -1
- package/lib/UuidUtilities.d.ts +30 -0
- package/lib/UuidUtilities.d.ts.map +1 -0
- package/lib/UuidUtilities.js +98 -0
- package/lib/UuidUtilities.js.map +1 -0
- package/lib/id-compressor/AppendOnlySortedMap.d.ts +52 -28
- package/lib/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/AppendOnlySortedMap.js +165 -88
- package/lib/id-compressor/AppendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/IdCompressor.d.ts +43 -42
- package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
- package/lib/id-compressor/IdCompressor.js +97 -95
- package/lib/id-compressor/IdCompressor.js.map +1 -1
- package/lib/id-compressor/NumericUuid.d.ts +6 -14
- package/lib/id-compressor/NumericUuid.d.ts.map +1 -1
- package/lib/id-compressor/NumericUuid.js +11 -70
- package/lib/id-compressor/NumericUuid.js.map +1 -1
- package/lib/id-compressor/SessionIdNormalizer.d.ts +122 -0
- package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -0
- package/lib/id-compressor/SessionIdNormalizer.js +414 -0
- package/lib/id-compressor/SessionIdNormalizer.js.map +1 -0
- package/lib/id-compressor/persisted-types/0.0.1.d.ts +6 -13
- package/lib/id-compressor/persisted-types/0.0.1.d.ts.map +1 -1
- package/lib/id-compressor/persisted-types/0.0.1.js.map +1 -1
- package/lib/index.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/persisted-types/0.1.1.d.ts +1 -6
- package/lib/persisted-types/0.1.1.d.ts.map +1 -1
- package/lib/persisted-types/0.1.1.js.map +1 -1
- package/lib/test/AppendOnlySortedMap.perf.tests.d.ts +6 -0
- package/lib/test/AppendOnlySortedMap.perf.tests.d.ts.map +1 -0
- package/lib/test/AppendOnlySortedMap.perf.tests.js +49 -0
- package/lib/test/AppendOnlySortedMap.perf.tests.js.map +1 -0
- package/lib/test/AppendOnlySortedMap.tests.js +56 -14
- package/lib/test/AppendOnlySortedMap.tests.js.map +1 -1
- package/lib/test/Checkout.tests.js +2 -2
- package/lib/test/Checkout.tests.js.map +1 -1
- package/lib/test/Forest.tests.js.map +1 -1
- package/lib/test/IdCompressor.perf.tests.js +8 -2
- package/lib/test/IdCompressor.perf.tests.js.map +1 -1
- package/lib/test/IdCompressor.tests.js +75 -24
- package/lib/test/IdCompressor.tests.js.map +1 -1
- package/lib/test/LogViewer.tests.js +3 -5
- package/lib/test/LogViewer.tests.js.map +1 -1
- package/lib/test/NumericUuid.perf.tests.js +4 -4
- package/lib/test/NumericUuid.perf.tests.js.map +1 -1
- package/lib/test/NumericUuid.tests.js +5 -4
- package/lib/test/NumericUuid.tests.js.map +1 -1
- package/lib/test/RevisionValueCache.tests.js.map +1 -1
- package/lib/test/RevisionView.tests.js.map +1 -1
- package/lib/test/SessionIdNormalizer.tests.d.ts +6 -0
- package/lib/test/SessionIdNormalizer.tests.d.ts.map +1 -0
- package/lib/test/SessionIdNormalizer.tests.js +299 -0
- package/lib/test/SessionIdNormalizer.tests.js.map +1 -0
- package/lib/test/Summary.tests.js +1 -1
- package/lib/test/Summary.tests.js.map +1 -1
- package/lib/test/TreeCompression.tests.js +1 -1
- package/lib/test/TreeCompression.tests.js.map +1 -1
- package/lib/test/Virtualization.tests.js +1 -1
- package/lib/test/Virtualization.tests.js.map +1 -1
- package/lib/test/fuzz/Generators.d.ts +3 -14
- package/lib/test/fuzz/Generators.d.ts.map +1 -1
- package/lib/test/fuzz/Generators.js +60 -151
- package/lib/test/fuzz/Generators.js.map +1 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.d.ts +10 -7
- package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +1 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.js +94 -104
- package/lib/test/fuzz/SharedTreeFuzzTests.js.map +1 -1
- package/lib/test/fuzz/Types.d.ts +2 -9
- package/lib/test/fuzz/Types.d.ts.map +1 -1
- package/lib/test/fuzz/Types.js +1 -1
- package/lib/test/fuzz/Types.js.map +1 -1
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts +57 -11
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +1 -1
- package/lib/test/utilities/IdCompressorTestUtilities.js +112 -98
- package/lib/test/utilities/IdCompressorTestUtilities.js.map +1 -1
- package/lib/test/utilities/PendingLocalStateTests.d.ts.map +1 -1
- package/lib/test/utilities/PendingLocalStateTests.js +2 -1
- package/lib/test/utilities/PendingLocalStateTests.js.map +1 -1
- package/lib/test/utilities/SharedTreeTests.d.ts.map +1 -1
- package/lib/test/utilities/SharedTreeTests.js +30 -1
- package/lib/test/utilities/SharedTreeTests.js.map +1 -1
- package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +1 -1
- package/lib/test/utilities/SharedTreeVersioningTests.js +20 -0
- package/lib/test/utilities/SharedTreeVersioningTests.js.map +1 -1
- package/lib/test/utilities/SummaryLoadPerfTests.d.ts.map +1 -1
- package/lib/test/utilities/SummaryLoadPerfTests.js +6 -3
- package/lib/test/utilities/SummaryLoadPerfTests.js.map +1 -1
- package/lib/test/utilities/TestNode.js.map +1 -1
- package/lib/test/utilities/TestUtilities.d.ts +9 -1
- package/lib/test/utilities/TestUtilities.d.ts.map +1 -1
- package/lib/test/utilities/TestUtilities.js +27 -13
- package/lib/test/utilities/TestUtilities.js.map +1 -1
- package/package.json +19 -17
- package/src/Common.ts +42 -4
- package/src/EditLog.ts +1 -1
- package/src/Identifiers.ts +5 -0
- package/src/LogViewer.ts +4 -20
- package/src/RevisionValueCache.ts +11 -8
- package/src/SharedTree.ts +222 -75
- package/src/SharedTreeEncoder.ts +17 -11
- package/src/TreeCompressor.ts +2 -4
- package/src/UuidUtilities.ts +123 -0
- package/src/id-compressor/AppendOnlySortedMap.ts +183 -94
- package/src/id-compressor/IdCompressor.ts +144 -132
- package/src/id-compressor/NumericUuid.ts +11 -80
- package/src/id-compressor/SessionIdNormalizer.ts +497 -0
- package/src/id-compressor/persisted-types/0.0.1.ts +12 -15
- package/src/index.ts +5 -0
|
@@ -2,17 +2,12 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import Prando from 'prando';
|
|
6
|
-
import { v5 } from 'uuid';
|
|
7
5
|
import { IsoBuffer } from '@fluidframework/common-utils';
|
|
6
|
+
import { createWeightedAsyncGenerator, done, makeRandom, } from '@fluid-internal/stochastic-test-utils';
|
|
8
7
|
import { Side, WriteFormat } from '../../persisted-types';
|
|
9
8
|
import { ChangeType, StablePlace, StableRange } from '../../ChangeTypes';
|
|
10
9
|
import { fail } from '../../Common';
|
|
11
10
|
import { rangeFromStableRange } from '../../TreeViewUtilities';
|
|
12
|
-
import { done, } from './Types';
|
|
13
|
-
function uuid(rand) {
|
|
14
|
-
return v5(rand.nextString(16), '33f960ec-f1e4-4fca-8dcd-223c6647fcc7');
|
|
15
|
-
}
|
|
16
11
|
const defaultJoinConfig = {
|
|
17
12
|
maximumActiveCollaborators: 10,
|
|
18
13
|
maximumPassiveCollaborators: 10,
|
|
@@ -21,11 +16,11 @@ const defaultJoinConfig = {
|
|
|
21
16
|
};
|
|
22
17
|
function makeJoinGenerator(passedConfig) {
|
|
23
18
|
const config = Object.assign(Object.assign({}, defaultJoinConfig), passedConfig);
|
|
24
|
-
return async ({
|
|
19
|
+
return async ({ random, activeCollaborators, passiveCollaborators }) => {
|
|
25
20
|
const activeAllowed = activeCollaborators.length < config.maximumActiveCollaborators;
|
|
26
21
|
const passiveAllowed = passiveCollaborators.length < config.maximumPassiveCollaborators;
|
|
27
22
|
const isObserver = activeAllowed && passiveAllowed
|
|
28
|
-
?
|
|
23
|
+
? random.bool()
|
|
29
24
|
: activeAllowed
|
|
30
25
|
? false
|
|
31
26
|
: passiveAllowed
|
|
@@ -33,23 +28,23 @@ function makeJoinGenerator(passedConfig) {
|
|
|
33
28
|
: fail('Cannot generate join op when both active and passive collaborators are at the configured limit.');
|
|
34
29
|
return {
|
|
35
30
|
type: 'join',
|
|
36
|
-
summarizeHistory:
|
|
37
|
-
writeFormat:
|
|
31
|
+
summarizeHistory: random.pick(config.summarizeHistory),
|
|
32
|
+
writeFormat: random.pick(config.writeFormat),
|
|
38
33
|
isObserver,
|
|
39
34
|
};
|
|
40
35
|
};
|
|
41
36
|
}
|
|
42
|
-
async function leaveGenerator({
|
|
37
|
+
async function leaveGenerator({ random, activeCollaborators, passiveCollaborators, }) {
|
|
43
38
|
const canUsePassive = passiveCollaborators.length > 0;
|
|
44
39
|
const canUseActive = activeCollaborators.length > 0;
|
|
45
40
|
const isObserver = canUsePassive && canUseActive
|
|
46
|
-
?
|
|
41
|
+
? random.bool()
|
|
47
42
|
: canUsePassive
|
|
48
43
|
? true
|
|
49
44
|
: canUseActive
|
|
50
45
|
? false
|
|
51
46
|
: fail('Cannot generate a leave op when there are no clients.');
|
|
52
|
-
const index =
|
|
47
|
+
const index = random.integer(0, (isObserver ? passiveCollaborators : activeCollaborators).length - 1);
|
|
53
48
|
return { type: 'leave', isObserver, index };
|
|
54
49
|
}
|
|
55
50
|
const defaultInsertConfig = {
|
|
@@ -68,46 +63,45 @@ const defaultEditConfig = {
|
|
|
68
63
|
const makeEditGenerator = (passedConfig) => {
|
|
69
64
|
const config = Object.assign(Object.assign({}, defaultEditConfig), passedConfig);
|
|
70
65
|
const insertConfig = Object.assign(Object.assign({}, defaultInsertConfig), config.insertConfig);
|
|
71
|
-
const poolRand =
|
|
72
|
-
const traitLabelPool = Array.from({ length: config.traitLabelPoolSize }, () =>
|
|
73
|
-
const traitLabelGenerator = ({
|
|
74
|
-
const definitionPool = Array.from({ length: insertConfig.definitionPoolSize }, () =>
|
|
75
|
-
const definitionGenerator = ({
|
|
76
|
-
function traitGenerator(state
|
|
66
|
+
const poolRand = makeRandom(0);
|
|
67
|
+
const traitLabelPool = Array.from({ length: config.traitLabelPoolSize }, () => poolRand.uuid4());
|
|
68
|
+
const traitLabelGenerator = ({ random }) => random.pick(traitLabelPool);
|
|
69
|
+
const definitionPool = Array.from({ length: insertConfig.definitionPoolSize }, () => poolRand.uuid4());
|
|
70
|
+
const definitionGenerator = ({ random }) => random.pick(definitionPool);
|
|
71
|
+
function traitGenerator(state) {
|
|
77
72
|
var _a;
|
|
78
|
-
const
|
|
73
|
+
const { idList, random, view } = state;
|
|
74
|
+
const id = random.pick(idList);
|
|
79
75
|
return (_a = view.tryGetTraitLocation(id)) !== null && _a !== void 0 ? _a : { parent: id, label: traitLabelGenerator(state) };
|
|
80
76
|
}
|
|
81
|
-
function placeGenerator(state
|
|
82
|
-
const {
|
|
83
|
-
const { view, idList } = context;
|
|
77
|
+
function placeGenerator(state) {
|
|
78
|
+
const { idList, random, view } = state;
|
|
84
79
|
// Note: this gives a 50% chance of adding to a new trait; we may want to tune this at some point
|
|
85
|
-
if (
|
|
86
|
-
const parent =
|
|
80
|
+
if (random.bool()) {
|
|
81
|
+
const parent = random.pick(idList);
|
|
87
82
|
return StablePlace.atStartOf({ parent, label: traitLabelGenerator(state) });
|
|
88
83
|
}
|
|
89
|
-
const traitLocation = traitGenerator(state
|
|
84
|
+
const traitLocation = traitGenerator(state);
|
|
90
85
|
const trait = view.getTrait(traitLocation);
|
|
91
86
|
// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.
|
|
92
87
|
// index === trait.length is treated as either the start or end of the trait.
|
|
93
88
|
const makeDescriptor = () => ({
|
|
94
|
-
index:
|
|
95
|
-
side:
|
|
89
|
+
index: random.integer(0, trait.length),
|
|
90
|
+
side: random.bool() ? Side.Before : Side.After,
|
|
96
91
|
});
|
|
97
92
|
const descriptor = makeDescriptor();
|
|
98
93
|
const placeFromDescriptor = ({ index, side }) => index === trait.length ? { referenceTrait: traitLocation, side } : { referenceSibling: trait[index], side };
|
|
99
94
|
return placeFromDescriptor(descriptor);
|
|
100
95
|
}
|
|
101
|
-
function rangeGenerator(state
|
|
102
|
-
const {
|
|
103
|
-
const
|
|
104
|
-
const traitLocation = traitGenerator(state, context);
|
|
96
|
+
function rangeGenerator(state) {
|
|
97
|
+
const { random, view } = state;
|
|
98
|
+
const traitLocation = traitGenerator(state);
|
|
105
99
|
const trait = view.getTrait(traitLocation);
|
|
106
100
|
// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.
|
|
107
101
|
// index === trait.length is treated as either the start or end of the trait.
|
|
108
102
|
const makeDescriptor = () => ({
|
|
109
|
-
index:
|
|
110
|
-
side:
|
|
103
|
+
index: random.integer(0, trait.length),
|
|
104
|
+
side: random.bool() ? Side.Before : Side.After,
|
|
111
105
|
});
|
|
112
106
|
const descriptor1 = makeDescriptor();
|
|
113
107
|
let descriptor2;
|
|
@@ -142,11 +136,11 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
142
136
|
const end = placeFromDescriptor(endDescriptor);
|
|
143
137
|
return StableRange.from(start).to(end);
|
|
144
138
|
}
|
|
145
|
-
function treeGenerator(state
|
|
146
|
-
const {
|
|
147
|
-
const treeType =
|
|
139
|
+
function treeGenerator(state) {
|
|
140
|
+
const { random, idGenerator } = state;
|
|
141
|
+
const treeType = random.pick(['leaf', 'stick', 'balanced']);
|
|
148
142
|
const makeNode = (traits) => ({
|
|
149
|
-
identifier:
|
|
143
|
+
identifier: idGenerator.generateNodeId(),
|
|
150
144
|
definition: definitionGenerator(state),
|
|
151
145
|
traits: traits !== null && traits !== void 0 ? traits : {},
|
|
152
146
|
});
|
|
@@ -166,10 +160,10 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
166
160
|
fail(`Unexpected treeType ${treeType}`);
|
|
167
161
|
}
|
|
168
162
|
}
|
|
169
|
-
async function insertGenerator(state
|
|
163
|
+
async function insertGenerator(state) {
|
|
170
164
|
const { maxTreeSequenceSize } = insertConfig;
|
|
171
165
|
const id = 1;
|
|
172
|
-
const { view } =
|
|
166
|
+
const { view } = state;
|
|
173
167
|
const isValidInsertPlace = (destination) => {
|
|
174
168
|
// Disallow insertion adjacent to the root node.
|
|
175
169
|
if (destination.referenceSibling === view.root) {
|
|
@@ -179,14 +173,14 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
179
173
|
};
|
|
180
174
|
let destination;
|
|
181
175
|
do {
|
|
182
|
-
destination = placeGenerator(state
|
|
176
|
+
destination = placeGenerator(state);
|
|
183
177
|
} while (!isValidInsertPlace(destination));
|
|
184
178
|
return {
|
|
185
179
|
fuzzType: 'insert',
|
|
186
180
|
build: {
|
|
187
181
|
type: ChangeType.Build,
|
|
188
182
|
destination: id,
|
|
189
|
-
source: Array.from({ length: state.
|
|
183
|
+
source: Array.from({ length: state.random.integer(1, maxTreeSequenceSize) }, () => treeGenerator(state)),
|
|
190
184
|
},
|
|
191
185
|
insert: {
|
|
192
186
|
type: ChangeType.Insert,
|
|
@@ -195,8 +189,8 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
195
189
|
},
|
|
196
190
|
};
|
|
197
191
|
}
|
|
198
|
-
async function deleteGenerator(state
|
|
199
|
-
const { view } =
|
|
192
|
+
async function deleteGenerator(state) {
|
|
193
|
+
const { view } = state;
|
|
200
194
|
const isValidDeleteRange = (source) => {
|
|
201
195
|
// Disallow deletion of the root node.
|
|
202
196
|
if (source.start.referenceSibling === view.root || source.end.referenceSibling === view.root) {
|
|
@@ -206,7 +200,7 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
206
200
|
};
|
|
207
201
|
let source;
|
|
208
202
|
do {
|
|
209
|
-
source = rangeGenerator(state
|
|
203
|
+
source = rangeGenerator(state);
|
|
210
204
|
} while (!isValidDeleteRange(source));
|
|
211
205
|
return {
|
|
212
206
|
fuzzType: 'delete',
|
|
@@ -214,9 +208,9 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
214
208
|
source,
|
|
215
209
|
};
|
|
216
210
|
}
|
|
217
|
-
async function moveGenerator(state
|
|
211
|
+
async function moveGenerator(state) {
|
|
218
212
|
const id = 1;
|
|
219
|
-
const { view } =
|
|
213
|
+
const { view } = state;
|
|
220
214
|
const isValidMoveRange = ({ start, end }, destination) => {
|
|
221
215
|
var _a, _b, _c, _d;
|
|
222
216
|
// An ancestor cannot be moved to be a sibling of its descendant.
|
|
@@ -236,8 +230,8 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
236
230
|
let source;
|
|
237
231
|
let destination;
|
|
238
232
|
do {
|
|
239
|
-
source = rangeGenerator(state
|
|
240
|
-
destination = placeGenerator(state
|
|
233
|
+
source = rangeGenerator(state);
|
|
234
|
+
destination = placeGenerator(state);
|
|
241
235
|
} while (!isValidMoveRange(rangeFromStableRange(view, source), destination));
|
|
242
236
|
return {
|
|
243
237
|
fuzzType: 'move',
|
|
@@ -253,46 +247,38 @@ const makeEditGenerator = (passedConfig) => {
|
|
|
253
247
|
},
|
|
254
248
|
};
|
|
255
249
|
}
|
|
256
|
-
async function setPayloadGenerator({
|
|
257
|
-
const nodeToModify =
|
|
258
|
-
const getPayloadContents = async (
|
|
259
|
-
if (
|
|
260
|
-
return
|
|
250
|
+
async function setPayloadGenerator({ dataStoreRuntime, idList, random, view }) {
|
|
251
|
+
const nodeToModify = random.pick(idList);
|
|
252
|
+
const getPayloadContents = async (random) => {
|
|
253
|
+
if (random.bool()) {
|
|
254
|
+
return random.string(4);
|
|
261
255
|
}
|
|
262
|
-
const handle = await dataStoreRuntime.uploadBlob(IsoBuffer.from(
|
|
256
|
+
const handle = await dataStoreRuntime.uploadBlob(IsoBuffer.from(random.string(10)));
|
|
263
257
|
return { blob: handle };
|
|
264
258
|
};
|
|
265
259
|
const viewNode = view.getViewNode(nodeToModify);
|
|
266
|
-
const payload = viewNode.payload !== undefined
|
|
267
|
-
? rand.nextBoolean()
|
|
268
|
-
? await getPayloadContents(rand)
|
|
269
|
-
: undefined
|
|
270
|
-
: undefined;
|
|
260
|
+
const payload = viewNode.payload !== undefined ? (random.bool() ? await getPayloadContents(random) : undefined) : undefined;
|
|
271
261
|
return {
|
|
272
262
|
fuzzType: 'setPayload',
|
|
273
263
|
type: ChangeType.SetValue,
|
|
274
|
-
nodeToModify:
|
|
264
|
+
nodeToModify: random.pick(idList),
|
|
275
265
|
payload,
|
|
276
266
|
};
|
|
277
267
|
}
|
|
278
|
-
const baseEditGenerator =
|
|
279
|
-
[insertGenerator, config.insertWeight, (
|
|
280
|
-
[deleteGenerator, config.deleteWeight, (
|
|
281
|
-
[moveGenerator, config.moveWeight, (
|
|
268
|
+
const baseEditGenerator = createWeightedAsyncGenerator([
|
|
269
|
+
[insertGenerator, config.insertWeight, ({ idList }) => idList.length < config.maxTreeSize],
|
|
270
|
+
[deleteGenerator, config.deleteWeight, ({ idList }) => idList.length > 1],
|
|
271
|
+
[moveGenerator, config.moveWeight, ({ idList }) => idList.length > 1],
|
|
282
272
|
[setPayloadGenerator, config.setPayloadWeight],
|
|
283
273
|
]);
|
|
284
274
|
return async (state) => {
|
|
285
|
-
const {
|
|
286
|
-
const index =
|
|
275
|
+
const { random, activeCollaborators } = state;
|
|
276
|
+
const index = random.integer(0, activeCollaborators.length - 1);
|
|
287
277
|
const { tree } = activeCollaborators[index];
|
|
288
278
|
const view = tree.currentView;
|
|
289
279
|
const idList = getIdList(view);
|
|
290
|
-
const contents = await baseEditGenerator(state, {
|
|
291
|
-
|
|
292
|
-
idList,
|
|
293
|
-
dataStoreRuntime: tree.getRuntime(),
|
|
294
|
-
idGenerator: tree,
|
|
295
|
-
});
|
|
280
|
+
const contents = await baseEditGenerator(Object.assign(Object.assign({}, state), { view,
|
|
281
|
+
idList, dataStoreRuntime: tree.getRuntime(), idGenerator: tree }));
|
|
296
282
|
if (contents === done) {
|
|
297
283
|
return done;
|
|
298
284
|
}
|
|
@@ -324,38 +310,7 @@ export function makeOpGenerator(passedConfig) {
|
|
|
324
310
|
[leaveGenerator, config.leaveWeight, atLeastOneClient],
|
|
325
311
|
[{ type: 'synchronize' }, config.synchronizeWeight, atLeastOneClient],
|
|
326
312
|
];
|
|
327
|
-
return
|
|
328
|
-
}
|
|
329
|
-
function createWeightedGenerator(weights) {
|
|
330
|
-
const cumulativeSums = [];
|
|
331
|
-
let totalWeight = 0;
|
|
332
|
-
for (const [tOrGenerator, weight, shouldAccept] of weights) {
|
|
333
|
-
const cumulativeWeight = totalWeight + weight;
|
|
334
|
-
cumulativeSums.push([tOrGenerator, cumulativeWeight, shouldAccept]);
|
|
335
|
-
totalWeight = cumulativeWeight;
|
|
336
|
-
}
|
|
337
|
-
return async (state, additionalState) => {
|
|
338
|
-
var _a;
|
|
339
|
-
const { rand } = state;
|
|
340
|
-
const sample = () => {
|
|
341
|
-
const weightSelected = rand.nextInt(1, totalWeight);
|
|
342
|
-
let opIndex = 0;
|
|
343
|
-
while (cumulativeSums[opIndex][1] < weightSelected) {
|
|
344
|
-
opIndex++;
|
|
345
|
-
}
|
|
346
|
-
return opIndex;
|
|
347
|
-
};
|
|
348
|
-
let index;
|
|
349
|
-
let shouldAccept;
|
|
350
|
-
do {
|
|
351
|
-
index = sample();
|
|
352
|
-
shouldAccept = cumulativeSums[index][2];
|
|
353
|
-
} while (!((_a = shouldAccept === null || shouldAccept === void 0 ? void 0 : shouldAccept(state, additionalState)) !== null && _a !== void 0 ? _a : true));
|
|
354
|
-
const [tOrGenerator] = cumulativeSums[index];
|
|
355
|
-
return typeof tOrGenerator === 'function'
|
|
356
|
-
? tOrGenerator(state, additionalState)
|
|
357
|
-
: tOrGenerator;
|
|
358
|
-
};
|
|
313
|
+
return createWeightedAsyncGenerator(opWeights);
|
|
359
314
|
}
|
|
360
315
|
function getIdList(tree) {
|
|
361
316
|
var _a;
|
|
@@ -371,50 +326,4 @@ function getIdList(tree) {
|
|
|
371
326
|
}
|
|
372
327
|
return allIds;
|
|
373
328
|
}
|
|
374
|
-
/**
|
|
375
|
-
* Higher-order generator operator which creates a new generator producing the first `n` elements of `generator`.
|
|
376
|
-
*/
|
|
377
|
-
export function take(n, generator) {
|
|
378
|
-
let count = 0;
|
|
379
|
-
return async (state, additionalState) => {
|
|
380
|
-
if (count < n) {
|
|
381
|
-
count++;
|
|
382
|
-
return generator(state, additionalState);
|
|
383
|
-
}
|
|
384
|
-
return done;
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
/**
|
|
388
|
-
* @returns a deterministic generator that always returns the items of `contents` in order.
|
|
389
|
-
*/
|
|
390
|
-
export function generatorFromArray(contents) {
|
|
391
|
-
let index = -1;
|
|
392
|
-
return async () => {
|
|
393
|
-
var _a;
|
|
394
|
-
if (index < contents.length) {
|
|
395
|
-
index++;
|
|
396
|
-
return (_a = contents[index]) !== null && _a !== void 0 ? _a : done;
|
|
397
|
-
}
|
|
398
|
-
return done;
|
|
399
|
-
};
|
|
400
|
-
}
|
|
401
|
-
/**
|
|
402
|
-
* Higher-order generator operator which exhausts each input generator sequentially before moving on to the next.
|
|
403
|
-
*/
|
|
404
|
-
export function chain(...generators) {
|
|
405
|
-
let currentIndex = 0;
|
|
406
|
-
return async (state, additionalState) => {
|
|
407
|
-
while (currentIndex < generators.length) {
|
|
408
|
-
const generator = generators[currentIndex];
|
|
409
|
-
const result = await generator(state, additionalState);
|
|
410
|
-
if (result !== done) {
|
|
411
|
-
return result;
|
|
412
|
-
}
|
|
413
|
-
else {
|
|
414
|
-
currentIndex++;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
return done;
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
329
|
//# sourceMappingURL=Generators.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Generators.js","sourceRoot":"","sources":["../../../src/test/fuzz/Generators.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEzD,OAAO,EAAE,IAAI,EAAY,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EAAa,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGpF,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACN,IAAI,GAcJ,MAAM,SAAS,CAAC;AAEjB,SAAS,IAAI,CAAC,IAAY;IACzB,OAAO,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,sCAAsC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,iBAAiB,GAAmC;IACzD,0BAA0B,EAAE,EAAE;IAC9B,2BAA2B,EAAE,EAAE;IAC/B,WAAW,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;IACrD,gBAAgB,EAAE,CAAC,KAAK,CAAC;CACzB,CAAC;AAEF,SAAS,iBAAiB,CAAC,YAAkC;IAC5D,MAAM,MAAM,mCAAQ,iBAAiB,GAAK,YAAY,CAAE,CAAC;IACzD,OAAO,KAAK,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,EAAE,EAAE;QACpE,MAAM,aAAa,GAAG,mBAAmB,CAAC,MAAM,GAAG,MAAM,CAAC,0BAA0B,CAAC;QACrF,MAAM,cAAc,GAAG,oBAAoB,CAAC,MAAM,GAAG,MAAM,CAAC,2BAA2B,CAAC;QACxF,MAAM,UAAU,GACf,aAAa,IAAI,cAAc;YAC9B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;YACpB,CAAC,CAAC,aAAa;gBACf,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,IAAI;oBACN,CAAC,CAAC,IAAI,CACJ,iGAAiG,CAChG,CAAC;QACN,OAAO;YACN,IAAI,EAAE,MAAM;YACZ,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC;YAC7D,WAAW,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC;YACnD,UAAU;SACV,CAAC;IACH,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,oBAAoB,EAAiB;IAC/F,MAAM,aAAa,GAAG,oBAAoB,CAAC,MAAM,GAAG,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;IACpD,MAAM,UAAU,GACf,aAAa,IAAI,YAAY;QAC5B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;QACpB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,YAAY;gBACd,CAAC,CAAC,KAAK;gBACP,CAAC,CAAC,IAAI,CAAC,uDAAuD,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACpG,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,mBAAmB,GAAqC;IAC7D,kBAAkB,EAAE,EAAE;IACtB,mBAAmB,EAAE,CAAC;CACtB,CAAC;AAEF,MAAM,iBAAiB,GAAmC;IACzD,WAAW,EAAE,MAAM,CAAC,iBAAiB;IACrC,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,mBAAmB;IACjC,YAAY,EAAE,CAAC;IACf,UAAU,EAAE,CAAC;IACb,gBAAgB,EAAE,CAAC;IACnB,kBAAkB,EAAE,EAAE;CACtB,CAAC;AAEF,MAAM,iBAAiB,GAAG,CAAC,YAAkC,EAAwC,EAAE;IACtG,MAAM,MAAM,mCAAQ,iBAAiB,GAAK,YAAY,CAAE,CAAC;IACzD,MAAM,YAAY,mCAAQ,mBAAmB,GAAK,MAAM,CAAC,YAAY,CAAE,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAe,CAAC,CAAC;IAC7G,MAAM,mBAAmB,GAAG,CAAC,EAAE,IAAI,EAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IAE5F,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAe,CAAC,CAAC;IACnH,MAAM,mBAAmB,GAAG,CAAC,EAAE,IAAI,EAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IAE5F,SAAS,cAAc,CAAC,KAAoB,EAAE,EAAE,IAAI,EAAE,MAAM,EAAe;;QAC1E,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5C,aAAO,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,mCAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC;IAC1F,CAAC;IAED,SAAS,cAAc,CAAC,KAAoB,EAAE,OAAoB;QACjE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACvB,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QACjC,iGAAiG;QACjG,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;SAC5E;QACD,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAK3C,oGAAoG;QACpG,6EAA6E;QAC7E,MAAM,cAAc,GAAG,GAAe,EAAE,CAAC,CAAC;YACzC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;SACnD,CAAC,CAAC;QACH,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC;QAEpC,MAAM,mBAAmB,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAc,EAAe,EAAE,CACxE,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QAC7G,OAAO,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,cAAc,CAAC,KAAoB,EAAE,OAAoB;QACjE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACvB,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QAK3C,oGAAoG;QACpG,6EAA6E;QAC7E,MAAM,cAAc,GAAG,GAAe,EAAE,CAAC,CAAC;YACzC,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC;YACpC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK;SACnD,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;QACrC,IAAI,WAAuB,CAAC;QAC5B,GAAG;YACF,WAAW,GAAG,cAAc,EAAE,CAAC;SAC/B,QAAQ,WAAW,CAAC,KAAK,KAAK,WAAW,CAAC,KAAK,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,CAAC,IAAI,EAAE;QAE3F,MAAM,iBAAiB,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACrD,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAC/B,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE;gBAC7C,OAAO,CAAC,CAAC;aACT;YACD,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE;gBAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE;oBAC1B,OAAO,CAAC,CAAC,CAAC;iBACV;gBACD,OAAO,CAAC,CAAC;aACT;YACD,IAAI,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE;gBAC7B,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE;oBAC1B,OAAO,CAAC,CAAC;iBACT;gBACD,OAAO,CAAC,CAAC,CAAC;aACV;YACD,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE;gBACtB,OAAO,CAAC,CAAC,CAAC;aACV;YACD,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC,GAAG,iBAAiB,CAAC;QAC3D,MAAM,mBAAmB,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAc,EAAe,EAAE,CACxE,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QAC7G,MAAM,KAAK,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;QAC/C,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,SAAS,aAAa,CAAC,KAAoB,EAAE,OAAoB;QAChE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,CAAC,MAA4B,EAAa,EAAE,CAAC,CAAC;YAC9D,UAAU,EAAE,OAAO,CAAC,WAAW,CAAC,cAAc,EAAE;YAChD,UAAU,EAAE,mBAAmB,CAAC,KAAK,CAAC;YACtC,MAAM,EAAE,MAAM,aAAN,MAAM,cAAN,MAAM,GAAI,EAAE;SACpB,CAAC,CAAC;QACH,QAAQ,QAAQ,EAAE;YACjB,KAAK,MAAM;gBACV,OAAO,QAAQ,EAAE,CAAC;YACnB,KAAK,OAAO;gBACX,OAAO,QAAQ,CAAC;oBACf,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;iBACxF,CAAC,CAAC;YACJ,KAAK,UAAU;gBACd,OAAO,QAAQ,CAAC;oBACf,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC1C,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;iBAC1C,CAAC,CAAC;YACJ;gBACC,IAAI,CAAC,uBAAuB,QAAQ,EAAE,CAAC,CAAC;SACzC;IACF,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,KAAoB,EAAE,OAAoB;QACxE,MAAM,EAAE,mBAAmB,EAAE,GAAG,YAAY,CAAC;QAC7C,MAAM,EAAE,GAAG,CAAuB,CAAC;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,MAAM,kBAAkB,GAAG,CAAC,WAAwB,EAAW,EAAE;YAChE,gDAAgD;YAChD,IAAI,WAAW,CAAC,gBAAgB,KAAK,IAAI,CAAC,IAAI,EAAE;gBAC/C,OAAO,KAAK,CAAC;aACb;YAED,OAAO,IAAI,CAAC;QACb,CAAC,CAAC;QAEF,IAAI,WAAwB,CAAC;QAC7B,GAAG;YACF,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SAC7C,QAAQ,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE;QAE3C,OAAO;YACN,QAAQ,EAAE,QAAQ;YAClB,KAAK,EAAE;gBACN,IAAI,EAAE,UAAU,CAAC,KAAK;gBACtB,WAAW,EAAE,EAAE;gBACf,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC,EAAE,EAAE,GAAG,EAAE,CAC/E,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAC7B;aACD;YACD,MAAM,EAAE;gBACP,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,WAAW;gBACX,MAAM,EAAE,EAAE;aACV;SACD,CAAC;IACH,CAAC;IAED,KAAK,UAAU,eAAe,CAAC,KAAoB,EAAE,OAAoB;QACxE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACzB,MAAM,kBAAkB,GAAG,CAAC,MAAmB,EAAW,EAAE;YAC3D,sCAAsC;YACtC,IAAI,MAAM,CAAC,KAAK,CAAC,gBAAgB,KAAK,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,gBAAgB,KAAK,IAAI,CAAC,IAAI,EAAE;gBAC7F,OAAO,KAAK,CAAC;aACb;YAED,OAAO,IAAI,CAAC;QACb,CAAC,CAAC;QAEF,IAAI,MAAmB,CAAC;QACxB,GAAG;YACF,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SACxC,QAAQ,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE;QAEtC,OAAO;YACN,QAAQ,EAAE,QAAQ;YAClB,IAAI,EAAE,UAAU,CAAC,MAAM;YACvB,MAAM;SACN,CAAC;IACH,CAAC;IAED,KAAK,UAAU,aAAa,CAAC,KAAoB,EAAE,OAAoB;QACtE,MAAM,EAAE,GAAG,CAAuB,CAAC;QACnC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QAEzB,MAAM,gBAAgB,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAiB,EAAE,WAAwB,EAAW,EAAE;;YAC7F,iEAAiE;YACjE,MAAM,qBAAqB,qBAC1B,WAAW,CAAC,cAAc,0CAAE,MAAM,mCAAI,WAAW,CAAC,gBAAgB,mCAAI,IAAI,CAAC,eAAe,CAAC,CAAC;YAE7F,MAAM,oBAAoB,GAAW,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;YACtE,MAAM,kBAAkB,GAAW,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;YAClE,MAAM,UAAU,GAAG,oBAAoB,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9E,MAAM,QAAQ,GAAG,kBAAkB,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAExE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpF,KACC,IAAI,OAAO,GAAuB,qBAAqB,EACvD,OAAO,KAAK,SAAS,EACrB,OAAO,SAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,0CAAE,UAAU,EACvD;gBACD,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;oBAC7B,OAAO,KAAK,CAAC;iBACb;aACD;YACD,OAAO,IAAI,CAAC;QACb,CAAC,CAAC;QAEF,IAAI,MAAmB,CAAC;QACxB,IAAI,WAAwB,CAAC;QAC7B,GAAG;YACF,MAAM,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACxC,WAAW,GAAG,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;SAC7C,QAAQ,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,WAAW,CAAC,EAAE;QAE7E,OAAO;YACN,QAAQ,EAAE,MAAM;YAChB,MAAM,EAAE;gBACP,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,WAAW,EAAE,EAAE;gBACf,MAAM;aACN;YACD,MAAM,EAAE;gBACP,IAAI,EAAE,UAAU,CAAC,MAAM;gBACvB,WAAW;gBACX,MAAM,EAAE,EAAE;aACV;SACD,CAAC;IACH,CAAC;IAED,KAAK,UAAU,mBAAmB,CACjC,EAAE,IAAI,EAAiB,EACvB,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAe;QAE/C,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,kBAAkB,GAAG,KAAK,EAAE,IAAY,EAA6D,EAAE;YAC5G,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE;gBACvB,OAAO,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;aAC1B;YACD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACtF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QAChD,MAAM,OAAO,GACZ,QAAQ,CAAC,OAAO,KAAK,SAAS;YAC7B,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE;gBACnB,CAAC,CAAC,MAAM,kBAAkB,CAAC,IAAI,CAAC;gBAChC,CAAC,CAAC,SAAS;YACZ,CAAC,CAAC,SAAS,CAAC;QACd,OAAO;YACN,QAAQ,EAAE,YAAY;YACtB,IAAI,EAAE,UAAU,CAAC,QAAQ;YACzB,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YACxC,OAAO;SACP,CAAC;IACH,CAAC;IAED,MAAM,iBAAiB,GAAG,uBAAuB,CAA0B;QAC1E,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC;QAC7F,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5E,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACxE,CAAC,mBAAmB,EAAE,MAAM,CAAC,gBAAgB,CAAC;KAC9C,CAAC,CAAC;IAEH,OAAO,KAAK,EAAE,KAAoB,EAAoC,EAAE;QACvE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,GAAG,KAAK,CAAC;QAC5C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC;QAC9B,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,KAAK,EAAE;YAC/C,IAAI;YACJ,MAAM;YACN,gBAAgB,EAAE,IAAI,CAAC,UAAU,EAAE;YACnC,WAAW,EAAE,IAAI;SACjB,CAAC,CAAC;QACH,IAAI,QAAQ,KAAK,IAAI,EAAE;YACtB,OAAO,IAAI,CAAC;SACZ;QACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,eAAe,GAAwC;IAC5D,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,EAAE;IACd,UAAU,EAAE,CAAC;IACb,WAAW,EAAE,CAAC;IACd,iBAAiB,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,YAAuC;IACtE,MAAM,MAAM,mCACR,eAAe,GACf,YAAY,CACf,CAAC;IAEF,MAAM,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,mCAAQ,iBAAiB,GAAK,MAAM,CAAC,UAAU,CAAE,CAAC;IACnH,MAAM,oBAAoB,GAAG,2BAA2B,GAAG,0BAA0B,CAAC;IAEtF,MAAM,oBAAoB,GACzB,CAAC,QAAgD,EAAkC,EAAE,CACrF,CAAC,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,EAAE,EAAE,CACjD,QAAQ,CAAC,mBAAmB,CAAC,MAAM,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IACrE,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IACpE,MAAM,sBAAsB,GAAmC,CAAC,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAC1F,mBAAmB,CAAC,MAAM,GAAG,CAAC,CAAC;IAChC,MAAM,SAAS,GAAkC;QAChD,CAAC,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,sBAAsB,CAAC;QACjF;YACC,iBAAiB,CAAC,MAAM,CAAC,UAAU,CAAC;YACpC,MAAM,CAAC,UAAU;YACjB,oBAAoB,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,oBAAoB,CAAC;SAC7D;QACD,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,EAAE,gBAAgB,CAAC;QACtD,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;KACrE,CAAC;IACF,OAAO,uBAAuB,CAAC,SAAS,CAAC,CAAC;AAC3C,CAAC;AAiBD,SAAS,uBAAuB,CAC/B,OAAqC;IAErC,MAAM,cAAc,GACnB,EAAE,CAAC;IACJ,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,KAAK,MAAM,CAAC,YAAY,EAAE,MAAM,EAAE,YAAY,CAAC,IAAI,OAAO,EAAE;QAC3D,MAAM,gBAAgB,GAAG,WAAW,GAAG,MAAM,CAAC;QAC9C,cAAc,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAC,CAAC;QACpE,WAAW,GAAG,gBAAgB,CAAC;KAC/B;IAED,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;;QACvC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;QACvB,MAAM,MAAM,GAAG,GAAG,EAAE;YACnB,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;YAEpD,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,EAAE;gBACnD,OAAO,EAAE,CAAC;aACV;YAED,OAAO,OAAO,CAAC;QAChB,CAAC,CAAC;QAEF,IAAI,KAAK,CAAC;QACV,IAAI,YAA+D,CAAC;QACpE,GAAG;YACF,KAAK,GAAG,MAAM,EAAE,CAAC;YACjB,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;SACxC,QAAQ,CAAC,OAAC,YAAY,aAAZ,YAAY,uBAAZ,YAAY,CAAG,KAAK,EAAE,eAAe,oCAAK,IAAI,CAAC,EAAE;QAE5D,MAAM,CAAC,YAAY,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QAC7C,OAAO,OAAO,YAAY,KAAK,UAAU;YACxC,CAAC,CAAE,YAAoD,CAAC,KAAK,EAAE,eAAe,CAAC;YAC/E,CAAC,CAAE,YAA6B,CAAC;IACnC,CAAC,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;;IAChC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,OAAO,GAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE;QAC1B,MAAM,EAAE,SAAG,OAAO,CAAC,GAAG,EAAE,mCAAI,IAAI,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,KAAK,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE;YACxC,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;SAC1B;KACD;IACD,OAAO,MAAM,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CACnB,CAAS,EACT,SAA8C;IAE9C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;QACvC,IAAI,KAAK,GAAG,CAAC,EAAE;YACd,KAAK,EAAE,CAAC;YACR,OAAO,SAAS,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;SACzC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAsB,QAAa;IACpE,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;IACf,OAAO,KAAK,IAAI,EAAE;;QACjB,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE;YAC5B,KAAK,EAAE,CAAC;YACR,aAAO,QAAQ,CAAC,KAAK,CAAC,mCAAI,IAAI,CAAC;SAC/B;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CACpB,GAAG,UAAiD;IAEpD,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;QACvC,OAAO,YAAY,GAAG,UAAU,CAAC,MAAM,EAAE;YACxC,MAAM,SAAS,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;YAC3C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;YACvD,IAAI,MAAM,KAAK,IAAI,EAAE;gBACpB,OAAO,MAAM,CAAC;aACd;iBAAM;gBACN,YAAY,EAAE,CAAC;aACf;SACD;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC;AACH,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport Prando from 'prando';\nimport { v5 } from 'uuid';\nimport { IsoBuffer } from '@fluidframework/common-utils';\nimport { IFluidHandle } from '@fluidframework/core-interfaces';\nimport { Side, TraitMap, WriteFormat } from '../../persisted-types';\nimport { BuildNode, ChangeType, StablePlace, StableRange } from '../../ChangeTypes';\nimport { TraitLocation, TreeView, TreeViewRange } from '../../TreeView';\nimport { Definition, DetachedSequenceId, NodeId, TraitLabel } from '../../Identifiers';\nimport { fail } from '../../Common';\nimport { rangeFromStableRange } from '../../TreeViewUtilities';\nimport {\n\tdone,\n\tEditGenerationConfig,\n\tFuzzChange,\n\tFuzzDelete,\n\tFuzzInsert,\n\tFuzzMove,\n\tFuzzTestState,\n\tAsyncGenerator,\n\tInsertGenerationConfig,\n\tJoinGenerationConfig,\n\tOperation,\n\tOperationGenerationConfig,\n\tTreeContext,\n\tTreeLeave,\n} from './Types';\n\nfunction uuid(rand: Prando): string {\n\treturn v5(rand.nextString(16), '33f960ec-f1e4-4fca-8dcd-223c6647fcc7');\n}\n\nconst defaultJoinConfig: Required<JoinGenerationConfig> = {\n\tmaximumActiveCollaborators: 10,\n\tmaximumPassiveCollaborators: 10,\n\twriteFormat: [WriteFormat.v0_0_2, WriteFormat.v0_1_1],\n\tsummarizeHistory: [false],\n};\n\nfunction makeJoinGenerator(passedConfig: JoinGenerationConfig): AsyncGenerator<Operation, undefined> {\n\tconst config = { ...defaultJoinConfig, ...passedConfig };\n\treturn async ({ rand, activeCollaborators, passiveCollaborators }) => {\n\t\tconst activeAllowed = activeCollaborators.length < config.maximumActiveCollaborators;\n\t\tconst passiveAllowed = passiveCollaborators.length < config.maximumPassiveCollaborators;\n\t\tconst isObserver =\n\t\t\tactiveAllowed && passiveAllowed\n\t\t\t\t? rand.nextBoolean()\n\t\t\t\t: activeAllowed\n\t\t\t\t? false\n\t\t\t\t: passiveAllowed\n\t\t\t\t? true\n\t\t\t\t: fail(\n\t\t\t\t\t\t'Cannot generate join op when both active and passive collaborators are at the configured limit.'\n\t\t\t\t );\n\t\treturn {\n\t\t\ttype: 'join',\n\t\t\tsummarizeHistory: rand.nextArrayItem(config.summarizeHistory),\n\t\t\twriteFormat: rand.nextArrayItem(config.writeFormat),\n\t\t\tisObserver,\n\t\t};\n\t};\n}\n\nasync function leaveGenerator({ rand, activeCollaborators, passiveCollaborators }: FuzzTestState): Promise<TreeLeave> {\n\tconst canUsePassive = passiveCollaborators.length > 0;\n\tconst canUseActive = activeCollaborators.length > 0;\n\tconst isObserver =\n\t\tcanUsePassive && canUseActive\n\t\t\t? rand.nextBoolean()\n\t\t\t: canUsePassive\n\t\t\t? true\n\t\t\t: canUseActive\n\t\t\t? false\n\t\t\t: fail('Cannot generate a leave op when there are no clients.');\n\tconst index = rand.nextInt(0, (isObserver ? passiveCollaborators : activeCollaborators).length - 1);\n\treturn { type: 'leave', isObserver, index };\n}\n\nconst defaultInsertConfig: Required<InsertGenerationConfig> = {\n\tdefinitionPoolSize: 20,\n\tmaxTreeSequenceSize: 3,\n};\n\nconst defaultEditConfig: Required<EditGenerationConfig> = {\n\tmaxTreeSize: Number.POSITIVE_INFINITY,\n\tinsertWeight: 3,\n\tinsertConfig: defaultInsertConfig,\n\tdeleteWeight: 1,\n\tmoveWeight: 1,\n\tsetPayloadWeight: 1,\n\ttraitLabelPoolSize: 20,\n};\n\nconst makeEditGenerator = (passedConfig: EditGenerationConfig): AsyncGenerator<Operation, undefined> => {\n\tconst config = { ...defaultEditConfig, ...passedConfig };\n\tconst insertConfig = { ...defaultInsertConfig, ...config.insertConfig };\n\tconst poolRand = new Prando(0);\n\tconst traitLabelPool = Array.from({ length: config.traitLabelPoolSize }, () => uuid(poolRand) as TraitLabel);\n\tconst traitLabelGenerator = ({ rand }: FuzzTestState) => rand.nextArrayItem(traitLabelPool);\n\n\tconst definitionPool = Array.from({ length: insertConfig.definitionPoolSize }, () => uuid(poolRand) as Definition);\n\tconst definitionGenerator = ({ rand }: FuzzTestState) => rand.nextArrayItem(definitionPool);\n\n\tfunction traitGenerator(state: FuzzTestState, { view, idList }: TreeContext): TraitLocation {\n\t\tconst id = state.rand.nextArrayItem(idList);\n\t\treturn view.tryGetTraitLocation(id) ?? { parent: id, label: traitLabelGenerator(state) };\n\t}\n\n\tfunction placeGenerator(state: FuzzTestState, context: TreeContext): StablePlace {\n\t\tconst { rand } = state;\n\t\tconst { view, idList } = context;\n\t\t// Note: this gives a 50% chance of adding to a new trait; we may want to tune this at some point\n\t\tif (rand.nextBoolean()) {\n\t\t\tconst parent = rand.nextArrayItem(idList);\n\t\t\treturn StablePlace.atStartOf({ parent, label: traitLabelGenerator(state) });\n\t\t}\n\t\tconst traitLocation = traitGenerator(state, context);\n\t\tconst trait = view.getTrait(traitLocation);\n\t\tinterface Descriptor {\n\t\t\tindex: number;\n\t\t\tside: Side;\n\t\t}\n\t\t// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.\n\t\t// index === trait.length is treated as either the start or end of the trait.\n\t\tconst makeDescriptor = (): Descriptor => ({\n\t\t\tindex: rand.nextInt(0, trait.length),\n\t\t\tside: rand.nextBoolean() ? Side.Before : Side.After,\n\t\t});\n\t\tconst descriptor = makeDescriptor();\n\n\t\tconst placeFromDescriptor = ({ index, side }: Descriptor): StablePlace =>\n\t\t\tindex === trait.length ? { referenceTrait: traitLocation, side } : { referenceSibling: trait[index], side };\n\t\treturn placeFromDescriptor(descriptor);\n\t}\n\n\tfunction rangeGenerator(state: FuzzTestState, context: TreeContext): StableRange {\n\t\tconst { rand } = state;\n\t\tconst { view } = context;\n\t\tconst traitLocation = traitGenerator(state, context);\n\t\tconst trait = view.getTrait(traitLocation);\n\t\tinterface Descriptor {\n\t\t\tindex: number;\n\t\t\tside: Side;\n\t\t}\n\t\t// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.\n\t\t// index === trait.length is treated as either the start or end of the trait.\n\t\tconst makeDescriptor = (): Descriptor => ({\n\t\t\tindex: rand.nextInt(0, trait.length),\n\t\t\tside: rand.nextBoolean() ? Side.Before : Side.After,\n\t\t});\n\t\tconst descriptor1 = makeDescriptor();\n\t\tlet descriptor2: Descriptor;\n\t\tdo {\n\t\t\tdescriptor2 = makeDescriptor();\n\t\t} while (descriptor1.index === descriptor2.index && descriptor1.side === descriptor2.side);\n\n\t\tconst sortedDescriptors = [descriptor1, descriptor2];\n\t\tsortedDescriptors.sort((a, b) => {\n\t\t\tif (a.index === b.index && a.side === b.side) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (a.index === trait.length) {\n\t\t\t\tif (a.side === Side.After) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (b.index === trait.length) {\n\t\t\t\tif (b.side === Side.After) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (a.index < b.index) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\treturn a.side === Side.Before ? -1 : 1;\n\t\t});\n\t\tconst [startDescriptor, endDescriptor] = sortedDescriptors;\n\t\tconst placeFromDescriptor = ({ index, side }: Descriptor): StablePlace =>\n\t\t\tindex === trait.length ? { referenceTrait: traitLocation, side } : { referenceSibling: trait[index], side };\n\t\tconst start = placeFromDescriptor(startDescriptor);\n\t\tconst end = placeFromDescriptor(endDescriptor);\n\t\treturn StableRange.from(start).to(end);\n\t}\n\n\tfunction treeGenerator(state: FuzzTestState, context: TreeContext): BuildNode {\n\t\tconst { rand } = state;\n\t\tconst treeType = rand.nextArrayItem(['leaf', 'stick', 'balanced']);\n\t\tconst makeNode = (traits?: TraitMap<BuildNode>): BuildNode => ({\n\t\t\tidentifier: context.idGenerator.generateNodeId(),\n\t\t\tdefinition: definitionGenerator(state),\n\t\t\ttraits: traits ?? {},\n\t\t});\n\t\tswitch (treeType) {\n\t\t\tcase 'leaf':\n\t\t\t\treturn makeNode();\n\t\t\tcase 'stick':\n\t\t\t\treturn makeNode({\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode({ [traitLabelGenerator(state)]: [makeNode()] })],\n\t\t\t\t});\n\t\t\tcase 'balanced':\n\t\t\t\treturn makeNode({\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode()],\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode()],\n\t\t\t\t});\n\t\t\tdefault:\n\t\t\t\tfail(`Unexpected treeType ${treeType}`);\n\t\t}\n\t}\n\n\tasync function insertGenerator(state: FuzzTestState, context: TreeContext): Promise<FuzzInsert> {\n\t\tconst { maxTreeSequenceSize } = insertConfig;\n\t\tconst id = 1 as DetachedSequenceId;\n\t\tconst { view } = context;\n\t\tconst isValidInsertPlace = (destination: StablePlace): boolean => {\n\t\t\t// Disallow insertion adjacent to the root node.\n\t\t\tif (destination.referenceSibling === view.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tlet destination: StablePlace;\n\t\tdo {\n\t\t\tdestination = placeGenerator(state, context);\n\t\t} while (!isValidInsertPlace(destination));\n\n\t\treturn {\n\t\t\tfuzzType: 'insert',\n\t\t\tbuild: {\n\t\t\t\ttype: ChangeType.Build,\n\t\t\t\tdestination: id,\n\t\t\t\tsource: Array.from({ length: state.rand.nextInt(1, maxTreeSequenceSize) }, () =>\n\t\t\t\t\ttreeGenerator(state, context)\n\t\t\t\t),\n\t\t\t},\n\t\t\tinsert: {\n\t\t\t\ttype: ChangeType.Insert,\n\t\t\t\tdestination,\n\t\t\t\tsource: id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync function deleteGenerator(state: FuzzTestState, context: TreeContext): Promise<FuzzDelete> {\n\t\tconst { view } = context;\n\t\tconst isValidDeleteRange = (source: StableRange): boolean => {\n\t\t\t// Disallow deletion of the root node.\n\t\t\tif (source.start.referenceSibling === view.root || source.end.referenceSibling === view.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tlet source: StableRange;\n\t\tdo {\n\t\t\tsource = rangeGenerator(state, context);\n\t\t} while (!isValidDeleteRange(source));\n\n\t\treturn {\n\t\t\tfuzzType: 'delete',\n\t\t\ttype: ChangeType.Detach,\n\t\t\tsource,\n\t\t};\n\t}\n\n\tasync function moveGenerator(state: FuzzTestState, context: TreeContext): Promise<FuzzMove> {\n\t\tconst id = 1 as DetachedSequenceId;\n\t\tconst { view } = context;\n\n\t\tconst isValidMoveRange = ({ start, end }: TreeViewRange, destination: StablePlace): boolean => {\n\t\t\t// An ancestor cannot be moved to be a sibling of its descendant.\n\t\t\tconst forbiddenDescendantId =\n\t\t\t\tdestination.referenceTrait?.parent ?? destination.referenceSibling ?? fail('Invalid place');\n\n\t\t\tconst unadjustedStartIndex: number = view.findIndexWithinTrait(start);\n\t\t\tconst unadjustedEndIndex: number = view.findIndexWithinTrait(end);\n\t\t\tconst startIndex = unadjustedStartIndex + (start.side === Side.After ? 1 : 0);\n\t\t\tconst endIndex = unadjustedEndIndex + (end.side === Side.After ? 1 : 0);\n\n\t\t\tconst idsInSource = new Set(view.getTrait(start.trait).slice(startIndex, endIndex));\n\t\t\tfor (\n\t\t\t\tlet current: NodeId | undefined = forbiddenDescendantId;\n\t\t\t\tcurrent !== undefined;\n\t\t\t\tcurrent = view.tryGetParentViewNode(current)?.identifier\n\t\t\t) {\n\t\t\t\tif (idsInSource.has(current)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tlet source: StableRange;\n\t\tlet destination: StablePlace;\n\t\tdo {\n\t\t\tsource = rangeGenerator(state, context);\n\t\t\tdestination = placeGenerator(state, context);\n\t\t} while (!isValidMoveRange(rangeFromStableRange(view, source), destination));\n\n\t\treturn {\n\t\t\tfuzzType: 'move',\n\t\t\tdetach: {\n\t\t\t\ttype: ChangeType.Detach,\n\t\t\t\tdestination: id,\n\t\t\t\tsource,\n\t\t\t},\n\t\t\tinsert: {\n\t\t\t\ttype: ChangeType.Insert,\n\t\t\t\tdestination,\n\t\t\t\tsource: id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync function setPayloadGenerator(\n\t\t{ rand }: FuzzTestState,\n\t\t{ idList, view, dataStoreRuntime }: TreeContext\n\t): Promise<FuzzChange> {\n\t\tconst nodeToModify = rand.nextArrayItem(idList);\n\t\tconst getPayloadContents = async (rand: Prando): Promise<string | { blob: IFluidHandle<ArrayBufferLike> }> => {\n\t\t\tif (rand.nextBoolean()) {\n\t\t\t\treturn rand.nextString(4);\n\t\t\t}\n\t\t\tconst handle = await dataStoreRuntime.uploadBlob(IsoBuffer.from(rand.nextString(10)));\n\t\t\treturn { blob: handle };\n\t\t};\n\n\t\tconst viewNode = view.getViewNode(nodeToModify);\n\t\tconst payload =\n\t\t\tviewNode.payload !== undefined\n\t\t\t\t? rand.nextBoolean()\n\t\t\t\t\t? await getPayloadContents(rand)\n\t\t\t\t\t: undefined\n\t\t\t\t: undefined;\n\t\treturn {\n\t\t\tfuzzType: 'setPayload',\n\t\t\ttype: ChangeType.SetValue,\n\t\t\tnodeToModify: rand.nextArrayItem(idList),\n\t\t\tpayload,\n\t\t};\n\t}\n\n\tconst baseEditGenerator = createWeightedGenerator<FuzzChange, TreeContext>([\n\t\t[insertGenerator, config.insertWeight, (_, { idList }) => idList.length < config.maxTreeSize],\n\t\t[deleteGenerator, config.deleteWeight, (_, { idList }) => idList.length > 1],\n\t\t[moveGenerator, config.moveWeight, (_, { idList }) => idList.length > 1],\n\t\t[setPayloadGenerator, config.setPayloadWeight],\n\t]);\n\n\treturn async (state: FuzzTestState): Promise<Operation | typeof done> => {\n\t\tconst { rand, activeCollaborators } = state;\n\t\tconst index = rand.nextInt(0, activeCollaborators.length - 1);\n\t\tconst { tree } = activeCollaborators[index];\n\t\tconst view = tree.currentView;\n\t\tconst idList = getIdList(view);\n\t\tconst contents = await baseEditGenerator(state, {\n\t\t\tview,\n\t\t\tidList,\n\t\t\tdataStoreRuntime: tree.getRuntime(),\n\t\t\tidGenerator: tree,\n\t\t});\n\t\tif (contents === done) {\n\t\t\treturn done;\n\t\t}\n\t\treturn { type: 'edit', contents, index };\n\t};\n};\n\nconst defaultOpConfig: Required<OperationGenerationConfig> = {\n\teditConfig: defaultEditConfig,\n\tjoinConfig: defaultJoinConfig,\n\teditWeight: 10,\n\tjoinWeight: 1,\n\tleaveWeight: 1,\n\tsynchronizeWeight: 1,\n};\n\nexport function makeOpGenerator(passedConfig: OperationGenerationConfig): AsyncGenerator<Operation, undefined> {\n\tconst config = {\n\t\t...defaultOpConfig,\n\t\t...passedConfig,\n\t};\n\n\tconst { maximumPassiveCollaborators, maximumActiveCollaborators } = { ...defaultJoinConfig, ...config.joinConfig };\n\tconst maximumCollaborators = maximumPassiveCollaborators + maximumActiveCollaborators;\n\n\tconst collaboratorsMatches =\n\t\t(criteria: (collaboratorCount: number) => boolean): AcceptanceCondition<undefined> =>\n\t\t({ activeCollaborators, passiveCollaborators }) =>\n\t\t\tcriteria(activeCollaborators.length + passiveCollaborators.length);\n\tconst atLeastOneClient = collaboratorsMatches((count) => count > 0);\n\tconst atLeastOneActiveClient: AcceptanceCondition<undefined> = ({ activeCollaborators }) =>\n\t\tactiveCollaborators.length > 0;\n\tconst opWeights: Weights<Operation, undefined> = [\n\t\t[makeEditGenerator(config.editConfig), config.editWeight, atLeastOneActiveClient],\n\t\t[\n\t\t\tmakeJoinGenerator(config.joinConfig),\n\t\t\tconfig.joinWeight,\n\t\t\tcollaboratorsMatches((count) => count < maximumCollaborators),\n\t\t],\n\t\t[leaveGenerator, config.leaveWeight, atLeastOneClient],\n\t\t[{ type: 'synchronize' }, config.synchronizeWeight, atLeastOneClient],\n\t];\n\treturn createWeightedGenerator(opWeights);\n}\n\ntype AcceptanceCondition<TAdditionalState> = (state: FuzzTestState, additionalState: TAdditionalState) => boolean;\n\n/**\n * Array of weighted generators to select from.\n *\n * A generator should only be invoked if the corresponding `AcceptanceCondition` evaluates to true.\n * This is useful in practice to avoid invoking generators for known-to-be invalid actions based on the current state:\n * for example, a \"leave\" op cannot be generated if there are no currently connected clients.\n */\ntype Weights<T, TAdditionalState> = [\n\tT | AsyncGenerator<T, TAdditionalState>,\n\tnumber,\n\tAcceptanceCondition<TAdditionalState>?\n][];\n\nfunction createWeightedGenerator<T, TAdditionalState>(\n\tweights: Weights<T, TAdditionalState>\n): AsyncGenerator<T, TAdditionalState> {\n\tconst cumulativeSums: [T | AsyncGenerator<T, TAdditionalState>, number, AcceptanceCondition<TAdditionalState>?][] =\n\t\t[];\n\tlet totalWeight = 0;\n\tfor (const [tOrGenerator, weight, shouldAccept] of weights) {\n\t\tconst cumulativeWeight = totalWeight + weight;\n\t\tcumulativeSums.push([tOrGenerator, cumulativeWeight, shouldAccept]);\n\t\ttotalWeight = cumulativeWeight;\n\t}\n\n\treturn async (state, additionalState) => {\n\t\tconst { rand } = state;\n\t\tconst sample = () => {\n\t\t\tconst weightSelected = rand.nextInt(1, totalWeight);\n\n\t\t\tlet opIndex = 0;\n\t\t\twhile (cumulativeSums[opIndex][1] < weightSelected) {\n\t\t\t\topIndex++;\n\t\t\t}\n\n\t\t\treturn opIndex;\n\t\t};\n\n\t\tlet index;\n\t\tlet shouldAccept: AcceptanceCondition<TAdditionalState> | undefined;\n\t\tdo {\n\t\t\tindex = sample();\n\t\t\tshouldAccept = cumulativeSums[index][2];\n\t\t} while (!(shouldAccept?.(state, additionalState) ?? true));\n\n\t\tconst [tOrGenerator] = cumulativeSums[index];\n\t\treturn typeof tOrGenerator === 'function'\n\t\t\t? (tOrGenerator as AsyncGenerator<T, TAdditionalState>)(state, additionalState)\n\t\t\t: (tOrGenerator as unknown as T);\n\t};\n}\n\nfunction getIdList(tree: TreeView): NodeId[] {\n\tconst allIds: NodeId[] = [];\n\tconst toVisit: NodeId[] = [tree.root];\n\twhile (toVisit.length > 0) {\n\t\tconst id = toVisit.pop() ?? fail();\n\t\tallIds.push(id);\n\t\tconst node = tree.getViewNode(id);\n\t\tfor (const [_, childIds] of node.traits) {\n\t\t\ttoVisit.push(...childIds);\n\t\t}\n\t}\n\treturn allIds;\n}\n\n/**\n * Higher-order generator operator which creates a new generator producing the first `n` elements of `generator`.\n */\nexport function take<T, TAdditionalState>(\n\tn: number,\n\tgenerator: AsyncGenerator<T, TAdditionalState>\n): AsyncGenerator<T, TAdditionalState> {\n\tlet count = 0;\n\treturn async (state, additionalState) => {\n\t\tif (count < n) {\n\t\t\tcount++;\n\t\t\treturn generator(state, additionalState);\n\t\t}\n\t\treturn done;\n\t};\n}\n\n/**\n * @returns a deterministic generator that always returns the items of `contents` in order.\n */\nexport function generatorFromArray<T, TAdditionalState>(contents: T[]): AsyncGenerator<T, TAdditionalState> {\n\tlet index = -1;\n\treturn async () => {\n\t\tif (index < contents.length) {\n\t\t\tindex++;\n\t\t\treturn contents[index] ?? done;\n\t\t}\n\t\treturn done;\n\t};\n}\n\n/**\n * Higher-order generator operator which exhausts each input generator sequentially before moving on to the next.\n */\nexport function chain<T, TAdditionalState>(\n\t...generators: AsyncGenerator<T, TAdditionalState>[]\n): AsyncGenerator<T, TAdditionalState> {\n\tlet currentIndex = 0;\n\treturn async (state, additionalState) => {\n\t\twhile (currentIndex < generators.length) {\n\t\t\tconst generator = generators[currentIndex];\n\t\t\tconst result = await generator(state, additionalState);\n\t\t\tif (result !== done) {\n\t\t\t\treturn result;\n\t\t\t} else {\n\t\t\t\tcurrentIndex++;\n\t\t\t}\n\t\t}\n\t\treturn done;\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Generators.js","sourceRoot":"","sources":["../../../src/test/fuzz/Generators.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 Random from 'random-js';\nimport { IsoBuffer } from '@fluidframework/common-utils';\nimport { IFluidHandle } from '@fluidframework/core-interfaces';\nimport {\n\tAcceptanceCondition,\n\tAsyncGenerator,\n\tAsyncWeights,\n\tcreateWeightedAsyncGenerator,\n\tdone,\n\tmakeRandom,\n} from '@fluid-internal/stochastic-test-utils';\nimport { Side, TraitMap, WriteFormat } from '../../persisted-types';\nimport { BuildNode, ChangeType, StablePlace, StableRange } from '../../ChangeTypes';\nimport { TraitLocation, TreeView, TreeViewRange } from '../../TreeView';\nimport { Definition, DetachedSequenceId, NodeId, TraitLabel } from '../../Identifiers';\nimport { fail } from '../../Common';\nimport { rangeFromStableRange } from '../../TreeViewUtilities';\nimport {\n\tEditGenerationConfig,\n\tFuzzChange,\n\tFuzzDelete,\n\tFuzzInsert,\n\tFuzzMove,\n\tFuzzTestState,\n\tInsertGenerationConfig,\n\tJoinGenerationConfig,\n\tOperation,\n\tOperationGenerationConfig,\n\tTreeContext,\n\tTreeLeave,\n} from './Types';\n\nconst defaultJoinConfig: Required<JoinGenerationConfig> = {\n\tmaximumActiveCollaborators: 10,\n\tmaximumPassiveCollaborators: 10,\n\twriteFormat: [WriteFormat.v0_0_2, WriteFormat.v0_1_1],\n\tsummarizeHistory: [false],\n};\n\nfunction makeJoinGenerator(passedConfig: JoinGenerationConfig): AsyncGenerator<Operation, FuzzTestState> {\n\tconst config = { ...defaultJoinConfig, ...passedConfig };\n\treturn async ({ random, activeCollaborators, passiveCollaborators }) => {\n\t\tconst activeAllowed = activeCollaborators.length < config.maximumActiveCollaborators;\n\t\tconst passiveAllowed = passiveCollaborators.length < config.maximumPassiveCollaborators;\n\t\tconst isObserver =\n\t\t\tactiveAllowed && passiveAllowed\n\t\t\t\t? random.bool()\n\t\t\t\t: activeAllowed\n\t\t\t\t? false\n\t\t\t\t: passiveAllowed\n\t\t\t\t? true\n\t\t\t\t: fail(\n\t\t\t\t\t\t'Cannot generate join op when both active and passive collaborators are at the configured limit.'\n\t\t\t\t );\n\t\treturn {\n\t\t\ttype: 'join',\n\t\t\tsummarizeHistory: random.pick(config.summarizeHistory),\n\t\t\twriteFormat: random.pick(config.writeFormat),\n\t\t\tisObserver,\n\t\t};\n\t};\n}\n\nasync function leaveGenerator({\n\trandom,\n\tactiveCollaborators,\n\tpassiveCollaborators,\n}: FuzzTestState): Promise<TreeLeave> {\n\tconst canUsePassive = passiveCollaborators.length > 0;\n\tconst canUseActive = activeCollaborators.length > 0;\n\tconst isObserver =\n\t\tcanUsePassive && canUseActive\n\t\t\t? random.bool()\n\t\t\t: canUsePassive\n\t\t\t? true\n\t\t\t: canUseActive\n\t\t\t? false\n\t\t\t: fail('Cannot generate a leave op when there are no clients.');\n\tconst index = random.integer(0, (isObserver ? passiveCollaborators : activeCollaborators).length - 1);\n\treturn { type: 'leave', isObserver, index };\n}\n\nconst defaultInsertConfig: Required<InsertGenerationConfig> = {\n\tdefinitionPoolSize: 20,\n\tmaxTreeSequenceSize: 3,\n};\n\nconst defaultEditConfig: Required<EditGenerationConfig> = {\n\tmaxTreeSize: Number.POSITIVE_INFINITY,\n\tinsertWeight: 3,\n\tinsertConfig: defaultInsertConfig,\n\tdeleteWeight: 1,\n\tmoveWeight: 1,\n\tsetPayloadWeight: 1,\n\ttraitLabelPoolSize: 20,\n};\n\nconst makeEditGenerator = (passedConfig: EditGenerationConfig): AsyncGenerator<Operation, FuzzTestState> => {\n\tconst config = { ...defaultEditConfig, ...passedConfig };\n\tconst insertConfig = { ...defaultInsertConfig, ...config.insertConfig };\n\tconst poolRand = makeRandom(0);\n\tconst traitLabelPool = Array.from({ length: config.traitLabelPoolSize }, () => poolRand.uuid4() as TraitLabel);\n\tconst traitLabelGenerator = ({ random }: FuzzTestState) => random.pick(traitLabelPool);\n\n\tconst definitionPool = Array.from(\n\t\t{ length: insertConfig.definitionPoolSize },\n\t\t() => poolRand.uuid4() as Definition\n\t);\n\tconst definitionGenerator = ({ random }: FuzzTestState) => random.pick(definitionPool);\n\ttype EditState = FuzzTestState & TreeContext;\n\n\tfunction traitGenerator(state: EditState): TraitLocation {\n\t\tconst { idList, random, view } = state;\n\t\tconst id = random.pick(idList);\n\t\treturn view.tryGetTraitLocation(id) ?? { parent: id, label: traitLabelGenerator(state) };\n\t}\n\n\tfunction placeGenerator(state: EditState): StablePlace {\n\t\tconst { idList, random, view } = state;\n\t\t// Note: this gives a 50% chance of adding to a new trait; we may want to tune this at some point\n\t\tif (random.bool()) {\n\t\t\tconst parent = random.pick(idList);\n\t\t\treturn StablePlace.atStartOf({ parent, label: traitLabelGenerator(state) });\n\t\t}\n\t\tconst traitLocation = traitGenerator(state);\n\t\tconst trait = view.getTrait(traitLocation);\n\t\tinterface Descriptor {\n\t\t\tindex: number;\n\t\t\tside: Side;\n\t\t}\n\t\t// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.\n\t\t// index === trait.length is treated as either the start or end of the trait.\n\t\tconst makeDescriptor = (): Descriptor => ({\n\t\t\tindex: random.integer(0, trait.length),\n\t\t\tside: random.bool() ? Side.Before : Side.After,\n\t\t});\n\t\tconst descriptor = makeDescriptor();\n\n\t\tconst placeFromDescriptor = ({ index, side }: Descriptor): StablePlace =>\n\t\t\tindex === trait.length ? { referenceTrait: traitLocation, side } : { referenceSibling: trait[index], side };\n\t\treturn placeFromDescriptor(descriptor);\n\t}\n\n\tfunction rangeGenerator(state: EditState): StableRange {\n\t\tconst { random, view } = state;\n\t\tconst traitLocation = traitGenerator(state);\n\t\tconst trait = view.getTrait(traitLocation);\n\t\tinterface Descriptor {\n\t\t\tindex: number;\n\t\t\tside: Side;\n\t\t}\n\t\t// For a trait of length N, there are 2N + 2valid places: start, before index 1, after index 1, etc.\n\t\t// index === trait.length is treated as either the start or end of the trait.\n\t\tconst makeDescriptor = (): Descriptor => ({\n\t\t\tindex: random.integer(0, trait.length),\n\t\t\tside: random.bool() ? Side.Before : Side.After,\n\t\t});\n\t\tconst descriptor1 = makeDescriptor();\n\t\tlet descriptor2: Descriptor;\n\t\tdo {\n\t\t\tdescriptor2 = makeDescriptor();\n\t\t} while (descriptor1.index === descriptor2.index && descriptor1.side === descriptor2.side);\n\n\t\tconst sortedDescriptors = [descriptor1, descriptor2];\n\t\tsortedDescriptors.sort((a, b) => {\n\t\t\tif (a.index === b.index && a.side === b.side) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif (a.index === trait.length) {\n\t\t\t\tif (a.side === Side.After) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif (b.index === trait.length) {\n\t\t\t\tif (b.side === Side.After) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (a.index < b.index) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\treturn a.side === Side.Before ? -1 : 1;\n\t\t});\n\t\tconst [startDescriptor, endDescriptor] = sortedDescriptors;\n\t\tconst placeFromDescriptor = ({ index, side }: Descriptor): StablePlace =>\n\t\t\tindex === trait.length ? { referenceTrait: traitLocation, side } : { referenceSibling: trait[index], side };\n\t\tconst start = placeFromDescriptor(startDescriptor);\n\t\tconst end = placeFromDescriptor(endDescriptor);\n\t\treturn StableRange.from(start).to(end);\n\t}\n\n\tfunction treeGenerator(state: EditState): BuildNode {\n\t\tconst { random, idGenerator } = state;\n\t\tconst treeType = random.pick(['leaf', 'stick', 'balanced']);\n\t\tconst makeNode = (traits?: TraitMap<BuildNode>): BuildNode => ({\n\t\t\tidentifier: idGenerator.generateNodeId(),\n\t\t\tdefinition: definitionGenerator(state),\n\t\t\ttraits: traits ?? {},\n\t\t});\n\t\tswitch (treeType) {\n\t\t\tcase 'leaf':\n\t\t\t\treturn makeNode();\n\t\t\tcase 'stick':\n\t\t\t\treturn makeNode({\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode({ [traitLabelGenerator(state)]: [makeNode()] })],\n\t\t\t\t});\n\t\t\tcase 'balanced':\n\t\t\t\treturn makeNode({\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode()],\n\t\t\t\t\t[traitLabelGenerator(state)]: [makeNode()],\n\t\t\t\t});\n\t\t\tdefault:\n\t\t\t\tfail(`Unexpected treeType ${treeType}`);\n\t\t}\n\t}\n\n\tasync function insertGenerator(state: EditState): Promise<FuzzInsert> {\n\t\tconst { maxTreeSequenceSize } = insertConfig;\n\t\tconst id = 1 as DetachedSequenceId;\n\t\tconst { view } = state;\n\t\tconst isValidInsertPlace = (destination: StablePlace): boolean => {\n\t\t\t// Disallow insertion adjacent to the root node.\n\t\t\tif (destination.referenceSibling === view.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tlet destination: StablePlace;\n\t\tdo {\n\t\t\tdestination = placeGenerator(state);\n\t\t} while (!isValidInsertPlace(destination));\n\n\t\treturn {\n\t\t\tfuzzType: 'insert',\n\t\t\tbuild: {\n\t\t\t\ttype: ChangeType.Build,\n\t\t\t\tdestination: id,\n\t\t\t\tsource: Array.from({ length: state.random.integer(1, maxTreeSequenceSize) }, () =>\n\t\t\t\t\ttreeGenerator(state)\n\t\t\t\t),\n\t\t\t},\n\t\t\tinsert: {\n\t\t\t\ttype: ChangeType.Insert,\n\t\t\t\tdestination,\n\t\t\t\tsource: id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync function deleteGenerator(state: EditState): Promise<FuzzDelete> {\n\t\tconst { view } = state;\n\t\tconst isValidDeleteRange = (source: StableRange): boolean => {\n\t\t\t// Disallow deletion of the root node.\n\t\t\tif (source.start.referenceSibling === view.root || source.end.referenceSibling === view.root) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\treturn true;\n\t\t};\n\n\t\tlet source: StableRange;\n\t\tdo {\n\t\t\tsource = rangeGenerator(state);\n\t\t} while (!isValidDeleteRange(source));\n\n\t\treturn {\n\t\t\tfuzzType: 'delete',\n\t\t\ttype: ChangeType.Detach,\n\t\t\tsource,\n\t\t};\n\t}\n\n\tasync function moveGenerator(state: EditState): Promise<FuzzMove> {\n\t\tconst id = 1 as DetachedSequenceId;\n\t\tconst { view } = state;\n\n\t\tconst isValidMoveRange = ({ start, end }: TreeViewRange, destination: StablePlace): boolean => {\n\t\t\t// An ancestor cannot be moved to be a sibling of its descendant.\n\t\t\tconst forbiddenDescendantId =\n\t\t\t\tdestination.referenceTrait?.parent ?? destination.referenceSibling ?? fail('Invalid place');\n\n\t\t\tconst unadjustedStartIndex: number = view.findIndexWithinTrait(start);\n\t\t\tconst unadjustedEndIndex: number = view.findIndexWithinTrait(end);\n\t\t\tconst startIndex = unadjustedStartIndex + (start.side === Side.After ? 1 : 0);\n\t\t\tconst endIndex = unadjustedEndIndex + (end.side === Side.After ? 1 : 0);\n\n\t\t\tconst idsInSource = new Set(view.getTrait(start.trait).slice(startIndex, endIndex));\n\t\t\tfor (\n\t\t\t\tlet current: NodeId | undefined = forbiddenDescendantId;\n\t\t\t\tcurrent !== undefined;\n\t\t\t\tcurrent = view.tryGetParentViewNode(current)?.identifier\n\t\t\t) {\n\t\t\t\tif (idsInSource.has(current)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tlet source: StableRange;\n\t\tlet destination: StablePlace;\n\t\tdo {\n\t\t\tsource = rangeGenerator(state);\n\t\t\tdestination = placeGenerator(state);\n\t\t} while (!isValidMoveRange(rangeFromStableRange(view, source), destination));\n\n\t\treturn {\n\t\t\tfuzzType: 'move',\n\t\t\tdetach: {\n\t\t\t\ttype: ChangeType.Detach,\n\t\t\t\tdestination: id,\n\t\t\t\tsource,\n\t\t\t},\n\t\t\tinsert: {\n\t\t\t\ttype: ChangeType.Insert,\n\t\t\t\tdestination,\n\t\t\t\tsource: id,\n\t\t\t},\n\t\t};\n\t}\n\n\tasync function setPayloadGenerator({ dataStoreRuntime, idList, random, view }: EditState): Promise<FuzzChange> {\n\t\tconst nodeToModify = random.pick(idList);\n\t\tconst getPayloadContents = async (\n\t\t\trandom: Random\n\t\t): Promise<string | { blob: IFluidHandle<ArrayBufferLike> }> => {\n\t\t\tif (random.bool()) {\n\t\t\t\treturn random.string(4);\n\t\t\t}\n\t\t\tconst handle = await dataStoreRuntime.uploadBlob(IsoBuffer.from(random.string(10)));\n\t\t\treturn { blob: handle };\n\t\t};\n\n\t\tconst viewNode = view.getViewNode(nodeToModify);\n\t\tconst payload =\n\t\t\tviewNode.payload !== undefined ? (random.bool() ? await getPayloadContents(random) : undefined) : undefined;\n\t\treturn {\n\t\t\tfuzzType: 'setPayload',\n\t\t\ttype: ChangeType.SetValue,\n\t\t\tnodeToModify: random.pick(idList),\n\t\t\tpayload,\n\t\t};\n\t}\n\n\tconst baseEditGenerator = createWeightedAsyncGenerator<FuzzChange, EditState>([\n\t\t[insertGenerator, config.insertWeight, ({ idList }) => idList.length < config.maxTreeSize],\n\t\t[deleteGenerator, config.deleteWeight, ({ idList }) => idList.length > 1],\n\t\t[moveGenerator, config.moveWeight, ({ idList }) => idList.length > 1],\n\t\t[setPayloadGenerator, config.setPayloadWeight],\n\t]);\n\n\treturn async (state: FuzzTestState): Promise<Operation | typeof done> => {\n\t\tconst { random, activeCollaborators } = state;\n\t\tconst index = random.integer(0, activeCollaborators.length - 1);\n\t\tconst { tree } = activeCollaborators[index];\n\t\tconst view = tree.currentView;\n\t\tconst idList = getIdList(view);\n\t\tconst contents = await baseEditGenerator({\n\t\t\t...state,\n\t\t\tview,\n\t\t\tidList,\n\t\t\tdataStoreRuntime: tree.getRuntime(),\n\t\t\tidGenerator: tree,\n\t\t});\n\t\tif (contents === done) {\n\t\t\treturn done;\n\t\t}\n\t\treturn { type: 'edit', contents, index };\n\t};\n};\n\nconst defaultOpConfig: Required<OperationGenerationConfig> = {\n\teditConfig: defaultEditConfig,\n\tjoinConfig: defaultJoinConfig,\n\teditWeight: 10,\n\tjoinWeight: 1,\n\tleaveWeight: 1,\n\tsynchronizeWeight: 1,\n};\n\nexport function makeOpGenerator(passedConfig: OperationGenerationConfig): AsyncGenerator<Operation, FuzzTestState> {\n\tconst config = {\n\t\t...defaultOpConfig,\n\t\t...passedConfig,\n\t};\n\n\tconst { maximumPassiveCollaborators, maximumActiveCollaborators } = { ...defaultJoinConfig, ...config.joinConfig };\n\tconst maximumCollaborators = maximumPassiveCollaborators + maximumActiveCollaborators;\n\n\tconst collaboratorsMatches =\n\t\t(criteria: (collaboratorCount: number) => boolean): AcceptanceCondition<FuzzTestState> =>\n\t\t({ activeCollaborators, passiveCollaborators }) =>\n\t\t\tcriteria(activeCollaborators.length + passiveCollaborators.length);\n\tconst atLeastOneClient = collaboratorsMatches((count) => count > 0);\n\tconst atLeastOneActiveClient: AcceptanceCondition<FuzzTestState> = ({ activeCollaborators }) =>\n\t\tactiveCollaborators.length > 0;\n\tconst opWeights: AsyncWeights<Operation, FuzzTestState> = [\n\t\t[makeEditGenerator(config.editConfig), config.editWeight, atLeastOneActiveClient],\n\t\t[\n\t\t\tmakeJoinGenerator(config.joinConfig),\n\t\t\tconfig.joinWeight,\n\t\t\tcollaboratorsMatches((count) => count < maximumCollaborators),\n\t\t],\n\t\t[leaveGenerator, config.leaveWeight, atLeastOneClient],\n\t\t[{ type: 'synchronize' }, config.synchronizeWeight, atLeastOneClient],\n\t];\n\treturn createWeightedAsyncGenerator(opWeights);\n}\n\nfunction getIdList(tree: TreeView): NodeId[] {\n\tconst allIds: NodeId[] = [];\n\tconst toVisit: NodeId[] = [tree.root];\n\twhile (toVisit.length > 0) {\n\t\tconst id = toVisit.pop() ?? fail();\n\t\tallIds.push(id);\n\t\tconst node = tree.getViewNode(id);\n\t\tfor (const [_, childIds] of node.traits) {\n\t\t\ttoVisit.push(...childIds);\n\t\t}\n\t}\n\treturn allIds;\n}\n"]}
|
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { AsyncGenerator } from '@fluid-internal/stochastic-test-utils';
|
|
6
|
+
import { FuzzTestState, Operation } from './Types';
|
|
6
7
|
/**
|
|
7
8
|
* Performs random actions on a set of clients.
|
|
8
|
-
* @param generator finite generator for a sequence of Operations to test. The test will run until this generator is
|
|
9
|
-
*
|
|
10
|
-
* @param
|
|
11
|
-
* @param
|
|
12
|
-
*
|
|
9
|
+
* @param generator - finite generator for a sequence of Operations to test. The test will run until this generator is
|
|
10
|
+
* exhausted.
|
|
11
|
+
* @param seed - the seed for the random generation of the fuzz actions
|
|
12
|
+
* @param synchronizeAtEnd - if provided, all client will have all operations delivered from the server at the end of
|
|
13
|
+
* the test
|
|
14
|
+
* @param saveInfo - optionally provide an operation number at which a history of all operations will be saved to disk
|
|
15
|
+
* at a given filepath. This can be useful for debugging why a fuzz test may have failed.
|
|
13
16
|
*/
|
|
14
|
-
export declare function performFuzzActions(generator: AsyncGenerator<Operation,
|
|
17
|
+
export declare function performFuzzActions(generator: AsyncGenerator<Operation, FuzzTestState>, seed: number, synchronizeAtEnd?: boolean, saveInfo?: {
|
|
15
18
|
saveAt?: number;
|
|
16
19
|
saveOnFailure: boolean;
|
|
17
20
|
filepath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SharedTreeFuzzTests.d.ts","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"SharedTreeFuzzTests.d.ts","sourceRoot":"","sources":["../../../src/test/fuzz/SharedTreeFuzzTests.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EACN,cAAc,EAKd,MAAM,uCAAuC,CAAC;AAK/C,OAAO,EAAE,aAAa,EAAwB,SAAS,EAAE,MAAM,SAAS,CAAC;AASzE;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACvC,SAAS,EAAE,cAAc,CAAC,SAAS,EAAE,aAAa,CAAC,EACnD,IAAI,EAAE,MAAM,EACZ,gBAAgB,GAAE,OAAc,EAChC,QAAQ,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACtE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CA8GlC;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAkI1D"}
|