@fluidframework/merge-tree 2.20.0 → 2.21.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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # @fluidframework/merge-tree
2
2
 
3
+ ## 2.21.0
4
+
5
+ Dependency updates only.
6
+
3
7
  ## 2.20.0
4
8
 
5
9
  ### Minor Changes
@@ -0,0 +1,12 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { IConfigRange, IMergeTreeOperationRunnerConfig } from "./mergeTreeOperationRunner.js";
6
+ interface IObliterateFarmConfig extends IMergeTreeOperationRunnerConfig {
7
+ minLength: IConfigRange;
8
+ clients: IConfigRange;
9
+ }
10
+ export declare const defaultOptions: IObliterateFarmConfig;
11
+ export {};
12
+ //# sourceMappingURL=client.obliterateFarm.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.obliterateFarm.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.obliterateFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,YAAY,EACZ,+BAA+B,EAK/B,MAAM,+BAA+B,CAAC;AAWvC,UAAU,qBAAsB,SAAQ,+BAA+B;IACtE,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;CACtB;AAUD,eAAO,MAAM,cAAc,EAAE,qBAQ5B,CAAC"}
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.defaultOptions = void 0;
8
+ const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
9
+ const mergeTreeOperationRunner_js_1 = require("./mergeTreeOperationRunner.js");
10
+ const obliterateOperations_js_1 = require("./obliterateOperations.js");
11
+ const testClient_js_1 = require("./testClient.js");
12
+ const allOperations = [
13
+ obliterateOperations_js_1.removeWithField,
14
+ obliterateOperations_js_1.annotateWithField,
15
+ obliterateOperations_js_1.insertAvoidField,
16
+ obliterateOperations_js_1.insertField,
17
+ obliterateOperations_js_1.obliterateField,
18
+ ];
19
+ exports.defaultOptions = {
20
+ minLength: { min: 1, max: 512 },
21
+ clients: { min: 1, max: 8 },
22
+ opsPerRoundRange: { min: 1, max: 128 },
23
+ rounds: 8,
24
+ operations: allOperations,
25
+ growthFunc: (input) => input * 2,
26
+ insertText: obliterateOperations_js_1.generateInsertWithField,
27
+ };
28
+ // Generate a list of single character client names, support up to 69 clients
29
+ const clientNames = (0, mergeTreeOperationRunner_js_1.generateClientNames)();
30
+ function runObliterateFarmTests(opts, extraSeed) {
31
+ (0, mergeTreeOperationRunner_js_1.doOverRange)(opts.minLength, opts.growthFunc, (minLength) => {
32
+ for (const { name, config } of [
33
+ {
34
+ name: "obliterate with exact range replacement",
35
+ config: {
36
+ ...opts,
37
+ // TODO: ensure that obliterate and inserts are not separated before enabling this
38
+ // applyOpDuringGeneration: true,
39
+ },
40
+ },
41
+ ])
42
+ it(`${name}: ObliterateFarm_${minLength}`, async () => {
43
+ const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, minLength, extraSeed ?? 0);
44
+ const clients = [
45
+ new testClient_js_1.TestClient({
46
+ mergeTreeEnableObliterate: true,
47
+ mergeTreeEnableSidedObliterate: true,
48
+ mergeTreeEnableAnnotateAdjust: true,
49
+ }),
50
+ ];
51
+ for (const [i, c] of clients.entries())
52
+ c.startOrUpdateCollaboration(clientNames[i]);
53
+ let seq = 0;
54
+ while (clients.length < config.clients.max) {
55
+ for (const c of clients)
56
+ c.updateMinSeq(seq);
57
+ // Add double the number of clients each iteration
58
+ const targetClients = Math.max(config.clients.min, config.growthFunc(clients.length));
59
+ for (let cc = clients.length; cc < targetClients; cc++) {
60
+ const newClient = await testClient_js_1.TestClient.createFromClientSnapshot(clients[0], clientNames[cc]);
61
+ clients.push(newClient);
62
+ }
63
+ seq = (0, mergeTreeOperationRunner_js_1.runMergeTreeOperationRunner)(random, seq, clients, minLength, config);
64
+ }
65
+ }).timeout(30 * 10000);
66
+ });
67
+ }
68
+ stochastic_test_utils_1.describeFuzz.skip("MergeTree.Client Obliterate", ({ testCount }) => {
69
+ if (testCount > 1) {
70
+ (0, mergeTreeOperationRunner_js_1.doOverRange)({ min: 0, max: testCount - 1 }, (x) => x + 1, (seed) => {
71
+ describe(`with seed ${seed}`, () => {
72
+ runObliterateFarmTests(exports.defaultOptions, seed);
73
+ });
74
+ });
75
+ }
76
+ else {
77
+ runObliterateFarmTests(exports.defaultOptions);
78
+ }
79
+ });
80
+ //# sourceMappingURL=client.obliterateFarm.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.obliterateFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.obliterateFarm.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tTestOperation,\n\tdoOverRange,\n\tgenerateClientNames,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport {\n\tannotateWithField,\n\tgenerateInsertWithField,\n\tinsertAvoidField,\n\tinsertField,\n\tobliterateField,\n\tremoveWithField,\n} from \"./obliterateOperations.js\";\nimport { TestClient } from \"./testClient.js\";\n\ninterface IObliterateFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: IConfigRange;\n\tclients: IConfigRange;\n}\n\nconst allOperations: TestOperation[] = [\n\tremoveWithField,\n\tannotateWithField,\n\tinsertAvoidField,\n\tinsertField,\n\tobliterateField,\n];\n\nexport const defaultOptions: IObliterateFarmConfig = {\n\tminLength: { min: 1, max: 512 },\n\tclients: { min: 1, max: 8 },\n\topsPerRoundRange: { min: 1, max: 128 },\n\trounds: 8,\n\toperations: allOperations,\n\tgrowthFunc: (input: number) => input * 2,\n\tinsertText: generateInsertWithField,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runObliterateFarmTests(opts: IObliterateFarmConfig, extraSeed?: number): void {\n\tdoOverRange(opts.minLength, opts.growthFunc, (minLength) => {\n\t\tfor (const { name, config } of [\n\t\t\t{\n\t\t\t\tname: \"obliterate with exact range replacement\",\n\t\t\t\tconfig: {\n\t\t\t\t\t...opts,\n\t\t\t\t\t// TODO: ensure that obliterate and inserts are not separated before enabling this\n\t\t\t\t\t// applyOpDuringGeneration: true,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t\t\tit(`${name}: ObliterateFarm_${minLength}`, async () => {\n\t\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, minLength, extraSeed ?? 0);\n\n\t\t\t\tconst clients: TestClient[] = [\n\t\t\t\t\tnew TestClient({\n\t\t\t\t\t\tmergeTreeEnableObliterate: true,\n\t\t\t\t\t\tmergeTreeEnableSidedObliterate: true,\n\t\t\t\t\t\tmergeTreeEnableAnnotateAdjust: true,\n\t\t\t\t\t}),\n\t\t\t\t];\n\t\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\t\tlet seq = 0;\n\t\t\t\twhile (clients.length < config.clients.max) {\n\t\t\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\n\t\t\t\t\t// Add double the number of clients each iteration\n\t\t\t\t\tconst targetClients = Math.max(\n\t\t\t\t\t\tconfig.clients.min,\n\t\t\t\t\t\tconfig.growthFunc(clients.length),\n\t\t\t\t\t);\n\t\t\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\t\t\tclients[0],\n\t\t\t\t\t\t\tclientNames[cc],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tclients.push(newClient);\n\t\t\t\t\t}\n\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, minLength, config);\n\t\t\t\t}\n\t\t\t}).timeout(30 * 10000);\n\t});\n}\n\ndescribeFuzz.skip(\"MergeTree.Client Obliterate\", ({ testCount }) => {\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunObliterateFarmTests(defaultOptions, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunObliterateFarmTests(defaultOptions);\n\t}\n});\n"]}
@@ -48,6 +48,11 @@ export interface IMergeTreeOperationRunnerConfig {
48
48
  readonly applyOpDuringGeneration?: boolean;
49
49
  growthFunc(input: number): number;
50
50
  resultsFilePostfix?: string;
51
+ insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;
52
+ updateEndpoints?: (client: TestClient, random: IRandom) => {
53
+ start: number;
54
+ end: number;
55
+ };
51
56
  }
52
57
  export interface ReplayGroup {
53
58
  msgs: ISequencedDocumentMessage[];
@@ -57,7 +62,7 @@ export interface ReplayGroup {
57
62
  }
58
63
  export declare const replayResultsPath: string;
59
64
  export declare function runMergeTreeOperationRunner(random: IRandom, startingSeq: number, clients: readonly TestClient[], minLength: number, config: IMergeTreeOperationRunnerConfig, apply?: ApplyMessagesFn): number;
60
- export declare function generateOperationMessagesForClients(random: IRandom, startingSeq: number, clients: readonly TestClient[], logger: TestClientLogger, opsPerRound: number, minLength: number, operations: readonly TestOperation[], applyOpDuringGeneration?: boolean): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][];
65
+ export declare function generateOperationMessagesForClients(random: IRandom, startingSeq: number, clients: readonly TestClient[], logger: TestClientLogger, opsPerRound: number, minLength: number, operations: readonly TestOperation[], applyOpDuringGeneration?: boolean, insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][];
61
66
  export declare function generateClientNames(): string[];
62
67
  type ApplyMessagesFn = (startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger, random: IRandom) => number;
63
68
  export declare function applyMessages(startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger): number;
@@ -1 +1 @@
1
- {"version":3,"file":"mergeTreeOperationRunner.d.ts","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mergeTreeOperationRunner.d.ts","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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"}
@@ -118,6 +118,11 @@ const insert = (client, _start, _end, random) => {
118
118
  return client.insertTextLocal(start, text);
119
119
  };
120
120
  exports.insert = insert;
