@fluidframework/merge-tree 2.41.0 → 2.43.0-343119
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/dist/client.d.ts +9 -6
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +79 -36
- package/dist/client.js.map +1 -1
- package/dist/collections/list.d.ts +95 -5
- package/dist/collections/list.d.ts.map +1 -1
- package/dist/collections/list.js +67 -5
- package/dist/collections/list.js.map +1 -1
- package/dist/constants.d.ts +5 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/mergeTree.d.ts +9 -9
- package/dist/mergeTree.d.ts.map +1 -1
- package/dist/mergeTree.js +15 -7
- package/dist/mergeTree.js.map +1 -1
- package/dist/perspective.d.ts +15 -0
- package/dist/perspective.d.ts.map +1 -1
- package/dist/perspective.js +25 -1
- package/dist/perspective.js.map +1 -1
- package/dist/revertibles.js +1 -1
- package/dist/revertibles.js.map +1 -1
- package/dist/stamps.d.ts +1 -0
- package/dist/stamps.d.ts.map +1 -1
- package/dist/stamps.js +5 -1
- package/dist/stamps.js.map +1 -1
- package/dist/test/beastTest.spec.js +1 -1
- package/dist/test/beastTest.spec.js.map +1 -1
- package/dist/test/client.annotateMarker.spec.js +1 -1
- package/dist/test/client.annotateMarker.spec.js.map +1 -1
- package/dist/test/client.applyMsg.spec.js +25 -25
- package/dist/test/client.applyMsg.spec.js.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.d.ts.map +1 -1
- package/dist/test/client.applyStashedOpFarm.spec.js +3 -3
- package/dist/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/dist/test/client.attributionFarm.spec.js +1 -1
- package/dist/test/client.attributionFarm.spec.js.map +1 -1
- package/dist/test/client.getPosition.spec.js +1 -0
- package/dist/test/client.getPosition.spec.js.map +1 -1
- package/dist/test/client.localReference.spec.js +62 -48
- package/dist/test/client.localReference.spec.js.map +1 -1
- package/dist/test/client.localReferenceFarm.spec.js +1 -0
- package/dist/test/client.localReferenceFarm.spec.js.map +1 -1
- package/dist/test/client.reconnectFarm.spec.js +1 -1
- package/dist/test/client.reconnectFarm.spec.js.map +1 -1
- package/dist/test/client.rollback.spec.js +8 -6
- package/dist/test/client.rollback.spec.js.map +1 -1
- package/dist/test/client.searchForMarker.spec.js +2 -2
- package/dist/test/client.searchForMarker.spec.js.map +1 -1
- package/dist/test/clientTestHelper.js +1 -1
- package/dist/test/clientTestHelper.js.map +1 -1
- package/dist/test/mergeTree.annotate.spec.js +25 -25
- package/dist/test/mergeTree.annotate.spec.js.map +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js +1 -1
- package/dist/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/dist/test/obliterate.spec.js +4 -4
- package/dist/test/obliterate.spec.js.map +1 -1
- package/dist/test/resetPendingSegmentsToOp.spec.js +14 -14
- package/dist/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/dist/test/snapshot.utils.js +1 -1
- package/dist/test/snapshot.utils.js.map +1 -1
- package/dist/test/sortedSegmentSet.spec.js +3 -3
- package/dist/test/sortedSegmentSet.spec.js.map +1 -1
- package/dist/test/testClient.js +3 -3
- package/dist/test/testClient.js.map +1 -1
- package/dist/test/tracking.spec.js +7 -7
- package/dist/test/tracking.spec.js.map +1 -1
- package/dist/test/wordUnitTests.spec.js.map +1 -1
- package/lib/client.d.ts +9 -6
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +81 -38
- package/lib/client.js.map +1 -1
- package/lib/collections/list.d.ts +95 -5
- package/lib/collections/list.d.ts.map +1 -1
- package/lib/collections/list.js +67 -5
- package/lib/collections/list.js.map +1 -1
- package/lib/constants.d.ts +5 -0
- package/lib/constants.d.ts.map +1 -1
- package/lib/constants.js +5 -0
- package/lib/constants.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/mergeTree.d.ts +9 -9
- package/lib/mergeTree.d.ts.map +1 -1
- package/lib/mergeTree.js +15 -7
- package/lib/mergeTree.js.map +1 -1
- package/lib/perspective.d.ts +15 -0
- package/lib/perspective.d.ts.map +1 -1
- package/lib/perspective.js +23 -0
- package/lib/perspective.js.map +1 -1
- package/lib/revertibles.js +1 -1
- package/lib/revertibles.js.map +1 -1
- package/lib/stamps.d.ts +1 -0
- package/lib/stamps.d.ts.map +1 -1
- package/lib/stamps.js +4 -1
- package/lib/stamps.js.map +1 -1
- package/lib/test/beastTest.spec.js +1 -1
- package/lib/test/beastTest.spec.js.map +1 -1
- package/lib/test/client.annotateMarker.spec.js +1 -1
- package/lib/test/client.annotateMarker.spec.js.map +1 -1
- package/lib/test/client.applyMsg.spec.js +25 -25
- package/lib/test/client.applyMsg.spec.js.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.d.ts.map +1 -1
- package/lib/test/client.applyStashedOpFarm.spec.js +3 -3
- package/lib/test/client.applyStashedOpFarm.spec.js.map +1 -1
- package/lib/test/client.attributionFarm.spec.js +1 -1
- package/lib/test/client.attributionFarm.spec.js.map +1 -1
- package/lib/test/client.getPosition.spec.js +1 -0
- package/lib/test/client.getPosition.spec.js.map +1 -1
- package/lib/test/client.localReference.spec.js +62 -48
- package/lib/test/client.localReference.spec.js.map +1 -1
- package/lib/test/client.localReferenceFarm.spec.js +1 -0
- package/lib/test/client.localReferenceFarm.spec.js.map +1 -1
- package/lib/test/client.reconnectFarm.spec.js +1 -1
- package/lib/test/client.reconnectFarm.spec.js.map +1 -1
- package/lib/test/client.rollback.spec.js +8 -6
- package/lib/test/client.rollback.spec.js.map +1 -1
- package/lib/test/client.searchForMarker.spec.js +2 -2
- package/lib/test/client.searchForMarker.spec.js.map +1 -1
- package/lib/test/clientTestHelper.js +1 -1
- package/lib/test/clientTestHelper.js.map +1 -1
- package/lib/test/mergeTree.annotate.spec.js +25 -25
- package/lib/test/mergeTree.annotate.spec.js.map +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js +1 -1
- package/lib/test/mergeTree.markRangeRemoved.spec.js.map +1 -1
- package/lib/test/obliterate.spec.js +4 -4
- package/lib/test/obliterate.spec.js.map +1 -1
- package/lib/test/resetPendingSegmentsToOp.spec.js +14 -14
- package/lib/test/resetPendingSegmentsToOp.spec.js.map +1 -1
- package/lib/test/snapshot.utils.js +1 -1
- package/lib/test/snapshot.utils.js.map +1 -1
- package/lib/test/sortedSegmentSet.spec.js +3 -3
- package/lib/test/sortedSegmentSet.spec.js.map +1 -1
- package/lib/test/testClient.js +3 -3
- package/lib/test/testClient.js.map +1 -1
- package/lib/test/tracking.spec.js +7 -7
- package/lib/test/tracking.spec.js.map +1 -1
- package/lib/test/wordUnitTests.spec.js.map +1 -1
- package/package.json +16 -16
- package/src/client.ts +117 -50
- package/src/collections/list.ts +101 -5
- package/src/constants.ts +6 -0
- package/src/index.ts +3 -0
- package/src/mergeTree.ts +30 -24
- package/src/perspective.ts +26 -0
- package/src/revertibles.ts +1 -1
- package/src/stamps.ts +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.applyStashedOpFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.applyStashedOpFarm.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tannotateRange,\n\tdoOverRange,\n\tgenerateClientNames,\n\tinsert,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nfunction applyMessagesWithReconnect(\n\tstartingSeq: number,\n\tmessageDatas: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tstashClients: readonly TestClient[],\n): number {\n\tlet seq = startingSeq;\n\tconst reconnectClientMsgs: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] = [];\n\tlet minSeq = 0;\n\n\t// apply ops as stashed ops except for client #1\n\tconst stashedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[], number][] = [];\n\tfor (const messageData of messageDatas) {\n\t\tif (messageData[0].clientId !== clients[1].longClientId) {\n\t\t\tconst index = clients\n\t\t\t\t.map((c) => c.longClientId)\n\t\t\t\t.indexOf(messageData[0].clientId as string);\n\t\t\tconst op = messageData[0].contents as IMergeTreeOp;\n\t\t\tstashClients[index].applyStashedOp(op);\n\t\t\tstashedOps.push([\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[index].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t\tindex,\n\t\t\t]);\n\t\t}\n\t}\n\t// this should put all stash clients (except #1) in the same state as the\n\t// respective normal clients, having local changes only.\n\tfor (let i = 0; i < clients.length; ++i) {\n\t\tif (i !== 1) {\n\t\t\tTestClientLogger.validate([clients[i], stashClients[i]]);\n\t\t}\n\t}\n\tTestClientLogger.validate([clients[0], stashClients[1]]);\n\n\t// apply the ops to the normal clients. they will all be the same now,\n\t// except #1 which has local changes other clients haven't seen yet\n\tfor (const [message, sg] of messageDatas) {\n\t\tif (message.clientId === clients[1].longClientId) {\n\t\t\treconnectClientMsgs.push([message.contents as IMergeTreeOp, sg]);\n\t\t} else {\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) c.applyMsg(message);\n\t\t\tminSeq = message.minimumSequenceNumber;\n\t\t}\n\t}\n\n\t// regenerate the ops that were applied as stashed ops. this simulates resubmit()\n\tconst regeneratedStashedOps = stashedOps.map((op) =>\n\t\tstashClients[op[2]].makeOpMessage(stashClients[op[2]].regeneratePendingOp(op[0], op[1])),\n\t);\n\n\t// apply the regenerated stashed ops\n\tlet stashedOpSeq = startingSeq;\n\tfor (const msg of regeneratedStashedOps) {\n\t\tmsg.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(msg);\n\t}\n\t// all stash and normal clients should now be in the same state,\n\t// except #1 (normal) which still has local changes\n\tTestClientLogger.validate([...clients.filter((_, i) => i !== 1), ...stashClients]);\n\n\t// regenerate ops for client #1\n\tconst reconnectMsgs: ISequencedDocumentMessage[] = [];\n\tfor (const opData of reconnectClientMsgs) {\n\t\tconst newMsg = clients[1].makeOpMessage(\n\t\t\tclients[1].regeneratePendingOp(opData[0], opData[1]),\n\t\t);\n\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\treconnectMsgs.push(newMsg);\n\t}\n\n\t// apply regenerated ops as stashed ops for client #1\n\tconst stashedRegeneratedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] =\n\t\treconnectMsgs.map((message) => {\n\t\t\tconst op = message.contents as IMergeTreeOp;\n\t\t\tstashClients[1].applyStashedOp(op);\n\t\t\treturn [\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[1].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t];\n\t\t});\n\t// now both clients at index 1 should be the same\n\tTestClientLogger.validate([clients[1], stashClients[1]]);\n\n\t// apply the regenerated ops from client #1\n\tfor (const message of reconnectMsgs) {\n\t\tmessage.sequenceNumber = ++seq;\n\t\tfor (const c of clients) c.applyMsg(message);\n\t}\n\n\t// resubmit regenerated stashed ops\n\tconst reRegeneratedStashedMessages = stashedRegeneratedOps.map((stashedOp) =>\n\t\tstashClients[1].makeOpMessage(\n\t\t\tstashClients[1].regeneratePendingOp(stashedOp[0], stashedOp[1]),\n\t\t),\n\t);\n\n\tfor (const reRegeneratedStashedOp of reRegeneratedStashedMessages) {\n\t\treRegeneratedStashedOp.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(reRegeneratedStashedOp);\n\t}\n\n\t// all clients should now be the same\n\tTestClientLogger.validate([...clients, ...stashClients]);\n\n\treturn seq;\n}\n\ninterface IApplyStashedOpFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IApplyStashedOpFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 3, max: 12 },\n\topsPerRoundRange: { min: 40, max: 120 },\n\trounds: 3,\n\toperations: [annotateRange, removeRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runApplyStashedOpFarmTests(\n\topts: IApplyStashedOpFarmConfig,\n\textraSeed?: number,\n): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`applyStashedOpFarm_${clientCount}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, clientCount, extraSeed ?? 0);\n\t\t\tconst testOpts = { ...opts };\n\t\t\tif (extraSeed) {\n\t\t\t\ttestOpts.resultsFilePostfix ??= \"\";\n\t\t\t\ttestOpts.resultsFilePostfix += extraSeed;\n\t\t\t}\n\n\t\t\tconst clients: TestClient[] = [new TestClient({ mergeTreeEnableAnnotateAdjust: true })];\n\t\t\t// This test is based on reconnectFarm, but we keep a second set of clients. For\n\t\t\t// these clients, we apply the generated ops as stashed ops, then regenerate\n\t\t\t// them to simulate resubmit(), then apply them. In the end, they should arrive\n\t\t\t// at the same state as the \"normal\" set of clients\n\t\t\tlet stashClients: TestClient[] = [];\n\n\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\t\t\tstashClients = [new TestClient({ mergeTreeEnableAnnotateAdjust: true })];\n\t\t\tfor (const [i, c] of stashClients.entries())\n\t\t\t\tc.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\tlet seq = 0;\n\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\t\t\tfor (const c of stashClients) c.updateMinSeq(seq);\n\n\t\t\t// Add double the number of clients each iteration\n\t\t\tconst targetClients = Math.max(opts.clients.min, clientCount);\n\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tclients.push(newClient);\n\t\t\t\t// add 1 stash client per normal client\n\t\t\t\tconst anotherNewClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tstashClients.push(anotherNewClient);\n\t\t\t}\n\n\t\t\tseq = runMergeTreeOperationRunner(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\topts.minLength,\n\t\t\t\topts,\n\t\t\t\t(s, m, c) => applyMessagesWithReconnect(s, m, c, stashClients),\n\t\t\t);\n\t\t}).timeout(30 * 1000);\n\t});\n}\n\ndescribeFuzz(\"MergeTree.Client\", ({ testCount }) => {\n\tconst opts = defaultOptions;\n\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunApplyStashedOpFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunApplyStashedOpFarmTests(opts);\n\t}\n});\n"]}
|
|
1
|
+
{"version":3,"file":"client.applyStashedOpFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.applyStashedOpFarm.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport { SegmentGroup } from \"../mergeTreeNodes.js\";\nimport { IMergeTreeOp, MergeTreeDeltaType } from \"../ops.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tannotateRange,\n\tdoOverRange,\n\tgenerateClientNames,\n\tinsert,\n\tremoveRange,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nfunction applyMessagesWithReconnect(\n\tstartingSeq: number,\n\tmessageDatas: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][],\n\tclients: readonly TestClient[],\n\tstashClients: readonly TestClient[],\n): number {\n\tlet seq = startingSeq;\n\tconst reconnectClientMsgs: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] = [];\n\tlet minSeq = 0;\n\n\t// apply ops as stashed ops except for client #1\n\tconst stashedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[], number][] = [];\n\tfor (const messageData of messageDatas) {\n\t\tif (messageData[0].clientId !== clients[1].longClientId) {\n\t\t\tconst index = clients\n\t\t\t\t.map((c) => c.longClientId)\n\t\t\t\t.indexOf(messageData[0].clientId as string);\n\t\t\tconst op = messageData[0].contents as IMergeTreeOp;\n\t\t\tstashClients[index].applyStashedOp(op);\n\t\t\tstashedOps.push([\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[index].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t\tindex,\n\t\t\t]);\n\t\t}\n\t}\n\t// this should put all stash clients (except #1) in the same state as the\n\t// respective normal clients, having local changes only.\n\tfor (let i = 0; i < clients.length; ++i) {\n\t\tif (i !== 1) {\n\t\t\tTestClientLogger.validate([clients[i], stashClients[i]]);\n\t\t}\n\t}\n\tTestClientLogger.validate([clients[0], stashClients[1]]);\n\n\t// apply the ops to the normal clients. they will all be the same now,\n\t// except #1 which has local changes other clients haven't seen yet\n\tfor (const [message, sg] of messageDatas) {\n\t\tif (message.clientId === clients[1].longClientId) {\n\t\t\treconnectClientMsgs.push([message.contents as IMergeTreeOp, sg]);\n\t\t} else {\n\t\t\tmessage.sequenceNumber = ++seq;\n\t\t\tfor (const c of clients) c.applyMsg(message);\n\t\t\tminSeq = message.minimumSequenceNumber;\n\t\t}\n\t}\n\n\t// regenerate the ops that were applied as stashed ops. this simulates resubmit()\n\tconst regeneratedStashedOps = stashedOps.map((op) =>\n\t\tstashClients[op[2]].makeOpMessage(\n\t\t\tstashClients[op[2]].regeneratePendingOp(op[0], op[1], false),\n\t\t),\n\t);\n\n\t// apply the regenerated stashed ops\n\tlet stashedOpSeq = startingSeq;\n\tfor (const msg of regeneratedStashedOps) {\n\t\tmsg.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(msg);\n\t}\n\t// all stash and normal clients should now be in the same state,\n\t// except #1 (normal) which still has local changes\n\tTestClientLogger.validate([...clients.filter((_, i) => i !== 1), ...stashClients]);\n\n\t// regenerate ops for client #1\n\tconst reconnectMsgs: ISequencedDocumentMessage[] = [];\n\tfor (const opData of reconnectClientMsgs) {\n\t\tconst newMsg = clients[1].makeOpMessage(\n\t\t\tclients[1].regeneratePendingOp(opData[0], opData[1], false),\n\t\t);\n\t\tnewMsg.minimumSequenceNumber = minSeq;\n\t\treconnectMsgs.push(newMsg);\n\t}\n\n\t// apply regenerated ops as stashed ops for client #1\n\tconst stashedRegeneratedOps: [IMergeTreeOp, SegmentGroup | SegmentGroup[]][] =\n\t\treconnectMsgs.map((message) => {\n\t\t\tconst op = message.contents as IMergeTreeOp;\n\t\t\tstashClients[1].applyStashedOp(op);\n\t\t\treturn [\n\t\t\t\top,\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n\t\t\t\tstashClients[1].peekPendingSegmentGroups(\n\t\t\t\t\top.type === MergeTreeDeltaType.GROUP ? op.ops.length : 1,\n\t\t\t\t)!,\n\t\t\t];\n\t\t});\n\t// now both clients at index 1 should be the same\n\tTestClientLogger.validate([clients[1], stashClients[1]]);\n\n\t// apply the regenerated ops from client #1\n\tfor (const message of reconnectMsgs) {\n\t\tmessage.sequenceNumber = ++seq;\n\t\tfor (const c of clients) c.applyMsg(message);\n\t}\n\n\t// resubmit regenerated stashed ops\n\tconst reRegeneratedStashedMessages = stashedRegeneratedOps.map((stashedOp) =>\n\t\tstashClients[1].makeOpMessage(\n\t\t\tstashClients[1].regeneratePendingOp(stashedOp[0], stashedOp[1], false),\n\t\t),\n\t);\n\n\tfor (const reRegeneratedStashedOp of reRegeneratedStashedMessages) {\n\t\treRegeneratedStashedOp.sequenceNumber = ++stashedOpSeq;\n\t\tfor (const c of stashClients) c.applyMsg(reRegeneratedStashedOp);\n\t}\n\n\t// all clients should now be the same\n\tTestClientLogger.validate([...clients, ...stashClients]);\n\n\treturn seq;\n}\n\ninterface IApplyStashedOpFarmConfig extends IMergeTreeOperationRunnerConfig {\n\tminLength: number;\n\tclients: IConfigRange;\n}\n\nexport const defaultOptions: IApplyStashedOpFarmConfig = {\n\tminLength: 16,\n\tclients: { min: 3, max: 12 },\n\topsPerRoundRange: { min: 40, max: 120 },\n\trounds: 3,\n\toperations: [annotateRange, removeRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\n// Generate a list of single character client names, support up to 69 clients\nconst clientNames = generateClientNames();\n\nfunction runApplyStashedOpFarmTests(\n\topts: IApplyStashedOpFarmConfig,\n\textraSeed?: number,\n): void {\n\tdoOverRange(opts.clients, opts.growthFunc.bind(opts), (clientCount) => {\n\t\tit(`applyStashedOpFarm_${clientCount}`, async () => {\n\t\t\tconst random = makeRandom(0xdeadbeef, 0xfeedbed, clientCount, extraSeed ?? 0);\n\t\t\tconst testOpts = { ...opts };\n\t\t\tif (extraSeed) {\n\t\t\t\ttestOpts.resultsFilePostfix ??= \"\";\n\t\t\t\ttestOpts.resultsFilePostfix += extraSeed;\n\t\t\t}\n\n\t\t\tconst clients: TestClient[] = [new TestClient({ mergeTreeEnableAnnotateAdjust: true })];\n\t\t\t// This test is based on reconnectFarm, but we keep a second set of clients. For\n\t\t\t// these clients, we apply the generated ops as stashed ops, then regenerate\n\t\t\t// them to simulate resubmit(), then apply them. In the end, they should arrive\n\t\t\t// at the same state as the \"normal\" set of clients\n\t\t\tlet stashClients: TestClient[] = [];\n\n\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\t\t\tstashClients = [new TestClient({ mergeTreeEnableAnnotateAdjust: true })];\n\t\t\tfor (const [i, c] of stashClients.entries())\n\t\t\t\tc.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\tlet seq = 0;\n\t\t\tfor (const c of clients) c.updateMinSeq(seq);\n\t\t\tfor (const c of stashClients) c.updateMinSeq(seq);\n\n\t\t\t// Add double the number of clients each iteration\n\t\t\tconst targetClients = Math.max(opts.clients.min, clientCount);\n\t\t\tfor (let cc = clients.length; cc < targetClients; cc++) {\n\t\t\t\tconst newClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tclients.push(newClient);\n\t\t\t\t// add 1 stash client per normal client\n\t\t\t\tconst anotherNewClient = await TestClient.createFromClientSnapshot(\n\t\t\t\t\tclients[0],\n\t\t\t\t\tclientNames[cc],\n\t\t\t\t);\n\t\t\t\tstashClients.push(anotherNewClient);\n\t\t\t}\n\n\t\t\tseq = runMergeTreeOperationRunner(\n\t\t\t\trandom,\n\t\t\t\tseq,\n\t\t\t\tclients,\n\t\t\t\topts.minLength,\n\t\t\t\topts,\n\t\t\t\t(s, m, c) => applyMessagesWithReconnect(s, m, c, stashClients),\n\t\t\t);\n\t\t}).timeout(30 * 1000);\n\t});\n}\n\ndescribeFuzz(\"MergeTree.Client\", ({ testCount }) => {\n\tconst opts = defaultOptions;\n\n\tif (testCount > 1) {\n\t\tdoOverRange(\n\t\t\t{ min: 0, max: testCount - 1 },\n\t\t\t(x) => x + 1,\n\t\t\t(seed) => {\n\t\t\t\tdescribe(`with seed ${seed}`, () => {\n\t\t\t\t\trunApplyStashedOpFarmTests(opts, seed);\n\t\t\t\t});\n\t\t\t},\n\t\t);\n\t} else {\n\t\trunApplyStashedOpFarmTests(opts);\n\t}\n});\n"]}
|
|
@@ -41,7 +41,7 @@ const defaultOptions = {
|
|
|
41
41
|
for (const [i, c] of clients.entries())
|
|
42
42
|
c.startOrUpdateCollaboration(clientNames[i]);
|
|
43
43
|
const getAttributionAtPosition = (client, pos) => {
|
|
44
|
-
const { segment, offset } = client.getContainingSegment(pos);
|
|
44
|
+
const { segment, offset } = client.getContainingSegment(pos) ?? {};
|
|
45
45
|
if (segment?.attribution === undefined || offset === undefined) {
|
|
46
46
|
return undefined;
|
|
47
47
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.attributionFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.attributionFarm.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAA+C;AAE/C,gFAAgF;AAChF,oFAAiF;AAGjF,kEAAqG;AAGrG,+EASuC;AACvC,mDAA6C;AAC7C,+DAAyD;AAElD,MAAM,aAAa,GAAkB,CAC3C,MAAkB,EAClB,OAAe,EACf,KAAa,EACZ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;AAJxE,QAAA,aAAa,iBAI2D;AAErF,MAAM,cAAc,GACe;IAClC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC3B,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC1B,gBAAgB,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACtC,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,CAAC,yCAAW,EAAE,qBAAa,EAAE,oCAAM,CAAC;IAChD,UAAU,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC;CACxC,CAAC;AAEF,IAAA,oCAAY,EAAC,uBAAuB,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;IACvD,6EAA6E;IAC7E,MAAM,WAAW,GAAG,IAAA,iDAAmB,GAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAA,2CAAa,EAAC,cAAc,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC9E,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC;QAC5D,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,IAAA,iDAAuB,EAC1E,YAAY,CACZ,EAAE,CAAC;YACH,EAAE,CAAC,mBAAmB,OAAO,IAAI,MAAM,IAAI,gBAAgB,EAAE,EAAE,KAAK,IAAI,EAAE;gBACzE,MAAM,MAAM,GAAG,IAAA,kCAAU,EAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC;gBAEvE,MAAM,OAAO,GAAiB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;qBACrD,IAAI,CAAC,CAAC,CAAC;qBACP,GAAG,CACH,GAAG,EAAE,CACJ,IAAI,0BAAU,CAAC;oBACd,WAAW,EAAE;wBACZ,KAAK,EAAE,IAAI;wBACX,aAAa,EACZ,IAAA,iFAA0D,EAAC,aAAa,CAAC;qBAC1E;iBACD,CAAC,CACH,CAAC;gBACH,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE;oBAAE,CAAC,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBAErF,MAAM,wBAAwB,GAAG,CAChC,MAAkB,EAClB,GAAW,EAKC,EAAE;oBACd,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAkB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"client.attributionFarm.spec.js","sourceRoot":"","sources":["../../src/test/client.attributionFarm.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,6CAA+C;AAE/C,gFAAgF;AAChF,oFAAiF;AAGjF,kEAAqG;AAGrG,+EASuC;AACvC,mDAA6C;AAC7C,+DAAyD;AAElD,MAAM,aAAa,GAAkB,CAC3C,MAAkB,EAClB,OAAe,EACf,KAAa,EACZ,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;AAJxE,QAAA,aAAa,iBAI2D;AAErF,MAAM,cAAc,GACe;IAClC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC3B,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;IAC1B,gBAAgB,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;IACtC,MAAM,EAAE,EAAE;IACV,UAAU,EAAE,CAAC,yCAAW,EAAE,qBAAa,EAAE,oCAAM,CAAC;IAChD,UAAU,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC;CACxC,CAAC;AAEF,IAAA,oCAAY,EAAC,uBAAuB,EAAE,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE;IACvD,6EAA6E;IAC7E,MAAM,WAAW,GAAG,IAAA,iDAAmB,GAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,IAAA,2CAAa,EAAC,cAAc,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IAC9E,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC;QAC5D,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,IAAA,iDAAuB,EAC1E,YAAY,CACZ,EAAE,CAAC;YACH,EAAE,CAAC,mBAAmB,OAAO,IAAI,MAAM,IAAI,gBAAgB,EAAE,EAAE,KAAK,IAAI,EAAE;gBACzE,MAAM,MAAM,GAAG,IAAA,kCAAU,EAAC,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,IAAI,CAAC,CAAC,CAAC;gBAEvE,MAAM,OAAO,GAAiB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;qBACrD,IAAI,CAAC,CAAC,CAAC;qBACP,GAAG,CACH,GAAG,EAAE,CACJ,IAAI,0BAAU,CAAC;oBACd,WAAW,EAAE;wBACZ,KAAK,EAAE,IAAI;wBACX,aAAa,EACZ,IAAA,iFAA0D,EAAC,aAAa,CAAC;qBAC1E;iBACD,CAAC,CACH,CAAC;gBACH,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE;oBAAE,CAAC,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;gBAErF,MAAM,wBAAwB,GAAG,CAChC,MAAkB,EAClB,GAAW,EAKC,EAAE;oBACd,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,oBAAoB,CAAkB,GAAG,CAAC,IAAI,EAAE,CAAC;oBACpF,IAAI,OAAO,EAAE,WAAW,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBAChE,OAAO,SAAS,CAAC;oBAClB,CAAC;oBACD,MAAM,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;oBAChC,IAAI,QAAoE,CAAC;oBACzE,MAAM,MAAM,GAGR;wBACH,IAAI,EAAE,WAAW,CAAC,WAAW,CAAC,MAAM,CAAC;qBACrC,CAAC;oBACF,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;wBAC7C,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;wBAChE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;oBAC5B,CAAC;oBACD,OAAO,QAAQ,CAAC;gBACjB,CAAC,CAAC;gBAEF,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,QAAoB,EAAQ,EAAE;oBACzE,MAAM,WAAW,GAAG,sCAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACvD,QAAQ,EAAE,CAAC;oBACX,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAChF,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACvC,CAAC;oBACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;4BACjD,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;4BACrC,MAAM,YAAY,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;4BAC7D,IAAI,YAAY,KAAK,YAAY,EAAE,CAAC;gCACnC,oBAAM,CAAC,SAAS,CACf,YAAY,EACZ,YAAY,EACZ,GAAG,MAAM,MAAM,WAAW,KAAK,sCAAgB,CAAC,QAAQ,CAAC;oCACxD,OAAO,CAAC,CAAC,CAAC;oCACV,OAAO,CAAC,CAAC,CAAC;iCACV,CAAC,EAAE,CACJ,CAAC;4BACH,CAAC;wBACF,CAAC;oBACF,CAAC;gBACF,CAAC,CAAC;gBAEF,IAAI,GAAG,GAAG,CAAC,CAAC;gBAEZ,kBAAkB,CAAC,YAAY,EAAE,GAAG,EAAE;oBACrC,GAAG,GAAG,IAAA,yDAA2B,EAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;gBAClF,CAAC,CAAC,CAAC;gBAEH,kBAAkB,CAAC,oBAAoB,EAAE,GAAG,EAAE;oBAC7C,sDAAsD;oBACtD,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;wBACjE,KAAK,MAAM,CAAC,IAAI,OAAO;4BAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAC5C,CAAC;gBACF,CAAC,CAAC,CAAC;gBAEH,kBAAkB,CAAC,gBAAgB,EAAE,GAAG,EAAE;oBACzC,GAAG,GAAG,IAAA,yDAA2B,EAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;gBACjF,CAAC,CAAC,CAAC;gBAEH,kBAAkB,CAAC,qBAAqB,EAAE,GAAG,EAAE;oBAC9C,sDAAsD;oBACtD,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;wBACjE,KAAK,MAAM,CAAC,IAAI,OAAO;4BAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;oBAC5C,CAAC;gBACF,CAAC,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { describeFuzz, makeRandom } from \"@fluid-private/stochastic-test-utils\";\nimport { generatePairwiseOptions } from \"@fluid-private/test-pairwise-generator\";\nimport { AttributionKey } from \"@fluidframework/runtime-definitions/internal\";\n\nimport { createPropertyTrackingAndInsertionAttributionPolicyFactory } from \"../attributionPolicy.js\";\nimport type { ISegmentPrivate } from \"../mergeTreeNodes.js\";\n\nimport {\n\tIConfigRange,\n\tIMergeTreeOperationRunnerConfig,\n\tTestOperation,\n\tgenerateClientNames,\n\tinsert,\n\tremoveRange,\n\tresolveRanges,\n\trunMergeTreeOperationRunner,\n} from \"./mergeTreeOperationRunner.js\";\nimport { TestClient } from \"./testClient.js\";\nimport { TestClientLogger } from \"./testClientLogger.js\";\n\nexport const annotateRange: TestOperation = (\n\tclient: TestClient,\n\topStart: number,\n\topEnd: number,\n) => client.annotateRangeLocal(opStart, opEnd, { trackedProp: client.longClientId });\n\nconst defaultOptions: Record<\"initLen\" | \"modLen\", IConfigRange> &\n\tIMergeTreeOperationRunnerConfig = {\n\tinitLen: { min: 2, max: 4 },\n\tmodLen: { min: 1, max: 8 },\n\topsPerRoundRange: { min: 10, max: 40 },\n\trounds: 10,\n\toperations: [removeRange, annotateRange, insert],\n\tgrowthFunc: (input: number) => input * 2,\n};\n\ndescribeFuzz(\"MergeTree.Attribution\", ({ testCount }) => {\n\t// Generate a list of single character client names, support up to 69 clients\n\tconst clientNames = generateClientNames();\n\tconst rangeOptions = resolveRanges(defaultOptions, defaultOptions.growthFunc);\n\tfor (let extraSeed = 0; extraSeed < testCount; extraSeed++) {\n\t\tfor (const { initLen, modLen, opsPerRoundRange } of generatePairwiseOptions(\n\t\t\trangeOptions,\n\t\t)) {\n\t\t\tit(`AttributionFarm_${initLen}_${modLen}_${opsPerRoundRange}`, async () => {\n\t\t\t\tconst random = makeRandom(0xdeadbeef, initLen, modLen, extraSeed ?? 0);\n\n\t\t\t\tconst clients: TestClient[] = Array.from({ length: 3 })\n\t\t\t\t\t.fill(0)\n\t\t\t\t\t.map(\n\t\t\t\t\t\t() =>\n\t\t\t\t\t\t\tnew TestClient({\n\t\t\t\t\t\t\t\tattribution: {\n\t\t\t\t\t\t\t\t\ttrack: true,\n\t\t\t\t\t\t\t\t\tpolicyFactory:\n\t\t\t\t\t\t\t\t\t\tcreatePropertyTrackingAndInsertionAttributionPolicyFactory(\"trackedProp\"),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\t\t\t\tfor (const [i, c] of clients.entries()) c.startOrUpdateCollaboration(clientNames[i]);\n\n\t\t\t\tconst getAttributionAtPosition = (\n\t\t\t\t\tclient: TestClient,\n\t\t\t\t\tpos: number,\n\t\t\t\t):\n\t\t\t\t\t| {\n\t\t\t\t\t\t\t[name: string]: AttributionKey | undefined;\n\t\t\t\t\t }\n\t\t\t\t\t| undefined => {\n\t\t\t\t\tconst { segment, offset } = client.getContainingSegment<ISegmentPrivate>(pos) ?? {};\n\t\t\t\t\tif (segment?.attribution === undefined || offset === undefined) {\n\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t}\n\t\t\t\t\tconst { attribution } = segment;\n\t\t\t\t\tlet channels: { [name: string]: AttributionKey | undefined } | undefined;\n\t\t\t\t\tconst result: {\n\t\t\t\t\t\troot: AttributionKey | undefined;\n\t\t\t\t\t\tchannels?: { [name: string]: AttributionKey | undefined };\n\t\t\t\t\t} = {\n\t\t\t\t\t\troot: attribution.getAtOffset(offset),\n\t\t\t\t\t};\n\t\t\t\t\tfor (const name of attribution.channelNames) {\n\t\t\t\t\t\t(channels ??= {})[name] = attribution.getAtOffset(offset, name);\n\t\t\t\t\t\tresult.channels = channels;\n\t\t\t\t\t}\n\t\t\t\t\treturn channels;\n\t\t\t\t};\n\n\t\t\t\tconst validateAnnotation = (reason: string, workload: () => void): void => {\n\t\t\t\t\tconst preWorkload = TestClientLogger.toString(clients);\n\t\t\t\t\tworkload();\n\t\t\t\t\tconst attributions = Array.from({ length: clients[0].getLength() }).map((_, i) =>\n\t\t\t\t\t\tgetAttributionAtPosition(clients[0], i),\n\t\t\t\t\t);\n\t\t\t\t\tfor (let c = 1; c < clients.length; c++) {\n\t\t\t\t\t\tfor (let i = 0; i < clients[c].getLength(); i++) {\n\t\t\t\t\t\t\tconst attribution0 = attributions[i];\n\t\t\t\t\t\t\tconst attributionC = getAttributionAtPosition(clients[c], i);\n\t\t\t\t\t\t\tif (attribution0 !== attributionC) {\n\t\t\t\t\t\t\t\tassert.deepEqual(\n\t\t\t\t\t\t\t\t\tattribution0,\n\t\t\t\t\t\t\t\t\tattributionC,\n\t\t\t\t\t\t\t\t\t`${reason}:\\n${preWorkload}\\n${TestClientLogger.toString([\n\t\t\t\t\t\t\t\t\t\tclients[0],\n\t\t\t\t\t\t\t\t\t\tclients[c],\n\t\t\t\t\t\t\t\t\t])}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tlet seq = 0;\n\n\t\t\t\tvalidateAnnotation(\"Initialize\", () => {\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, initLen, defaultOptions);\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After Init Zamboni\", () => {\n\t\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After More Ops\", () => {\n\t\t\t\t\tseq = runMergeTreeOperationRunner(random, seq, clients, modLen, defaultOptions);\n\t\t\t\t});\n\n\t\t\t\tvalidateAnnotation(\"After Final Zamboni\", () => {\n\t\t\t\t\t// trigger zamboni multiple times as it is incremental\n\t\t\t\t\tfor (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {\n\t\t\t\t\t\tfor (const c of clients) c.updateMinSeq(i);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t}\n});\n"]}
|
|
@@ -21,6 +21,7 @@ describe("client.getPosition", () => {
|
|
|
21
21
|
}
|
|
22
22
|
client.startOrUpdateCollaboration(localUserLongId);
|
|
23
23
|
const segOff = client.getContainingSegment(segPos);
|
|
24
|
+
(0, node_assert_1.strict)(segOff);
|
|
24
25
|
(0, node_assert_1.strict)(textSegment_js_1.TextSegment.is(segOff.segment));
|
|
25
26
|
node_assert_1.strict.strictEqual(segOff.offset, 0);
|
|
26
27
|
node_assert_1.strict.strictEqual(segOff.segment.text, "o");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.getPosition.spec.js","sourceRoot":"","sources":["../../src/test/client.getPosition.spec.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAEH,6DAA6D;AAE7D,6CAA+C;AAE/C,4DAA8E;AAC9E,sDAAgD;AAEhD,mDAA6C;AAE7C,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IACnC,MAAM,eAAe,GAAG,WAAW,CAAC;IACpC,IAAI,MAAkB,CAAC;IACvB,IAAI,OAAoB,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,CAAC;IACjB,UAAU,CAAC,GAAG,EAAE;QACf,MAAM,GAAG,IAAI,0BAAU,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,CAAC,0BAA0B,CAAC,eAAe,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,CAAC,oBAAoB,CAAkB,MAAM,CAAC,CAAC;QACpE,IAAA,oBAAM,EAAC,4BAAW,CAAC,EAAE,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"client.getPosition.spec.js","sourceRoot":"","sources":["../../src/test/client.getPosition.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/no-non-null-assertion */\n\nimport { strict as assert } from \"node:assert\";\n\nimport { segmentIsRemoved, type ISegmentPrivate } from \"../mergeTreeNodes.js\";\nimport { TextSegment } from \"../textSegment.js\";\n\nimport { TestClient } from \"./testClient.js\";\n\ndescribe(\"client.getPosition\", () => {\n\tconst localUserLongId = \"localUser\";\n\tlet client: TestClient;\n\tlet segment: TextSegment;\n\tconst segPos = 4;\n\tbeforeEach(() => {\n\t\tclient = new TestClient();\n\t\tfor (const c of \"hello world\") {\n\t\t\tclient.insertTextLocal(client.getLength(), c);\n\t\t}\n\t\tclient.startOrUpdateCollaboration(localUserLongId);\n\n\t\tconst segOff = client.getContainingSegment<ISegmentPrivate>(segPos);\n\t\tassert(segOff);\n\t\tassert(TextSegment.is(segOff.segment));\n\t\tassert.strictEqual(segOff.offset, 0);\n\t\tassert.strictEqual(segOff.segment.text, \"o\");\n\t\tsegment = segOff.segment;\n\t});\n\n\tit(\"Existing Segment\", () => {\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos);\n\t});\n\n\tit(\"Deleted Segment\", () => {\n\t\tclient.removeRangeLocal(segPos, segPos + 1);\n\t\tassert.strictEqual(segmentIsRemoved(segment), true);\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos);\n\t});\n\n\tit(\"Detached Segment\", () => {\n\t\tclient.applyMsg(client.makeOpMessage(client.removeRangeLocal(segPos, segPos + 1), 1));\n\t\t// do some work and move the client's min seq forward, so zamboni runs\n\t\tfor (const c of \"hello world\") {\n\t\t\tclient.applyMsg(\n\t\t\t\tclient.makeOpMessage(\n\t\t\t\t\tclient.insertTextLocal(client.getLength(), c),\n\t\t\t\t\tclient.getCurrentSeq() + 1,\n\t\t\t\t\tclient.getCurrentSeq(),\n\t\t\t\t\tundefined,\n\t\t\t\t\tclient.getCurrentSeq(),\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tassert.strictEqual(segmentIsRemoved(segment), true);\n\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, -1);\n\t});\n\n\tit(\"Removed Segment\", () => {\n\t\tclient.removeRangeLocal(segPos - 1, segPos);\n\t\tconst pos = client.getPosition(segment);\n\t\tassert.strictEqual(pos, segPos - 1);\n\t});\n});\n"]}
|
|
@@ -47,7 +47,8 @@ describe("MergeTree.Client", () => {
|
|
|
47
47
|
client2.applyMsg(insert);
|
|
48
48
|
}
|
|
49
49
|
const segInfo = client1.getContainingSegment(2);
|
|
50
|
-
|
|
50
|
+
(0, node_assert_1.strict)(segInfo);
|
|
51
|
+
const c1LocalRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.Simple, undefined);
|
|
51
52
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(c1LocalRef), 2, "create position");
|
|
52
53
|
const remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);
|
|
53
54
|
remove.minimumSequenceNumber = seq - 1;
|
|
@@ -77,7 +78,8 @@ describe("MergeTree.Client", () => {
|
|
|
77
78
|
client2.applyMsg(insert);
|
|
78
79
|
}
|
|
79
80
|
const segInfo = client1.getContainingSegment(2);
|
|
80
|
-
|
|
81
|
+
(0, node_assert_1.strict)(segInfo);
|
|
82
|
+
const c1LocalRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
81
83
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);
|
|
82
84
|
const remove = client2.makeOpMessage(client2.removeRangeLocal(2, 3), ++seq);
|
|
83
85
|
remove.minimumSequenceNumber = seq - 1;
|
|
@@ -105,7 +107,8 @@ describe("MergeTree.Client", () => {
|
|
|
105
107
|
client2.applyMsg(insert);
|
|
106
108
|
}
|
|
107
109
|
const segInfo = client1.getContainingSegment(2);
|
|
108
|
-
|
|
110
|
+
(0, node_assert_1.strict)(segInfo);
|
|
111
|
+
const c1LocalRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
109
112
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);
|
|
110
113
|
const remove = client2.makeOpMessage(client2.removeRangeLocal(2, client2.getLength()), ++seq);
|
|
111
114
|
remove.minimumSequenceNumber = seq - 1;
|
|
@@ -126,7 +129,7 @@ describe("MergeTree.Client", () => {
|
|
|
126
129
|
helper.insertText("A", 0, "AxxC");
|
|
127
130
|
helper.processAllOps();
|
|
128
131
|
const [localRefA, localRefB] = [A, B].map((client) => {
|
|
129
|
-
const { segment, offset } = client.getContainingSegment(2);
|
|
132
|
+
const { segment, offset } = client.getContainingSegment(2) ?? {};
|
|
130
133
|
(0, node_assert_1.strict)(segment !== undefined && offset !== undefined);
|
|
131
134
|
return client.createLocalReferencePosition(segment, offset, ops_js_1.ReferenceType.SlideOnRemove, undefined, localReference_js_1.SlidingPreference.BACKWARD);
|
|
132
135
|
});
|
|
@@ -146,7 +149,7 @@ describe("MergeTree.Client", () => {
|
|
|
146
149
|
helper.insertText("A", 0, "AxxC");
|
|
147
150
|
helper.processAllOps();
|
|
148
151
|
const [localRefA, localRefB] = [A, B].map((client) => {
|
|
149
|
-
const { segment, offset } = client.getContainingSegment(2);
|
|
152
|
+
const { segment, offset } = client.getContainingSegment(2) ?? {};
|
|
150
153
|
(0, node_assert_1.strict)(segment !== undefined && offset !== undefined);
|
|
151
154
|
return client.createLocalReferencePosition(segment, offset, ops_js_1.ReferenceType.SlideOnRemove, undefined, localReference_js_1.SlidingPreference.BACKWARD);
|
|
152
155
|
});
|
|
@@ -167,7 +170,8 @@ describe("MergeTree.Client", () => {
|
|
|
167
170
|
insert.minimumSequenceNumber = seq - 1;
|
|
168
171
|
client1.applyMsg(insert);
|
|
169
172
|
const segInfo = client1.getContainingSegment(3);
|
|
170
|
-
|
|
173
|
+
(0, node_assert_1.strict)(segInfo);
|
|
174
|
+
const c1LocalRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
171
175
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(c1LocalRef), 3, "ref created");
|
|
172
176
|
const remove1 = client1.makeOpMessage(client1.removeRangeLocal(3, 4), ++seq);
|
|
173
177
|
remove1.minimumSequenceNumber = seq - 1;
|
|
@@ -192,41 +196,41 @@ describe("MergeTree.Client", () => {
|
|
|
192
196
|
// Position depends on op
|
|
193
197
|
const createReference1 = client2.makeOpMessage({ type: ops_js_1.MergeTreeDeltaType.INSERT }, ++seq, insert1.sequenceNumber);
|
|
194
198
|
let segoff = getSlideOnRemoveReferencePosition(client1, 1, createReference1);
|
|
195
|
-
(0, node_assert_1.strict)(segoff
|
|
196
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
199
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
200
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 3);
|
|
197
201
|
node_assert_1.strict.equal(segoff.offset, 1);
|
|
198
202
|
const createReference2 = client2.makeOpMessage({ type: ops_js_1.MergeTreeDeltaType.INSERT }, ++seq, insert2.sequenceNumber);
|
|
199
203
|
segoff = getSlideOnRemoveReferencePosition(client1, 2, createReference2);
|
|
200
|
-
(0, node_assert_1.strict)(segoff
|
|
201
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
204
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
205
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 0);
|
|
202
206
|
node_assert_1.strict.equal(segoff.offset, 2);
|
|
203
207
|
// On a removed, unacked segment
|
|
204
208
|
let remove = client1.makeOpMessage(client1.removeRangeLocal(2, 5), ++seq);
|
|
205
209
|
segoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);
|
|
206
|
-
(0, node_assert_1.strict)(segoff
|
|
207
|
-
node_assert_1.strict.notEqual((0, segmentInfos_js_1.toRemovalInfo)(segoff
|
|
208
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
210
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
211
|
+
node_assert_1.strict.notEqual((0, segmentInfos_js_1.toRemovalInfo)(segoff?.segment), undefined);
|
|
212
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 2);
|
|
209
213
|
node_assert_1.strict.equal(segoff.offset, 0);
|
|
210
214
|
// Slid from a removed, acked segment
|
|
211
215
|
client1.applyMsg(remove);
|
|
212
216
|
segoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);
|
|
213
|
-
(0, node_assert_1.strict)(segoff
|
|
214
|
-
node_assert_1.strict.equal((0, segmentInfos_js_1.toRemovalInfo)(segoff
|
|
215
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
217
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
218
|
+
node_assert_1.strict.equal((0, segmentInfos_js_1.toRemovalInfo)(segoff?.segment), undefined);
|
|
219
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 2);
|
|
216
220
|
node_assert_1.strict.equal(segoff.offset, 0);
|
|
217
221
|
// On a removed, unacked segment, end of string
|
|
218
222
|
remove = client1.makeOpMessage(client1.removeRangeLocal(2, 3), ++seq);
|
|
219
223
|
segoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);
|
|
220
|
-
(0, node_assert_1.strict)(segoff
|
|
221
|
-
node_assert_1.strict.notEqual((0, segmentInfos_js_1.toRemovalInfo)(segoff
|
|
222
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
224
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
225
|
+
node_assert_1.strict.notEqual((0, segmentInfos_js_1.toRemovalInfo)(segoff?.segment), undefined);
|
|
226
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 2);
|
|
223
227
|
node_assert_1.strict.equal(segoff.offset, 0);
|
|
224
228
|
// Slid from a removed, acked segment, end of string
|
|
225
229
|
client1.applyMsg(remove);
|
|
226
230
|
segoff = getSlideOnRemoveReferencePosition(client1, 3, createReference2);
|
|
227
|
-
(0, node_assert_1.strict)(segoff
|
|
228
|
-
node_assert_1.strict.equal((0, segmentInfos_js_1.toRemovalInfo)(segoff
|
|
229
|
-
node_assert_1.strict.equal(client1.getPosition(segoff
|
|
231
|
+
(0, node_assert_1.strict)(segoff?.segment);
|
|
232
|
+
node_assert_1.strict.equal((0, segmentInfos_js_1.toRemovalInfo)(segoff?.segment), undefined);
|
|
233
|
+
node_assert_1.strict.equal(client1.getPosition(segoff?.segment), 0);
|
|
230
234
|
node_assert_1.strict.equal(segoff.offset, 1);
|
|
231
235
|
});
|
|
232
236
|
it("Remove all segments with sliding local reference", () => {
|
|
@@ -242,7 +246,8 @@ describe("MergeTree.Client", () => {
|
|
|
242
246
|
client2.applyMsg(insert);
|
|
243
247
|
}
|
|
244
248
|
const segInfo = client1.getContainingSegment(2);
|
|
245
|
-
|
|
249
|
+
(0, node_assert_1.strict)(segInfo);
|
|
250
|
+
const c1LocalRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
246
251
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(c1LocalRef), 2);
|
|
247
252
|
const remove = client2.makeOpMessage(client2.removeRangeLocal(0, client2.getLength()), ++seq);
|
|
248
253
|
remove.minimumSequenceNumber = seq - 1;
|
|
@@ -261,14 +266,18 @@ describe("MergeTree.Client", () => {
|
|
|
261
266
|
client1.applyMsg(insert1);
|
|
262
267
|
client2.applyMsg(insert1);
|
|
263
268
|
const segInfo1 = client1.getContainingSegment(1);
|
|
269
|
+
(0, node_assert_1.strict)(segInfo1);
|
|
264
270
|
const LocalRef1 = client1.createLocalReferencePosition(segInfo1.segment, segInfo1.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
265
271
|
const segInfo3 = client1.getContainingSegment(3);
|
|
272
|
+
(0, node_assert_1.strict)(segInfo3);
|
|
266
273
|
const LocalRef2 = client1.createLocalReferencePosition(segInfo3.segment, segInfo3.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
267
274
|
const insert2 = client1.makeOpMessage(client1.insertTextLocal(2, "XY"), ++seq);
|
|
268
275
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(LocalRef1), 1);
|
|
269
276
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(LocalRef2), 5);
|
|
270
277
|
const c2SegInfo1 = client2.getContainingSegment(1);
|
|
278
|
+
(0, node_assert_1.strict)(c2SegInfo1);
|
|
271
279
|
const c2SegInfo3 = client2.getContainingSegment(3);
|
|
280
|
+
(0, node_assert_1.strict)(c2SegInfo3);
|
|
272
281
|
const remove = client2.makeOpMessage(client2.removeRangeLocal(0, client2.getLength()), ++seq);
|
|
273
282
|
const c2LocalRef1 = client2.createLocalReferencePosition(c2SegInfo1.segment, c2SegInfo1.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
274
283
|
const c2LocalRef2 = client2.createLocalReferencePosition(c2SegInfo3.segment, c2SegInfo3.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
@@ -301,7 +310,7 @@ describe("MergeTree.Client", () => {
|
|
|
301
310
|
const { segment, offset } = client1.getContainingSegment(0, {
|
|
302
311
|
referenceSequenceNumber: opFromBeforeRemovePerspective.referenceSequenceNumber,
|
|
303
312
|
clientId: opFromBeforeRemovePerspective.clientId,
|
|
304
|
-
});
|
|
313
|
+
}) ?? {};
|
|
305
314
|
(0, node_assert_1.strict)(segment && (0, segmentInfos_js_1.toRemovalInfo)(segment) !== undefined);
|
|
306
315
|
const transientRef = client1.createLocalReferencePosition(segment, offset, ops_js_1.ReferenceType.Transient, {});
|
|
307
316
|
node_assert_1.strict.equal(transientRef.getSegment(), segment);
|
|
@@ -317,13 +326,15 @@ describe("MergeTree.Client", () => {
|
|
|
317
326
|
client1.applyMsg(insert1);
|
|
318
327
|
client2.applyMsg(insert1);
|
|
319
328
|
const segInfo = client1.getContainingSegment(4);
|
|
320
|
-
|
|
329
|
+
(0, node_assert_1.strict)(segInfo);
|
|
330
|
+
const localRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
321
331
|
const createReference1 = client1.makeOpMessage({ type: ops_js_1.MergeTreeDeltaType.INSERT }, ++seq, insert1.sequenceNumber);
|
|
322
332
|
const remove1 = client2.makeOpMessage(client2.removeRangeLocal(4, 5), ++seq);
|
|
323
333
|
const insert2 = client1.makeOpMessage(client1.insertTextLocal(2, "XY"), ++seq);
|
|
324
334
|
const remove2 = client2.makeOpMessage(client2.removeRangeLocal(1, 4), ++seq);
|
|
325
335
|
const segoff = getSlideOnRemoveReferencePosition(client2, 4, createReference1);
|
|
326
|
-
|
|
336
|
+
(0, node_assert_1.strict)(segoff);
|
|
337
|
+
const c2LocalRef = client2.createLocalReferencePosition(segoff?.segment, segoff.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
327
338
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(localRef), 6);
|
|
328
339
|
node_assert_1.strict.equal(client2.localReferencePositionToPosition(c2LocalRef), 1);
|
|
329
340
|
client1.applyMsg(remove1);
|
|
@@ -348,6 +359,7 @@ describe("MergeTree.Client", () => {
|
|
|
348
359
|
// initialize the local reference collection on the segment, but keep it empty
|
|
349
360
|
{
|
|
350
361
|
const segInfo = clients.A.getContainingSegment(9);
|
|
362
|
+
(0, node_assert_1.strict)(segInfo);
|
|
351
363
|
const segment = segInfo.segment;
|
|
352
364
|
(0, node_assert_1.strict)(segment !== undefined && textSegment_js_1.TextSegment.is(segment));
|
|
353
365
|
node_assert_1.strict.strictEqual(segment.text[segInfo.offset], "9");
|
|
@@ -359,7 +371,8 @@ describe("MergeTree.Client", () => {
|
|
|
359
371
|
// add a local reference to the newly inserted segment that caused the split
|
|
360
372
|
{
|
|
361
373
|
const segInfo = clients.A.getContainingSegment(6);
|
|
362
|
-
|
|
374
|
+
(0, node_assert_1.strict)(segInfo);
|
|
375
|
+
const segment = segInfo?.segment;
|
|
363
376
|
(0, node_assert_1.strict)(segment !== undefined && textSegment_js_1.TextSegment.is(segment));
|
|
364
377
|
node_assert_1.strict.strictEqual(segment.text[segInfo.offset], "B");
|
|
365
378
|
clients.A.createLocalReferencePosition(segment, segInfo.offset, ops_js_1.ReferenceType.Simple, undefined);
|
|
@@ -425,7 +438,8 @@ describe("MergeTree.Client", () => {
|
|
|
425
438
|
client1.applyMsg(insert1);
|
|
426
439
|
client2.applyMsg(insert1);
|
|
427
440
|
const segInfo = client1.getContainingSegment(3);
|
|
428
|
-
|
|
441
|
+
(0, node_assert_1.strict)(segInfo);
|
|
442
|
+
const localRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined, localReference_js_1.SlidingPreference.BACKWARD);
|
|
429
443
|
node_assert_1.strict.equal(client1.localReferencePositionToPosition(localRef), 3);
|
|
430
444
|
const insert2 = client1.makeOpMessage(client1.insertTextLocal(4, "ghi"), ++seq);
|
|
431
445
|
client1.applyMsg(insert2);
|
|
@@ -471,20 +485,20 @@ describe("MergeTree.Client", () => {
|
|
|
471
485
|
client1.applyMsg(insert1);
|
|
472
486
|
client2.applyMsg(insert1);
|
|
473
487
|
const segInfo = client1.getContainingSegment(3);
|
|
474
|
-
(0, node_assert_1.strict)(segInfo
|
|
475
|
-
const localRef = client1.createLocalReferencePosition(segInfo
|
|
488
|
+
(0, node_assert_1.strict)(segInfo?.segment);
|
|
489
|
+
const localRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
476
490
|
addRef(localRef);
|
|
477
|
-
node_assert_1.strict.equal(localRef.getSegment(), segInfo
|
|
478
|
-
(0, node_assert_1.strict)(segInfo
|
|
479
|
-
(0, node_assert_1.strict)(!segInfo
|
|
480
|
-
segInfo
|
|
481
|
-
(0, node_assert_1.strict)(segInfo
|
|
491
|
+
node_assert_1.strict.equal(localRef.getSegment(), segInfo?.segment);
|
|
492
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs);
|
|
493
|
+
(0, node_assert_1.strict)(!segInfo?.segment.localRefs.empty);
|
|
494
|
+
segInfo?.segment.localRefs.removeLocalRef(localRef);
|
|
495
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs.empty);
|
|
482
496
|
// Cast is necessary because LocalReference is not exported, so we can't directly call link.
|
|
483
497
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
484
498
|
localRef.link(undefined, 0, undefined);
|
|
485
|
-
(0, node_assert_1.strict)(segInfo
|
|
486
|
-
node_assert_1.strict.equal(segInfo
|
|
487
|
-
node_assert_1.strict.equal(segInfo
|
|
499
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs.empty);
|
|
500
|
+
node_assert_1.strict.equal(segInfo?.segment.localRefs.empty, true);
|
|
501
|
+
node_assert_1.strict.equal(segInfo?.segment.localRefs.has(localRef), false);
|
|
488
502
|
node_assert_1.strict.equal(localRef.getSegment(), undefined);
|
|
489
503
|
node_assert_1.strict.equal(localRef.getOffset(), 0);
|
|
490
504
|
});
|
|
@@ -502,20 +516,20 @@ describe("MergeTree.Client", () => {
|
|
|
502
516
|
client1.applyMsg(insert1);
|
|
503
517
|
client2.applyMsg(insert1);
|
|
504
518
|
const segInfo = client1.getContainingSegment(3);
|
|
505
|
-
(0, node_assert_1.strict)(segInfo
|
|
506
|
-
const localRef = client1.createLocalReferencePosition(segInfo
|
|
519
|
+
(0, node_assert_1.strict)(segInfo?.segment);
|
|
520
|
+
const localRef = client1.createLocalReferencePosition(segInfo?.segment, segInfo.offset, ops_js_1.ReferenceType.SlideOnRemove, undefined);
|
|
507
521
|
addRef(localRef);
|
|
508
|
-
node_assert_1.strict.equal(localRef.getSegment(), segInfo
|
|
509
|
-
(0, node_assert_1.strict)(segInfo
|
|
510
|
-
(0, node_assert_1.strict)(!segInfo
|
|
522
|
+
node_assert_1.strict.equal(localRef.getSegment(), segInfo?.segment);
|
|
523
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs);
|
|
524
|
+
(0, node_assert_1.strict)(!segInfo?.segment.localRefs.empty);
|
|
511
525
|
// Cast is necessary because LocalReference is not exported, so we can't directly call link
|
|
512
526
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
513
527
|
localRef.link(undefined, 0, undefined);
|
|
514
|
-
(0, node_assert_1.strict)(segInfo
|
|
515
|
-
segInfo
|
|
516
|
-
(0, node_assert_1.strict)(segInfo
|
|
517
|
-
node_assert_1.strict.equal(segInfo
|
|
518
|
-
node_assert_1.strict.equal(segInfo
|
|
528
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs.empty);
|
|
529
|
+
segInfo?.segment.localRefs.removeLocalRef(localRef);
|
|
530
|
+
(0, node_assert_1.strict)(segInfo?.segment.localRefs.empty);
|
|
531
|
+
node_assert_1.strict.equal(segInfo?.segment.localRefs.empty, true);
|
|
532
|
+
node_assert_1.strict.equal(segInfo?.segment.localRefs.has(localRef), false);
|
|
519
533
|
node_assert_1.strict.equal(localRef.getSegment(), undefined);
|
|
520
534
|
node_assert_1.strict.equal(localRef.getOffset(), 0);
|
|
521
535
|
});
|