@fluidframework/merge-tree 2.2.0 → 2.3.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 +4 -0
- package/api-report/merge-tree.legacy.alpha.api.md +20 -0
- package/dist/attributionCollection.d.ts.map +1 -1
- package/dist/attributionCollection.js +1 -29
- package/dist/attributionCollection.js.map +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +3 -4
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/legacy.d.ts +1 -0
- package/dist/localReference.d.ts.map +1 -1
- package/dist/localReference.js +0 -2
- package/dist/localReference.js.map +1 -1
- package/dist/mergeTree.d.ts +1 -30
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +131 -167
- package/dist/mergeTree.js.map +1 -1
- package/dist/mergeTreeNodes.d.ts +16 -1
- package/dist/mergeTreeNodes.d.ts.map +1 -1
- package/dist/mergeTreeNodes.js +5 -2
- package/dist/mergeTreeNodes.js.map +1 -1
- package/dist/partialLengths.d.ts.map +1 -1
- package/dist/partialLengths.js +8 -54
- package/dist/partialLengths.js.map +1 -1
- package/dist/properties.d.ts.map +1 -1
- package/dist/properties.js +0 -2
- package/dist/properties.js.map +1 -1
- package/dist/revertibles.d.ts.map +1 -1
- package/dist/revertibles.js +0 -14
- package/dist/revertibles.js.map +1 -1
- package/dist/segmentGroupCollection.d.ts.map +1 -1
- package/dist/segmentGroupCollection.js +0 -2
- package/dist/segmentGroupCollection.js.map +1 -1
- package/dist/segmentPropertiesManager.d.ts.map +1 -1
- package/dist/segmentPropertiesManager.js +1 -3
- package/dist/segmentPropertiesManager.js.map +1 -1
- package/dist/snapshotLoader.d.ts.map +1 -1
- package/dist/snapshotLoader.js +1 -4
- package/dist/snapshotLoader.js.map +1 -1
- package/dist/snapshotV1.d.ts.map +1 -1
- package/dist/snapshotV1.js +1 -11
- package/dist/snapshotV1.js.map +1 -1
- package/dist/snapshotlegacy.d.ts.map +1 -1
- package/dist/snapshotlegacy.js +0 -1
- package/dist/snapshotlegacy.js.map +1 -1
- package/dist/sortedSegmentSet.d.ts +0 -1
- package/dist/sortedSegmentSet.d.ts.map +1 -1
- package/dist/sortedSegmentSet.js +1 -9
- package/dist/sortedSegmentSet.js.map +1 -1
- package/dist/sortedSet.d.ts.map +1 -1
- package/dist/sortedSet.js +0 -4
- package/dist/sortedSet.js.map +1 -1
- package/dist/test/client.conflictFarm.spec.d.ts.map +1 -1
- package/dist/test/client.conflictFarm.spec.js +36 -27
- package/dist/test/client.conflictFarm.spec.js.map +1 -1
- package/dist/test/client.replay.spec.js +1 -1
- package/dist/test/client.replay.spec.js.map +1 -1
- package/dist/test/mergeTreeOperationRunner.d.ts +2 -1
- package/dist/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/dist/test/mergeTreeOperationRunner.js +29 -11
- package/dist/test/mergeTreeOperationRunner.js.map +1 -1
- package/dist/test/obliterate.spec.js +55 -0
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/reconnectHelper.d.ts +0 -1
- package/dist/test/reconnectHelper.d.ts.map +1 -1
- package/dist/test/reconnectHelper.js +1 -1
- package/dist/test/reconnectHelper.js.map +1 -1
- package/dist/test/testClientLogger.d.ts.map +1 -1
- package/dist/test/testClientLogger.js +17 -7
- package/dist/test/testClientLogger.js.map +1 -1
- package/dist/zamboni.d.ts.map +1 -1
- package/dist/zamboni.js +0 -4
- package/dist/zamboni.js.map +1 -1
- package/lib/attributionCollection.d.ts.map +1 -1
- package/lib/attributionCollection.js +1 -29
- package/lib/attributionCollection.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +3 -4
- package/lib/client.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/legacy.d.ts +1 -0
- package/lib/localReference.d.ts.map +1 -1
- package/lib/localReference.js +0 -2
- package/lib/localReference.js.map +1 -1
- package/lib/mergeTree.d.ts +1 -30
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +132 -168
- package/lib/mergeTree.js.map +1 -1
- package/lib/mergeTreeNodes.d.ts +16 -1
- package/lib/mergeTreeNodes.d.ts.map +1 -1
- package/lib/mergeTreeNodes.js +5 -2
- package/lib/mergeTreeNodes.js.map +1 -1
- package/lib/partialLengths.d.ts.map +1 -1
- package/lib/partialLengths.js +8 -54
- package/lib/partialLengths.js.map +1 -1
- package/lib/properties.d.ts.map +1 -1
- package/lib/properties.js +0 -2
- package/lib/properties.js.map +1 -1
- package/lib/revertibles.d.ts.map +1 -1
- package/lib/revertibles.js +0 -14
- package/lib/revertibles.js.map +1 -1
- package/lib/segmentGroupCollection.d.ts.map +1 -1
- package/lib/segmentGroupCollection.js +0 -2
- package/lib/segmentGroupCollection.js.map +1 -1
- package/lib/segmentPropertiesManager.d.ts.map +1 -1
- package/lib/segmentPropertiesManager.js +1 -3
- package/lib/segmentPropertiesManager.js.map +1 -1
- package/lib/snapshotLoader.d.ts.map +1 -1
- package/lib/snapshotLoader.js +1 -4
- package/lib/snapshotLoader.js.map +1 -1
- package/lib/snapshotV1.d.ts.map +1 -1
- package/lib/snapshotV1.js +1 -11
- package/lib/snapshotV1.js.map +1 -1
- package/lib/snapshotlegacy.d.ts.map +1 -1
- package/lib/snapshotlegacy.js +0 -1
- package/lib/snapshotlegacy.js.map +1 -1
- package/lib/sortedSegmentSet.d.ts +0 -1
- package/lib/sortedSegmentSet.d.ts.map +1 -1
- package/lib/sortedSegmentSet.js +1 -9
- package/lib/sortedSegmentSet.js.map +1 -1
- package/lib/sortedSet.d.ts.map +1 -1
- package/lib/sortedSet.js +0 -4
- package/lib/sortedSet.js.map +1 -1
- package/lib/test/client.conflictFarm.spec.d.ts.map +1 -1
- package/lib/test/client.conflictFarm.spec.js +37 -28
- package/lib/test/client.conflictFarm.spec.js.map +1 -1
- package/lib/test/client.replay.spec.js +1 -1
- package/lib/test/client.replay.spec.js.map +1 -1
- package/lib/test/mergeTreeOperationRunner.d.ts +2 -1
- package/lib/test/mergeTreeOperationRunner.d.ts.map +1 -1
- package/lib/test/mergeTreeOperationRunner.js +30 -12
- package/lib/test/mergeTreeOperationRunner.js.map +1 -1
- package/lib/test/obliterate.spec.js +55 -0
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/reconnectHelper.d.ts +0 -1
- package/lib/test/reconnectHelper.d.ts.map +1 -1
- package/lib/test/reconnectHelper.js +1 -1
- package/lib/test/reconnectHelper.js.map +1 -1
- package/lib/test/testClientLogger.d.ts.map +1 -1
- package/lib/test/testClientLogger.js +18 -8
- package/lib/test/testClientLogger.js.map +1 -1
- package/lib/tsdoc-metadata.json +1 -1
- package/lib/zamboni.d.ts.map +1 -1
- package/lib/zamboni.js +0 -4
- package/lib/zamboni.js.map +1 -1
- package/package.json +22 -21
- package/src/attributionCollection.ts +14 -42
- package/src/client.ts +8 -9
- package/src/index.ts +1 -0
- package/src/localReference.ts +1 -3
- package/src/mergeTree.ts +185 -208
- package/src/mergeTreeNodes.ts +22 -3
- package/src/partialLengths.ts +23 -68
- package/src/properties.ts +1 -3
- package/src/revertibles.ts +7 -21
- package/src/segmentGroupCollection.ts +1 -3
- package/src/segmentPropertiesManager.ts +0 -1
- package/src/snapshotLoader.ts +2 -4
- package/src/snapshotV1.ts +5 -15
- package/src/snapshotlegacy.ts +1 -2
- package/src/sortedSegmentSet.ts +3 -10
- package/src/sortedSet.ts +2 -6
- package/src/zamboni.ts +4 -8
- package/tsconfig.json +1 -0
|
@@ -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 { ISegment, SegmentGroup, toRemovalInfo } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.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 annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.annotateRangeLocal(opStart, opEnd, { client: client.longClientId });\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegment[] = [];\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 lref = client.createLocalReferencePosition(\n\t\t\tseg,\n\t\t\ttoRemovalInfo(seg) ? 0 : random.integer(0, seg.cachedLength - 1),\n\t\t\ttoRemovalInfo(seg)\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\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\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);\n\t\t\tconst msgs = messageData.map((md) => md[0]);\n\t\t\tseq = apply(seq, 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,\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, 4));\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): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][] {\n\tconst minimumSequenceNumber = startingSeq;\n\tlet tempSeq = startingSeq * -1;\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\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, --tempSeq);\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\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) c.applyMsg(message);\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 { ISegment, SegmentGroup, toMoveInfo, toRemovalInfo } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType, ReferenceType } from \"../ops.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 annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.annotateRangeLocal(opStart, opEnd, { client: client.longClientId });\n\nexport const insertAtRefPos: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n\trandom: IRandom,\n) => {\n\tconst segs: ISegment[] = [];\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"]}
|
|
@@ -158,5 +158,60 @@ describe("obliterate", () => {
|
|
|
158
158
|
node_assert_1.strict.equal(client.getText(), "");
|
|
159
159
|
});
|
|
160
160
|
});
|
|
161
|
+
describe("local references", () => {
|
|
162
|
+
it("cleans up local references once the collab window advances enough", () => {
|
|
163
|
+
const client2 = new testClient_js_1.TestClient({ mergeTreeEnableObliterate: true });
|
|
164
|
+
client2.startOrUpdateCollaboration("client2");
|
|
165
|
+
const obliterateStart = 0;
|
|
166
|
+
const obliterateEnd = client.getLength();
|
|
167
|
+
const startSeg = client.getContainingSegment(obliterateStart);
|
|
168
|
+
const endSeg = client.getContainingSegment(obliterateEnd);
|
|
169
|
+
client.obliterateRange({
|
|
170
|
+
start: obliterateStart,
|
|
171
|
+
end: obliterateEnd,
|
|
172
|
+
refSeq,
|
|
173
|
+
clientId: remoteClientId,
|
|
174
|
+
seq: refSeq + 1,
|
|
175
|
+
overwrite: false,
|
|
176
|
+
opArgs: undefined,
|
|
177
|
+
});
|
|
178
|
+
(0, testUtils_js_1.insertText)({
|
|
179
|
+
mergeTree: client.mergeTree,
|
|
180
|
+
pos: 1,
|
|
181
|
+
refSeq,
|
|
182
|
+
clientId: remoteClientId + 1,
|
|
183
|
+
seq: refSeq + 2,
|
|
184
|
+
text: "more ",
|
|
185
|
+
props: undefined,
|
|
186
|
+
opArgs: { op: { type: ops_js_1.MergeTreeDeltaType.INSERT } },
|
|
187
|
+
});
|
|
188
|
+
node_assert_1.strict.equal(client.getText(), "");
|
|
189
|
+
startSeg.segment?.localRefs?.walkReferences((ref) => {
|
|
190
|
+
const oblProps = ref.properties?.obliterate;
|
|
191
|
+
(0, node_assert_1.strict)(oblProps?.start !== undefined, "start ref should NOT be removed");
|
|
192
|
+
});
|
|
193
|
+
endSeg.segment?.localRefs?.walkReferences((ref) => {
|
|
194
|
+
const oblProps = ref.properties?.obliterate;
|
|
195
|
+
(0, node_assert_1.strict)(oblProps?.end !== undefined, "end ref should NOT be removed");
|
|
196
|
+
});
|
|
197
|
+
// this will force Zamboni to run
|
|
198
|
+
let seq = refSeq;
|
|
199
|
+
for (let i = 0; i < 5; i++) {
|
|
200
|
+
const insert = client.makeOpMessage(client.insertTextLocal(client.getLength(), i.toString()), ++seq);
|
|
201
|
+
insert.minimumSequenceNumber = seq - 1;
|
|
202
|
+
client.applyMsg(insert);
|
|
203
|
+
client2.applyMsg(insert);
|
|
204
|
+
}
|
|
205
|
+
// want to check that the start and end segment don't have the obliterate refs on them
|
|
206
|
+
startSeg.segment?.localRefs?.walkReferences((ref) => {
|
|
207
|
+
const oblProps = ref.properties?.obliterate;
|
|
208
|
+
(0, node_assert_1.strict)(oblProps.start === undefined, "start ref should be removed");
|
|
209
|
+
});
|
|
210
|
+
endSeg.segment?.localRefs?.walkReferences((ref) => {
|
|
211
|
+
const oblProps = ref.properties?.obliterate;
|
|
212
|
+
(0, node_assert_1.strict)(oblProps.end === undefined, "end ref should be removed");
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
});
|
|
161
216
|
});
|
|
162
217
|
//# sourceMappingURL=obliterate.spec.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obliterate.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { MergeTreeDeltaType } from \"../ops.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { insertText } from \"./testUtils.js\";\n\ndescribe(\"obliterate\", () => {\n\tlet client: TestClient;\n\tlet refSeq: number;\n\tconst localClientId = 17;\n\tconst remoteClientId = localClientId + 1;\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\t\tfor (const char of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), char),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\trefSeq = client.getCurrentSeq();\n\t});\n\n\tit(\"removes text\", () => {\n\t\tclient.obliterateRangeLocal(0, client.getLength());\n\t\tassert.equal(client.getText(), \"\");\n\t});\n\n\tdescribe(\"concurrent obliterate and insert\", () => {\n\t\tit(\"removes text for obliterate then insert\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: client.getLength(),\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t\tit(\"removes text for insert then obliterate when deleting entire string\", () => {\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t\tit(\"removes text for insert then obliterate\", () => {\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 1,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"h\");\n\t\t});\n\t});\n\n\tdescribe(\"endpoint behavior\", () => {\n\t\tit(\"does not expand to include text inserted at start\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 5,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"helloXXX\");\n\t\t});\n\t\tit(\"does not expand to include text inserted at end\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"XXX world\");\n\t\t});\n\t});\n\n\tdescribe(\"local obliterate with concurrent inserts\", () => {\n\t\tit(\"removes range when pending local obliterate op\", () => {\n\t\t\tclient.obliterateRangeLocal(0, \"hello world\".length);\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"obliterate.spec.js","sourceRoot":"","sources":["../../src/test/obliterate.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport type { ObliterateInfo } from \"../mergeTreeNodes.js\";\nimport { MergeTreeDeltaType } from \"../ops.js\";\n\nimport { TestClient } from \"./testClient.js\";\nimport { insertText } from \"./testUtils.js\";\n\ndescribe(\"obliterate\", () => {\n\tlet client: TestClient;\n\tlet refSeq: number;\n\tconst localClientId = 17;\n\tconst remoteClientId = localClientId + 1;\n\n\tbeforeEach(() => {\n\t\tclient = new TestClient({\n\t\t\tmergeTreeEnableObliterate: true,\n\t\t});\n\t\tclient.startOrUpdateCollaboration(\"local\");\n\t\tfor (const char of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), char),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.equal(client.getText(), \"hello world\");\n\t\trefSeq = client.getCurrentSeq();\n\t});\n\n\tit(\"removes text\", () => {\n\t\tclient.obliterateRangeLocal(0, client.getLength());\n\t\tassert.equal(client.getText(), \"\");\n\t});\n\n\tdescribe(\"concurrent obliterate and insert\", () => {\n\t\tit(\"removes text for obliterate then insert\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: client.getLength(),\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t\tit(\"removes text for insert then obliterate when deleting entire string\", () => {\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t\tit(\"removes text for insert then obliterate\", () => {\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 1,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"h\");\n\t\t});\n\t});\n\n\tdescribe(\"endpoint behavior\", () => {\n\t\tit(\"does not expand to include text inserted at start\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 5,\n\t\t\t\tend: \"hello world\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"helloXXX\");\n\t\t});\n\t\tit(\"does not expand to include text inserted at end\", () => {\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: 0,\n\t\t\t\tend: \"hello\".length,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 5,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"XXX world\");\n\t\t});\n\t});\n\n\tdescribe(\"local obliterate with concurrent inserts\", () => {\n\t\tit(\"removes range when pending local obliterate op\", () => {\n\t\t\tclient.obliterateRangeLocal(0, \"hello world\".length);\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"XXX\",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\t\t});\n\t});\n\n\tdescribe(\"local references\", () => {\n\t\tit(\"cleans up local references once the collab window advances enough\", () => {\n\t\t\tconst client2 = new TestClient({ mergeTreeEnableObliterate: true });\n\t\t\tclient2.startOrUpdateCollaboration(\"client2\");\n\n\t\t\tconst obliterateStart = 0;\n\t\t\tconst obliterateEnd = client.getLength();\n\t\t\tconst startSeg = client.getContainingSegment(obliterateStart);\n\t\t\tconst endSeg = client.getContainingSegment(obliterateEnd);\n\t\t\tclient.obliterateRange({\n\t\t\t\tstart: obliterateStart,\n\t\t\t\tend: obliterateEnd,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId,\n\t\t\t\tseq: refSeq + 1,\n\t\t\t\toverwrite: false,\n\t\t\t\topArgs: undefined as never,\n\t\t\t});\n\t\t\tinsertText({\n\t\t\t\tmergeTree: client.mergeTree,\n\t\t\t\tpos: 1,\n\t\t\t\trefSeq,\n\t\t\t\tclientId: remoteClientId + 1,\n\t\t\t\tseq: refSeq + 2,\n\t\t\t\ttext: \"more \",\n\t\t\t\tprops: undefined,\n\t\t\t\topArgs: { op: { type: MergeTreeDeltaType.INSERT } },\n\t\t\t});\n\t\t\tassert.equal(client.getText(), \"\");\n\n\t\t\tstartSeg.segment?.localRefs?.walkReferences((ref) => {\n\t\t\t\tconst oblProps = ref.properties?.obliterate as ObliterateInfo | undefined;\n\t\t\t\tassert(oblProps?.start !== undefined, \"start ref should NOT be removed\");\n\t\t\t});\n\t\t\tendSeg.segment?.localRefs?.walkReferences((ref) => {\n\t\t\t\tconst oblProps = ref.properties?.obliterate as ObliterateInfo | undefined;\n\t\t\t\tassert(oblProps?.end !== undefined, \"end ref should NOT be removed\");\n\t\t\t});\n\n\t\t\t// this will force Zamboni to run\n\t\t\tlet seq = refSeq;\n\t\t\tfor (let i = 0; i < 5; i++) {\n\t\t\t\tconst insert = client.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), i.toString()),\n\t\t\t\t\t++seq,\n\t\t\t\t);\n\t\t\t\tinsert.minimumSequenceNumber = seq - 1;\n\t\t\t\tclient.applyMsg(insert);\n\t\t\t\tclient2.applyMsg(insert);\n\t\t\t}\n\n\t\t\t// want to check that the start and end segment don't have the obliterate refs on them\n\t\t\tstartSeg.segment?.localRefs?.walkReferences((ref) => {\n\t\t\t\tconst oblProps = ref.properties?.obliterate as ObliterateInfo;\n\t\t\t\tassert(oblProps.start === undefined, \"start ref should be removed\");\n\t\t\t});\n\t\t\tendSeg.segment?.localRefs?.walkReferences((ref) => {\n\t\t\t\tconst oblProps = ref.properties?.obliterate as ObliterateInfo;\n\t\t\t\tassert(oblProps.end === undefined, \"end ref should be removed\");\n\t\t\t});\n\t\t});\n\t});\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnectHelper.d.ts","sourceRoot":"","sources":["../../src/test/reconnectHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAExF,OAAO,EAAE,YAAY,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EACN,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAA+B,MAAM,uBAAuB,CAAC;AAEtF,QAAA,MAAM,SAAS,+BAAgC,CAAC;AAChD,KAAK,UAAU,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7C,qBAAa,mBAAmB;IAC/B,OAAO;;MAML;IAEF,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIrC,MAAM,mBAA0C;IAEhD,GAAG,EAAE,yBAAyB,EAAE,CAAM;IACtC,YAAY,EAAE,yBAAyB,EAAE,EAAE,CAAkC;IAE7E,GAAG,EAAE,MAAM,CAAK;IAET,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKnE,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAKrE,eAAe,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,GAChB,IAAI;IAkBA,eAAe,CACrB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACV;QACF,EAAE,EAAE,mBAAmB,CAAC;QACxB,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IASM,gBAAgB,CACtB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACT;QACF,EAAE,EAAE,mBAAmB,CAAC;QACxB,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IASM,oBAAoB,CAC1B,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,GAChB;QACF,EAAE,EAAE,uBAAuB,CAAC;QAC5B,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IAoBM,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAY3C,aAAa,IAAI,IAAI;IAOrB,SAAS,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAS1C,oBAAoB,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE;QAAE,EAAE,EAAE,iBAAiB,CAAC;QAAC,GAAG,EAAE,YAAY,GAAG,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"reconnectHelper.d.ts","sourceRoot":"","sources":["../../src/test/reconnectHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAExF,OAAO,EAAE,YAAY,EAAsB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EACN,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,gBAAgB,EAA+B,MAAM,uBAAuB,CAAC;AAEtF,QAAA,MAAM,SAAS,+BAAgC,CAAC;AAChD,KAAK,UAAU,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7C,qBAAa,mBAAmB;IAC/B,OAAO;;MAML;IAEF,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIrC,MAAM,mBAA0C;IAEhD,GAAG,EAAE,yBAAyB,EAAE,CAAM;IACtC,YAAY,EAAE,yBAAyB,EAAE,EAAE,CAAkC;IAE7E,GAAG,EAAE,MAAM,CAAK;IAET,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKnE,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAKrE,eAAe,CACrB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,GAChB,IAAI;IAkBA,eAAe,CACrB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACV;QACF,EAAE,EAAE,mBAAmB,CAAC;QACxB,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IASM,gBAAgB,CACtB,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,GACT;QACF,EAAE,EAAE,mBAAmB,CAAC;QACxB,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IASM,oBAAoB,CAC1B,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,aAAa,GAChB;QACF,EAAE,EAAE,uBAAuB,CAAC;QAC5B,GAAG,EAAE,YAAY,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KACf;IAoBM,UAAU,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAY3C,aAAa,IAAI,IAAI;IAOrB,SAAS,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI;IAS1C,oBAAoB,CAC1B,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE;QAAE,EAAE,EAAE,iBAAiB,CAAC;QAAC,GAAG,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;KAAE,GAC/D,IAAI;CAIP"}
|
|
@@ -98,7 +98,7 @@ class ReconnectTestHelper {
|
|
|
98
98
|
}
|
|
99
99
|
submitDisconnectedOp(clientName, op) {
|
|
100
100
|
const client = this.clients[clientName];
|
|
101
|
-
this.ops.push(client.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq
|
|
101
|
+
this.ops.push(client.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq));
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
exports.ReconnectTestHelper = ReconnectTestHelper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconnectHelper.js","sourceRoot":"","sources":["../../src/test/reconnectHelper.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup, endpointPosAndSide, type SequencePlace } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOp,\n\ttype IMergeTreeInsertMsg,\n\ttype IMergeTreeObliterateMsg,\n\ttype IMergeTreeRemoveMsg,\n} from \"../ops.js\";\n\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\nconst ClientIds = [\"A\", \"B\", \"C\", \"D\"] as const;\ntype ClientName = (typeof ClientIds)[number];\n\nexport class ReconnectTestHelper {\n\tclients = createClientsAtInitialState(\n\t\t{\n\t\t\tinitialState: \"\",\n\t\t\toptions: { mergeTreeEnableObliterate: true, mergeTreeEnableObliterateReconnect: true },\n\t\t},\n\t\t...ClientIds,\n\t);\n\n\tidxFromName(name: ClientName): number {\n\t\treturn (name.codePointAt(0) ?? 0) - (\"A\".codePointAt(0) ?? 0);\n\t}\n\n\tlogger = new TestClientLogger(this.clients.all);\n\n\tops: ISequencedDocumentMessage[] = [];\n\tperClientOps: ISequencedDocumentMessage[][] = this.clients.all.map(() => []);\n\n\tseq: number = 0;\n\n\tpublic insertText(clientName: ClientName, pos: number, text: string): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));\n\t}\n\n\tpublic removeRange(clientName: ClientName, start: number, end: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));\n\t}\n\n\tpublic obliterateRange(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tthis.ops.push(\n\t\t\tclient.makeOpMessage(client.obliterateRangeLocal(startPos, endPos), ++this.seq),\n\t\t);\n\t}\n\n\tpublic insertTextLocal(\n\t\tclientName: ClientName,\n\t\tpos: number,\n\t\ttext: string,\n\t): {\n\t\top: IMergeTreeInsertMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.insertTextLocal(pos, text);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic removeRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: number,\n\t\tend: number,\n\t): {\n\t\top: IMergeTreeRemoveMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.removeRangeLocal(start, end);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic obliterateRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): {\n\t\top: IMergeTreeObliterateMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tconst op = client.obliterateRangeLocal(startPos, endPos);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic disconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const [i, c] of this.clients.all.entries()) {\n\t\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\t\tthis.perClientOps[i].push(op);\n\t\t\t\t} else {\n\t\t\t\t\tc.applyMsg(op);\n\t\t\t\t}\n\t\t\t}\n\t}\n\n\tpublic processAllOps(): void {\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const c of this.clients.all) {\n\t\t\t\tc.applyMsg(op);\n\t\t\t}\n\t}\n\n\tpublic reconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const [i, clientOps] of this.perClientOps.entries()) {\n\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\tfor (const op of clientOps.splice(0)) this.clients.all[i].applyMsg(op);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic submitDisconnectedOp(\n\t\tclientName: ClientName,\n\t\top: { op: IMergeTreeDeltaOp; seg: SegmentGroup | SegmentGroup[]; refSeq: number },\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(\n\t\t\tclient.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq, op.refSeq),\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reconnectHelper.js","sourceRoot":"","sources":["../../src/test/reconnectHelper.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup, endpointPosAndSide, type SequencePlace } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOp,\n\ttype IMergeTreeInsertMsg,\n\ttype IMergeTreeObliterateMsg,\n\ttype IMergeTreeRemoveMsg,\n} from \"../ops.js\";\n\nimport { TestClientLogger, createClientsAtInitialState } from \"./testClientLogger.js\";\n\nconst ClientIds = [\"A\", \"B\", \"C\", \"D\"] as const;\ntype ClientName = (typeof ClientIds)[number];\n\nexport class ReconnectTestHelper {\n\tclients = createClientsAtInitialState(\n\t\t{\n\t\t\tinitialState: \"\",\n\t\t\toptions: { mergeTreeEnableObliterate: true, mergeTreeEnableObliterateReconnect: true },\n\t\t},\n\t\t...ClientIds,\n\t);\n\n\tidxFromName(name: ClientName): number {\n\t\treturn (name.codePointAt(0) ?? 0) - (\"A\".codePointAt(0) ?? 0);\n\t}\n\n\tlogger = new TestClientLogger(this.clients.all);\n\n\tops: ISequencedDocumentMessage[] = [];\n\tperClientOps: ISequencedDocumentMessage[][] = this.clients.all.map(() => []);\n\n\tseq: number = 0;\n\n\tpublic insertText(clientName: ClientName, pos: number, text: string): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.insertTextLocal(pos, text), ++this.seq));\n\t}\n\n\tpublic removeRange(clientName: ClientName, start: number, end: number): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.removeRangeLocal(start, end), ++this.seq));\n\t}\n\n\tpublic obliterateRange(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tthis.ops.push(\n\t\t\tclient.makeOpMessage(client.obliterateRangeLocal(startPos, endPos), ++this.seq),\n\t\t);\n\t}\n\n\tpublic insertTextLocal(\n\t\tclientName: ClientName,\n\t\tpos: number,\n\t\ttext: string,\n\t): {\n\t\top: IMergeTreeInsertMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.insertTextLocal(pos, text);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic removeRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: number,\n\t\tend: number,\n\t): {\n\t\top: IMergeTreeRemoveMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tconst op = client.removeRangeLocal(start, end);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic obliterateRangeLocal(\n\t\tclientName: ClientName,\n\t\tstart: SequencePlace,\n\t\tend: SequencePlace,\n\t): {\n\t\top: IMergeTreeObliterateMsg;\n\t\tseg: SegmentGroup;\n\t\trefSeq: number;\n\t} {\n\t\tconst client = this.clients[clientName];\n\t\tlet { startPos, endPos } = endpointPosAndSide(start, end);\n\t\tassert(\n\t\t\tstartPos !== undefined && endPos !== undefined,\n\t\t\t\"start and end positions must be defined\",\n\t\t);\n\t\tstartPos = startPos === \"start\" ? 0 : startPos;\n\t\tendPos = endPos === \"end\" ? client.getLength() : endPos;\n\t\tassert(\n\t\t\tstartPos !== \"end\" && endPos !== \"start\",\n\t\t\t\"start cannot be end and end cannot be start\",\n\t\t);\n\t\tconst op = client.obliterateRangeLocal(startPos, endPos);\n\t\tassert(op);\n\t\tconst seg = client.peekPendingSegmentGroups();\n\t\tassert(seg);\n\t\treturn { op, seg, refSeq: client.getCollabWindow().currentSeq };\n\t}\n\n\tpublic disconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const [i, c] of this.clients.all.entries()) {\n\t\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\t\tthis.perClientOps[i].push(op);\n\t\t\t\t} else {\n\t\t\t\t\tc.applyMsg(op);\n\t\t\t\t}\n\t\t\t}\n\t}\n\n\tpublic processAllOps(): void {\n\t\tfor (const op of this.ops.splice(0))\n\t\t\tfor (const c of this.clients.all) {\n\t\t\t\tc.applyMsg(op);\n\t\t\t}\n\t}\n\n\tpublic reconnect(clientNames: ClientName[]): void {\n\t\tconst clientIdxs = new Set(clientNames.map((element) => this.idxFromName(element)));\n\t\tfor (const [i, clientOps] of this.perClientOps.entries()) {\n\t\t\tif (clientIdxs.has(i)) {\n\t\t\t\tfor (const op of clientOps.splice(0)) this.clients.all[i].applyMsg(op);\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic submitDisconnectedOp(\n\t\tclientName: ClientName,\n\t\top: { op: IMergeTreeDeltaOp; seg: SegmentGroup | SegmentGroup[] },\n\t): void {\n\t\tconst client = this.clients[clientName];\n\t\tthis.ops.push(client.makeOpMessage(client.regeneratePendingOp(op.op, op.seg), ++this.seq));\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"testClientLogger.d.ts","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAehD,OAAO,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAGhE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAmC7C,KAAK,SAAS,CAAC,WAAW,SAAS,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC,CAAC;AAEtF,wBAAgB,2BAA2B,CAC1C,QAAQ,SAAS,SAAS,CAAC,WAAW,CAAC,EACvC,WAAW,SAAS,MAAM,GAAG,MAAM,GAAG,MAAM,QAAQ,EAEpD,IAAI,EAAE;IACL,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,iBAAiB,GAAG,WAAW,CAAC;CAC1C,EACD,GAAG,SAAS,EAAE,WAAW,EAAE,GACzB,MAAM,CAAC,MAAM,QAAQ,EAAE,UAAU,CAAC,GAAG;IAAE,GAAG,EAAE,UAAU,EAAE,CAAA;CAAE,CAuB5D;AACD,qBAAa,gBAAgB;IA0C3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;WA1CV,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM;IAiB9D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAkB;IAEhD,OAAO,CAAC,SAAS,CAAgB;IACjC,OAAO,CAAC,SAAS,CAAgB;IAEjC,OAAO,CAAC,aAAa,CAAoC;IAEzD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsB;IAEvD;;;OAGG;IACI,OAAO,IAAI,IAAI;gBAQJ,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,KAAK,CAAC,oBAAQ;IA4DhC,OAAO,CAAC,aAAa;IA+Bd,QAAQ,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,MAAM;IA+DV,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhE,QAAQ,CAAC,aAAa,GAAE,OAAe,GAAG,MAAM;IAuBhD,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK;IASxC,OAAO,CAAC,MAAM,CAAC,YAAY;CAkD3B"}
|
|
@@ -26,8 +26,8 @@ function getOpString(msg) {
|
|
|
26
26
|
? ""
|
|
27
27
|
: // eslint-disable-next-line @typescript-eslint/dot-notation
|
|
28
28
|
`@${op["pos1"]}${op["pos2"] === undefined ? "" : `,${op["pos2"]}`}`;
|
|
29
|
-
const seq = msg.sequenceNumber < 0 ? "L" :
|
|
30
|
-
const ref =
|
|
29
|
+
const seq = msg.sequenceNumber < 0 ? "L" : msg.sequenceNumber.toString();
|
|
30
|
+
const ref = msg.referenceSequenceNumber.toString();
|
|
31
31
|
const client = msg.clientId;
|
|
32
32
|
return `${seq}:${ref}:${client}${opType}${opPos}`;
|
|
33
33
|
}
|
|
@@ -174,7 +174,7 @@ class TestClientLogger {
|
|
|
174
174
|
}
|
|
175
175
|
let pos = 0;
|
|
176
176
|
(0, mergeTreeNodeWalk_js_1.depthFirstNodeWalk)(c.mergeTree.root, c.mergeTree.root.children[0], undefined, (seg) => {
|
|
177
|
-
if ((
|
|
177
|
+
if (toMoveOrRemove(seg) === undefined) {
|
|
178
178
|
const segProps = seg.properties;
|
|
179
179
|
for (let i = 0; i < seg.cachedLength; i++) {
|
|
180
180
|
if (!matchPropertiesHandleEmpty(segProps, properties[pos + i])) {
|
|
@@ -209,7 +209,7 @@ class TestClientLogger {
|
|
|
209
209
|
`${this.clients[0].getCollabWindow().minSeq}: msn/offset\n` +
|
|
210
210
|
`Op format <seq>:<ref>:<client><type>@<pos1>,<pos2>\n` +
|
|
211
211
|
`sequence number represented as offset from msn. L means local.\n` +
|
|
212
|
-
`op types: 0) insert 1) remove 2) annotate\n`;
|
|
212
|
+
`op types: 0) insert 1) remove 2) annotate 4) obliterate\n`;
|
|
213
213
|
if (this.title) {
|
|
214
214
|
str += `${this.title}\n`;
|
|
215
215
|
}
|
|
@@ -245,7 +245,7 @@ class TestClientLogger {
|
|
|
245
245
|
}
|
|
246
246
|
const text = textSegment_js_1.TextSegment.is(node) ? node.text : mergeTreeNodes_js_1.Marker.is(node) ? "¶" : undefined;
|
|
247
247
|
if (text !== undefined) {
|
|
248
|
-
const removedNode = (
|
|
248
|
+
const removedNode = toMoveOrRemove(node);
|
|
249
249
|
if (removedNode === undefined) {
|
|
250
250
|
if (node.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
251
251
|
acked += "_".repeat(text.length);
|
|
@@ -257,7 +257,7 @@ class TestClientLogger {
|
|
|
257
257
|
}
|
|
258
258
|
}
|
|
259
259
|
else {
|
|
260
|
-
if (removedNode.
|
|
260
|
+
if (removedNode.seq === constants_js_1.UnassignedSequenceNumber) {
|
|
261
261
|
acked += "_".repeat(text.length);
|
|
262
262
|
local +=
|
|
263
263
|
node.seq === constants_js_1.UnassignedSequenceNumber
|
|
@@ -265,7 +265,7 @@ class TestClientLogger {
|
|
|
265
265
|
: "-".repeat(text.length);
|
|
266
266
|
}
|
|
267
267
|
else {
|
|
268
|
-
const removedSymbol = (0, mergeTreeNodes_js_1.seqLTE)(removedNode.
|
|
268
|
+
const removedSymbol = (0, mergeTreeNodes_js_1.seqLTE)(removedNode.seq, client.getCollabWindow().minSeq)
|
|
269
269
|
? "~"
|
|
270
270
|
: "-";
|
|
271
271
|
acked += removedSymbol.repeat(text.length);
|
|
@@ -283,4 +283,14 @@ class TestClientLogger {
|
|
|
283
283
|
}
|
|
284
284
|
}
|
|
285
285
|
exports.TestClientLogger = TestClientLogger;
|
|
286
|
+
function toMoveOrRemove(segment) {
|
|
287
|
+
const mi = (0, mergeTreeNodes_js_1.toMoveInfo)(segment);
|
|
288
|
+
const ri = (0, mergeTreeNodes_js_1.toRemovalInfo)(segment);
|
|
289
|
+
if (mi !== undefined || ri !== undefined) {
|
|
290
|
+
return {
|
|
291
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
292
|
+
seq: mi?.movedSeq ?? ri?.removedSeq,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
286
296
|
//# sourceMappingURL=testClientLogger.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testClientLogger.js","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\tMergeTreeMaintenanceType,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"../mergeTreeNodeWalk.js\";\nimport { Marker, seqLTE, toRemovalInfo } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp } from \"../ops.js\";\nimport { PropertySet, matchProperties } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\nfunction getOpString(msg: ISequencedDocumentMessage | undefined): string {\n\tif (msg === undefined) {\n\t\treturn \"\";\n\t}\n\tconst op = msg.contents as IMergeTreeOp;\n\tconst opType = op.type.toString();\n\tconst opPos =\n\t\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\t\top?.[\"pos1\"] === undefined\n\t\t\t? \"\"\n\t\t\t: // eslint-disable-next-line @typescript-eslint/dot-notation\n\t\t\t\t`@${op[\"pos1\"]}${op[\"pos2\"] === undefined ? \"\" : `,${op[\"pos2\"]}`}`;\n\n\tconst seq =\n\t\tmsg.sequenceNumber < 0 ? \"L\" : (msg.sequenceNumber - msg.minimumSequenceNumber).toString();\n\tconst ref = (msg.referenceSequenceNumber - msg.minimumSequenceNumber).toString();\n\tconst client = msg.clientId;\n\treturn `${seq}:${ref}:${client}${opType}${opPos}`;\n}\n\nfunction arePropsEmpty(props: PropertySet | undefined): boolean {\n\treturn props === undefined || Object.entries(props).length === 0;\n}\n\n/**\n * Compare properties, allowing empty to match undefined\n */\nfunction matchPropertiesHandleEmpty(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\treturn matchProperties(a, b) || (arePropsEmpty(a) && arePropsEmpty(b));\n}\n\ntype ClientMap<TClientName extends string> = Partial<Record<TClientName, TestClient>>;\n\nexport function createClientsAtInitialState<\n\tTClients extends ClientMap<TClientName>,\n\tTClientName extends string = string & keyof TClients,\n>(\n\topts: {\n\t\tinitialState: string;\n\t\toptions?: IMergeTreeOptions & PropertySet;\n\t},\n\t...clientIds: TClientName[]\n): Record<keyof TClients, TestClient> & { all: TestClient[] } {\n\tconst setup = (c: TestClient): void => {\n\t\tif (opts.initialState.length > 0) {\n\t\t\tc.insertTextLocal(0, opts.initialState);\n\t\t\twhile (c.getText().includes(\"-\")) {\n\t\t\t\tconst index = c.getText().indexOf(\"-\");\n\t\t\t\tc.removeRangeLocal(index, index + 1);\n\t\t\t}\n\t\t}\n\t};\n\tconst all: TestClient[] = [];\n\tconst clients: Partial<Record<keyof TClients, TestClient>> = {};\n\tfor (const id of clientIds) {\n\t\tif (clients[id] === undefined) {\n\t\t\tconst client = new TestClient(opts.options);\n\t\t\tclients[id] = client;\n\t\t\tall.push(client);\n\t\t\tsetup(client);\n\t\t\tclient.startOrUpdateCollaboration(id);\n\t\t}\n\t}\n\n\treturn { ...(clients as Record<keyof TClients, TestClient>), all };\n}\nexport class TestClientLogger {\n\tpublic static toString(clients: readonly TestClient[]): string {\n\t\treturn (\n\t\t\tclients\n\t\t\t\t.map((c) => this.getSegString(c))\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-reduce\n\t\t\t\t.reduce<[string, string]>(\n\t\t\t\t\t(pv, cv) => {\n\t\t\t\t\t\tpv[0] += `|${cv.acked.padEnd(cv.local.length, \"\")}`;\n\t\t\t\t\t\tpv[1] += `|${cv.local.padEnd(cv.acked.length, \"\")}`;\n\t\t\t\t\t\treturn pv;\n\t\t\t\t\t},\n\t\t\t\t\t[\"\", \"\"],\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\")\n\t\t);\n\t}\n\n\tprivate readonly incrementalLog = false;\n\n\tprivate readonly paddings: number[] = [];\n\tprivate readonly roundLogLines: string[][] = [];\n\n\tprivate ackedLine: string[] = [];\n\tprivate localLine: string[] = [];\n\t// initialize to private instance, so first real edit will create a new line\n\tprivate lastDeltaArgs: IMergeTreeDeltaOpArgs | undefined;\n\n\tprivate readonly disposeCallbacks: (() => void)[] = [];\n\n\t/**\n\t * Unsubscribes this logger from its clients' events. Consider using this for tests with client lifetime\n\t * extending significantly past the logger's.\n\t */\n\tpublic dispose(): void {\n\t\tfor (const cb of this.disposeCallbacks) {\n\t\t\tcb();\n\t\t}\n\t\tthis.disposeCallbacks.length = 0;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clients: readonly TestClient[],\n\t\tprivate readonly title?: string,\n\t) {\n\t\tconst logHeaders: string[] = [];\n\t\tfor (const [i, c] of clients.entries()) {\n\t\t\tlogHeaders.push(\"op\", `client ${c.longClientId}`);\n\t\t\tconst callback = (deltaArgs: IMergeTreeDeltaOpArgs | undefined): void => {\n\t\t\t\tif (\n\t\t\t\t\tthis.lastDeltaArgs?.sequencedMessage !== deltaArgs?.sequencedMessage ||\n\t\t\t\t\tthis.lastDeltaArgs?.op !== deltaArgs?.op\n\t\t\t\t) {\n\t\t\t\t\tthis.addNewLogLine();\n\t\t\t\t\tthis.lastDeltaArgs = deltaArgs;\n\t\t\t\t}\n\t\t\t\tconst clientLogIndex = i * 2;\n\n\t\t\t\tthis.ackedLine[clientLogIndex] =\n\t\t\t\t\tdeltaArgs === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: getOpString(\n\t\t\t\t\t\t\t\tdeltaArgs.sequencedMessage === undefined\n\t\t\t\t\t\t\t\t\t? c.makeOpMessage(deltaArgs.op)\n\t\t\t\t\t\t\t\t\t: { ...deltaArgs.sequencedMessage, contents: deltaArgs.op },\n\t\t\t\t\t\t\t);\n\t\t\t\tconst segStrings = TestClientLogger.getSegString(c);\n\t\t\t\tthis.ackedLine[clientLogIndex + 1] = segStrings.acked;\n\t\t\t\tthis.localLine[clientLogIndex + 1] = segStrings.local;\n\n\t\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t\t);\n\n\t\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tconst maintenanceCallback = (\n\t\t\t\tmain: IMergeTreeMaintenanceCallbackArgs,\n\t\t\t\top: IMergeTreeDeltaOpArgs | undefined,\n\t\t\t): void => {\n\t\t\t\tif (main.operation === MergeTreeMaintenanceType.ACKNOWLEDGED) {\n\t\t\t\t\tcallback(op);\n\t\t\t\t}\n\t\t\t};\n\t\t\tc.on(\"delta\", callback);\n\t\t\tc.on(\"maintenance\", maintenanceCallback);\n\t\t\tthis.disposeCallbacks.push(() => {\n\t\t\t\tc.off(\"delta\", callback);\n\t\t\t\tc.off(\"maintenance\", maintenanceCallback);\n\t\t\t});\n\t\t}\n\t\tthis.roundLogLines.push(logHeaders);\n\t\tfor (const v of this.roundLogLines[0]) this.paddings.push(v.length);\n\t\tthis.addNewLogLine(); // capture initial state\n\t}\n\n\tprivate addNewLogLine(): void {\n\t\tif (this.incrementalLog) {\n\t\t\twhile (this.roundLogLines.length > 0) {\n\t\t\t\tconst logLine = this.roundLogLines.shift();\n\t\t\t\tif (logLine?.some((c) => c.trim().length > 0)) {\n\t\t\t\t\tconsole.log(logLine.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.ackedLine = [];\n\t\tthis.localLine = [];\n\t\tfor (const [clientLogIndex, cc] of this.clients.entries()) {\n\t\t\tconst segStrings = TestClientLogger.getSegString(cc);\n\t\t\tthis.ackedLine.push(\"\", segStrings.acked);\n\t\t\tthis.localLine.push(\"\", segStrings.local);\n\n\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t);\n\n\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t);\n\t\t}\n\t\tthis.roundLogLines.push(this.ackedLine, this.localLine);\n\t}\n\n\tpublic validate(opts?: {\n\t\tclear?: boolean;\n\t\tbaseText?: string;\n\t\terrorPrefix?: string;\n\t}): string {\n\t\tconst baseText = opts?.baseText ?? this.clients[0].getText();\n\t\tconst errorPrefix = opts?.errorPrefix ? `${opts?.errorPrefix}: ` : \"\";\n\t\t// cache all the properties of client 0 for faster look up\n\t\tconst properties = Array.from({ length: this.clients[0].getLength() }).map((_, i) =>\n\t\t\tthis.clients[0].getPropertiesAtPosition(i),\n\t\t);\n\t\tfor (const c of this.clients) {\n\t\t\tif (opts?.baseText === undefined && c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// ensure all clients have seen the same ops\n\t\t\tassert.equal(\n\t\t\t\tc.getCurrentSeq(),\n\t\t\t\tthis.clients[0].getCurrentSeq(),\n\t\t\t\t`${errorPrefix}${c.longClientId} current seq does not match client ${this.clients[0].longClientId}`,\n\t\t\t);\n\t\t\t// Pre-check to avoid this.toString() in the string template\n\t\t\tif (c.getText() !== baseText) {\n\t\t\t\tassert.equal(\n\t\t\t\t\tc.getText(),\n\t\t\t\t\tbaseText,\n\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t} does not match client ${\n\t\t\t\t\t\topts?.baseText ? \"baseText\" : this.clients[0].longClientId\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet pos = 0;\n\t\t\tdepthFirstNodeWalk(c.mergeTree.root, c.mergeTree.root.children[0], undefined, (seg) => {\n\t\t\t\tif (toRemovalInfo(seg) === undefined) {\n\t\t\t\t\tconst segProps = seg.properties;\n\t\t\t\t\tfor (let i = 0; i < seg.cachedLength; i++) {\n\t\t\t\t\t\tif (!matchPropertiesHandleEmpty(segProps, properties[pos + i])) {\n\t\t\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\t\t\tsegProps,\n\t\t\t\t\t\t\t\tproperties[pos + i],\n\t\t\t\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t\t\t\t} does not match client ${this.clients[0].longClientId} properties at pos ${\n\t\t\t\t\t\t\t\t\tpos + i\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpos += seg.cachedLength;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (opts?.clear === true) {\n\t\t\tthis.roundLogLines.splice(1, this.roundLogLines.length);\n\t\t\tfor (const [i, v] of this.roundLogLines[0].entries()) this.paddings[i] = v.length;\n\t\t\tthis.addNewLogLine(); // capture initial state\n\t\t}\n\t\treturn baseText;\n\t}\n\n\tstatic validate(clients: readonly TestClient[], title?: string): string {\n\t\tconst logger = new TestClientLogger(clients, title);\n\t\tconst result = logger.validate();\n\t\tlogger.dispose();\n\t\treturn result;\n\t}\n\n\tpublic toString(excludeHeader: boolean = false): string {\n\t\tlet str = \"\";\n\t\tif (!excludeHeader) {\n\t\t\tstr +=\n\t\t\t\t`_: Local State\\n` +\n\t\t\t\t`-: Deleted ~:Deleted <= MinSeq\\n` +\n\t\t\t\t`*: Unacked Insert and Delete\\n` +\n\t\t\t\t`${this.clients[0].getCollabWindow().minSeq}: msn/offset\\n` +\n\t\t\t\t`Op format <seq>:<ref>:<client><type>@<pos1>,<pos2>\\n` +\n\t\t\t\t`sequence number represented as offset from msn. L means local.\\n` +\n\t\t\t\t`op types: 0) insert 1) remove 2) annotate\\n`;\n\n\t\t\tif (this.title) {\n\t\t\t\tstr += `${this.title}\\n`;\n\t\t\t}\n\t\t}\n\t\tstr += this.roundLogLines\n\t\t\t.filter((line) => line.some((c) => c.trim().length > 0))\n\t\t\t.map((line) => line.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"))\n\t\t\t.join(\"\\n\");\n\t\treturn str;\n\t}\n\n\tpublic addLogsToError(e: unknown): Error {\n\t\tif (e instanceof Error) {\n\t\t\te.message += `\\n${this.toString()}`;\n\t\t\treturn e;\n\t\t}\n\n\t\treturn new LoggingError(`${e}\\n${this.toString()}`);\n\t}\n\n\tprivate static getSegString(client: TestClient): { acked: string; local: string } {\n\t\tlet acked: string = \"\";\n\t\tlet local: string = \"\";\n\t\tconst nodes = [...client.mergeTree.root.children];\n\t\tlet parent = nodes[0]?.parent;\n\t\twhile (nodes.length > 0) {\n\t\t\tconst node = nodes.shift();\n\t\t\tif (node) {\n\t\t\t\tif (node.isLeaf()) {\n\t\t\t\t\tif (node.parent !== parent) {\n\t\t\t\t\t\tif (acked.length > 0) {\n\t\t\t\t\t\t\tacked += \" \";\n\t\t\t\t\t\t\tlocal += \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent = node.parent;\n\t\t\t\t\t}\n\t\t\t\t\tconst text = TextSegment.is(node) ? node.text : Marker.is(node) ? \"¶\" : undefined;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\tconst removedNode = toRemovalInfo(node);\n\t\t\t\t\t\tif (removedNode === undefined) {\n\t\t\t\t\t\t\tif (node.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += text;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tacked += text;\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (removedNode.removedSeq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal +=\n\t\t\t\t\t\t\t\t\tnode.seq === UnassignedSequenceNumber\n\t\t\t\t\t\t\t\t\t\t? \"*\".repeat(text.length)\n\t\t\t\t\t\t\t\t\t\t: \"-\".repeat(text.length);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst removedSymbol = seqLTE(\n\t\t\t\t\t\t\t\t\tremovedNode.removedSeq,\n\t\t\t\t\t\t\t\t\tclient.getCollabWindow().minSeq,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t? \"~\"\n\t\t\t\t\t\t\t\t\t: \"-\";\n\t\t\t\t\t\t\t\tacked += removedSymbol.repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnodes.push(...node.children);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn { acked, local };\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"testClientLogger.js","sourceRoot":"","sources":["../../src/test/testClientLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport { LoggingError } from \"@fluidframework/telemetry-utils/internal\";\n\nimport { UnassignedSequenceNumber } from \"../constants.js\";\nimport { IMergeTreeOptions } from \"../index.js\";\nimport {\n\tIMergeTreeDeltaOpArgs,\n\tMergeTreeMaintenanceType,\n\ttype IMergeTreeMaintenanceCallbackArgs,\n} from \"../mergeTreeDeltaCallback.js\";\nimport { depthFirstNodeWalk } from \"../mergeTreeNodeWalk.js\";\nimport {\n\tMarker,\n\tseqLTE,\n\ttoMoveInfo,\n\ttoRemovalInfo,\n\ttype ISegment,\n} from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp } from \"../ops.js\";\nimport { PropertySet, matchProperties } from \"../properties.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\nfunction getOpString(msg: ISequencedDocumentMessage | undefined): string {\n\tif (msg === undefined) {\n\t\treturn \"\";\n\t}\n\tconst op = msg.contents as IMergeTreeOp;\n\tconst opType = op.type.toString();\n\tconst opPos =\n\t\t// eslint-disable-next-line @typescript-eslint/dot-notation\n\t\top?.[\"pos1\"] === undefined\n\t\t\t? \"\"\n\t\t\t: // eslint-disable-next-line @typescript-eslint/dot-notation\n\t\t\t\t`@${op[\"pos1\"]}${op[\"pos2\"] === undefined ? \"\" : `,${op[\"pos2\"]}`}`;\n\n\tconst seq = msg.sequenceNumber < 0 ? \"L\" : msg.sequenceNumber.toString();\n\tconst ref = msg.referenceSequenceNumber.toString();\n\tconst client = msg.clientId;\n\treturn `${seq}:${ref}:${client}${opType}${opPos}`;\n}\n\nfunction arePropsEmpty(props: PropertySet | undefined): boolean {\n\treturn props === undefined || Object.entries(props).length === 0;\n}\n\n/**\n * Compare properties, allowing empty to match undefined\n */\nfunction matchPropertiesHandleEmpty(\n\ta: PropertySet | undefined,\n\tb: PropertySet | undefined,\n): boolean {\n\treturn matchProperties(a, b) || (arePropsEmpty(a) && arePropsEmpty(b));\n}\n\ntype ClientMap<TClientName extends string> = Partial<Record<TClientName, TestClient>>;\n\nexport function createClientsAtInitialState<\n\tTClients extends ClientMap<TClientName>,\n\tTClientName extends string = string & keyof TClients,\n>(\n\topts: {\n\t\tinitialState: string;\n\t\toptions?: IMergeTreeOptions & PropertySet;\n\t},\n\t...clientIds: TClientName[]\n): Record<keyof TClients, TestClient> & { all: TestClient[] } {\n\tconst setup = (c: TestClient): void => {\n\t\tif (opts.initialState.length > 0) {\n\t\t\tc.insertTextLocal(0, opts.initialState);\n\t\t\twhile (c.getText().includes(\"-\")) {\n\t\t\t\tconst index = c.getText().indexOf(\"-\");\n\t\t\t\tc.removeRangeLocal(index, index + 1);\n\t\t\t}\n\t\t}\n\t};\n\tconst all: TestClient[] = [];\n\tconst clients: Partial<Record<keyof TClients, TestClient>> = {};\n\tfor (const id of clientIds) {\n\t\tif (clients[id] === undefined) {\n\t\t\tconst client = new TestClient(opts.options);\n\t\t\tclients[id] = client;\n\t\t\tall.push(client);\n\t\t\tsetup(client);\n\t\t\tclient.startOrUpdateCollaboration(id);\n\t\t}\n\t}\n\n\treturn { ...(clients as Record<keyof TClients, TestClient>), all };\n}\nexport class TestClientLogger {\n\tpublic static toString(clients: readonly TestClient[]): string {\n\t\treturn (\n\t\t\tclients\n\t\t\t\t.map((c) => this.getSegString(c))\n\t\t\t\t// eslint-disable-next-line unicorn/no-array-reduce\n\t\t\t\t.reduce<[string, string]>(\n\t\t\t\t\t(pv, cv) => {\n\t\t\t\t\t\tpv[0] += `|${cv.acked.padEnd(cv.local.length, \"\")}`;\n\t\t\t\t\t\tpv[1] += `|${cv.local.padEnd(cv.acked.length, \"\")}`;\n\t\t\t\t\t\treturn pv;\n\t\t\t\t\t},\n\t\t\t\t\t[\"\", \"\"],\n\t\t\t\t)\n\t\t\t\t.join(\"\\n\")\n\t\t);\n\t}\n\n\tprivate readonly incrementalLog = false;\n\n\tprivate readonly paddings: number[] = [];\n\tprivate readonly roundLogLines: string[][] = [];\n\n\tprivate ackedLine: string[] = [];\n\tprivate localLine: string[] = [];\n\t// initialize to private instance, so first real edit will create a new line\n\tprivate lastDeltaArgs: IMergeTreeDeltaOpArgs | undefined;\n\n\tprivate readonly disposeCallbacks: (() => void)[] = [];\n\n\t/**\n\t * Unsubscribes this logger from its clients' events. Consider using this for tests with client lifetime\n\t * extending significantly past the logger's.\n\t */\n\tpublic dispose(): void {\n\t\tfor (const cb of this.disposeCallbacks) {\n\t\t\tcb();\n\t\t}\n\t\tthis.disposeCallbacks.length = 0;\n\t}\n\n\tconstructor(\n\t\tprivate readonly clients: readonly TestClient[],\n\t\tprivate readonly title?: string,\n\t) {\n\t\tconst logHeaders: string[] = [];\n\t\tfor (const [i, c] of clients.entries()) {\n\t\t\tlogHeaders.push(\"op\", `client ${c.longClientId}`);\n\t\t\tconst callback = (deltaArgs: IMergeTreeDeltaOpArgs | undefined): void => {\n\t\t\t\tif (\n\t\t\t\t\tthis.lastDeltaArgs?.sequencedMessage !== deltaArgs?.sequencedMessage ||\n\t\t\t\t\tthis.lastDeltaArgs?.op !== deltaArgs?.op\n\t\t\t\t) {\n\t\t\t\t\tthis.addNewLogLine();\n\t\t\t\t\tthis.lastDeltaArgs = deltaArgs;\n\t\t\t\t}\n\t\t\t\tconst clientLogIndex = i * 2;\n\n\t\t\t\tthis.ackedLine[clientLogIndex] =\n\t\t\t\t\tdeltaArgs === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: getOpString(\n\t\t\t\t\t\t\t\tdeltaArgs.sequencedMessage === undefined\n\t\t\t\t\t\t\t\t\t? c.makeOpMessage(deltaArgs.op)\n\t\t\t\t\t\t\t\t\t: { ...deltaArgs.sequencedMessage, contents: deltaArgs.op },\n\t\t\t\t\t\t\t);\n\t\t\t\tconst segStrings = TestClientLogger.getSegString(c);\n\t\t\t\tthis.ackedLine[clientLogIndex + 1] = segStrings.acked;\n\t\t\t\tthis.localLine[clientLogIndex + 1] = segStrings.local;\n\n\t\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t\t);\n\n\t\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t\t);\n\t\t\t};\n\n\t\t\tconst maintenanceCallback = (\n\t\t\t\tmain: IMergeTreeMaintenanceCallbackArgs,\n\t\t\t\top: IMergeTreeDeltaOpArgs | undefined,\n\t\t\t): void => {\n\t\t\t\tif (main.operation === MergeTreeMaintenanceType.ACKNOWLEDGED) {\n\t\t\t\t\tcallback(op);\n\t\t\t\t}\n\t\t\t};\n\t\t\tc.on(\"delta\", callback);\n\t\t\tc.on(\"maintenance\", maintenanceCallback);\n\t\t\tthis.disposeCallbacks.push(() => {\n\t\t\t\tc.off(\"delta\", callback);\n\t\t\t\tc.off(\"maintenance\", maintenanceCallback);\n\t\t\t});\n\t\t}\n\t\tthis.roundLogLines.push(logHeaders);\n\t\tfor (const v of this.roundLogLines[0]) this.paddings.push(v.length);\n\t\tthis.addNewLogLine(); // capture initial state\n\t}\n\n\tprivate addNewLogLine(): void {\n\t\tif (this.incrementalLog) {\n\t\t\twhile (this.roundLogLines.length > 0) {\n\t\t\t\tconst logLine = this.roundLogLines.shift();\n\t\t\t\tif (logLine?.some((c) => c.trim().length > 0)) {\n\t\t\t\t\tconsole.log(logLine.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.ackedLine = [];\n\t\tthis.localLine = [];\n\t\tfor (const [clientLogIndex, cc] of this.clients.entries()) {\n\t\t\tconst segStrings = TestClientLogger.getSegString(cc);\n\t\t\tthis.ackedLine.push(\"\", segStrings.acked);\n\t\t\tthis.localLine.push(\"\", segStrings.local);\n\n\t\t\tthis.paddings[clientLogIndex] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex].length,\n\t\t\t\tthis.localLine[clientLogIndex].length,\n\t\t\t\tthis.paddings[clientLogIndex],\n\t\t\t);\n\n\t\t\tthis.paddings[clientLogIndex + 1] = Math.max(\n\t\t\t\tthis.ackedLine[clientLogIndex + 1].length,\n\t\t\t\tthis.localLine[clientLogIndex + 1].length,\n\t\t\t\tthis.paddings[clientLogIndex + 1],\n\t\t\t);\n\t\t}\n\t\tthis.roundLogLines.push(this.ackedLine, this.localLine);\n\t}\n\n\tpublic validate(opts?: {\n\t\tclear?: boolean;\n\t\tbaseText?: string;\n\t\terrorPrefix?: string;\n\t}): string {\n\t\tconst baseText = opts?.baseText ?? this.clients[0].getText();\n\t\tconst errorPrefix = opts?.errorPrefix ? `${opts?.errorPrefix}: ` : \"\";\n\t\t// cache all the properties of client 0 for faster look up\n\t\tconst properties = Array.from({ length: this.clients[0].getLength() }).map((_, i) =>\n\t\t\tthis.clients[0].getPropertiesAtPosition(i),\n\t\t);\n\t\tfor (const c of this.clients) {\n\t\t\tif (opts?.baseText === undefined && c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// ensure all clients have seen the same ops\n\t\t\tassert.equal(\n\t\t\t\tc.getCurrentSeq(),\n\t\t\t\tthis.clients[0].getCurrentSeq(),\n\t\t\t\t`${errorPrefix}${c.longClientId} current seq does not match client ${this.clients[0].longClientId}`,\n\t\t\t);\n\t\t\t// Pre-check to avoid this.toString() in the string template\n\t\t\tif (c.getText() !== baseText) {\n\t\t\t\tassert.equal(\n\t\t\t\t\tc.getText(),\n\t\t\t\t\tbaseText,\n\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t} does not match client ${\n\t\t\t\t\t\topts?.baseText ? \"baseText\" : this.clients[0].longClientId\n\t\t\t\t\t}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif (c === this.clients[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tlet pos = 0;\n\t\t\tdepthFirstNodeWalk(c.mergeTree.root, c.mergeTree.root.children[0], undefined, (seg) => {\n\t\t\t\tif (toMoveOrRemove(seg) === undefined) {\n\t\t\t\t\tconst segProps = seg.properties;\n\t\t\t\t\tfor (let i = 0; i < seg.cachedLength; i++) {\n\t\t\t\t\t\tif (!matchPropertiesHandleEmpty(segProps, properties[pos + i])) {\n\t\t\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\t\t\tsegProps,\n\t\t\t\t\t\t\t\tproperties[pos + i],\n\t\t\t\t\t\t\t\t`${errorPrefix}\\n${this.toString()}\\nClient ${\n\t\t\t\t\t\t\t\t\tc.longClientId\n\t\t\t\t\t\t\t\t} does not match client ${this.clients[0].longClientId} properties at pos ${\n\t\t\t\t\t\t\t\t\tpos + i\n\t\t\t\t\t\t\t\t}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpos += seg.cachedLength;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (opts?.clear === true) {\n\t\t\tthis.roundLogLines.splice(1, this.roundLogLines.length);\n\t\t\tfor (const [i, v] of this.roundLogLines[0].entries()) this.paddings[i] = v.length;\n\t\t\tthis.addNewLogLine(); // capture initial state\n\t\t}\n\t\treturn baseText;\n\t}\n\n\tstatic validate(clients: readonly TestClient[], title?: string): string {\n\t\tconst logger = new TestClientLogger(clients, title);\n\t\tconst result = logger.validate();\n\t\tlogger.dispose();\n\t\treturn result;\n\t}\n\n\tpublic toString(excludeHeader: boolean = false): string {\n\t\tlet str = \"\";\n\t\tif (!excludeHeader) {\n\t\t\tstr +=\n\t\t\t\t`_: Local State\\n` +\n\t\t\t\t`-: Deleted ~:Deleted <= MinSeq\\n` +\n\t\t\t\t`*: Unacked Insert and Delete\\n` +\n\t\t\t\t`${this.clients[0].getCollabWindow().minSeq}: msn/offset\\n` +\n\t\t\t\t`Op format <seq>:<ref>:<client><type>@<pos1>,<pos2>\\n` +\n\t\t\t\t`sequence number represented as offset from msn. L means local.\\n` +\n\t\t\t\t`op types: 0) insert 1) remove 2) annotate 4) obliterate\\n`;\n\n\t\t\tif (this.title) {\n\t\t\t\tstr += `${this.title}\\n`;\n\t\t\t}\n\t\t}\n\t\tstr += this.roundLogLines\n\t\t\t.filter((line) => line.some((c) => c.trim().length > 0))\n\t\t\t.map((line) => line.map((v, i) => v.padEnd(this.paddings[i])).join(\" | \"))\n\t\t\t.join(\"\\n\");\n\t\treturn str;\n\t}\n\n\tpublic addLogsToError(e: unknown): Error {\n\t\tif (e instanceof Error) {\n\t\t\te.message += `\\n${this.toString()}`;\n\t\t\treturn e;\n\t\t}\n\n\t\treturn new LoggingError(`${e}\\n${this.toString()}`);\n\t}\n\n\tprivate static getSegString(client: TestClient): { acked: string; local: string } {\n\t\tlet acked: string = \"\";\n\t\tlet local: string = \"\";\n\t\tconst nodes = [...client.mergeTree.root.children];\n\t\tlet parent = nodes[0]?.parent;\n\t\twhile (nodes.length > 0) {\n\t\t\tconst node = nodes.shift();\n\t\t\tif (node) {\n\t\t\t\tif (node.isLeaf()) {\n\t\t\t\t\tif (node.parent !== parent) {\n\t\t\t\t\t\tif (acked.length > 0) {\n\t\t\t\t\t\t\tacked += \" \";\n\t\t\t\t\t\t\tlocal += \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t\tparent = node.parent;\n\t\t\t\t\t}\n\t\t\t\t\tconst text = TextSegment.is(node) ? node.text : Marker.is(node) ? \"¶\" : undefined;\n\t\t\t\t\tif (text !== undefined) {\n\t\t\t\t\t\tconst removedNode = toMoveOrRemove(node);\n\t\t\t\t\t\tif (removedNode === undefined) {\n\t\t\t\t\t\t\tif (node.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += text;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tacked += text;\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (removedNode.seq === UnassignedSequenceNumber) {\n\t\t\t\t\t\t\t\tacked += \"_\".repeat(text.length);\n\t\t\t\t\t\t\t\tlocal +=\n\t\t\t\t\t\t\t\t\tnode.seq === UnassignedSequenceNumber\n\t\t\t\t\t\t\t\t\t\t? \"*\".repeat(text.length)\n\t\t\t\t\t\t\t\t\t\t: \"-\".repeat(text.length);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tconst removedSymbol = seqLTE(removedNode.seq, client.getCollabWindow().minSeq)\n\t\t\t\t\t\t\t\t\t? \"~\"\n\t\t\t\t\t\t\t\t\t: \"-\";\n\t\t\t\t\t\t\t\tacked += removedSymbol.repeat(text.length);\n\t\t\t\t\t\t\t\tlocal += \" \".repeat(text.length);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tnodes.push(...node.children);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn { acked, local };\n\t}\n}\n\nfunction toMoveOrRemove(segment: ISegment): { seq: number } | undefined {\n\tconst mi = toMoveInfo(segment);\n\tconst ri = toRemovalInfo(segment);\n\tif (mi !== undefined || ri !== undefined) {\n\t\treturn {\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain\n\t\t\tseq: mi?.movedSeq ?? ri?.removedSeq!,\n\t\t};\n\t}\n}\n"]}
|
package/dist/zamboni.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zamboni.d.ts","sourceRoot":"","sources":["../src/zamboni.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EACN,KAAK,UAAU,EAQf,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAKpC,wBAAgB,eAAe,CAC9B,SAAS,EAAE,SAAS,EACpB,uBAAuB,SAAqB,GAC1C,IAAI,
|
|
1
|
+
{"version":3,"file":"zamboni.d.ts","sourceRoot":"","sources":["../src/zamboni.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EACN,KAAK,UAAU,EAQf,MAAM,qBAAqB,CAAC;AAG7B,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAKpC,wBAAgB,eAAe,CAC9B,SAAS,EAAE,SAAS,EACpB,uBAAuB,SAAqB,GAC1C,IAAI,CAyCN;AAGD,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAwDzE"}
|
package/dist/zamboni.js
CHANGED
|
@@ -38,7 +38,6 @@ function zamboniSegments(mergeTree, zamboniSegmentsMaxCount = exports.zamboniSeg
|
|
|
38
38
|
block.childCount = newChildCount;
|
|
39
39
|
block.children = childrenCopy;
|
|
40
40
|
for (let j = 0; j < newChildCount; j++) {
|
|
41
|
-
// Non null asserting here since its looping though childrenCopy.length so j at childrenCopy will always exist
|
|
42
41
|
block.assignChild(childrenCopy[j], j, false);
|
|
43
42
|
}
|
|
44
43
|
if (underflow(block) && block.parent) {
|
|
@@ -85,7 +84,6 @@ function packParent(parent, mergeTree) {
|
|
|
85
84
|
}
|
|
86
85
|
const packedBlock = mergeTree.makeBlock(nodeCount);
|
|
87
86
|
for (let packedNodeIndex = 0; packedNodeIndex < nodeCount; packedNodeIndex++) {
|
|
88
|
-
// TODO Non null asserting, why is this not null?
|
|
89
87
|
const nodeToPack = holdNodes[childrenPackedCount++];
|
|
90
88
|
packedBlock.assignChild(nodeToPack, packedNodeIndex, false);
|
|
91
89
|
}
|
|
@@ -95,7 +93,6 @@ function packParent(parent, mergeTree) {
|
|
|
95
93
|
}
|
|
96
94
|
parent.children = packedBlocks;
|
|
97
95
|
for (let j = 0; j < childCount; j++) {
|
|
98
|
-
// TODO Non null asserting, why is this not null?
|
|
99
96
|
parent.assignChild(packedBlocks[j], j, false);
|
|
100
97
|
}
|
|
101
98
|
parent.childCount = childCount;
|
|
@@ -118,7 +115,6 @@ function scourNode(node, holdNodes, mergeTree) {
|
|
|
118
115
|
// when possible.
|
|
119
116
|
let prevSegment;
|
|
120
117
|
for (let k = 0; k < node.childCount; k++) {
|
|
121
|
-
// TODO Non null asserting, why is this not null?
|
|
122
118
|
const childNode = node.children[k];
|
|
123
119
|
if (!childNode.isLeaf() || !childNode.segmentGroups.empty) {
|
|
124
120
|
holdNodes.push(childNode);
|