121
+ const generateInsert = (client, random) => {
122
+ const len = client.getLength();
123
+ const text = client.longClientId.repeat(random.integer(1, 3));
124
+ return client.insertTextLocal(random.integer(0, len), text);
125
+ };
121
126
  function doOverRange(range, defaultGrowthFunc, doAction) {
122
127
  let lastCurrent = Number.NaN;
123
128
  for (let current = range.min; current <= range.max; current = (range.growthFunc ?? defaultGrowthFunc)(current)) {
@@ -199,7 +204,7 @@ function runMergeTreeOperationRunner(random, startingSeq, clients, minLength, co
199
204
  for (let round = 0; round < config.rounds; round++) {
200
205
  const initialText = clients[0].getText();
201
206
  const logger = new testClientLogger_js_1.TestClientLogger(clients, `Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`);
202
- const messageData = generateOperationMessagesForClients(random, seq, clients, logger, opsPerRound, minLength, config.operations, config.applyOpDuringGeneration);
207
+ const messageData = generateOperationMessagesForClients(random, seq, clients, logger, opsPerRound, minLength, config.operations, config.applyOpDuringGeneration, config.insertText);
203
208
  seq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);
204
209
  const resultText = logger.validate();
205
210
  results.push({
@@ -218,7 +223,7 @@ function runMergeTreeOperationRunner(random, startingSeq, clients, minLength, co
218
223
  return seq;
219
224
  }
220
225
  exports.runMergeTreeOperationRunner = runMergeTreeOperationRunner;
221
- function generateOperationMessagesForClients(random, startingSeq, clients, logger, opsPerRound, minLength, operations, applyOpDuringGeneration) {
226
+ function generateOperationMessagesForClients(random, startingSeq, clients, logger, opsPerRound, minLength, operations, applyOpDuringGeneration, insertText) {
222
227
  const minimumSequenceNumber = startingSeq;
223
228
  let runningSeq = startingSeq;
224
229
  const messages = [];
@@ -236,8 +241,8 @@ function generateOperationMessagesForClients(random, startingSeq, clients, logge
236
241
  const sg = client.peekPendingSegmentGroups();
237
242
  let op;
238
243
  if (len === 0 || len < minLength) {
239
- const text = client.longClientId.repeat(random.integer(1, 3));
240
- op = client.insertTextLocal(random.integer(0, len), text);
244
+ op =
245
+ insertText === undefined ? generateInsert(client, random) : insertText(client, random);
241
246
  }
242
247
  else {
243
248
  let opIndex = random.integer(0, operations.length - 1);
@@ -1 +1 @@
1
- {"version":3,"file":"mergeTreeOperationRunner.js","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,6DAA6D;AAE7D,6CAA+C;AAC/C,4CAA8B;AAK9B,kEAA+D;AAE/D,sCAA4E;AAC5E,wDAA+D;AAC/D,0DAA2C;AAC3C,sDAAgD;AAEhD,+CAAyC;AAEzC,+DAAyD;AASlD,MAAM,WAAW,GAAkB,CACzC,MAAkB,EAClB,OAAe,EACf,KAAa,EACZ,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAJhC,QAAA,WAAW,eAIqB;AAEtC,MAAM,eAAe,GAAkB,CAC7C,MAAkB,EAClB,OAAe,EACf,KAAa,EACZ,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAJpC,QAAA,eAAe,mBAIqB;AAE1C,MAAM,oBAAoB,GAAkB,CAClD,MAAkB,EAClB,OAAe,EACf,KAAa,EACb,MAAe,EACd,EAAE;IACH,IAAI,SAAe,CAAC;IACpB,IAAI,OAAa,CAAC;IAElB,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC;IAC/D,kEAAkE;IAClE,wEAAwE;IACxE,WAAW;IACX,IAAI,MAAM,GAAG,OAAO,IAAI,CAAC,EAAE,CAAC;QAC3B,SAAS,GAAG,uBAAI,CAAC,MAAM,CAAC;QACxB,OAAO,GAAG,uBAAI,CAAC,KAAK,CAAC;IACtB,CAAC;SAAM,CAAC;QACP,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAI,CAAC,MAAM,EAAE,uBAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QACnD,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,uBAAI,CAAC,MAAM,EAAE,uBAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3C,OAAO,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC,CAAC;AAxBW,QAAA,oBAAoB,wBAwB/B;AAEK,MAAM,aAAa,GAAkB,CAC3C,MAAkB,EAClB,OAAe,EACf,KAAa,EACb,MAAe,EACd,EAAE;IACH,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE;YAChD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,YAAY;SAC3C,CAAC,CAAC;IACJ,CAAC;SAAM,CAAC;QACP,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/D,OAAO,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE;YACtD,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE;gBAClC,KAAK,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC5B,GAAG,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG;gBACrD,GAAG;aACH;SACD,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC;AArBW,QAAA,aAAa,iBAqBxB;AAEK,MAAM,cAAc,GAAkB,CAC5C,MAAkB,EAClB,OAAe,EACf,KAAa,EACb,MAAe,EACd,EAAE;IACH,MAAM,IAAI,GAAsB,EAAE,CAAC;IACnC,iEAAiE;IACjE,IAAA,2CAAoB,EAAC,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,EAAE;QACnD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;YACpB,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;gBACpB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACf,OAAO,IAAI,CAAC;YACb,CAAC;YACD,OAAO,KAAK,CAAC;QACd,CAAC;QACD,OAAO,IAAI,CAAC;IACb,CAAC,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,GAAG,MAAM,CAAC,YAAa,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,MAAM,cAAc,GAAG,IAAA,+BAAa,EAAC,GAAG,CAAC,IAAI,IAAA,4BAAU,EAAC,GAAG,CAAC,CAAC;QAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,4BAA4B,CAC/C,GAAG,EACH,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,EAC5D,cAAc;YACb,CAAC,CAAC,sBAAa,CAAC,aAAa;YAC7B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC;gBACZ,sBAAa,CAAC,MAAM;gBACpB,sBAAa,CAAC,aAAa;gBAC3B,sBAAa,CAAC,SAAS;aACvB,CAAC,EACJ,SAAS,CACT,CAAC;QAEF,OAAO,MAAM,CAAC,8BAA8B,CAAC,IAAI,EAAE,4BAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,CAAC;AACF,CAAC,CAAC;AAtCW,QAAA,cAAc,kBAsCzB;AAEK,MAAM,MAAM,GAAkB,CACpC,MAAkB,EAClB,MAAc,EACd,IAAY,EACZ,MAAe,EACd,EAAE;IACH,qGAAqG;IACrG,wBAAwB;IACxB,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,YAAa,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC5C,CAAC,CAAC;AAXW,QAAA,MAAM,UAWjB;AAQF,SAAgB,WAAW,CAC1B,KAAmB,EACnB,iBAA4C,EAC5C,QAAmC;IAEnC,IAAI,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC;IAC7B,KACC,IAAI,OAAO,GAAG,KAAK,CAAC,GAAG,EACvB,OAAO,IAAI,KAAK,CAAC,GAAG,EACpB,OAAO,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,iBAAiB,CAAC,CAAC,OAAO,CAAC,EACzD,CAAC;QACF,6BAA6B;QAC7B,4BAA4B;QAC5B,8BAA8B;QAC9B,oBAAoB;QACpB,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACX,CAAC;QACD,IAAI,OAAO,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YAC1B,WAAW,GAAG,OAAO,CAAC;YACtB,QAAQ,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;IACF,CAAC;AACF,CAAC;AAvBD,kCAuBC;AAED,SAAgB,YAAY,CAC3B,KAAmB,EACnB,iBAA4C;IAE5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,IAAI,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE;QACjE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IACH,OAAO,OAAO,CAAC;AAChB,CAAC;AATD,oCASC;AAED,SAAgB,aAAa,CAC5B,MAAS,EACT,iBAA4C;IAE5C,yEAAyE;IACzE,MAAM,cAAc,GAAsB,EAAuB,CAAC;IAClE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,cAAc,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC;IACD,OAAO,cAAc,CAAC;AACvB,CAAC;AAZD,sCAYC;AAED,8DAA8D;AAC9D,SAAS,aAAa,CAAC,CAAM;IAC5B,sEAAsE;IACtE,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC;AACxF,CAAC;AAoBD,SAAgB,YAAY,CAC3B,MAAS,EACT,QAAqE;IAErE,MAAM,YAAY,GAA6B,EAAE,CAAC;IAClD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,MAAM,kBAAkB,GAAG,CAAC,UAA8B,EAAQ,EAAE;QACnE,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY,CAAC,MAAM,EAAE,CAAC;YAC/C,MAAM,aAAa,GAAG,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;gBACvC,aAAa,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC5B,CAAC;YACD,MAAM,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAClF,QAAQ,CAAC,aAAkC,EAAE,WAAW,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACrD,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE;gBACvE,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC,CAAC;gBAClC,kBAAkB,CAAC,UAAU,CAAC,CAAC;gBAC/B,UAAU,CAAC,GAAG,EAAE,CAAC;YAClB,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC,CAAC;IAEF,kBAAkB,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AA9BD,oCA8BC;AAmBY,QAAA,iBAAiB,GAAG,GAAG,sBAAQ,yBAAyB,CAAC;AAEtE,SAAgB,2BAA2B,CAC1C,MAAe,EACf,WAAmB,EACnB,OAA8B,EAC9B,SAAiB,EACjB,MAAuC,EACvC,QAAyB,aAAa;IAEtC,IAAI,GAAG,GAAG,WAAW,CAAC;IACtB,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,IAAI,QAAQ,GAAG,aAAa,CAAC;IAE7B,WAAW,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,EAAE;QACvE,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CACV,cAAc,SAAS,aAAa,OAAO,CAAC,MAAM,SAAS,WAAW,SAAS,GAAG,EAAE,CACpF,CAAC;QACH,CAAC;QACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YACpD,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACzC,MAAM,MAAM,GAAG,IAAI,sCAAgB,CAClC,OAAO,EACP,YAAY,OAAO,CAAC,MAAM,SAAS,WAAW,WAAW,KAAK,EAAE,CAChE,CAAC;YACF,MAAM,WAAW,GAAG,mCAAmC,CACtD,MAAM,EACN,GAAG,EACH,OAAO,EACP,MAAM,EACN,WAAW,EACX,SAAS,EACT,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,uBAAuB,CAC9B,CAAC;YACF,GAAG,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACxF,MAAM,UAAU,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC;gBACZ,WAAW;gBACX,UAAU;gBACV,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACpE,GAAG;aACH,CAAC,CAAC;YACH,MAAM,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;QAC7C,MAAM,eAAe,GAAG,GAAG,yBAAiB,QAAQ,SAAS,YAAY,OAAO,CAAC,MAAM,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;QACvH,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,GAAG,CAAC;AACZ,CAAC;AArDD,kEAqDC;AAED,SAAgB,mCAAmC,CAClD,MAAe,EACf,WAAmB,EACnB,OAA8B,EAC9B,MAAwB,EACxB,WAAmB,EACnB,SAAiB,EACjB,UAAoC,EACpC,uBAAiC;IAEjC,MAAM,qBAAqB,GAAG,WAAW,CAAC;IAC1C,IAAI,UAAU,GAAG,WAAW,CAAC;IAC7B,MAAM,QAAQ,GAAiE,EAAE,CAAC;IAElF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,iEAAiE;QACjE,sBAAsB;QACtB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QAE9D,IAAI,uBAAuB,KAAK,IAAI,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC9E,MAAM,OAAO,GAAG,QAAQ;iBACtB,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC;iBAC3E,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACjC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5E,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,wBAAwB,EAAE,CAAC;QAC7C,IAAI,EAA4B,CAAC;QACjC,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,GAAG,SAAS,EAAE,CAAC;YAClC,MAAM,IAAI,GAAG,MAAM,CAAC,YAAa,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC/D,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACP,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACvD,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;YAE3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;gBAChE,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBACrD,OAAO,EAAE,CAAC;gBACV,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC;YAC9B,CAAC;QACF,CAAC;QACD,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;YACtB,8DAA8D;YAC9D,IAAI,EAAE,KAAK,MAAM,CAAC,wBAAwB,EAAE,EAAE,CAAC;gBAC9C,oBAAM,CAAC,QAAQ,CACd,EAAE,EACF,MAAM,CAAC,wBAAwB,EAAE,EACjC,6CAA6C,MAAM,EAAE,CACrD,CAAC;YACH,CAAC;YACD,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;YACvD,OAAO,CAAC,qBAAqB,GAAG,qBAAqB,CAAC;YACtD,QAAQ,CAAC,IAAI,CAAC;gBACb,OAAO;gBACP,MAAM,CAAC,wBAAwB,CAC9B,EAAE,CAAC,IAAI,KAAK,2BAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CACvD;aACF,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACxF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,cAAc,KAAK,eAAe,CAAC,CAAC;QACpF,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;YAC5C,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACvE,CAAC;IACF,CAAC;IAED,OAAO,QAAQ,CAAC;AACjB,CAAC;AAzED,kFAyEC;AAED,SAAgB,mBAAmB;IAClC,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,SAAS,cAAc,CAAC,SAAiB,EAAE,KAAa;QACvD,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3C,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACzD,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;QACvD,CAAC;IACF,CAAC;IAED,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxB,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxB,cAAc,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAExB,OAAO,WAAW,CAAC;AACpB,CAAC;AAjBD,kDAiBC;AAUD,SAAgB,aAAa,CAC5B,WAAmB,EACnB,WAAyE,EACzE,OAA8B,EAC9B,MAAwB;IAExB,IAAI,GAAG,GAAG,WAAW,CAAC;IACtB,IAAI,CAAC;QACJ,iDAAiD;QACjD,4DAA4D;QAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YACjC,OAAO,CAAC,cAAc,GAAG,EAAE,GAAG,CAAC;YAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACzB,IAAI,CAAC,CAAC,eAAe,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;oBAC7D,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACrB,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAvBD,sCAuBC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\nimport * as fs from \"node:fs\";\n\nimport { IRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { ISegmentPrivate, SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { toMoveInfo, toRemovalInfo } from \"../segmentInfos.js\";\nimport { Side } from \"../sequencePlace.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { _dirname } from \"./dirname.cjs\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport type TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => IMergeTreeOp | undefined;\n\nexport const removeRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.removeRangeLocal(opStart, opEnd);\n\nexport const obliterateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.obliterateRangeLocal(opStart, opEnd);\n\nexport const obliterateRangeSided: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet startSide: Side;\n\tlet endSide: Side;\n\n\tconst oblEnd = random.integer(opStart, client.getLength() - 1);\n\t// TODO: to create zero length obliterate ops, change '<=' to '<'.\n\t// Doing so may cause different failures than those without zero length.\n\t// AB#19930\n\tif (oblEnd - opStart <= 1) {\n\t\tstartSide = Side.Before;\n\t\tendSide = Side.After;\n\t} else {\n\t\tstartSide = random.pick([Side.Before, Side.After]);\n\t\tendSide = random.pick([Side.Before, Side.After]);\n\t}\n\n\tconst start = { pos: opStart, side: startSide };\n\tconst end = { pos: oblEnd, side: endSide };\n\treturn client.obliterateRangeLocal(start, end);\n};\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tif (random.bool()) {\n\t\treturn client.annotateRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(1, 5)]: client.longClientId,\n\t\t});\n\t} else {\n\t\tconst max = random.pick([undefined, random.integer(-10, 100)]);\n\t\tconst min = random.pick([undefined, random.integer(-100, 10)]);\n\t\treturn client.annotateAdjustRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(0, 2).toString()]: {\n\t\t\t\tdelta: random.integer(-5, 5),\n\t\t\t\tmin: (min ?? max ?? 0) > (max ?? 0) ? undefined : min,\n\t\t\t\tmax,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegmentPrivate[] = [];\n\t// gather all the segments at the pos, including removed segments\n\twalkAllChildSegments(client.mergeTree.root, (seg) => {\n\t\tconst pos = client.getPosition(seg);\n\t\tif (pos >= opStart) {\n\t\t\tif (pos <= opStart) {\n\t\t\t\tsegs.push(seg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\tif (segs.length > 0) {\n\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\tconst seg = random.pick(segs);\n\t\tconst movedOrRemoved = toRemovalInfo(seg) ?? toMoveInfo(seg);\n\t\tconst lref = client.createLocalReferencePosition(\n\t\t\tseg,\n\t\t\tmovedOrRemoved ? 0 : random.integer(0, seg.cachedLength - 1),\n\t\t\tmovedOrRemoved\n\t\t\t\t? ReferenceType.SlideOnRemove\n\t\t\t\t: random.pick([\n\t\t\t\t\t\tReferenceType.Simple,\n\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\tReferenceType.Transient,\n\t\t\t\t\t]),\n\t\t\tundefined,\n\t\t);\n\n\t\treturn client.insertAtReferencePositionLocal(lref, TextSegment.make(text));\n\t}\n};\n\nexport const insert: TestOperation = (\n\tclient: TestClient,\n\t_start: number,\n\t_end: number,\n\trandom: IRandom,\n) => {\n\t// Note: the _start param is generated using exclusive range. This provides more coverage by allowing\n\t// insertion at the end.\n\tconst start = random.integer(0, client.getLength());\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(start, text);\n};\n\nexport interface IConfigRange {\n\tmin: number;\n\tmax: number;\n\tgrowthFunc?: (input: number) => number;\n}\n\nexport function doOverRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n\tdoAction: (current: number) => void,\n): void {\n\tlet lastCurrent = Number.NaN;\n\tfor (\n\t\tlet current = range.min;\n\t\tcurrent <= range.max;\n\t\tcurrent = (range.growthFunc ?? defaultGrowthFunc)(current)\n\t) {\n\t\t// let growth funcs be simple\n\t\t// especially around 0 and 1\n\t\t// if the value didn't change,\n\t\t// just increment it\n\t\tif (current === lastCurrent) {\n\t\t\tcurrent++;\n\t\t}\n\t\tif (current <= range.max) {\n\t\t\tlastCurrent = current;\n\t\t\tdoAction(current);\n\t\t}\n\t}\n}\n\nexport function resolveRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n): number[] {\n\tconst results: number[] = [];\n\tdoOverRange(range, range.growthFunc ?? defaultGrowthFunc, (num) => {\n\t\tresults.push(num);\n\t});\n\treturn results;\n}\n\nexport function resolveRanges<T extends object>(\n\tranges: T,\n\tdefaultGrowthFunc: (input: number) => number,\n): ResolvedRanges<T> {\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst resolvedRanges: ResolvedRanges<T> = {} as ResolvedRanges<T>;\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\tresolvedRanges[key] = resolveRange(value, defaultGrowthFunc);\n\t\t}\n\t}\n\treturn resolvedRanges;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isConfigRange(t: any): t is IConfigRange {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\treturn typeof t === \"object\" && typeof t.min === \"number\" && typeof t.max === \"number\";\n}\n\ntype ReplaceRangeWith<T, TReplace> = T extends { min: number; max: number } ? TReplace : never;\n\ntype RangePropertyNames<T> = {\n\t[K in keyof T]-?: T[K] extends IConfigRange ? K : never;\n}[keyof T];\n\ntype PickFromRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number>;\n};\n\ntype ResolvedRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number[]>;\n};\n\ninterface ProvidesGrowthFunc {\n\tgrowthFunc: (input: number) => number;\n}\n\nexport function doOverRanges<T extends ProvidesGrowthFunc>(\n\tranges: T,\n\tdoAction: (selection: PickFromRanges<T>, description: string) => void,\n): void {\n\tconst rangeEntries: [string, IConfigRange][] = [];\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\trangeEntries.push([key, value]);\n\t\t}\n\t}\n\n\tconst doOverRangesHelper = (selections: [string, number][]): void => {\n\t\tif (selections.length === rangeEntries.length) {\n\t\t\tconst selectionsObj = {};\n\t\t\tfor (const [key, value] of selections) {\n\t\t\t\tselectionsObj[key] = value;\n\t\t\t}\n\t\t\tconst description = selections.map(([key, value]) => `${key}:${value}`).join(\"_\");\n\t\t\tdoAction(selectionsObj as PickFromRanges<T>, description);\n\t\t} else {\n\t\t\tconst [key, value] = rangeEntries[selections.length];\n\t\t\tdoOverRange(value, value.growthFunc ?? ranges.growthFunc, (selection) => {\n\t\t\t\tselections.push([key, selection]);\n\t\t\t\tdoOverRangesHelper(selections);\n\t\t\t\tselections.pop();\n\t\t\t});\n\t\t}\n\t};\n\n\tdoOverRangesHelper([]);\n}\n\nexport interface IMergeTreeOperationRunnerConfig {\n\treadonly rounds: number;\n\treadonly opsPerRoundRange: IConfigRange;\n\treadonly incrementalLog?: boolean;\n\treadonly operations: readonly TestOperation[];\n\treadonly applyOpDuringGeneration?: boolean;\n\tgrowthFunc(input: number): number;\n\tresultsFilePostfix?: string;\n}\n\nexport interface ReplayGroup {\n\tmsgs: ISequencedDocumentMessage[];\n\tinitialText: string;\n\tresultText: string;\n\tseq: number;\n}\n\nexport const replayResultsPath = `${_dirname}/../../src/test/results`;\n\nexport function runMergeTreeOperationRunner(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tminLength: number,\n\tconfig: IMergeTreeOperationRunnerConfig,\n\tapply: ApplyMessagesFn = applyMessages,\n): number {\n\tlet seq = startingSeq;\n\tconst results: ReplayGroup[] = [];\n\n\tlet fakeTime = 1725916319097;\n\n\tdoOverRange(config.opsPerRoundRange, config.growthFunc, (opsPerRound) => {\n\t\tif (config.incrementalLog) {\n\t\t\tconsole.log(\n\t\t\t\t`MinLength: ${minLength} Clients: ${clients.length} Ops: ${opsPerRound} Seq: ${seq}`,\n\t\t\t);\n\t\t}\n\t\tfor (let round = 0; round < config.rounds; round++) {\n\t\t\tconst initialText = clients[0].getText();\n\t\t\tconst logger = new TestClientLogger(\n\t\t\t\tclients,\n\t\t\t\t`Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`,\n\t\t\t);\n\t\t\tconst messageData = generateOperationMessagesForClients(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\tlogger,\n\t\t\t\topsPerRound,\n\t\t\t\tminLength,\n\t\t\t\tconfig.operations,\n\t\t\t\tconfig.applyOpDuringGeneration,\n\t\t\t);\n\t\t\tseq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);\n\t\t\tconst resultText = logger.validate();\n\t\t\tresults.push({\n\t\t\t\tinitialText,\n\t\t\t\tresultText,\n\t\t\t\tmsgs: messageData.map((md) => ({ ...md[0], timestamp: fakeTime++ })),\n\t\t\t\tseq,\n\t\t\t});\n\t\t\tlogger.dispose();\n\t\t}\n\t});\n\n\tif (config.resultsFilePostfix !== undefined) {\n\t\tconst resultsFilePath = `${replayResultsPath}/len_${minLength}-clients_${clients.length}-${config.resultsFilePostfix}`;\n\t\tfs.writeFileSync(resultsFilePath, JSON.stringify(results, undefined, \"\\t\"));\n\t}\n\n\treturn seq;\n}\n\nexport function generateOperationMessagesForClients(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\topsPerRound: number,\n\tminLength: number,\n\toperations: readonly TestOperation[],\n\tapplyOpDuringGeneration?: boolean,\n): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] {\n\tconst minimumSequenceNumber = startingSeq;\n\tlet runningSeq = startingSeq;\n\tconst messages: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\n\tfor (let i = 0; i < opsPerRound; i++) {\n\t\t// pick a client greater than 0, client 0 only applies remote ops\n\t\t// and is our baseline\n\t\tconst client = clients[random.integer(1, clients.length - 1)];\n\n\t\tif (applyOpDuringGeneration === true && messages.length > 0 && random.bool()) {\n\t\t\tconst toApply = messages\n\t\t\t\t.filter(([msg]) => msg.sequenceNumber > client.getCollabWindow().currentSeq)\n\t\t\t\t.slice(0, random.integer(1, 3));\n\t\t\tapplyMessages(toApply[0][0].sequenceNumber - 1, toApply, [client], logger);\n\t\t}\n\n\t\tconst len = client.getLength();\n\t\tconst sg = client.peekPendingSegmentGroups();\n\t\tlet op: IMergeTreeOp | undefined;\n\t\tif (len === 0 || len < minLength) {\n\t\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\t\top = client.insertTextLocal(random.integer(0, len), text);\n\t\t} else {\n\t\t\tlet opIndex = random.integer(0, operations.length - 1);\n\t\t\tconst start = random.integer(0, len - 1);\n\t\t\tconst end = random.integer(start + 1, len);\n\n\t\t\tfor (let y = 0; y < operations.length && op === undefined; y++) {\n\t\t\t\top = operations[opIndex](client, start, end, random);\n\t\t\t\topIndex++;\n\t\t\t\topIndex %= operations.length;\n\t\t\t}\n\t\t}\n\t\tif (op !== undefined) {\n\t\t\t// Pre-check to avoid logger.toString() in the string template\n\t\t\tif (sg === client.peekPendingSegmentGroups()) {\n\t\t\t\tassert.notEqual(\n\t\t\t\t\tsg,\n\t\t\t\t\tclient.peekPendingSegmentGroups(),\n\t\t\t\t\t`op created but segment group not enqueued.${logger}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst message = client.makeOpMessage(op, ++runningSeq);\n\t\t\tmessage.minimumSequenceNumber = minimumSequenceNumber;\n\t\t\tmessages.push([\n\t\t\t\tmessage,\n\t\t\t\tclient.peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t]);\n\t\t}\n\t}\n\n\tconst maxProcessedSeq = Math.max(...clients.map((c) => c.getCollabWindow().currentSeq));\n\tif (messages.length > 0) {\n\t\tconst index = messages.findIndex(([msg]) => msg.sequenceNumber === maxProcessedSeq);\n\t\tif (index !== -1) {\n\t\t\tconst apply = messages.splice(0, index + 1);\n\t\t\tapplyMessages(apply[0][0].sequenceNumber - 1, apply, clients, logger);\n\t\t}\n\t}\n\n\treturn messages;\n}\n\nexport function generateClientNames(): string[] {\n\tconst clientNames: string[] = [];\n\tfunction addClientNames(startChar: string, count: number): void {\n\t\tconst startCode = startChar.codePointAt(0);\n\t\tif (startCode === undefined) {\n\t\t\tthrow new Error(\"startCode must be a single character\");\n\t\t}\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tclientNames.push(String.fromCodePoint(startCode + i));\n\t\t}\n\t}\n\n\taddClientNames(\"A\", 26);\n\taddClientNames(\"a\", 26);\n\taddClientNames(\"0\", 17);\n\n\treturn clientNames;\n}\n\ntype ApplyMessagesFn = (\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n) => number;\n\nexport function applyMessages(\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n): number {\n\tlet seq = startingSeq;\n\ttry {\n\t\t// log and apply all the ops created in the round\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let i = 0; i < messageData.length; i++) {\n\t\t\tconst [message] = messageData[i];\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) {\n\t\t\t\tif (c.getCollabWindow().currentSeq < message.sequenceNumber) {\n\t\t\t\t\tc.applyMsg(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow logger.addLogsToError(error);\n\t}\n\treturn seq;\n}\n"]}
1
+ {"version":3,"file":"mergeTreeOperationRunner.js","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\nimport * as fs from \"node:fs\";\n\nimport { IRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { ISegmentPrivate, SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { toMoveInfo, toRemovalInfo } from \"../segmentInfos.js\";\nimport { Side } from \"../sequencePlace.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { _dirname } from \"./dirname.cjs\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport type TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => IMergeTreeOp | undefined;\n\nexport const removeRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.removeRangeLocal(opStart, opEnd);\n\nexport const obliterateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.obliterateRangeLocal(opStart, opEnd);\n\nexport const obliterateRangeSided: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet startSide: Side;\n\tlet endSide: Side;\n\n\tconst oblEnd = random.integer(opStart, client.getLength() - 1);\n\t// TODO: to create zero length obliterate ops, change '<=' to '<'.\n\t// Doing so may cause different failures than those without zero length.\n\t// AB#19930\n\tif (oblEnd - opStart <= 1) {\n\t\tstartSide = Side.Before;\n\t\tendSide = Side.After;\n\t} else {\n\t\tstartSide = random.pick([Side.Before, Side.After]);\n\t\tendSide = random.pick([Side.Before, Side.After]);\n\t}\n\n\tconst start = { pos: opStart, side: startSide };\n\tconst end = { pos: oblEnd, side: endSide };\n\treturn client.obliterateRangeLocal(start, end);\n};\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tif (random.bool()) {\n\t\treturn client.annotateRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(1, 5)]: client.longClientId,\n\t\t});\n\t} else {\n\t\tconst max = random.pick([undefined, random.integer(-10, 100)]);\n\t\tconst min = random.pick([undefined, random.integer(-100, 10)]);\n\t\treturn client.annotateAdjustRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(0, 2).toString()]: {\n\t\t\t\tdelta: random.integer(-5, 5),\n\t\t\t\tmin: (min ?? max ?? 0) > (max ?? 0) ? undefined : min,\n\t\t\t\tmax,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegmentPrivate[] = [];\n\t// gather all the segments at the pos, including removed segments\n\twalkAllChildSegments(client.mergeTree.root, (seg) => {\n\t\tconst pos = client.getPosition(seg);\n\t\tif (pos >= opStart) {\n\t\t\tif (pos <= opStart) {\n\t\t\t\tsegs.push(seg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\tif (segs.length > 0) {\n\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\tconst seg = random.pick(segs);\n\t\tconst movedOrRemoved = toRemovalInfo(seg) ?? toMoveInfo(seg);\n\t\tconst lref = client.createLocalReferencePosition(\n\t\t\tseg,\n\t\t\tmovedOrRemoved ? 0 : random.integer(0, seg.cachedLength - 1),\n\t\t\tmovedOrRemoved\n\t\t\t\t? ReferenceType.SlideOnRemove\n\t\t\t\t: random.pick([\n\t\t\t\t\t\tReferenceType.Simple,\n\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\tReferenceType.Transient,\n\t\t\t\t\t]),\n\t\t\tundefined,\n\t\t);\n\n\t\treturn client.insertAtReferencePositionLocal(lref, TextSegment.make(text));\n\t}\n};\n\nexport const insert: TestOperation = (\n\tclient: TestClient,\n\t_start: number,\n\t_end: number,\n\trandom: IRandom,\n) => {\n\t// Note: the _start param is generated using exclusive range. This provides more coverage by allowing\n\t// insertion at the end.\n\tconst start = random.integer(0, client.getLength());\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(start, text);\n};\n\nconst generateInsert = (client: TestClient, random: IRandom): IMergeTreeOp | undefined => {\n\tconst len = client.getLength();\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(random.integer(0, len), text);\n};\n\nexport interface IConfigRange {\n\tmin: number;\n\tmax: number;\n\tgrowthFunc?: (input: number) => number;\n}\n\nexport function doOverRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n\tdoAction: (current: number) => void,\n): void {\n\tlet lastCurrent = Number.NaN;\n\tfor (\n\t\tlet current = range.min;\n\t\tcurrent <= range.max;\n\t\tcurrent = (range.growthFunc ?? defaultGrowthFunc)(current)\n\t) {\n\t\t// let growth funcs be simple\n\t\t// especially around 0 and 1\n\t\t// if the value didn't change,\n\t\t// just increment it\n\t\tif (current === lastCurrent) {\n\t\t\tcurrent++;\n\t\t}\n\t\tif (current <= range.max) {\n\t\t\tlastCurrent = current;\n\t\t\tdoAction(current);\n\t\t}\n\t}\n}\n\nexport function resolveRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n): number[] {\n\tconst results: number[] = [];\n\tdoOverRange(range, range.growthFunc ?? defaultGrowthFunc, (num) => {\n\t\tresults.push(num);\n\t});\n\treturn results;\n}\n\nexport function resolveRanges<T extends object>(\n\tranges: T,\n\tdefaultGrowthFunc: (input: number) => number,\n): ResolvedRanges<T> {\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst resolvedRanges: ResolvedRanges<T> = {} as ResolvedRanges<T>;\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\tresolvedRanges[key] = resolveRange(value, defaultGrowthFunc);\n\t\t}\n\t}\n\treturn resolvedRanges;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isConfigRange(t: any): t is IConfigRange {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\treturn typeof t === \"object\" && typeof t.min === \"number\" && typeof t.max === \"number\";\n}\n\ntype ReplaceRangeWith<T, TReplace> = T extends { min: number; max: number } ? TReplace : never;\n\ntype RangePropertyNames<T> = {\n\t[K in keyof T]-?: T[K] extends IConfigRange ? K : never;\n}[keyof T];\n\ntype PickFromRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number>;\n};\n\ntype ResolvedRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number[]>;\n};\n\ninterface ProvidesGrowthFunc {\n\tgrowthFunc: (input: number) => number;\n}\n\nexport function doOverRanges<T extends ProvidesGrowthFunc>(\n\tranges: T,\n\tdoAction: (selection: PickFromRanges<T>, description: string) => void,\n): void {\n\tconst rangeEntries: [string, IConfigRange][] = [];\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\trangeEntries.push([key, value]);\n\t\t}\n\t}\n\n\tconst doOverRangesHelper = (selections: [string, number][]): void => {\n\t\tif (selections.length === rangeEntries.length) {\n\t\t\tconst selectionsObj = {};\n\t\t\tfor (const [key, value] of selections) {\n\t\t\t\tselectionsObj[key] = value;\n\t\t\t}\n\t\t\tconst description = selections.map(([key, value]) => `${key}:${value}`).join(\"_\");\n\t\t\tdoAction(selectionsObj as PickFromRanges<T>, description);\n\t\t} else {\n\t\t\tconst [key, value] = rangeEntries[selections.length];\n\t\t\tdoOverRange(value, value.growthFunc ?? ranges.growthFunc, (selection) => {\n\t\t\t\tselections.push([key, selection]);\n\t\t\t\tdoOverRangesHelper(selections);\n\t\t\t\tselections.pop();\n\t\t\t});\n\t\t}\n\t};\n\n\tdoOverRangesHelper([]);\n}\n\nexport interface IMergeTreeOperationRunnerConfig {\n\treadonly rounds: number;\n\treadonly opsPerRoundRange: IConfigRange;\n\treadonly incrementalLog?: boolean;\n\treadonly operations: readonly TestOperation[];\n\treadonly applyOpDuringGeneration?: boolean;\n\tgrowthFunc(input: number): number;\n\tresultsFilePostfix?: string;\n\tinsertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;\n\tupdateEndpoints?: (client: TestClient, random: IRandom) => { start: number; end: number };\n}\n\nexport interface ReplayGroup {\n\tmsgs: ISequencedDocumentMessage[];\n\tinitialText: string;\n\tresultText: string;\n\tseq: number;\n}\n\nexport const replayResultsPath = `${_dirname}/../../src/test/results`;\n\nexport function runMergeTreeOperationRunner(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tminLength: number,\n\tconfig: IMergeTreeOperationRunnerConfig,\n\tapply: ApplyMessagesFn = applyMessages,\n): number {\n\tlet seq = startingSeq;\n\tconst results: ReplayGroup[] = [];\n\n\tlet fakeTime = 1725916319097;\n\n\tdoOverRange(config.opsPerRoundRange, config.growthFunc, (opsPerRound) => {\n\t\tif (config.incrementalLog) {\n\t\t\tconsole.log(\n\t\t\t\t`MinLength: ${minLength} Clients: ${clients.length} Ops: ${opsPerRound} Seq: ${seq}`,\n\t\t\t);\n\t\t}\n\t\tfor (let round = 0; round < config.rounds; round++) {\n\t\t\tconst initialText = clients[0].getText();\n\t\t\tconst logger = new TestClientLogger(\n\t\t\t\tclients,\n\t\t\t\t`Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`,\n\t\t\t);\n\t\t\tconst messageData = generateOperationMessagesForClients(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\tlogger,\n\t\t\t\topsPerRound,\n\t\t\t\tminLength,\n\t\t\t\tconfig.operations,\n\t\t\t\tconfig.applyOpDuringGeneration,\n\t\t\t\tconfig.insertText,\n\t\t\t);\n\t\t\tseq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);\n\t\t\tconst resultText = logger.validate();\n\t\t\tresults.push({\n\t\t\t\tinitialText,\n\t\t\t\tresultText,\n\t\t\t\tmsgs: messageData.map((md) => ({ ...md[0], timestamp: fakeTime++ })),\n\t\t\t\tseq,\n\t\t\t});\n\t\t\tlogger.dispose();\n\t\t}\n\t});\n\n\tif (config.resultsFilePostfix !== undefined) {\n\t\tconst resultsFilePath = `${replayResultsPath}/len_${minLength}-clients_${clients.length}-${config.resultsFilePostfix}`;\n\t\tfs.writeFileSync(resultsFilePath, JSON.stringify(results, undefined, \"\\t\"));\n\t}\n\n\treturn seq;\n}\n\nexport function generateOperationMessagesForClients(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\topsPerRound: number,\n\tminLength: number,\n\toperations: readonly TestOperation[],\n\tapplyOpDuringGeneration?: boolean,\n\tinsertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined,\n): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] {\n\tconst minimumSequenceNumber = startingSeq;\n\tlet runningSeq = startingSeq;\n\tconst messages: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\n\tfor (let i = 0; i < opsPerRound; i++) {\n\t\t// pick a client greater than 0, client 0 only applies remote ops\n\t\t// and is our baseline\n\t\tconst client = clients[random.integer(1, clients.length - 1)];\n\n\t\tif (applyOpDuringGeneration === true && messages.length > 0 && random.bool()) {\n\t\t\tconst toApply = messages\n\t\t\t\t.filter(([msg]) => msg.sequenceNumber > client.getCollabWindow().currentSeq)\n\t\t\t\t.slice(0, random.integer(1, 3));\n\t\t\tapplyMessages(toApply[0][0].sequenceNumber - 1, toApply, [client], logger);\n\t\t}\n\n\t\tconst len = client.getLength();\n\t\tconst sg = client.peekPendingSegmentGroups();\n\t\tlet op: IMergeTreeOp | undefined;\n\t\tif (len === 0 || len < minLength) {\n\t\t\top =\n\t\t\t\tinsertText === undefined ? generateInsert(client, random) : insertText(client, random);\n\t\t} else {\n\t\t\tlet opIndex = random.integer(0, operations.length - 1);\n\t\t\tconst start = random.integer(0, len - 1);\n\t\t\tconst end = random.integer(start + 1, len);\n\n\t\t\tfor (let y = 0; y < operations.length && op === undefined; y++) {\n\t\t\t\top = operations[opIndex](client, start, end, random);\n\t\t\t\topIndex++;\n\t\t\t\topIndex %= operations.length;\n\t\t\t}\n\t\t}\n\t\tif (op !== undefined) {\n\t\t\t// Pre-check to avoid logger.toString() in the string template\n\t\t\tif (sg === client.peekPendingSegmentGroups()) {\n\t\t\t\tassert.notEqual(\n\t\t\t\t\tsg,\n\t\t\t\t\tclient.peekPendingSegmentGroups(),\n\t\t\t\t\t`op created but segment group not enqueued.${logger}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst message = client.makeOpMessage(op, ++runningSeq);\n\t\t\tmessage.minimumSequenceNumber = minimumSequenceNumber;\n\t\t\tmessages.push([\n\t\t\t\tmessage,\n\t\t\t\tclient.peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t]);\n\t\t}\n\t}\n\n\tconst maxProcessedSeq = Math.max(...clients.map((c) => c.getCollabWindow().currentSeq));\n\tif (messages.length > 0) {\n\t\tconst index = messages.findIndex(([msg]) => msg.sequenceNumber === maxProcessedSeq);\n\t\tif (index !== -1) {\n\t\t\tconst apply = messages.splice(0, index + 1);\n\t\t\tapplyMessages(apply[0][0].sequenceNumber - 1, apply, clients, logger);\n\t\t}\n\t}\n\n\treturn messages;\n}\n\nexport function generateClientNames(): string[] {\n\tconst clientNames: string[] = [];\n\tfunction addClientNames(startChar: string, count: number): void {\n\t\tconst startCode = startChar.codePointAt(0);\n\t\tif (startCode === undefined) {\n\t\t\tthrow new Error(\"startCode must be a single character\");\n\t\t}\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tclientNames.push(String.fromCodePoint(startCode + i));\n\t\t}\n\t}\n\n\taddClientNames(\"A\", 26);\n\taddClientNames(\"a\", 26);\n\taddClientNames(\"0\", 17);\n\n\treturn clientNames;\n}\n\ntype ApplyMessagesFn = (\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n) => number;\n\nexport function applyMessages(\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n): number {\n\tlet seq = startingSeq;\n\ttry {\n\t\t// log and apply all the ops created in the round\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let i = 0; i < messageData.length; i++) {\n\t\t\tconst [message] = messageData[i];\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) {\n\t\t\t\tif (c.getCollabWindow().currentSeq < message.sequenceNumber) {\n\t\t\t\t\tc.applyMsg(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow logger.addLogsToError(error);\n\t}\n\treturn seq;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { IRandom } from "@fluid-private/stochastic-test-utils";
6
+ import type { IMergeTreeOp } from "../ops.js";
7
+ import { type TestOperation } from "./mergeTreeOperationRunner.js";
8
+ import type { TestClient } from "./testClient.js";
9
+ export declare const insertField: TestOperation;
10
+ export declare const obliterateField: TestOperation;
11
+ export declare const insertAvoidField: TestOperation;
12
+ export declare const removeWithField: TestOperation;
13
+ export declare const annotateWithField: TestOperation;
14
+ export declare const generateInsertWithField: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;
15
+ //# sourceMappingURL=obliterateOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obliterateOperations.d.ts","sourceRoot":"","sources":["../../src/test/obliterateOperations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAGpE,OAAO,KAAK,EAAuB,YAAY,EAAE,MAAM,WAAW,CAAC;AAGnE,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAmElD,eAAO,MAAM,WAAW,EAAE,aAUzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aA8B7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,aAY9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aAc7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,aAc/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,WAC3B,UAAU,UACV,OAAO,KACb,YAAY,GAAG,SAQjB,CAAC"}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ /*!
3
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.generateInsertWithField = exports.annotateWithField = exports.removeWithField = exports.insertAvoidField = exports.obliterateField = exports.insertField = void 0;
8
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
9
+ const node_assert_1 = require("node:assert");
10
+ const opBuilder_js_1 = require("../opBuilder.js");
11
+ const sequencePlace_js_1 = require("../sequencePlace.js");
12
+ const mergeTreeOperationRunner_js_1 = require("./mergeTreeOperationRunner.js");
13
+ const posInField = (client, pos) => {
14
+ if (pos >= client.getLength() ||
15
+ (!Number.isInteger(Number(client.getText(pos, pos + 1))) &&
16
+ client.getText(pos, pos + 1) !== "{" &&
17
+ client.getText(pos, pos + 1) !== "}")) {
18
+ return undefined;
19
+ }
20
+ let startPos = pos;
21
+ let endPos = pos;
22
+ // To find the start and end separators, walk backwards and forwards until the desired character is found.
23
+ while (startPos > 0 &&
24
+ client.getText(startPos, startPos + 1) !== "{" &&
25
+ (client.getText(startPos, startPos + 1) === "}" ||
26
+ Number.isInteger(Number(client.getText(startPos, startPos + 1))))) {
27
+ startPos--;
28
+ }
29
+ while (endPos < client.getLength() &&
30
+ client.getText(endPos, endPos + 1) !== "}" &&
31
+ (client.getText(endPos, endPos + 1) === "{" ||
32
+ Number.isInteger(Number(client.getText(endPos, endPos + 1))))) {
33
+ endPos++;
34
+ }
35
+ return { startPos, endPos };
36
+ };
37
+ const getFieldEndpoints = (client, start, end) => {
38
+ const startField = posInField(client, start);
39
+ const endField = posInField(client, end);
40
+ if (startField === undefined && endField === undefined) {
41
+ return undefined;
42
+ }
43
+ return startField ?? endField;
44
+ };
45
+ const generateFieldText = (client, random) => {
46
+ const chunkLength = random.integer(1, 10);
47
+ return (client.longClientId.codePointAt(0) % 10).toString().repeat(chunkLength);
48
+ };
49
+ const insertFieldText = (client, opStart, random) => {
50
+ const text = generateFieldText(client, random);
51
+ return client.insertTextLocal(opStart, text);
52
+ };
53
+ const insertField = (client, opStart, opEnd, random) => {
54
+ const numberText = generateFieldText(client, random);
55
+ if (posInField(client, opStart) === undefined) {
56
+ return client.insertTextLocal(opStart, `{${numberText}}`);
57
+ }
58
+ };
59
+ exports.insertField = insertField;
60
+ const obliterateField = (client, opStart, opEnd, random) => {
61
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
62
+ let endISP;
63
+ if (fieldEndpoints !== undefined) {
64
+ const { startPos, endPos } = fieldEndpoints;
65
+ // Obliterate text bewteen the separators, but avoid the case where the obliterate range is zero length.
66
+ if (endPos - startPos > 1) {
67
+ const obliterateOp = client.obliterateRangeLocal({ pos: startPos, side: sequencePlace_js_1.Side.After }, { pos: endPos, side: sequencePlace_js_1.Side.Before });
68
+ const insertOp = insertFieldText(client, startPos + 1, random);
69
+ (0, node_assert_1.strict)(insertOp !== undefined, "Insert op should not be undefined");
70
+ const op = (0, opBuilder_js_1.createGroupOp)(obliterateOp, insertOp);
71
+ return op;
72
+ }
73
+ }
74
+ if (opEnd >= client.getLength()) {
75
+ endISP = { pos: client.getLength() - 1, side: sequencePlace_js_1.Side.After };
76
+ }
77
+ return client.obliterateRangeLocal({ pos: opStart, side: sequencePlace_js_1.Side.Before }, endISP ?? { pos: opEnd, side: sequencePlace_js_1.Side.After });
78
+ };
79
+ exports.obliterateField = obliterateField;
80
+ const insertAvoidField = (client, opStart, opEnd, random) => {
81
+ let start = opStart;
82
+ const endpoints = posInField(client, opStart);
83
+ if (endpoints !== undefined) {
84
+ start = endpoints.startPos;
85
+ }
86
+ return client.insertTextLocal(start, client.longClientId.repeat(random.integer(1, 3)));
87
+ };
88
+ exports.insertAvoidField = insertAvoidField;
89
+ const removeWithField = (client, opStart, opEnd, random) => {
90
+ let start = opStart;
91
+ let end = opEnd;
92
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
93
+ if (fieldEndpoints !== undefined) {
94
+ start = fieldEndpoints.startPos;
95
+ end = fieldEndpoints.endPos + 1;
96
+ }
97
+ return (0, mergeTreeOperationRunner_js_1.removeRange)(client, start, end, random);
98
+ };
99
+ exports.removeWithField = removeWithField;
100
+ const annotateWithField = (client, opStart, opEnd, random) => {
101
+ let start = opStart;
102
+ let end = opEnd;
103
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
104
+ if (fieldEndpoints !== undefined) {
105
+ start = fieldEndpoints.startPos;
106
+ end = fieldEndpoints.endPos + 1;
107
+ }
108
+ return (0, mergeTreeOperationRunner_js_1.annotateRange)(client, start, end, random);
109
+ };
110
+ exports.annotateWithField = annotateWithField;
111
+ const generateInsertWithField = (client, random) => {
112
+ const text = client.longClientId.repeat(random.integer(1, 3));
113
+ let pos = random.integer(0, client.getLength());
114
+ const endpoints = posInField(client, pos);
115
+ if (endpoints !== undefined) {
116
+ pos = 0;
117
+ }
118
+ return client.insertTextLocal(pos, text);
119
+ };
120
+ exports.generateInsertWithField = generateInsertWithField;
121
+ //# sourceMappingURL=obliterateOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obliterateOperations.js","sourceRoot":"","sources":["../../src/test/obliterateOperations.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport type { IRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport { createGroupOp } from \"../opBuilder.js\";\nimport type { IMergeTreeInsertMsg, IMergeTreeOp } from \"../ops.js\";\nimport { InteriorSequencePlace, Side } from \"../sequencePlace.js\";\n\nimport { annotateRange, removeRange, type TestOperation } from \"./mergeTreeOperationRunner.js\";\nimport type { TestClient } from \"./testClient.js\";\n\nconst posInField = (\n\tclient: TestClient,\n\tpos: number,\n): { startPos: number; endPos: number } | undefined => {\n\tif (\n\t\tpos >= client.getLength() ||\n\t\t(!Number.isInteger(Number(client.getText(pos, pos + 1))) &&\n\t\t\tclient.getText(pos, pos + 1) !== \"{\" &&\n\t\t\tclient.getText(pos, pos + 1) !== \"}\")\n\t) {\n\t\treturn undefined;\n\t}\n\n\tlet startPos = pos;\n\tlet endPos = pos;\n\t// To find the start and end separators, walk backwards and forwards until the desired character is found.\n\twhile (\n\t\tstartPos > 0 &&\n\t\tclient.getText(startPos, startPos + 1) !== \"{\" &&\n\t\t(client.getText(startPos, startPos + 1) === \"}\" ||\n\t\t\tNumber.isInteger(Number(client.getText(startPos, startPos + 1))))\n\t) {\n\t\tstartPos--;\n\t}\n\n\twhile (\n\t\tendPos < client.getLength() &&\n\t\tclient.getText(endPos, endPos + 1) !== \"}\" &&\n\t\t(client.getText(endPos, endPos + 1) === \"{\" ||\n\t\t\tNumber.isInteger(Number(client.getText(endPos, endPos + 1))))\n\t) {\n\t\tendPos++;\n\t}\n\n\treturn { startPos, endPos };\n};\n\nconst getFieldEndpoints = (\n\tclient: TestClient,\n\tstart: number,\n\tend: number,\n): { startPos: number; endPos: number } | undefined => {\n\tconst startField = posInField(client, start);\n\tconst endField = posInField(client, end);\n\n\tif (startField === undefined && endField === undefined) {\n\t\treturn undefined;\n\t}\n\treturn startField ?? endField;\n};\n\nconst generateFieldText = (client: TestClient, random: IRandom): string => {\n\tconst chunkLength = random.integer(1, 10);\n\treturn (client.longClientId!.codePointAt(0)! % 10).toString().repeat(chunkLength);\n};\n\nconst insertFieldText = (\n\tclient: TestClient,\n\topStart: number,\n\trandom: IRandom,\n): IMergeTreeInsertMsg | undefined => {\n\tconst text = generateFieldText(client, random);\n\treturn client.insertTextLocal(opStart, text);\n};\n\nexport const insertField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst numberText = generateFieldText(client, random);\n\tif (posInField(client, opStart) === undefined) {\n\t\treturn client.insertTextLocal(opStart, `{${numberText}}`);\n\t}\n};\n\nexport const obliterateField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\n\tlet endISP: InteriorSequencePlace | undefined;\n\tif (fieldEndpoints !== undefined) {\n\t\tconst { startPos, endPos } = fieldEndpoints;\n\t\t// Obliterate text bewteen the separators, but avoid the case where the obliterate range is zero length.\n\t\tif (endPos - startPos > 1) {\n\t\t\tconst obliterateOp = client.obliterateRangeLocal(\n\t\t\t\t{ pos: startPos, side: Side.After },\n\t\t\t\t{ pos: endPos, side: Side.Before },\n\t\t\t);\n\t\t\tconst insertOp = insertFieldText(client, startPos + 1, random);\n\t\t\tassert(insertOp !== undefined, \"Insert op should not be undefined\");\n\t\t\tconst op = createGroupOp(obliterateOp, insertOp);\n\t\t\treturn op;\n\t\t}\n\t}\n\tif (opEnd >= client.getLength()) {\n\t\tendISP = { pos: client.getLength() - 1, side: Side.After };\n\t}\n\treturn client.obliterateRangeLocal(\n\t\t{ pos: opStart, side: Side.Before },\n\t\tendISP ?? { pos: opEnd, side: Side.After },\n\t);\n};\n\nexport const insertAvoidField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tconst endpoints = posInField(client, opStart);\n\tif (endpoints !== undefined) {\n\t\tstart = endpoints.startPos;\n\t}\n\treturn client.insertTextLocal(start, client.longClientId!.repeat(random.integer(1, 3)));\n};\n\nexport const removeWithField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tlet end = opEnd;\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\tif (fieldEndpoints !== undefined) {\n\t\tstart = fieldEndpoints.startPos;\n\t\tend = fieldEndpoints.endPos + 1;\n\t}\n\treturn removeRange(client, start, end, random);\n};\n\nexport const annotateWithField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tlet end = opEnd;\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\tif (fieldEndpoints !== undefined) {\n\t\tstart = fieldEndpoints.startPos;\n\t\tend = fieldEndpoints.endPos + 1;\n\t}\n\treturn annotateRange(client, start, end, random);\n};\n\nexport const generateInsertWithField = (\n\tclient: TestClient,\n\trandom: IRandom,\n): IMergeTreeOp | undefined => {\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\tlet pos = random.integer(0, client.getLength());\n\tconst endpoints = posInField(client, pos);\n\tif (endpoints !== undefined) {\n\t\tpos = 0;\n\t}\n\treturn client.insertTextLocal(pos, text);\n};\n"]}
@@ -0,0 +1,12 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { IConfigRange, IMergeTreeOperationRunnerConfig } from "./mergeTreeOperationRunner.js";
6
+ interface IObliterateFarmConfig extends IMergeTreeOperationRunnerConfig {
7
+ minLength: IConfigRange;
8
+ clients: IConfigRange;
9
+ }
10
+ export declare const defaultOptions: IObliterateFarmConfig;
11
+ export {};
12
+ //# sourceMappingURL=client.obliterateFarm.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.obliterateFarm.spec.d.ts","sourceRoot":"","sources":["../../src/test/client.obliterateFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EACN,YAAY,EACZ,+BAA+B,EAK/B,MAAM,+BAA+B,CAAC;AAWvC,UAAU,qBAAsB,SAAQ,+BAA+B;IACtE,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;CACtB;AAUD,eAAO,MAAM,cAAc,EAAE,qBAQ5B,CAAC"}
@@ -0,0 +1,77 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { describeFuzz, makeRandom } from "@fluid-private/stochastic-test-utils";
6
+ import { doOverRange, generateClientNames, runMergeTreeOperationRunner, } from "./mergeTreeOperationRunner.js";
7
+ import { annotateWithField, generateInsertWithField, insertAvoidField, insertField, obliterateField, removeWithField, } from "./obliterateOperations.js";
8
+ import { TestClient } from "./testClient.js";
9
+ const allOperations = [
10
+ removeWithField,
11
+ annotateWithField,
12
+ insertAvoidField,
13
+ insertField,
14
+ obliterateField,
15
+ ];
16
+ export const defaultOptions = {
17
+ minLength: { min: 1, max: 512 },
18
+ clients: { min: 1, max: 8 },
19
+ opsPerRoundRange: { min: 1, max: 128 },
20
+ rounds: 8,
21
+ operations: allOperations,
22
+ growthFunc: (input) => input * 2,
23
+ insertText: generateInsertWithField,
24
+ };
25
+ // Generate a list of single character client names, support up to 69 clients
26
+ const clientNames = generateClientNames();
27
+ function runObliterateFarmTests(opts, extraSeed) {
28
+ doOverRange(opts.minLength, opts.growthFunc, (minLength) => {
29
+ for (const { name, config } of [
30
+ {
31
+ name: "obliterate with exact range replacement",
32
+ config: {
33
+ ...opts,
34
+ // TODO: ensure that obliterate and inserts are not separated before enabling this
35
+ // applyOpDuringGeneration: true,
36
+ },
37
+ },
38
+ ])
39
+ it(`${name}: ObliterateFarm_${minLength}`, async () => {
40
+ const random = makeRandom(0xdeadbeef, 0xfeedbed, minLength, extraSeed ?? 0);
41
+ const clients = [
42
+ new TestClient({
43
+ mergeTreeEnableObliterate: true,
44
+ mergeTreeEnableSidedObliterate: true,
45
+ mergeTreeEnableAnnotateAdjust: true,
46
+ }),
47
+ ];
48
+ for (const [i, c] of clients.entries())
49
+ c.startOrUpdateCollaboration(clientNames[i]);
50
+ let seq = 0;
51
+ while (clients.length < config.clients.max) {
52
+ for (const c of clients)
53
+ c.updateMinSeq(seq);
54
+ // Add double the number of clients each iteration
55
+ const targetClients = Math.max(config.clients.min, config.growthFunc(clients.length));
56
+ for (let cc = clients.length; cc < targetClients; cc++) {
57
+ const newClient = await TestClient.createFromClientSnapshot(clients[0], clientNames[cc]);
58
+ clients.push(newClient);
59
+ }
60
+ seq = runMergeTreeOperationRunner(random, seq, clients, minLength, config);
61
+ }
62
+ }).timeout(30 * 10000);
63
+ });
64
+ }
65
+ describeFuzz.skip("MergeTree.Client Obliterate", ({ testCount }) => {
66
+ if (testCount > 1) {
67
+ doOverRange({ min: 0, max: testCount - 1 }, (x) => x + 1, (seed) => {
68
+ describe(`with seed ${seed}`, () => {
69
+ runObliterateFarmTests(defaultOptions, seed);
70
+ });
71
+ });
72
+ }
73
+ else {
74
+ runObliterateFarmTests(defaultOptions);
75
+ }
76
+ });
77
+ //# sourceMappingURL=client.obliterateFarm.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.obliterateFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.obliterateFarm.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAEhF,OAAO,EAIN,WAAW,EACX,mBAAmB,EACnB,2BAA2B,GAC3B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACN,iBAAiB,EACjB,uBAAuB,EACvB,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,eAAe,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAO7C,MAAM,aAAa,GAAoB;IACtC,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,WAAW;IACX,eAAe;CACf,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAA0B;IACpD,SAAS,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE;IAC/B,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC3B,gBAAgB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE;IACtC,MAAM,EAAE,CAAC;IACT,UAAU,EAAE,aAAa;IACzB,UAAU,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC;IACxC,UAAU,EAAE,uBAAuB;CACnC,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;AAE1C,SAAS,sBAAsB,CAAC,IAA2B,EAAE,SAAkB;IAC9E,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,EAAE;QAC1D,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI;YAC9B;gBACC,IAAI,EAAE,yCAAyC;gBAC/C,MAAM,EAAE;oBACP,GAAG,IAAI;oBACP,kFAAkF;oBAClF,iCAAiC;iBACjC;aACD;SACD;YACA,EAAE,CAAC,GAAG,IAAI,oBAAoB,SAAS,EAAE,EAAE,KAAK,IAAI,EAAE;gBACrD,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC;gBAE5E,MAAM,OAAO,GAAiB;oBAC7B,IAAI,UAAU,CAAC;wBACd,yBAAyB,EAAE,IAAI;wBAC/B,8BAA8B,EAAE,IAAI;wBACpC,6BAA6B,EAAE,IAAI;qBACnC,CAAC;iBACF,CAAC;gBACF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE;oBAAE,CAAC,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBAErF,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,OAAO,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;oBAC5C,KAAK,MAAM,CAAC,IAAI,OAAO;wBAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;oBAE7C,kDAAkD;oBAClD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAC7B,MAAM,CAAC,OAAO,CAAC,GAAG,EAClB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CACjC,CAAC;oBACF,KAAK,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,EAAE,EAAE,CAAC;wBACxD,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,wBAAwB,CAC1D,OAAO,CAAC,CAAC,CAAC,EACV,WAAW,CAAC,EAAE,CAAC,CACf,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBACzB,CAAC;oBAED,GAAG,GAAG,2BAA2B,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC5E,CAAC;YACF,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,YAAY,CAAC,IAAI,CAAC,6BAA6B,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;IAClE,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;QACnB,WAAW,CACV,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,GAAG,CAAC,EAAE,EAC9B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EACZ,CAAC,IAAI,EAAE,EAAE;YACR,QAAQ,CAAC,aAAa,IAAI,EAAE,EAAE,GAAG,EAAE;gBAClC,sBAAsB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;QACJ,CAAC,CACD,CAAC;IACH,CAAC;SAAM,CAAC;QACP,sBAAsB,CAAC,cAAc,CAAC,CAAC;IACxC,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tTestOperation,\n\tdoOverRange,\n\tgenerateClientNames,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport {\n\tannotateWithField,\n\tgenerateInsertWithField,\n\tinsertAvoidField,\n\tinsertField,\n\tobliterateField,\n\tremoveWithField,\n} from \"./obliterateOperations.js\";\nimport { TestClient } from \"./testClient.js\";\n\ninterface IObliterateFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: IConfigRange;\n\tclients: IConfigRange;\n}\n\nconst allOperations: TestOperation[] = [\n\tremoveWithField,\n\tannotateWithField,\n\tinsertAvoidField,\n\tinsertField,\n\tobliterateField,\n];\n\nexport const defaultOptions: IObliterateFarmConfig = {\n\tminLength: { min: 1, max: 512 },\n\tclients: { min: 1, max: 8 },\n\topsPerRoundRange: { min: 1, max: 128 },\n\trounds: 8,\n\toperations: allOperations,\n\tgrowthFunc: (input: number) => input * 2,\n\tinsertText: generateInsertWithField,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runObliterateFarmTests(opts: IObliterateFarmConfig, extraSeed?: number): void {\n\tdoOverRange(opts.minLength, opts.growthFunc, (minLength) => {\n\t\tfor (const { name, config } of [\n\t\t\t{\n\t\t\t\tname: \"obliterate with exact range replacement\",\n\t\t\t\tconfig: {\n\t\t\t\t\t...opts,\n\t\t\t\t\t// TODO: ensure that obliterate and inserts are not separated before enabling this\n\t\t\t\t\t// applyOpDuringGeneration: true,\n\t\t\t\t},\n\t\t\t},\n\t\t])\n\t\t\tit(`${name}: ObliterateFarm_${minLength}`, async () => {\n\t\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, minLength, extraSeed ?? 0);\n\n\t\t\t\tconst clients: TestClient[] = [\n\t\t\t\t\tnew TestClient({\n\t\t\t\t\t\tmergeTreeEnableObliterate: true,\n\t\t\t\t\t\tmergeTreeEnableSidedObliterate: true,\n\t\t\t\t\t\tmergeTreeEnableAnnotateAdjust: true,\n\t\t\t\t\t}),\n\t\t\t\t];\n\t\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\t\tlet seq = 0;\n\t\t\t\twhile (clients.length < config.clients.max) {\n\t\t\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\n\t\t\t\t\t// Add double the number of clients each iteration\n\t\t\t\t\tconst targetClients = Math.max(\n\t\t\t\t\t\tconfig.clients.min,\n\t\t\t\t\t\tconfig.growthFunc(clients.length),\n\t\t\t\t\t);\n\t\t\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\t\t\tclients[0],\n\t\t\t\t\t\t\tclientNames[cc],\n\t\t\t\t\t\t);\n\t\t\t\t\t\tclients.push(newClient);\n\t\t\t\t\t}\n\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, minLength, config);\n\t\t\t\t}\n\t\t\t}).timeout(30 * 10000);\n\t});\n}\n\ndescribeFuzz.skip(\"MergeTree.Client Obliterate\", ({ testCount }) => {\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunObliterateFarmTests(defaultOptions, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunObliterateFarmTests(defaultOptions);\n\t}\n});\n"]}
@@ -48,6 +48,11 @@ export interface IMergeTreeOperationRunnerConfig {
48
48
  readonly applyOpDuringGeneration?: boolean;
49
49
  growthFunc(input: number): number;
50
50
  resultsFilePostfix?: string;
51
+ insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;
52
+ updateEndpoints?: (client: TestClient, random: IRandom) => {
53
+ start: number;
54
+ end: number;
55
+ };
51
56
  }
52
57
  export interface ReplayGroup {
53
58
  msgs: ISequencedDocumentMessage[];
@@ -57,7 +62,7 @@ export interface ReplayGroup {
57
62
  }
58
63
  export declare const replayResultsPath: string;
59
64
  export declare function runMergeTreeOperationRunner(random: IRandom, startingSeq: number, clients: readonly TestClient[], minLength: number, config: IMergeTreeOperationRunnerConfig, apply?: ApplyMessagesFn): number;
60
- export declare function generateOperationMessagesForClients(random: IRandom, startingSeq: number, clients: readonly TestClient[], logger: TestClientLogger, opsPerRound: number, minLength: number, operations: readonly TestOperation[], applyOpDuringGeneration?: boolean): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][];
65
+ export declare function generateOperationMessagesForClients(random: IRandom, startingSeq: number, clients: readonly TestClient[], logger: TestClientLogger, opsPerRound: number, minLength: number, operations: readonly TestOperation[], applyOpDuringGeneration?: boolean, insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][];
61
66
  export declare function generateClientNames(): string[];
62
67
  type ApplyMessagesFn = (startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger, random: IRandom) => number;
63
68
  export declare function applyMessages(startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger): number;
@@ -1 +1 @@
1
- {"version":3,"file":"mergeTreeOperationRunner.d.ts","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mergeTreeOperationRunner.d.ts","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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"}
@@ -86,6 +86,11 @@ export const insert = (client, _start, _end, random) => {
86
86
  const text = client.longClientId.repeat(random.integer(1, 3));
87
87
  return client.insertTextLocal(start, text);
88
88
  };
89
+ const generateInsert = (client, random) => {
90
+ const len = client.getLength();
91
+ const text = client.longClientId.repeat(random.integer(1, 3));
92
+ return client.insertTextLocal(random.integer(0, len), text);
93
+ };
89
94
  export function doOverRange(range, defaultGrowthFunc, doAction) {
90
95
  let lastCurrent = Number.NaN;
91
96
  for (let current = range.min; current <= range.max; current = (range.growthFunc ?? defaultGrowthFunc)(current)) {
@@ -163,7 +168,7 @@ export function runMergeTreeOperationRunner(random, startingSeq, clients, minLen
163
168
  for (let round = 0; round < config.rounds; round++) {
164
169
  const initialText = clients[0].getText();
165
170
  const logger = new TestClientLogger(clients, `Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`);
166
- const messageData = generateOperationMessagesForClients(random, seq, clients, logger, opsPerRound, minLength, config.operations, config.applyOpDuringGeneration);
171
+ const messageData = generateOperationMessagesForClients(random, seq, clients, logger, opsPerRound, minLength, config.operations, config.applyOpDuringGeneration, config.insertText);
167
172
  seq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);
168
173
  const resultText = logger.validate();
169
174
  results.push({
@@ -181,7 +186,7 @@ export function runMergeTreeOperationRunner(random, startingSeq, clients, minLen
181
186
  }
182
187
  return seq;
183
188
  }
184
- export function generateOperationMessagesForClients(random, startingSeq, clients, logger, opsPerRound, minLength, operations, applyOpDuringGeneration) {
189
+ export function generateOperationMessagesForClients(random, startingSeq, clients, logger, opsPerRound, minLength, operations, applyOpDuringGeneration, insertText) {
185
190
  const minimumSequenceNumber = startingSeq;
186
191
  let runningSeq = startingSeq;
187
192
  const messages = [];
@@ -199,8 +204,8 @@ export function generateOperationMessagesForClients(random, startingSeq, clients
199
204
  const sg = client.peekPendingSegmentGroups();
200
205
  let op;
201
206
  if (len === 0 || len < minLength) {
202
- const text = client.longClientId.repeat(random.integer(1, 3));
203
- op = client.insertTextLocal(random.integer(0, len), text);
207
+ op =
208
+ insertText === undefined ? generateInsert(client, random) : insertText(client, random);
204
209
  }
205
210
  else {
206
211
  let opIndex = random.integer(0, operations.length - 1);
@@ -1 +1 @@
1
- {"version":3,"file":"mergeTreeOperationRunner.js","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\nimport * as fs from \"node:fs\";\n\nimport { IRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { ISegmentPrivate, SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { toMoveInfo, toRemovalInfo } from \"../segmentInfos.js\";\nimport { Side } from \"../sequencePlace.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { _dirname } from \"./dirname.cjs\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport type TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => IMergeTreeOp | undefined;\n\nexport const removeRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.removeRangeLocal(opStart, opEnd);\n\nexport const obliterateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.obliterateRangeLocal(opStart, opEnd);\n\nexport const obliterateRangeSided: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet startSide: Side;\n\tlet endSide: Side;\n\n\tconst oblEnd = random.integer(opStart, client.getLength() - 1);\n\t// TODO: to create zero length obliterate ops, change '<=' to '<'.\n\t// Doing so may cause different failures than those without zero length.\n\t// AB#19930\n\tif (oblEnd - opStart <= 1) {\n\t\tstartSide = Side.Before;\n\t\tendSide = Side.After;\n\t} else {\n\t\tstartSide = random.pick([Side.Before, Side.After]);\n\t\tendSide = random.pick([Side.Before, Side.After]);\n\t}\n\n\tconst start = { pos: opStart, side: startSide };\n\tconst end = { pos: oblEnd, side: endSide };\n\treturn client.obliterateRangeLocal(start, end);\n};\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tif (random.bool()) {\n\t\treturn client.annotateRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(1, 5)]: client.longClientId,\n\t\t});\n\t} else {\n\t\tconst max = random.pick([undefined, random.integer(-10, 100)]);\n\t\tconst min = random.pick([undefined, random.integer(-100, 10)]);\n\t\treturn client.annotateAdjustRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(0, 2).toString()]: {\n\t\t\t\tdelta: random.integer(-5, 5),\n\t\t\t\tmin: (min ?? max ?? 0) > (max ?? 0) ? undefined : min,\n\t\t\t\tmax,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegmentPrivate[] = [];\n\t// gather all the segments at the pos, including removed segments\n\twalkAllChildSegments(client.mergeTree.root, (seg) => {\n\t\tconst pos = client.getPosition(seg);\n\t\tif (pos >= opStart) {\n\t\t\tif (pos <= opStart) {\n\t\t\t\tsegs.push(seg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\tif (segs.length > 0) {\n\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\tconst seg = random.pick(segs);\n\t\tconst movedOrRemoved = toRemovalInfo(seg) ?? toMoveInfo(seg);\n\t\tconst lref = client.createLocalReferencePosition(\n\t\t\tseg,\n\t\t\tmovedOrRemoved ? 0 : random.integer(0, seg.cachedLength - 1),\n\t\t\tmovedOrRemoved\n\t\t\t\t? ReferenceType.SlideOnRemove\n\t\t\t\t: random.pick([\n\t\t\t\t\t\tReferenceType.Simple,\n\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\tReferenceType.Transient,\n\t\t\t\t\t]),\n\t\t\tundefined,\n\t\t);\n\n\t\treturn client.insertAtReferencePositionLocal(lref, TextSegment.make(text));\n\t}\n};\n\nexport const insert: TestOperation = (\n\tclient: TestClient,\n\t_start: number,\n\t_end: number,\n\trandom: IRandom,\n) => {\n\t// Note: the _start param is generated using exclusive range. This provides more coverage by allowing\n\t// insertion at the end.\n\tconst start = random.integer(0, client.getLength());\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(start, text);\n};\n\nexport interface IConfigRange {\n\tmin: number;\n\tmax: number;\n\tgrowthFunc?: (input: number) => number;\n}\n\nexport function doOverRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n\tdoAction: (current: number) => void,\n): void {\n\tlet lastCurrent = Number.NaN;\n\tfor (\n\t\tlet current = range.min;\n\t\tcurrent <= range.max;\n\t\tcurrent = (range.growthFunc ?? defaultGrowthFunc)(current)\n\t) {\n\t\t// let growth funcs be simple\n\t\t// especially around 0 and 1\n\t\t// if the value didn't change,\n\t\t// just increment it\n\t\tif (current === lastCurrent) {\n\t\t\tcurrent++;\n\t\t}\n\t\tif (current <= range.max) {\n\t\t\tlastCurrent = current;\n\t\t\tdoAction(current);\n\t\t}\n\t}\n}\n\nexport function resolveRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n): number[] {\n\tconst results: number[] = [];\n\tdoOverRange(range, range.growthFunc ?? defaultGrowthFunc, (num) => {\n\t\tresults.push(num);\n\t});\n\treturn results;\n}\n\nexport function resolveRanges<T extends object>(\n\tranges: T,\n\tdefaultGrowthFunc: (input: number) => number,\n): ResolvedRanges<T> {\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst resolvedRanges: ResolvedRanges<T> = {} as ResolvedRanges<T>;\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\tresolvedRanges[key] = resolveRange(value, defaultGrowthFunc);\n\t\t}\n\t}\n\treturn resolvedRanges;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isConfigRange(t: any): t is IConfigRange {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\treturn typeof t === \"object\" && typeof t.min === \"number\" && typeof t.max === \"number\";\n}\n\ntype ReplaceRangeWith<T, TReplace> = T extends { min: number; max: number } ? TReplace : never;\n\ntype RangePropertyNames<T> = {\n\t[K in keyof T]-?: T[K] extends IConfigRange ? K : never;\n}[keyof T];\n\ntype PickFromRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number>;\n};\n\ntype ResolvedRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number[]>;\n};\n\ninterface ProvidesGrowthFunc {\n\tgrowthFunc: (input: number) => number;\n}\n\nexport function doOverRanges<T extends ProvidesGrowthFunc>(\n\tranges: T,\n\tdoAction: (selection: PickFromRanges<T>, description: string) => void,\n): void {\n\tconst rangeEntries: [string, IConfigRange][] = [];\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\trangeEntries.push([key, value]);\n\t\t}\n\t}\n\n\tconst doOverRangesHelper = (selections: [string, number][]): void => {\n\t\tif (selections.length === rangeEntries.length) {\n\t\t\tconst selectionsObj = {};\n\t\t\tfor (const [key, value] of selections) {\n\t\t\t\tselectionsObj[key] = value;\n\t\t\t}\n\t\t\tconst description = selections.map(([key, value]) => `${key}:${value}`).join(\"_\");\n\t\t\tdoAction(selectionsObj as PickFromRanges<T>, description);\n\t\t} else {\n\t\t\tconst [key, value] = rangeEntries[selections.length];\n\t\t\tdoOverRange(value, value.growthFunc ?? ranges.growthFunc, (selection) => {\n\t\t\t\tselections.push([key, selection]);\n\t\t\t\tdoOverRangesHelper(selections);\n\t\t\t\tselections.pop();\n\t\t\t});\n\t\t}\n\t};\n\n\tdoOverRangesHelper([]);\n}\n\nexport interface IMergeTreeOperationRunnerConfig {\n\treadonly rounds: number;\n\treadonly opsPerRoundRange: IConfigRange;\n\treadonly incrementalLog?: boolean;\n\treadonly operations: readonly TestOperation[];\n\treadonly applyOpDuringGeneration?: boolean;\n\tgrowthFunc(input: number): number;\n\tresultsFilePostfix?: string;\n}\n\nexport interface ReplayGroup {\n\tmsgs: ISequencedDocumentMessage[];\n\tinitialText: string;\n\tresultText: string;\n\tseq: number;\n}\n\nexport const replayResultsPath = `${_dirname}/../../src/test/results`;\n\nexport function runMergeTreeOperationRunner(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tminLength: number,\n\tconfig: IMergeTreeOperationRunnerConfig,\n\tapply: ApplyMessagesFn = applyMessages,\n): number {\n\tlet seq = startingSeq;\n\tconst results: ReplayGroup[] = [];\n\n\tlet fakeTime = 1725916319097;\n\n\tdoOverRange(config.opsPerRoundRange, config.growthFunc, (opsPerRound) => {\n\t\tif (config.incrementalLog) {\n\t\t\tconsole.log(\n\t\t\t\t`MinLength: ${minLength} Clients: ${clients.length} Ops: ${opsPerRound} Seq: ${seq}`,\n\t\t\t);\n\t\t}\n\t\tfor (let round = 0; round < config.rounds; round++) {\n\t\t\tconst initialText = clients[0].getText();\n\t\t\tconst logger = new TestClientLogger(\n\t\t\t\tclients,\n\t\t\t\t`Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`,\n\t\t\t);\n\t\t\tconst messageData = generateOperationMessagesForClients(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\tlogger,\n\t\t\t\topsPerRound,\n\t\t\t\tminLength,\n\t\t\t\tconfig.operations,\n\t\t\t\tconfig.applyOpDuringGeneration,\n\t\t\t);\n\t\t\tseq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);\n\t\t\tconst resultText = logger.validate();\n\t\t\tresults.push({\n\t\t\t\tinitialText,\n\t\t\t\tresultText,\n\t\t\t\tmsgs: messageData.map((md) => ({ ...md[0], timestamp: fakeTime++ })),\n\t\t\t\tseq,\n\t\t\t});\n\t\t\tlogger.dispose();\n\t\t}\n\t});\n\n\tif (config.resultsFilePostfix !== undefined) {\n\t\tconst resultsFilePath = `${replayResultsPath}/len_${minLength}-clients_${clients.length}-${config.resultsFilePostfix}`;\n\t\tfs.writeFileSync(resultsFilePath, JSON.stringify(results, undefined, \"\\t\"));\n\t}\n\n\treturn seq;\n}\n\nexport function generateOperationMessagesForClients(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\topsPerRound: number,\n\tminLength: number,\n\toperations: readonly TestOperation[],\n\tapplyOpDuringGeneration?: boolean,\n): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] {\n\tconst minimumSequenceNumber = startingSeq;\n\tlet runningSeq = startingSeq;\n\tconst messages: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\n\tfor (let i = 0; i < opsPerRound; i++) {\n\t\t// pick a client greater than 0, client 0 only applies remote ops\n\t\t// and is our baseline\n\t\tconst client = clients[random.integer(1, clients.length - 1)];\n\n\t\tif (applyOpDuringGeneration === true && messages.length > 0 && random.bool()) {\n\t\t\tconst toApply = messages\n\t\t\t\t.filter(([msg]) => msg.sequenceNumber > client.getCollabWindow().currentSeq)\n\t\t\t\t.slice(0, random.integer(1, 3));\n\t\t\tapplyMessages(toApply[0][0].sequenceNumber - 1, toApply, [client], logger);\n\t\t}\n\n\t\tconst len = client.getLength();\n\t\tconst sg = client.peekPendingSegmentGroups();\n\t\tlet op: IMergeTreeOp | undefined;\n\t\tif (len === 0 || len < minLength) {\n\t\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\t\top = client.insertTextLocal(random.integer(0, len), text);\n\t\t} else {\n\t\t\tlet opIndex = random.integer(0, operations.length - 1);\n\t\t\tconst start = random.integer(0, len - 1);\n\t\t\tconst end = random.integer(start + 1, len);\n\n\t\t\tfor (let y = 0; y < operations.length && op === undefined; y++) {\n\t\t\t\top = operations[opIndex](client, start, end, random);\n\t\t\t\topIndex++;\n\t\t\t\topIndex %= operations.length;\n\t\t\t}\n\t\t}\n\t\tif (op !== undefined) {\n\t\t\t// Pre-check to avoid logger.toString() in the string template\n\t\t\tif (sg === client.peekPendingSegmentGroups()) {\n\t\t\t\tassert.notEqual(\n\t\t\t\t\tsg,\n\t\t\t\t\tclient.peekPendingSegmentGroups(),\n\t\t\t\t\t`op created but segment group not enqueued.${logger}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst message = client.makeOpMessage(op, ++runningSeq);\n\t\t\tmessage.minimumSequenceNumber = minimumSequenceNumber;\n\t\t\tmessages.push([\n\t\t\t\tmessage,\n\t\t\t\tclient.peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t]);\n\t\t}\n\t}\n\n\tconst maxProcessedSeq = Math.max(...clients.map((c) => c.getCollabWindow().currentSeq));\n\tif (messages.length > 0) {\n\t\tconst index = messages.findIndex(([msg]) => msg.sequenceNumber === maxProcessedSeq);\n\t\tif (index !== -1) {\n\t\t\tconst apply = messages.splice(0, index + 1);\n\t\t\tapplyMessages(apply[0][0].sequenceNumber - 1, apply, clients, logger);\n\t\t}\n\t}\n\n\treturn messages;\n}\n\nexport function generateClientNames(): string[] {\n\tconst clientNames: string[] = [];\n\tfunction addClientNames(startChar: string, count: number): void {\n\t\tconst startCode = startChar.codePointAt(0);\n\t\tif (startCode === undefined) {\n\t\t\tthrow new Error(\"startCode must be a single character\");\n\t\t}\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tclientNames.push(String.fromCodePoint(startCode + i));\n\t\t}\n\t}\n\n\taddClientNames(\"A\", 26);\n\taddClientNames(\"a\", 26);\n\taddClientNames(\"0\", 17);\n\n\treturn clientNames;\n}\n\ntype ApplyMessagesFn = (\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n) => number;\n\nexport function applyMessages(\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n): number {\n\tlet seq = startingSeq;\n\ttry {\n\t\t// log and apply all the ops created in the round\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let i = 0; i < messageData.length; i++) {\n\t\t\tconst [message] = messageData[i];\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) {\n\t\t\t\tif (c.getCollabWindow().currentSeq < message.sequenceNumber) {\n\t\t\t\t\tc.applyMsg(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow logger.addLogsToError(error);\n\t}\n\treturn seq;\n}\n"]}
1
+ {"version":3,"file":"mergeTreeOperationRunner.js","sourceRoot":"","sources":["../../src/test/mergeTreeOperationRunner.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\nimport * as fs from \"node:fs\";\n\nimport { IRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { walkAllChildSegments } from \"../mergeTreeNodeWalk.js\";\nimport { ISegmentPrivate, SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.js\";\nimport { toMoveInfo, toRemovalInfo } from \"../segmentInfos.js\";\nimport { Side } from \"../sequencePlace.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { _dirname } from \"./dirname.cjs\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport type TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => IMergeTreeOp | undefined;\n\nexport const removeRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.removeRangeLocal(opStart, opEnd);\n\nexport const obliterateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.obliterateRangeLocal(opStart, opEnd);\n\nexport const obliterateRangeSided: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet startSide: Side;\n\tlet endSide: Side;\n\n\tconst oblEnd = random.integer(opStart, client.getLength() - 1);\n\t// TODO: to create zero length obliterate ops, change '<=' to '<'.\n\t// Doing so may cause different failures than those without zero length.\n\t// AB#19930\n\tif (oblEnd - opStart <= 1) {\n\t\tstartSide = Side.Before;\n\t\tendSide = Side.After;\n\t} else {\n\t\tstartSide = random.pick([Side.Before, Side.After]);\n\t\tendSide = random.pick([Side.Before, Side.After]);\n\t}\n\n\tconst start = { pos: opStart, side: startSide };\n\tconst end = { pos: oblEnd, side: endSide };\n\treturn client.obliterateRangeLocal(start, end);\n};\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tif (random.bool()) {\n\t\treturn client.annotateRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(1, 5)]: client.longClientId,\n\t\t});\n\t} else {\n\t\tconst max = random.pick([undefined, random.integer(-10, 100)]);\n\t\tconst min = random.pick([undefined, random.integer(-100, 10)]);\n\t\treturn client.annotateAdjustRangeLocal(opStart, opEnd, {\n\t\t\t[random.integer(0, 2).toString()]: {\n\t\t\t\tdelta: random.integer(-5, 5),\n\t\t\t\tmin: (min ?? max ?? 0) > (max ?? 0) ? undefined : min,\n\t\t\t\tmax,\n\t\t\t},\n\t\t});\n\t}\n};\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegmentPrivate[] = [];\n\t// gather all the segments at the pos, including removed segments\n\twalkAllChildSegments(client.mergeTree.root, (seg) => {\n\t\tconst pos = client.getPosition(seg);\n\t\tif (pos >= opStart) {\n\t\t\tif (pos <= opStart) {\n\t\t\t\tsegs.push(seg);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\tif (segs.length > 0) {\n\t\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\t\tconst seg = random.pick(segs);\n\t\tconst movedOrRemoved = toRemovalInfo(seg) ?? toMoveInfo(seg);\n\t\tconst lref = client.createLocalReferencePosition(\n\t\t\tseg,\n\t\t\tmovedOrRemoved ? 0 : random.integer(0, seg.cachedLength - 1),\n\t\t\tmovedOrRemoved\n\t\t\t\t? ReferenceType.SlideOnRemove\n\t\t\t\t: random.pick([\n\t\t\t\t\t\tReferenceType.Simple,\n\t\t\t\t\t\tReferenceType.SlideOnRemove,\n\t\t\t\t\t\tReferenceType.Transient,\n\t\t\t\t\t]),\n\t\t\tundefined,\n\t\t);\n\n\t\treturn client.insertAtReferencePositionLocal(lref, TextSegment.make(text));\n\t}\n};\n\nexport const insert: TestOperation = (\n\tclient: TestClient,\n\t_start: number,\n\t_end: number,\n\trandom: IRandom,\n) => {\n\t// Note: the _start param is generated using exclusive range. This provides more coverage by allowing\n\t// insertion at the end.\n\tconst start = random.integer(0, client.getLength());\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(start, text);\n};\n\nconst generateInsert = (client: TestClient, random: IRandom): IMergeTreeOp | undefined => {\n\tconst len = client.getLength();\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\treturn client.insertTextLocal(random.integer(0, len), text);\n};\n\nexport interface IConfigRange {\n\tmin: number;\n\tmax: number;\n\tgrowthFunc?: (input: number) => number;\n}\n\nexport function doOverRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n\tdoAction: (current: number) => void,\n): void {\n\tlet lastCurrent = Number.NaN;\n\tfor (\n\t\tlet current = range.min;\n\t\tcurrent <= range.max;\n\t\tcurrent = (range.growthFunc ?? defaultGrowthFunc)(current)\n\t) {\n\t\t// let growth funcs be simple\n\t\t// especially around 0 and 1\n\t\t// if the value didn't change,\n\t\t// just increment it\n\t\tif (current === lastCurrent) {\n\t\t\tcurrent++;\n\t\t}\n\t\tif (current <= range.max) {\n\t\t\tlastCurrent = current;\n\t\t\tdoAction(current);\n\t\t}\n\t}\n}\n\nexport function resolveRange(\n\trange: IConfigRange,\n\tdefaultGrowthFunc: (input: number) => number,\n): number[] {\n\tconst results: number[] = [];\n\tdoOverRange(range, range.growthFunc ?? defaultGrowthFunc, (num) => {\n\t\tresults.push(num);\n\t});\n\treturn results;\n}\n\nexport function resolveRanges<T extends object>(\n\tranges: T,\n\tdefaultGrowthFunc: (input: number) => number,\n): ResolvedRanges<T> {\n\t// eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n\tconst resolvedRanges: ResolvedRanges<T> = {} as ResolvedRanges<T>;\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\tresolvedRanges[key] = resolveRange(value, defaultGrowthFunc);\n\t\t}\n\t}\n\treturn resolvedRanges;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction isConfigRange(t: any): t is IConfigRange {\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\treturn typeof t === \"object\" && typeof t.min === \"number\" && typeof t.max === \"number\";\n}\n\ntype ReplaceRangeWith<T, TReplace> = T extends { min: number; max: number } ? TReplace : never;\n\ntype RangePropertyNames<T> = {\n\t[K in keyof T]-?: T[K] extends IConfigRange ? K : never;\n}[keyof T];\n\ntype PickFromRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number>;\n};\n\ntype ResolvedRanges<T> = {\n\t[K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number[]>;\n};\n\ninterface ProvidesGrowthFunc {\n\tgrowthFunc: (input: number) => number;\n}\n\nexport function doOverRanges<T extends ProvidesGrowthFunc>(\n\tranges: T,\n\tdoAction: (selection: PickFromRanges<T>, description: string) => void,\n): void {\n\tconst rangeEntries: [string, IConfigRange][] = [];\n\tfor (const [key, value] of Object.entries(ranges)) {\n\t\tif (isConfigRange(value)) {\n\t\t\trangeEntries.push([key, value]);\n\t\t}\n\t}\n\n\tconst doOverRangesHelper = (selections: [string, number][]): void => {\n\t\tif (selections.length === rangeEntries.length) {\n\t\t\tconst selectionsObj = {};\n\t\t\tfor (const [key, value] of selections) {\n\t\t\t\tselectionsObj[key] = value;\n\t\t\t}\n\t\t\tconst description = selections.map(([key, value]) => `${key}:${value}`).join(\"_\");\n\t\t\tdoAction(selectionsObj as PickFromRanges<T>, description);\n\t\t} else {\n\t\t\tconst [key, value] = rangeEntries[selections.length];\n\t\t\tdoOverRange(value, value.growthFunc ?? ranges.growthFunc, (selection) => {\n\t\t\t\tselections.push([key, selection]);\n\t\t\t\tdoOverRangesHelper(selections);\n\t\t\t\tselections.pop();\n\t\t\t});\n\t\t}\n\t};\n\n\tdoOverRangesHelper([]);\n}\n\nexport interface IMergeTreeOperationRunnerConfig {\n\treadonly rounds: number;\n\treadonly opsPerRoundRange: IConfigRange;\n\treadonly incrementalLog?: boolean;\n\treadonly operations: readonly TestOperation[];\n\treadonly applyOpDuringGeneration?: boolean;\n\tgrowthFunc(input: number): number;\n\tresultsFilePostfix?: string;\n\tinsertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;\n\tupdateEndpoints?: (client: TestClient, random: IRandom) => { start: number; end: number };\n}\n\nexport interface ReplayGroup {\n\tmsgs: ISequencedDocumentMessage[];\n\tinitialText: string;\n\tresultText: string;\n\tseq: number;\n}\n\nexport const replayResultsPath = `${_dirname}/../../src/test/results`;\n\nexport function runMergeTreeOperationRunner(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tminLength: number,\n\tconfig: IMergeTreeOperationRunnerConfig,\n\tapply: ApplyMessagesFn = applyMessages,\n): number {\n\tlet seq = startingSeq;\n\tconst results: ReplayGroup[] = [];\n\n\tlet fakeTime = 1725916319097;\n\n\tdoOverRange(config.opsPerRoundRange, config.growthFunc, (opsPerRound) => {\n\t\tif (config.incrementalLog) {\n\t\t\tconsole.log(\n\t\t\t\t`MinLength: ${minLength} Clients: ${clients.length} Ops: ${opsPerRound} Seq: ${seq}`,\n\t\t\t);\n\t\t}\n\t\tfor (let round = 0; round < config.rounds; round++) {\n\t\t\tconst initialText = clients[0].getText();\n\t\t\tconst logger = new TestClientLogger(\n\t\t\t\tclients,\n\t\t\t\t`Clients: ${clients.length} Ops: ${opsPerRound} Round: ${round}`,\n\t\t\t);\n\t\t\tconst messageData = generateOperationMessagesForClients(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\tlogger,\n\t\t\t\topsPerRound,\n\t\t\t\tminLength,\n\t\t\t\tconfig.operations,\n\t\t\t\tconfig.applyOpDuringGeneration,\n\t\t\t\tconfig.insertText,\n\t\t\t);\n\t\t\tseq = apply(messageData[0][0].sequenceNumber - 1, messageData, clients, logger, random);\n\t\t\tconst resultText = logger.validate();\n\t\t\tresults.push({\n\t\t\t\tinitialText,\n\t\t\t\tresultText,\n\t\t\t\tmsgs: messageData.map((md) => ({ ...md[0], timestamp: fakeTime++ })),\n\t\t\t\tseq,\n\t\t\t});\n\t\t\tlogger.dispose();\n\t\t}\n\t});\n\n\tif (config.resultsFilePostfix !== undefined) {\n\t\tconst resultsFilePath = `${replayResultsPath}/len_${minLength}-clients_${clients.length}-${config.resultsFilePostfix}`;\n\t\tfs.writeFileSync(resultsFilePath, JSON.stringify(results, undefined, \"\\t\"));\n\t}\n\n\treturn seq;\n}\n\nexport function generateOperationMessagesForClients(\n\trandom: IRandom,\n\tstartingSeq: number,\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\topsPerRound: number,\n\tminLength: number,\n\toperations: readonly TestOperation[],\n\tapplyOpDuringGeneration?: boolean,\n\tinsertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined,\n): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] {\n\tconst minimumSequenceNumber = startingSeq;\n\tlet runningSeq = startingSeq;\n\tconst messages: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] = [];\n\n\tfor (let i = 0; i < opsPerRound; i++) {\n\t\t// pick a client greater than 0, client 0 only applies remote ops\n\t\t// and is our baseline\n\t\tconst client = clients[random.integer(1, clients.length - 1)];\n\n\t\tif (applyOpDuringGeneration === true && messages.length > 0 && random.bool()) {\n\t\t\tconst toApply = messages\n\t\t\t\t.filter(([msg]) => msg.sequenceNumber > client.getCollabWindow().currentSeq)\n\t\t\t\t.slice(0, random.integer(1, 3));\n\t\t\tapplyMessages(toApply[0][0].sequenceNumber - 1, toApply, [client], logger);\n\t\t}\n\n\t\tconst len = client.getLength();\n\t\tconst sg = client.peekPendingSegmentGroups();\n\t\tlet op: IMergeTreeOp | undefined;\n\t\tif (len === 0 || len < minLength) {\n\t\t\top =\n\t\t\t\tinsertText === undefined ? generateInsert(client, random) : insertText(client, random);\n\t\t} else {\n\t\t\tlet opIndex = random.integer(0, operations.length - 1);\n\t\t\tconst start = random.integer(0, len - 1);\n\t\t\tconst end = random.integer(start + 1, len);\n\n\t\t\tfor (let y = 0; y < operations.length && op === undefined; y++) {\n\t\t\t\top = operations[opIndex](client, start, end, random);\n\t\t\t\topIndex++;\n\t\t\t\topIndex %= operations.length;\n\t\t\t}\n\t\t}\n\t\tif (op !== undefined) {\n\t\t\t// Pre-check to avoid logger.toString() in the string template\n\t\t\tif (sg === client.peekPendingSegmentGroups()) {\n\t\t\t\tassert.notEqual(\n\t\t\t\t\tsg,\n\t\t\t\t\tclient.peekPendingSegmentGroups(),\n\t\t\t\t\t`op created but segment group not enqueued.${logger}`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst message = client.makeOpMessage(op, ++runningSeq);\n\t\t\tmessage.minimumSequenceNumber = minimumSequenceNumber;\n\t\t\tmessages.push([\n\t\t\t\tmessage,\n\t\t\t\tclient.peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t]);\n\t\t}\n\t}\n\n\tconst maxProcessedSeq = Math.max(...clients.map((c) => c.getCollabWindow().currentSeq));\n\tif (messages.length > 0) {\n\t\tconst index = messages.findIndex(([msg]) => msg.sequenceNumber === maxProcessedSeq);\n\t\tif (index !== -1) {\n\t\t\tconst apply = messages.splice(0, index + 1);\n\t\t\tapplyMessages(apply[0][0].sequenceNumber - 1, apply, clients, logger);\n\t\t}\n\t}\n\n\treturn messages;\n}\n\nexport function generateClientNames(): string[] {\n\tconst clientNames: string[] = [];\n\tfunction addClientNames(startChar: string, count: number): void {\n\t\tconst startCode = startChar.codePointAt(0);\n\t\tif (startCode === undefined) {\n\t\t\tthrow new Error(\"startCode must be a single character\");\n\t\t}\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tclientNames.push(String.fromCodePoint(startCode + i));\n\t\t}\n\t}\n\n\taddClientNames(\"A\", 26);\n\taddClientNames(\"a\", 26);\n\taddClientNames(\"0\", 17);\n\n\treturn clientNames;\n}\n\ntype ApplyMessagesFn = (\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n\trandom: IRandom,\n) => number;\n\nexport function applyMessages(\n\tstartingSeq: number,\n\tmessageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tlogger: TestClientLogger,\n): number {\n\tlet seq = startingSeq;\n\ttry {\n\t\t// log and apply all the ops created in the round\n\t\t// eslint-disable-next-line @typescript-eslint/prefer-for-of\n\t\tfor (let i = 0; i < messageData.length; i++) {\n\t\t\tconst [message] = messageData[i];\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) {\n\t\t\t\tif (c.getCollabWindow().currentSeq < message.sequenceNumber) {\n\t\t\t\t\tc.applyMsg(message);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch (error) {\n\t\tthrow logger.addLogsToError(error);\n\t}\n\treturn seq;\n}\n"]}
@@ -0,0 +1,15 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import type { IRandom } from "@fluid-private/stochastic-test-utils";
6
+ import type { IMergeTreeOp } from "../ops.js";
7
+ import { type TestOperation } from "./mergeTreeOperationRunner.js";
8
+ import type { TestClient } from "./testClient.js";
9
+ export declare const insertField: TestOperation;
10
+ export declare const obliterateField: TestOperation;
11
+ export declare const insertAvoidField: TestOperation;
12
+ export declare const removeWithField: TestOperation;
13
+ export declare const annotateWithField: TestOperation;
14
+ export declare const generateInsertWithField: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;
15
+ //# sourceMappingURL=obliterateOperations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obliterateOperations.d.ts","sourceRoot":"","sources":["../../src/test/obliterateOperations.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sCAAsC,CAAC;AAGpE,OAAO,KAAK,EAAuB,YAAY,EAAE,MAAM,WAAW,CAAC;AAGnE,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAmElD,eAAO,MAAM,WAAW,EAAE,aAUzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aA8B7B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,aAY9B,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,aAc7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,aAc/B,CAAC;AAEF,eAAO,MAAM,uBAAuB,WAC3B,UAAU,UACV,OAAO,KACb,YAAY,GAAG,SAQjB,CAAC"}
@@ -0,0 +1,112 @@
1
+ /*!
2
+ * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
6
+ import { strict as assert } from "node:assert";
7
+ import { createGroupOp } from "../opBuilder.js";
8
+ import { Side } from "../sequencePlace.js";
9
+ import { annotateRange, removeRange } from "./mergeTreeOperationRunner.js";
10
+ const posInField = (client, pos) => {
11
+ if (pos >= client.getLength() ||
12
+ (!Number.isInteger(Number(client.getText(pos, pos + 1))) &&
13
+ client.getText(pos, pos + 1) !== "{" &&
14
+ client.getText(pos, pos + 1) !== "}")) {
15
+ return undefined;
16
+ }
17
+ let startPos = pos;
18
+ let endPos = pos;
19
+ // To find the start and end separators, walk backwards and forwards until the desired character is found.
20
+ while (startPos > 0 &&
21
+ client.getText(startPos, startPos + 1) !== "{" &&
22
+ (client.getText(startPos, startPos + 1) === "}" ||
23
+ Number.isInteger(Number(client.getText(startPos, startPos + 1))))) {
24
+ startPos--;
25
+ }
26
+ while (endPos < client.getLength() &&
27
+ client.getText(endPos, endPos + 1) !== "}" &&
28
+ (client.getText(endPos, endPos + 1) === "{" ||
29
+ Number.isInteger(Number(client.getText(endPos, endPos + 1))))) {
30
+ endPos++;
31
+ }
32
+ return { startPos, endPos };
33
+ };
34
+ const getFieldEndpoints = (client, start, end) => {
35
+ const startField = posInField(client, start);
36
+ const endField = posInField(client, end);
37
+ if (startField === undefined && endField === undefined) {
38
+ return undefined;
39
+ }
40
+ return startField ?? endField;
41
+ };
42
+ const generateFieldText = (client, random) => {
43
+ const chunkLength = random.integer(1, 10);
44
+ return (client.longClientId.codePointAt(0) % 10).toString().repeat(chunkLength);
45
+ };
46
+ const insertFieldText = (client, opStart, random) => {
47
+ const text = generateFieldText(client, random);
48
+ return client.insertTextLocal(opStart, text);
49
+ };
50
+ export const insertField = (client, opStart, opEnd, random) => {
51
+ const numberText = generateFieldText(client, random);
52
+ if (posInField(client, opStart) === undefined) {
53
+ return client.insertTextLocal(opStart, `{${numberText}}`);
54
+ }
55
+ };
56
+ export const obliterateField = (client, opStart, opEnd, random) => {
57
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
58
+ let endISP;
59
+ if (fieldEndpoints !== undefined) {
60
+ const { startPos, endPos } = fieldEndpoints;
61
+ // Obliterate text bewteen the separators, but avoid the case where the obliterate range is zero length.
62
+ if (endPos - startPos > 1) {
63
+ const obliterateOp = client.obliterateRangeLocal({ pos: startPos, side: Side.After }, { pos: endPos, side: Side.Before });
64
+ const insertOp = insertFieldText(client, startPos + 1, random);
65
+ assert(insertOp !== undefined, "Insert op should not be undefined");
66
+ const op = createGroupOp(obliterateOp, insertOp);
67
+ return op;
68
+ }
69
+ }
70
+ if (opEnd >= client.getLength()) {
71
+ endISP = { pos: client.getLength() - 1, side: Side.After };
72
+ }
73
+ return client.obliterateRangeLocal({ pos: opStart, side: Side.Before }, endISP ?? { pos: opEnd, side: Side.After });
74
+ };
75
+ export const insertAvoidField = (client, opStart, opEnd, random) => {
76
+ let start = opStart;
77
+ const endpoints = posInField(client, opStart);
78
+ if (endpoints !== undefined) {
79
+ start = endpoints.startPos;
80
+ }
81
+ return client.insertTextLocal(start, client.longClientId.repeat(random.integer(1, 3)));
82
+ };
83
+ export const removeWithField = (client, opStart, opEnd, random) => {
84
+ let start = opStart;
85
+ let end = opEnd;
86
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
87
+ if (fieldEndpoints !== undefined) {
88
+ start = fieldEndpoints.startPos;
89
+ end = fieldEndpoints.endPos + 1;
90
+ }
91
+ return removeRange(client, start, end, random);
92
+ };
93
+ export const annotateWithField = (client, opStart, opEnd, random) => {
94
+ let start = opStart;
95
+ let end = opEnd;
96
+ const fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);
97
+ if (fieldEndpoints !== undefined) {
98
+ start = fieldEndpoints.startPos;
99
+ end = fieldEndpoints.endPos + 1;
100
+ }
101
+ return annotateRange(client, start, end, random);
102
+ };
103
+ export const generateInsertWithField = (client, random) => {
104
+ const text = client.longClientId.repeat(random.integer(1, 3));
105
+ let pos = random.integer(0, client.getLength());
106
+ const endpoints = posInField(client, pos);
107
+ if (endpoints !== undefined) {
108
+ pos = 0;
109
+ }
110
+ return client.insertTextLocal(pos, text);
111
+ };
112
+ //# sourceMappingURL=obliterateOperations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"obliterateOperations.js","sourceRoot":"","sources":["../../src/test/obliterateOperations.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport type { IRandom } from \"@fluid-private/stochastic-test-utils\";\n\nimport { createGroupOp } from \"../opBuilder.js\";\nimport type { IMergeTreeInsertMsg, IMergeTreeOp } from \"../ops.js\";\nimport { InteriorSequencePlace, Side } from \"../sequencePlace.js\";\n\nimport { annotateRange, removeRange, type TestOperation } from \"./mergeTreeOperationRunner.js\";\nimport type { TestClient } from \"./testClient.js\";\n\nconst posInField = (\n\tclient: TestClient,\n\tpos: number,\n): { startPos: number; endPos: number } | undefined => {\n\tif (\n\t\tpos >= client.getLength() ||\n\t\t(!Number.isInteger(Number(client.getText(pos, pos + 1))) &&\n\t\t\tclient.getText(pos, pos + 1) !== \"{\" &&\n\t\t\tclient.getText(pos, pos + 1) !== \"}\")\n\t) {\n\t\treturn undefined;\n\t}\n\n\tlet startPos = pos;\n\tlet endPos = pos;\n\t// To find the start and end separators, walk backwards and forwards until the desired character is found.\n\twhile (\n\t\tstartPos > 0 &&\n\t\tclient.getText(startPos, startPos + 1) !== \"{\" &&\n\t\t(client.getText(startPos, startPos + 1) === \"}\" ||\n\t\t\tNumber.isInteger(Number(client.getText(startPos, startPos + 1))))\n\t) {\n\t\tstartPos--;\n\t}\n\n\twhile (\n\t\tendPos < client.getLength() &&\n\t\tclient.getText(endPos, endPos + 1) !== \"}\" &&\n\t\t(client.getText(endPos, endPos + 1) === \"{\" ||\n\t\t\tNumber.isInteger(Number(client.getText(endPos, endPos + 1))))\n\t) {\n\t\tendPos++;\n\t}\n\n\treturn { startPos, endPos };\n};\n\nconst getFieldEndpoints = (\n\tclient: TestClient,\n\tstart: number,\n\tend: number,\n): { startPos: number; endPos: number } | undefined => {\n\tconst startField = posInField(client, start);\n\tconst endField = posInField(client, end);\n\n\tif (startField === undefined && endField === undefined) {\n\t\treturn undefined;\n\t}\n\treturn startField ?? endField;\n};\n\nconst generateFieldText = (client: TestClient, random: IRandom): string => {\n\tconst chunkLength = random.integer(1, 10);\n\treturn (client.longClientId!.codePointAt(0)! % 10).toString().repeat(chunkLength);\n};\n\nconst insertFieldText = (\n\tclient: TestClient,\n\topStart: number,\n\trandom: IRandom,\n): IMergeTreeInsertMsg | undefined => {\n\tconst text = generateFieldText(client, random);\n\treturn client.insertTextLocal(opStart, text);\n};\n\nexport const insertField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst numberText = generateFieldText(client, random);\n\tif (posInField(client, opStart) === undefined) {\n\t\treturn client.insertTextLocal(opStart, `{${numberText}}`);\n\t}\n};\n\nexport const obliterateField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\n\tlet endISP: InteriorSequencePlace | undefined;\n\tif (fieldEndpoints !== undefined) {\n\t\tconst { startPos, endPos } = fieldEndpoints;\n\t\t// Obliterate text bewteen the separators, but avoid the case where the obliterate range is zero length.\n\t\tif (endPos - startPos > 1) {\n\t\t\tconst obliterateOp = client.obliterateRangeLocal(\n\t\t\t\t{ pos: startPos, side: Side.After },\n\t\t\t\t{ pos: endPos, side: Side.Before },\n\t\t\t);\n\t\t\tconst insertOp = insertFieldText(client, startPos + 1, random);\n\t\t\tassert(insertOp !== undefined, \"Insert op should not be undefined\");\n\t\t\tconst op = createGroupOp(obliterateOp, insertOp);\n\t\t\treturn op;\n\t\t}\n\t}\n\tif (opEnd >= client.getLength()) {\n\t\tendISP = { pos: client.getLength() - 1, side: Side.After };\n\t}\n\treturn client.obliterateRangeLocal(\n\t\t{ pos: opStart, side: Side.Before },\n\t\tendISP ?? { pos: opEnd, side: Side.After },\n\t);\n};\n\nexport const insertAvoidField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tconst endpoints = posInField(client, opStart);\n\tif (endpoints !== undefined) {\n\t\tstart = endpoints.startPos;\n\t}\n\treturn client.insertTextLocal(start, client.longClientId!.repeat(random.integer(1, 3)));\n};\n\nexport const removeWithField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tlet end = opEnd;\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\tif (fieldEndpoints !== undefined) {\n\t\tstart = fieldEndpoints.startPos;\n\t\tend = fieldEndpoints.endPos + 1;\n\t}\n\treturn removeRange(client, start, end, random);\n};\n\nexport const annotateWithField: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tlet start = opStart;\n\tlet end = opEnd;\n\tconst fieldEndpoints = getFieldEndpoints(client, opStart, opEnd);\n\tif (fieldEndpoints !== undefined) {\n\t\tstart = fieldEndpoints.startPos;\n\t\tend = fieldEndpoints.endPos + 1;\n\t}\n\treturn annotateRange(client, start, end, random);\n};\n\nexport const generateInsertWithField = (\n\tclient: TestClient,\n\trandom: IRandom,\n): IMergeTreeOp | undefined => {\n\tconst text = client.longClientId!.repeat(random.integer(1, 3));\n\tlet pos = random.integer(0, client.getLength());\n\tconst endpoints = posInField(client, pos);\n\tif (endpoints !== undefined) {\n\t\tpos = 0;\n\t}\n\treturn client.insertTextLocal(pos, text);\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/merge-tree",
3
- "version": "2.20.0",
3
+ "version": "2.21.0",
4
4
  "description": "Merge tree",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -81,30 +81,30 @@
81
81
  "temp-directory": "nyc/.nyc_output"
82
82
  },
83
83
  "dependencies": {
84
- "@fluid-internal/client-utils": "~2.20.0",
85
- "@fluidframework/container-definitions": "~2.20.0",
86
- "@fluidframework/core-interfaces": "~2.20.0",
87
- "@fluidframework/core-utils": "~2.20.0",
88
- "@fluidframework/datastore-definitions": "~2.20.0",
89
- "@fluidframework/driver-definitions": "~2.20.0",
90
- "@fluidframework/runtime-definitions": "~2.20.0",
91
- "@fluidframework/runtime-utils": "~2.20.0",
92
- "@fluidframework/shared-object-base": "~2.20.0",
93
- "@fluidframework/telemetry-utils": "~2.20.0"
84
+ "@fluid-internal/client-utils": "~2.21.0",
85
+ "@fluidframework/container-definitions": "~2.21.0",
86
+ "@fluidframework/core-interfaces": "~2.21.0",
87
+ "@fluidframework/core-utils": "~2.21.0",
88
+ "@fluidframework/datastore-definitions": "~2.21.0",
89
+ "@fluidframework/driver-definitions": "~2.21.0",
90
+ "@fluidframework/runtime-definitions": "~2.21.0",
91
+ "@fluidframework/runtime-utils": "~2.21.0",
92
+ "@fluidframework/shared-object-base": "~2.21.0",
93
+ "@fluidframework/telemetry-utils": "~2.21.0"
94
94
  },
95
95
  "devDependencies": {
96
96
  "@arethetypeswrong/cli": "^0.17.1",
97
97
  "@biomejs/biome": "~1.9.3",
98
- "@fluid-internal/mocha-test-setup": "~2.20.0",
99
- "@fluid-private/stochastic-test-utils": "~2.20.0",
100
- "@fluid-private/test-pairwise-generator": "~2.20.0",
98
+ "@fluid-internal/mocha-test-setup": "~2.21.0",
99
+ "@fluid-private/stochastic-test-utils": "~2.21.0",
100
+ "@fluid-private/test-pairwise-generator": "~2.21.0",
101
101
  "@fluid-tools/benchmark": "^0.50.0",
102
102
  "@fluid-tools/build-cli": "^0.51.0",
103
103
  "@fluidframework/build-common": "^2.0.3",
104
104
  "@fluidframework/build-tools": "^0.51.0",
105
- "@fluidframework/eslint-config-fluid": "^5.6.0",
106
- "@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.13.0",
107
- "@fluidframework/test-runtime-utils": "~2.20.0",
105
+ "@fluidframework/eslint-config-fluid": "^5.7.3",
106
+ "@fluidframework/merge-tree-previous": "npm:@fluidframework/merge-tree@2.20.0",
107
+ "@fluidframework/test-runtime-utils": "~2.21.0",
108
108
  "@microsoft/api-extractor": "7.47.8",
109
109
  "@types/diff": "^3.5.1",
110
110
  "@types/mocha": "^10.0.10",
@@ -124,65 +124,7 @@
124
124
  "typescript": "~5.4.5"
125
125
  },
126
126
  "typeValidation": {
127
- "broken": {
128
- "Class_BaseSegment": {
129
- "backCompat": false
130
- },
131
- "Class_Marker": {
132
- "backCompat": false
133
- },
134
- "Class_TextSegment": {
135
- "backCompat": false
136
- },
137
- "Class_TrackingGroup": {
138
- "backCompat": false
139
- },
140
- "ClassStatics_BaseSegment": {
141
- "backCompat": false
142
- },
143
- "ClassStatics_Marker": {
144
- "backCompat": false
145
- },
146
- "ClassStatics_TextSegment": {
147
- "backCompat": false
148
- },
149
- "ClassStatics_TrackingGroup": {
150
- "backCompat": false
151
- },
152
- "Interface_IMergeTreeDeltaCallbackArgs": {
153
- "backCompat": false
154
- },
155
- "Interface_IMergeTreeMaintenanceCallbackArgs": {
156
- "backCompat": false
157
- },
158
- "Interface_IMergeTreeSegmentDelta": {
159
- "backCompat": false
160
- },
161
- "Interface_ISegment": {
162
- "backCompat": false
163
- },
164
- "Interface_ITrackingGroup": {
165
- "backCompat": false
166
- },
167
- "TypeAlias_MergeTreeDeltaRevertible": {
168
- "backCompat": false
169
- },
170
- "TypeAlias_Trackable": {
171
- "backCompat": false
172
- },
173
- "Interface_IMergeNodeCommon": {
174
- "forwardCompat": false,
175
- "backCompat": false
176
- },
177
- "Interface_IMoveInfo": {
178
- "forwardCompat": false,
179
- "backCompat": false
180
- },
181
- "Interface_IRemovalInfo": {
182
- "forwardCompat": false,
183
- "backCompat": false
184
- }
185
- },
127
+ "broken": {},
186
128
  "entrypoint": "legacy"
187
129
  },
188
130
  "scripts": {
@@ -214,7 +156,7 @@
214
156
  "ci:build:api-reports:current": "api-extractor run --config api-extractor/api-extractor.current.json",
215
157
  "ci:build:api-reports:legacy": "api-extractor run --config api-extractor/api-extractor.legacy.json",
216
158
  "ci:build:docs": "api-extractor run",
217
- "clean": "rimraf --glob dist lib \"*.d.ts\" \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
159
+ "clean": "rimraf --glob dist lib {alpha,beta,internal,legacy}.d.ts \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc",
218
160
  "eslint": "eslint --format stylish src",
219
161
  "eslint:fix": "eslint --format stylish src --fix",
220
162
  "format": "npm run format:biome",