@fluidframework/test-runtime-utils 2.74.0-368706 → 2.74.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/assertTagging.config.mjs +1 -1
- package/dist/assertionShortCodesMap.d.ts +8 -15
- package/dist/assertionShortCodesMap.d.ts.map +1 -1
- package/dist/assertionShortCodesMap.js +9 -16
- package/dist/assertionShortCodesMap.js.map +1 -1
- package/dist/deepFreeze.js.map +1 -1
- package/dist/mockDeltas.d.ts.map +1 -1
- package/dist/mockDeltas.js.map +1 -1
- package/dist/mockStorage.d.ts.map +1 -1
- package/dist/mockStorage.js.map +1 -1
- package/dist/mocks.d.ts.map +1 -1
- package/dist/mocks.js.map +1 -1
- package/dist/mocksDataStoreContext.d.ts.map +1 -1
- package/dist/mocksDataStoreContext.js.map +1 -1
- package/dist/mocksForReconnection.d.ts.map +1 -1
- package/dist/mocksForReconnection.js.map +1 -1
- package/eslint.config.mts +30 -0
- package/lib/assertionShortCodesMap.d.ts +8 -15
- package/lib/assertionShortCodesMap.d.ts.map +1 -1
- package/lib/assertionShortCodesMap.js +9 -16
- package/lib/assertionShortCodesMap.js.map +1 -1
- package/lib/deepFreeze.js.map +1 -1
- package/lib/mockDeltas.d.ts.map +1 -1
- package/lib/mockDeltas.js.map +1 -1
- package/lib/mockStorage.d.ts.map +1 -1
- package/lib/mockStorage.js.map +1 -1
- package/lib/mocks.d.ts.map +1 -1
- package/lib/mocks.js.map +1 -1
- package/lib/mocksDataStoreContext.d.ts.map +1 -1
- package/lib/mocksDataStoreContext.js.map +1 -1
- package/lib/mocksForReconnection.d.ts.map +1 -1
- package/lib/mocksForReconnection.js.map +1 -1
- package/package.json +19 -18
- package/src/assertionShortCodesMap.ts +9 -16
- package/src/deepFreeze.ts +1 -1
- package/src/mockDeltas.ts +9 -9
- package/src/mockStorage.ts +1 -1
- package/src/mocks.ts +39 -36
- package/src/mocksDataStoreContext.ts +5 -1
- package/src/mocksForReconnection.ts +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocksForReconnection.js","sourceRoot":"","sources":["../src/mocksForReconnection.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 { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tcreateChildLogger,\n\traiseConnectedEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\ttype IMockContainerRuntimeIdAllocationMessage,\n\tIMockContainerRuntimeOptions,\n\tMockContainerRuntime,\n\tMockContainerRuntimeFactory,\n\tMockFluidDataStoreRuntime,\n} from \"./mocks.js\";\n\n/**\n * Specialized implementation of MockContainerRuntime for testing ops during reconnection.\n * @legacy @beta\n */\nexport class MockContainerRuntimeForReconnection extends MockContainerRuntime {\n\t/**\n\t * Contains messages from other clients that were sequenced while this runtime was marked as disconnected.\n\t */\n\tprotected readonly pendingRemoteMessages: ISequencedDocumentMessage[] = [];\n\n\t/**\n\t * Returns the connection state of the container runtime.\n\t * Any messages that are submitted while not connected will be resubmitted via the resubmit flow on reconnection.\n\t * Any messages received while disconnected will be processed on reconnection.\n\t * Also, the clientId of the runtime will change on reconnection.\n\t */\n\tpublic get connected(): boolean {\n\t\treturn this._connected;\n\t}\n\n\tpublic set connected(connected: boolean) {\n\t\tthis.setConnectedState(connected);\n\t}\n\n\tprotected processPendingMessages(pendingMessages: ISequencedDocumentMessage[]) {\n\t\tfor (const remoteMessage of pendingMessages) {\n\t\t\tthis.process(remoteMessage);\n\t\t}\n\t}\n\n\tprotected setConnectedState(connected: boolean): void {\n\t\tif (this._connected === connected) {\n\t\t\treturn;\n\t\t}\n\n\t\traiseConnectedEvent(createChildLogger(), this, connected);\n\t\tthis._connected = connected;\n\n\t\tif (connected) {\n\t\t\tthis.processPendingMessages(this.pendingRemoteMessages);\n\t\t\tthis.pendingRemoteMessages.length = 0;\n\t\t\tthis.deltaManager.clientSequenceNumber = 0;\n\t\t\t// We should get a new clientId on reconnection.\n\t\t\tthis.clientId = uuid();\n\t\t\t// Update the clientId in FluidDataStoreRuntime.\n\t\t\tthis.dataStoreRuntime.clientId = this.clientId;\n\t\t\tthis.factory.quorum.addMember(this.clientId, {});\n\t\t\t// On reconnection, ask the DDSes to resubmit pending messages.\n\t\t\tconst messagesToResubmit = this.pendingMessages.slice();\n\t\t\tthis.pendingMessages.length = 0;\n\t\t\tthis.reSubmitMessages(messagesToResubmit);\n\t\t} else {\n\t\t\t// On disconnection, clear any outstanding messages for this client because it will be resent.\n\t\t\tthis.factory.clearOutstandingClientMessages(this.clientId);\n\t\t\tthis.factory.quorum.removeMember(this.clientId);\n\t\t\tfor (const message of this.outbox) {\n\t\t\t\tthis.addPendingMessage(\n\t\t\t\t\tmessage.content,\n\t\t\t\t\tmessage.localOpMetadata,\n\t\t\t\t\t++this.deltaManager.clientSequenceNumber,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.outbox.length = 0;\n\t\t}\n\n\t\t// Let the DDSes know that the connection state changed.\n\t\tthis.dataStoreRuntime.setConnectionState(this.connected, this.clientId);\n\t}\n\n\tprivate _connected = true;\n\tprotected readonly processedOps?: ISequencedDocumentMessage[];\n\tconstructor(\n\t\tdataStoreRuntime: MockFluidDataStoreRuntime,\n\t\tprotected override readonly factory: MockContainerRuntimeFactoryForReconnection,\n\t\truntimeOptions: IMockContainerRuntimeOptions = {},\n\t\toverrides?: { minimumSequenceNumber?: number; trackRemoteOps?: boolean },\n\t) {\n\t\tsuper(dataStoreRuntime, factory, runtimeOptions, overrides);\n\t\tif (overrides?.trackRemoteOps === true) {\n\t\t\tthis.processedOps = [];\n\t\t}\n\t}\n\n\toverride process(message: ISequencedDocumentMessage) {\n\t\tif (this.connected) {\n\t\t\tthis.processedOps?.push(message);\n\t\t\tsuper.process(message);\n\t\t} else {\n\t\t\tthis.pendingRemoteMessages.push(message);\n\t\t}\n\t}\n\n\toverride submit(messageContent: any, localOpMetadata: unknown) {\n\t\t// Submit messages only if we are connection, otherwise, just add it to the pending queue.\n\t\tif (this.connected) {\n\t\t\treturn super.submit(messageContent, localOpMetadata);\n\t\t}\n\n\t\tthis.addPendingMessage(messageContent, localOpMetadata, -1);\n\t\treturn -1;\n\t}\n\n\toverride flush() {\n\t\t// Flush messages only if we are connected, otherwise, just ignore it.\n\t\tif (this.connected) {\n\t\t\tsuper.flush();\n\t\t}\n\t}\n\n\tpublic async initializeWithStashedOps(\n\t\tfromContainerRuntime: MockContainerRuntimeForReconnection,\n\t) {\n\t\tif (this.pendingMessages.length !== 0 || this.deltaManager.clientSequenceNumber !== 0) {\n\t\t\tthrow new Error(\"applyStashedOps must be called first, and once.\");\n\t\t}\n\n\t\tif (fromContainerRuntime.processedOps === undefined) {\n\t\t\tthrow new Error(\"containerRuntime must have trackRemoteOps true\");\n\t\t}\n\n\t\t// shutdown the existing client\n\t\tfromContainerRuntime.connected = false;\n\t\tfromContainerRuntime.flush();\n\t\tthis.factory.removeContainerRuntime(fromContainerRuntime);\n\t\t// clear any unprocessed ops for this client\n\t\tthis.factory.clearOutstandingClientMessages(fromContainerRuntime.clientId);\n\n\t\t// get the saved ops seen by the client, and its pending ops\n\t\tconst pendingMessages = fromContainerRuntime.pendingMessages.splice(0);\n\t\tconst remoteOps = [\n\t\t\t...fromContainerRuntime.processedOps.splice(0),\n\t\t\t...fromContainerRuntime.pendingRemoteMessages.splice(0),\n\t\t];\n\n\t\t// ensure no ops are sent to, or produced by the old client\n\t\t// this can help find bugs in the the harness\n\t\tObject.freeze(fromContainerRuntime.pendingMessages);\n\t\tObject.freeze(fromContainerRuntime.pendingRemoteMessages);\n\t\tObject.freeze(fromContainerRuntime.processedOps);\n\n\t\tlet refSeq = Math.min(\n\t\t\tremoteOps[0]?.referenceSequenceNumber ?? Number.MAX_SAFE_INTEGER,\n\t\t\tpendingMessages[0]?.referenceSequenceNumber ?? Number.MAX_SAFE_INTEGER,\n\t\t);\n\t\tif (refSeq === Number.MAX_SAFE_INTEGER) {\n\t\t\trefSeq = 0;\n\t\t}\n\t\tif (\n\t\t\tthis.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber !== refSeq ||\n\t\t\tthis.dataStoreRuntime.deltaManagerInternal.minimumSequenceNumber !== refSeq\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t\"computed min and ref seq don't match the loaded values; this indicates a bad load, or missing messages\",\n\t\t\t);\n\t\t}\n\n\t\tconst stashedOps = new Map<number, any>();\n\n\t\tremoteOps.forEach((op) => {\n\t\t\tif (op.clientId === this.clientId) {\n\t\t\t\tconst ops = stashedOps.get(op.referenceSequenceNumber) ?? [];\n\t\t\t\tops.push(op.contents);\n\t\t\t\tstashedOps.set(op.referenceSequenceNumber, ops);\n\t\t\t}\n\t\t});\n\t\tpendingMessages.forEach((op) => {\n\t\t\tconst ops = stashedOps.get(op.referenceSequenceNumber) ?? [];\n\t\t\tops.push(op.content);\n\t\t\tstashedOps.set(op.referenceSequenceNumber, ops);\n\t\t});\n\n\t\tconst applyStashedOpsAtSeq = async (seq: number) => {\n\t\t\tconst pendingAtSeq = stashedOps.get(seq);\n\t\t\tfor (const message of pendingAtSeq ?? []) {\n\t\t\t\t// As in production, do not locally apply any stashed ID allocation messages.\n\t\t\t\t// Instead, simply resubmit them.\n\t\t\t\tif ((message as IMockContainerRuntimeIdAllocationMessage).type === \"idAllocation\") {\n\t\t\t\t\tthis.submit(message, undefined);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.dataStoreRuntime.applyStashedOp(message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tstashedOps.delete(seq);\n\t\t};\n\t\tawait applyStashedOpsAtSeq(this.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber);\n\t\t// apply the saved and pending ops\n\t\tfor (const savedOp of remoteOps) {\n\t\t\tthis.process(savedOp);\n\t\t\tawait applyStashedOpsAtSeq(\n\t\t\t\tthis.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber,\n\t\t\t);\n\t\t}\n\t\tif (stashedOps.size !== 0) {\n\t\t\tthrow new Error(\"There should be no pending message after saved ops are processed\");\n\t\t}\n\t\t// issue a reconnect to rebase pending ops\n\t\tthis.connected = false;\n\t\tthis.connected = true;\n\t}\n}\n\n/**\n * Specialized implementation of MockContainerRuntimeFactory for testing ops during reconnection.\n * @legacy @beta\n */\nexport class MockContainerRuntimeFactoryForReconnection extends MockContainerRuntimeFactory {\n\toverride createContainerRuntime(\n\t\tdataStoreRuntime: MockFluidDataStoreRuntime,\n\t\toverrides?: { minimumSequenceNumber?: number; trackRemoteOps?: boolean },\n\t): MockContainerRuntimeForReconnection {\n\t\tconst containerRuntime = new MockContainerRuntimeForReconnection(\n\t\t\tdataStoreRuntime,\n\t\t\tthis,\n\t\t\tthis.runtimeOptions,\n\t\t\toverrides,\n\t\t);\n\t\tthis.runtimes.add(containerRuntime);\n\t\treturn containerRuntime;\n\t}\n\n\tpublic clearOutstandingClientMessages(clientId: string) {\n\t\t// Delete all the messages for client with the given clientId.\n\t\tthis.messages = this.messages.filter((message: ISequencedDocumentMessage) => {\n\t\t\treturn message.clientId !== clientId;\n\t\t});\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mocksForReconnection.js","sourceRoot":"","sources":["../src/mocksForReconnection.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 { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\nimport {\n\tcreateChildLogger,\n\traiseConnectedEvent,\n} from \"@fluidframework/telemetry-utils/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport {\n\ttype IMockContainerRuntimeIdAllocationMessage,\n\tIMockContainerRuntimeOptions,\n\tMockContainerRuntime,\n\tMockContainerRuntimeFactory,\n\tMockFluidDataStoreRuntime,\n} from \"./mocks.js\";\n\n/**\n * Specialized implementation of MockContainerRuntime for testing ops during reconnection.\n * @legacy @beta\n */\nexport class MockContainerRuntimeForReconnection extends MockContainerRuntime {\n\t/**\n\t * Contains messages from other clients that were sequenced while this runtime was marked as disconnected.\n\t */\n\tprotected readonly pendingRemoteMessages: ISequencedDocumentMessage[] = [];\n\n\t/**\n\t * Returns the connection state of the container runtime.\n\t * Any messages that are submitted while not connected will be resubmitted via the resubmit flow on reconnection.\n\t * Any messages received while disconnected will be processed on reconnection.\n\t * Also, the clientId of the runtime will change on reconnection.\n\t */\n\tpublic get connected(): boolean {\n\t\treturn this._connected;\n\t}\n\n\tpublic set connected(connected: boolean) {\n\t\tthis.setConnectedState(connected);\n\t}\n\n\tprotected processPendingMessages(pendingMessages: ISequencedDocumentMessage[]): void {\n\t\tfor (const remoteMessage of pendingMessages) {\n\t\t\tthis.process(remoteMessage);\n\t\t}\n\t}\n\n\tprotected setConnectedState(connected: boolean): void {\n\t\tif (this._connected === connected) {\n\t\t\treturn;\n\t\t}\n\n\t\traiseConnectedEvent(createChildLogger(), this, connected);\n\t\tthis._connected = connected;\n\n\t\tif (connected) {\n\t\t\tthis.processPendingMessages(this.pendingRemoteMessages);\n\t\t\tthis.pendingRemoteMessages.length = 0;\n\t\t\tthis.deltaManager.clientSequenceNumber = 0;\n\t\t\t// We should get a new clientId on reconnection.\n\t\t\tthis.clientId = uuid();\n\t\t\t// Update the clientId in FluidDataStoreRuntime.\n\t\t\tthis.dataStoreRuntime.clientId = this.clientId;\n\t\t\tthis.factory.quorum.addMember(this.clientId, {});\n\t\t\t// On reconnection, ask the DDSes to resubmit pending messages.\n\t\t\tconst messagesToResubmit = this.pendingMessages.slice();\n\t\t\tthis.pendingMessages.length = 0;\n\t\t\tthis.reSubmitMessages(messagesToResubmit);\n\t\t} else {\n\t\t\t// On disconnection, clear any outstanding messages for this client because it will be resent.\n\t\t\tthis.factory.clearOutstandingClientMessages(this.clientId);\n\t\t\tthis.factory.quorum.removeMember(this.clientId);\n\t\t\tfor (const message of this.outbox) {\n\t\t\t\tthis.addPendingMessage(\n\t\t\t\t\tmessage.content,\n\t\t\t\t\tmessage.localOpMetadata,\n\t\t\t\t\t++this.deltaManager.clientSequenceNumber,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthis.outbox.length = 0;\n\t\t}\n\n\t\t// Let the DDSes know that the connection state changed.\n\t\tthis.dataStoreRuntime.setConnectionState(this.connected, this.clientId);\n\t}\n\n\tprivate _connected = true;\n\tprotected readonly processedOps?: ISequencedDocumentMessage[];\n\tconstructor(\n\t\tdataStoreRuntime: MockFluidDataStoreRuntime,\n\t\tprotected override readonly factory: MockContainerRuntimeFactoryForReconnection,\n\t\truntimeOptions: IMockContainerRuntimeOptions = {},\n\t\toverrides?: { minimumSequenceNumber?: number; trackRemoteOps?: boolean },\n\t) {\n\t\tsuper(dataStoreRuntime, factory, runtimeOptions, overrides);\n\t\tif (overrides?.trackRemoteOps === true) {\n\t\t\tthis.processedOps = [];\n\t\t}\n\t}\n\n\toverride process(message: ISequencedDocumentMessage): void {\n\t\tif (this.connected) {\n\t\t\tthis.processedOps?.push(message);\n\t\t\tsuper.process(message);\n\t\t} else {\n\t\t\tthis.pendingRemoteMessages.push(message);\n\t\t}\n\t}\n\n\toverride submit(messageContent: any, localOpMetadata: unknown): number {\n\t\t// Submit messages only if we are connection, otherwise, just add it to the pending queue.\n\t\tif (this.connected) {\n\t\t\treturn super.submit(messageContent, localOpMetadata);\n\t\t}\n\n\t\tthis.addPendingMessage(messageContent, localOpMetadata, -1);\n\t\treturn -1;\n\t}\n\n\toverride flush(): void {\n\t\t// Flush messages only if we are connected, otherwise, just ignore it.\n\t\tif (this.connected) {\n\t\t\tsuper.flush();\n\t\t}\n\t}\n\n\tpublic async initializeWithStashedOps(\n\t\tfromContainerRuntime: MockContainerRuntimeForReconnection,\n\t): Promise<void> {\n\t\tif (this.pendingMessages.length !== 0 || this.deltaManager.clientSequenceNumber !== 0) {\n\t\t\tthrow new Error(\"applyStashedOps must be called first, and once.\");\n\t\t}\n\n\t\tif (fromContainerRuntime.processedOps === undefined) {\n\t\t\tthrow new Error(\"containerRuntime must have trackRemoteOps true\");\n\t\t}\n\n\t\t// shutdown the existing client\n\t\tfromContainerRuntime.connected = false;\n\t\tfromContainerRuntime.flush();\n\t\tthis.factory.removeContainerRuntime(fromContainerRuntime);\n\t\t// clear any unprocessed ops for this client\n\t\tthis.factory.clearOutstandingClientMessages(fromContainerRuntime.clientId);\n\n\t\t// get the saved ops seen by the client, and its pending ops\n\t\tconst pendingMessages = fromContainerRuntime.pendingMessages.splice(0);\n\t\tconst remoteOps = [\n\t\t\t...fromContainerRuntime.processedOps.splice(0),\n\t\t\t...fromContainerRuntime.pendingRemoteMessages.splice(0),\n\t\t];\n\n\t\t// ensure no ops are sent to, or produced by the old client\n\t\t// this can help find bugs in the the harness\n\t\tObject.freeze(fromContainerRuntime.pendingMessages);\n\t\tObject.freeze(fromContainerRuntime.pendingRemoteMessages);\n\t\tObject.freeze(fromContainerRuntime.processedOps);\n\n\t\tlet refSeq = Math.min(\n\t\t\tremoteOps[0]?.referenceSequenceNumber ?? Number.MAX_SAFE_INTEGER,\n\t\t\tpendingMessages[0]?.referenceSequenceNumber ?? Number.MAX_SAFE_INTEGER,\n\t\t);\n\t\tif (refSeq === Number.MAX_SAFE_INTEGER) {\n\t\t\trefSeq = 0;\n\t\t}\n\t\tif (\n\t\t\tthis.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber !== refSeq ||\n\t\t\tthis.dataStoreRuntime.deltaManagerInternal.minimumSequenceNumber !== refSeq\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t\"computed min and ref seq don't match the loaded values; this indicates a bad load, or missing messages\",\n\t\t\t);\n\t\t}\n\n\t\tconst stashedOps = new Map<number, any>();\n\n\t\tremoteOps.forEach((op) => {\n\t\t\tif (op.clientId === this.clientId) {\n\t\t\t\tconst ops = stashedOps.get(op.referenceSequenceNumber) ?? [];\n\t\t\t\tops.push(op.contents);\n\t\t\t\tstashedOps.set(op.referenceSequenceNumber, ops);\n\t\t\t}\n\t\t});\n\t\tpendingMessages.forEach((op) => {\n\t\t\tconst ops = stashedOps.get(op.referenceSequenceNumber) ?? [];\n\t\t\tops.push(op.content);\n\t\t\tstashedOps.set(op.referenceSequenceNumber, ops);\n\t\t});\n\n\t\tconst applyStashedOpsAtSeq = async (seq: number): Promise<void> => {\n\t\t\tconst pendingAtSeq = stashedOps.get(seq);\n\t\t\tfor (const message of pendingAtSeq ?? []) {\n\t\t\t\t// As in production, do not locally apply any stashed ID allocation messages.\n\t\t\t\t// Instead, simply resubmit them.\n\t\t\t\tif ((message as IMockContainerRuntimeIdAllocationMessage).type === \"idAllocation\") {\n\t\t\t\t\tthis.submit(message, undefined);\n\t\t\t\t} else {\n\t\t\t\t\tawait this.dataStoreRuntime.applyStashedOp(message);\n\t\t\t\t}\n\t\t\t}\n\t\t\tstashedOps.delete(seq);\n\t\t};\n\t\tawait applyStashedOpsAtSeq(this.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber);\n\t\t// apply the saved and pending ops\n\t\tfor (const savedOp of remoteOps) {\n\t\t\tthis.process(savedOp);\n\t\t\tawait applyStashedOpsAtSeq(\n\t\t\t\tthis.dataStoreRuntime.deltaManagerInternal.lastSequenceNumber,\n\t\t\t);\n\t\t}\n\t\tif (stashedOps.size !== 0) {\n\t\t\tthrow new Error(\"There should be no pending message after saved ops are processed\");\n\t\t}\n\t\t// issue a reconnect to rebase pending ops\n\t\tthis.connected = false;\n\t\tthis.connected = true;\n\t}\n}\n\n/**\n * Specialized implementation of MockContainerRuntimeFactory for testing ops during reconnection.\n * @legacy @beta\n */\nexport class MockContainerRuntimeFactoryForReconnection extends MockContainerRuntimeFactory {\n\toverride createContainerRuntime(\n\t\tdataStoreRuntime: MockFluidDataStoreRuntime,\n\t\toverrides?: { minimumSequenceNumber?: number; trackRemoteOps?: boolean },\n\t): MockContainerRuntimeForReconnection {\n\t\tconst containerRuntime = new MockContainerRuntimeForReconnection(\n\t\t\tdataStoreRuntime,\n\t\t\tthis,\n\t\t\tthis.runtimeOptions,\n\t\t\toverrides,\n\t\t);\n\t\tthis.runtimes.add(containerRuntime);\n\t\treturn containerRuntime;\n\t}\n\n\tpublic clearOutstandingClientMessages(clientId: string): void {\n\t\t// Delete all the messages for client with the given clientId.\n\t\tthis.messages = this.messages.filter((message: ISequencedDocumentMessage) => {\n\t\t\treturn message.clientId !== clientId;\n\t\t});\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/test-runtime-utils",
|
|
3
|
-
"version": "2.74.0
|
|
3
|
+
"version": "2.74.0",
|
|
4
4
|
"description": "Fluid runtime test utilities",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -69,30 +69,30 @@
|
|
|
69
69
|
"temp-directory": "nyc/.nyc_output"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@fluid-internal/client-utils": "2.74.0
|
|
73
|
-
"@fluidframework/container-definitions": "2.74.0
|
|
74
|
-
"@fluidframework/container-runtime-definitions": "2.74.0
|
|
75
|
-
"@fluidframework/core-interfaces": "2.74.0
|
|
76
|
-
"@fluidframework/core-utils": "2.74.0
|
|
77
|
-
"@fluidframework/datastore-definitions": "2.74.0
|
|
78
|
-
"@fluidframework/driver-definitions": "2.74.0
|
|
79
|
-
"@fluidframework/driver-utils": "2.74.0
|
|
80
|
-
"@fluidframework/id-compressor": "2.74.0
|
|
81
|
-
"@fluidframework/routerlicious-driver": "2.74.0
|
|
82
|
-
"@fluidframework/runtime-definitions": "2.74.0
|
|
83
|
-
"@fluidframework/runtime-utils": "2.74.0
|
|
84
|
-
"@fluidframework/telemetry-utils": "2.74.0
|
|
72
|
+
"@fluid-internal/client-utils": "~2.74.0",
|
|
73
|
+
"@fluidframework/container-definitions": "~2.74.0",
|
|
74
|
+
"@fluidframework/container-runtime-definitions": "~2.74.0",
|
|
75
|
+
"@fluidframework/core-interfaces": "~2.74.0",
|
|
76
|
+
"@fluidframework/core-utils": "~2.74.0",
|
|
77
|
+
"@fluidframework/datastore-definitions": "~2.74.0",
|
|
78
|
+
"@fluidframework/driver-definitions": "~2.74.0",
|
|
79
|
+
"@fluidframework/driver-utils": "~2.74.0",
|
|
80
|
+
"@fluidframework/id-compressor": "~2.74.0",
|
|
81
|
+
"@fluidframework/routerlicious-driver": "~2.74.0",
|
|
82
|
+
"@fluidframework/runtime-definitions": "~2.74.0",
|
|
83
|
+
"@fluidframework/runtime-utils": "~2.74.0",
|
|
84
|
+
"@fluidframework/telemetry-utils": "~2.74.0",
|
|
85
85
|
"jsrsasign": "^11.0.0",
|
|
86
86
|
"uuid": "^11.1.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
89
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
90
90
|
"@biomejs/biome": "~1.9.3",
|
|
91
|
-
"@fluid-internal/mocha-test-setup": "2.74.0
|
|
92
|
-
"@fluid-tools/build-cli": "^0.
|
|
91
|
+
"@fluid-internal/mocha-test-setup": "~2.74.0",
|
|
92
|
+
"@fluid-tools/build-cli": "^0.61.0",
|
|
93
93
|
"@fluidframework/build-common": "^2.0.3",
|
|
94
|
-
"@fluidframework/build-tools": "^0.
|
|
95
|
-
"@fluidframework/eslint-config-fluid": "2.74.0
|
|
94
|
+
"@fluidframework/build-tools": "^0.61.0",
|
|
95
|
+
"@fluidframework/eslint-config-fluid": "~2.74.0",
|
|
96
96
|
"@fluidframework/test-runtime-utils-previous": "npm:@fluidframework/test-runtime-utils@2.73.0",
|
|
97
97
|
"@microsoft/api-extractor": "7.52.11",
|
|
98
98
|
"@types/jsrsasign": "^10.5.12",
|
|
@@ -103,6 +103,7 @@
|
|
|
103
103
|
"copyfiles": "^2.4.1",
|
|
104
104
|
"cross-env": "^7.0.3",
|
|
105
105
|
"eslint": "~8.57.1",
|
|
106
|
+
"jiti": "^2.6.1",
|
|
106
107
|
"mocha": "^10.8.2",
|
|
107
108
|
"mocha-multi-reporters": "^1.5.1",
|
|
108
109
|
"rimraf": "^4.4.0",
|
|
@@ -1422,18 +1422,6 @@ export const shortCodeMap = {
|
|
|
1422
1422
|
"0xa6f": "Pending changes must exist for rollback when collaborating",
|
|
1423
1423
|
"0xa70": "Pending changes must not exist when not collaborating",
|
|
1424
1424
|
"0xa71": "must have local change to ack",
|
|
1425
|
-
"0xa73": "The typeField must be present in new JSON content",
|
|
1426
|
-
"0xa74": "Expected object schema",
|
|
1427
|
-
"0xa75": "the field must be an array node",
|
|
1428
|
-
"0xa76": "the modification must be an array node",
|
|
1429
|
-
"0xa77": "node to move must exist",
|
|
1430
|
-
"0xa78": "node to move must exist",
|
|
1431
|
-
"0xa79": "objectId does not exist in nodeMap",
|
|
1432
|
-
"0xa7a": "Different scopes not supported yet.",
|
|
1433
|
-
"0xa7b": "Collision of object id property.",
|
|
1434
|
-
"0xa7c": "Ref not found.",
|
|
1435
|
-
"0xa7d": "Expected at least two types",
|
|
1436
|
-
"0xa7e": "Expected at least two types",
|
|
1437
1425
|
"0xa7f": "Delta manager does not have inbound/outbound queues.",
|
|
1438
1426
|
"0xa80": "Invalid delta manager",
|
|
1439
1427
|
"0xa83": "Expected commit(s) for a non no-op rebase",
|
|
@@ -1624,7 +1612,6 @@ export const shortCodeMap = {
|
|
|
1624
1612
|
"0xb5d": "Expected last remove to be unacked",
|
|
1625
1613
|
"0xb5e": "Expected prior remove to be acked",
|
|
1626
1614
|
"0xb5f": "Expected same length for client ids and seqs",
|
|
1627
|
-
"0xb60": "Invalid schema",
|
|
1628
1615
|
"0xb61": "Invalid old reference",
|
|
1629
1616
|
"0xb62": "Invalid new segment on rebase",
|
|
1630
1617
|
"0xb63": "Resubmitting obliterate op without obliterate info in segment group",
|
|
@@ -1777,7 +1764,6 @@ export const shortCodeMap = {
|
|
|
1777
1764
|
"0xc16": "missing schema for array node",
|
|
1778
1765
|
"0xc17": "Expected MapNodeStoredSchema",
|
|
1779
1766
|
"0xc1a": "Expected MapNodeStoredSchema",
|
|
1780
|
-
"0xc1b": "Expected at least two types",
|
|
1781
1767
|
"0xc1e": "Expected a constructed node to be an object",
|
|
1782
1768
|
"0xc1f": "Transaction did not complete.",
|
|
1783
1769
|
"0xc20": "snapshot tree not found for one of tree's summarizables",
|
|
@@ -1841,7 +1827,6 @@ export const shortCodeMap = {
|
|
|
1841
1827
|
"0xc62": "Cannot encode branch base without originatorId",
|
|
1842
1828
|
"0xc63": "Cannot decode branch id without originatorId",
|
|
1843
1829
|
"0xc64": "Cannot decode branch base without originatorId",
|
|
1844
|
-
"0xc65": "Cannot encode V5 summary without originator",
|
|
1845
1830
|
"0xc66": "Shared branches must have an id",
|
|
1846
1831
|
"0xc67": "Duplicate shared branch id",
|
|
1847
1832
|
"0xc68": "Only commit messages are supported",
|
|
@@ -1902,5 +1887,13 @@ export const shortCodeMap = {
|
|
|
1902
1887
|
"0xca0": "Unsupported FieldBatchFormatVersion for incremental encoding; must be v2 or higher",
|
|
1903
1888
|
"0xca1": "Unsupported FieldBatchFormatVersion for incremental encoding; must be v2 or higher",
|
|
1904
1889
|
"0xca2": "localOpActivity must be undefined when entering rollback",
|
|
1905
|
-
"0xca3": "localOpActivity must be undefined when entering applyStashedOp"
|
|
1890
|
+
"0xca3": "localOpActivity must be undefined when entering applyStashedOp",
|
|
1891
|
+
"0xca4": "Expected applied commit to be parented",
|
|
1892
|
+
"0xca5": "Cannot encode vSharedBranches summary without originator",
|
|
1893
|
+
"0xca6": "Unsupported write version requested.",
|
|
1894
|
+
"0xca7": "getUnhydratedContext should not be reentrant",
|
|
1895
|
+
"0xca8": "missing schema",
|
|
1896
|
+
"0xca9": "missing schema",
|
|
1897
|
+
"0xcaa": "Reachable schema missing from input TreeSchema",
|
|
1898
|
+
"0xcab": "missing kind"
|
|
1906
1899
|
};
|
package/src/deepFreeze.ts
CHANGED
package/src/mockDeltas.ts
CHANGED
|
@@ -28,7 +28,7 @@ export class MockDeltaQueue<T> extends EventEmitter implements IDeltaQueue<T> {
|
|
|
28
28
|
protected readonly queue: T[] = [];
|
|
29
29
|
protected pauseCount = 0;
|
|
30
30
|
|
|
31
|
-
public processCallback: (el: T) => void = () => {};
|
|
31
|
+
public processCallback: (el: T) => void = (): void => {};
|
|
32
32
|
|
|
33
33
|
public get disposed(): any {
|
|
34
34
|
return undefined;
|
|
@@ -38,7 +38,7 @@ export class MockDeltaQueue<T> extends EventEmitter implements IDeltaQueue<T> {
|
|
|
38
38
|
return this.pauseCount !== 0;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
public get length() {
|
|
41
|
+
public get length(): number {
|
|
42
42
|
return this.queue.length;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -46,7 +46,7 @@ export class MockDeltaQueue<T> extends EventEmitter implements IDeltaQueue<T> {
|
|
|
46
46
|
return this.queue.length === 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
protected process() {
|
|
49
|
+
protected process(): void {
|
|
50
50
|
void Promise.resolve().then(() => {
|
|
51
51
|
while (this.pauseCount === 0 && this.length > 0) {
|
|
52
52
|
const el = this.pop();
|
|
@@ -56,13 +56,13 @@ export class MockDeltaQueue<T> extends EventEmitter implements IDeltaQueue<T> {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
public push(el: T) {
|
|
59
|
+
public push(el: T): void {
|
|
60
60
|
this.queue.push(el);
|
|
61
61
|
this.emit("push", el);
|
|
62
62
|
this.process();
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
public pop() {
|
|
65
|
+
public pop(): T | undefined {
|
|
66
66
|
return this.queue.shift();
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -84,7 +84,7 @@ export class MockDeltaQueue<T> extends EventEmitter implements IDeltaQueue<T> {
|
|
|
84
84
|
return this.queue;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
public dispose() {}
|
|
87
|
+
public dispose(): void {}
|
|
88
88
|
|
|
89
89
|
public async waitTillProcessingDone(): Promise<{ count: number; duration: number }> {
|
|
90
90
|
throw new Error("NYI");
|
|
@@ -110,7 +110,7 @@ export class MockDeltaManager
|
|
|
110
110
|
public readOnlyInfo: ReadOnlyInfo = { readonly: false };
|
|
111
111
|
public readonly clientType: string = undefined as any;
|
|
112
112
|
public readonly clientDetails: IClientDetails = {} as any;
|
|
113
|
-
public get IDeltaSender() {
|
|
113
|
+
public get IDeltaSender(): this {
|
|
114
114
|
return this;
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -155,7 +155,7 @@ export class MockDeltaManager
|
|
|
155
155
|
|
|
156
156
|
public submitSignal(content: any): void {}
|
|
157
157
|
|
|
158
|
-
public flush() {}
|
|
158
|
+
public flush(): void {}
|
|
159
159
|
|
|
160
160
|
public submit(
|
|
161
161
|
type: MessageType,
|
|
@@ -166,7 +166,7 @@ export class MockDeltaManager
|
|
|
166
166
|
return 0;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
public dispose() {
|
|
169
|
+
public dispose(): void {
|
|
170
170
|
this.removeAllListeners();
|
|
171
171
|
}
|
|
172
172
|
|
package/src/mockStorage.ts
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
* @legacy @beta
|
|
20
20
|
*/
|
|
21
21
|
export class MockStorage implements IChannelStorageService {
|
|
22
|
-
public static createFromSummary(summaryTree: ISummaryTree) {
|
|
22
|
+
public static createFromSummary(summaryTree: ISummaryTree): MockStorage {
|
|
23
23
|
const tree = convertSummaryTreeToITree(summaryTree);
|
|
24
24
|
return new MockStorage(tree);
|
|
25
25
|
}
|
package/src/mocks.ts
CHANGED
|
@@ -106,16 +106,16 @@ export class MockDeltaConnection implements IDeltaConnection {
|
|
|
106
106
|
this.dirtyFn();
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
public setConnectionState(connected: boolean) {
|
|
109
|
+
public setConnectionState(connected: boolean): void {
|
|
110
110
|
this._connected = connected;
|
|
111
111
|
this.handler?.setConnectionState(connected);
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
public processMessages(messageCollection: IRuntimeMessageCollection) {
|
|
114
|
+
public processMessages(messageCollection: IRuntimeMessageCollection): void {
|
|
115
115
|
this.handler?.processMessages?.(messageCollection);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
-
public reSubmit(content: any, localOpMetadata: unknown, squash?: boolean) {
|
|
118
|
+
public reSubmit(content: any, localOpMetadata: unknown, squash?: boolean): void {
|
|
119
119
|
this.handler?.reSubmit(content, localOpMetadata, squash);
|
|
120
120
|
}
|
|
121
121
|
|
|
@@ -249,7 +249,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
249
249
|
return deltaConnection;
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
-
public finalizeIdRange(range: IdCreationRange) {
|
|
252
|
+
public finalizeIdRange(range: IdCreationRange): void {
|
|
253
253
|
assert(
|
|
254
254
|
this.dataStoreRuntime.idCompressor !== undefined,
|
|
255
255
|
"Shouldn't try to finalize IdRanges without an IdCompressor",
|
|
@@ -260,7 +260,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
260
260
|
// This enables manual control over flush mode, allowing operations like rollback to be executed in a controlled environment.
|
|
261
261
|
#manualFlushCalls: number = 0;
|
|
262
262
|
|
|
263
|
-
public async runWithManualFlush(act: () => void | Promise<void>) {
|
|
263
|
+
public async runWithManualFlush(act: () => void | Promise<void>): Promise<void> {
|
|
264
264
|
this.#manualFlushCalls++;
|
|
265
265
|
try {
|
|
266
266
|
await act();
|
|
@@ -333,7 +333,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
333
333
|
}
|
|
334
334
|
|
|
335
335
|
public dirty(): void {}
|
|
336
|
-
public get isDirty() {
|
|
336
|
+
public get isDirty(): boolean {
|
|
337
337
|
return this.pendingMessages.length > 0;
|
|
338
338
|
}
|
|
339
339
|
|
|
@@ -341,7 +341,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
341
341
|
* If flush mode is set to FlushMode.TurnBased, it will send all messages queued since the last time
|
|
342
342
|
* this method (or `flushSomeMessages`) was called. Otherwise, calling the method does nothing.
|
|
343
343
|
*/
|
|
344
|
-
public flush() {
|
|
344
|
+
public flush(): void {
|
|
345
345
|
this.flushSomeMessages(this.outbox.length);
|
|
346
346
|
}
|
|
347
347
|
|
|
@@ -393,7 +393,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
393
393
|
*
|
|
394
394
|
* The method requires `runtimeOptions.enableGroupedBatching` to be enabled.
|
|
395
395
|
*/
|
|
396
|
-
public rebase() {
|
|
396
|
+
public rebase(): void {
|
|
397
397
|
if (this.runtimeOptions.flushMode !== FlushMode.TurnBased) {
|
|
398
398
|
return;
|
|
399
399
|
}
|
|
@@ -461,7 +461,10 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
461
461
|
return undefined;
|
|
462
462
|
}
|
|
463
463
|
|
|
464
|
-
private submitInternal(
|
|
464
|
+
private submitInternal(
|
|
465
|
+
message: IInternalMockRuntimeMessage,
|
|
466
|
+
clientSequenceNumber: number,
|
|
467
|
+
): void {
|
|
465
468
|
// Here, we should instead push to the DeltaManager. And the DeltaManager will push things into the factory's messages
|
|
466
469
|
this.deltaManager.outbound.push([
|
|
467
470
|
{
|
|
@@ -475,7 +478,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
475
478
|
this.addPendingMessage(message.content, message.localOpMetadata, clientSequenceNumber);
|
|
476
479
|
}
|
|
477
480
|
|
|
478
|
-
public process(message: ISequencedDocumentMessage) {
|
|
481
|
+
public process(message: ISequencedDocumentMessage): void {
|
|
479
482
|
this.deltaManager.process(message);
|
|
480
483
|
const [local, localOpMetadata] = this.processInternal(message);
|
|
481
484
|
|
|
@@ -497,7 +500,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
497
500
|
content: any,
|
|
498
501
|
localOpMetadata: unknown,
|
|
499
502
|
clientSequenceNumber: number,
|
|
500
|
-
) {
|
|
503
|
+
): void {
|
|
501
504
|
const pendingMessage: IMockContainerRuntimePendingMessage = {
|
|
502
505
|
referenceSequenceNumber: this.deltaManager.lastSequenceNumber,
|
|
503
506
|
content,
|
|
@@ -521,7 +524,7 @@ export class MockContainerRuntime extends TypedEventEmitter<IContainerRuntimeEve
|
|
|
521
524
|
return [local, localOpMetadata];
|
|
522
525
|
}
|
|
523
526
|
|
|
524
|
-
public async resolveHandle(handle: IFluidHandle) {
|
|
527
|
+
public async resolveHandle(handle: IFluidHandle): Promise<IResponse> {
|
|
525
528
|
return this.dataStoreRuntime.resolveHandle({
|
|
526
529
|
url: toFluidHandleInternal(handle).absolutePath,
|
|
527
530
|
});
|
|
@@ -563,7 +566,7 @@ export class MockContainerRuntimeFactory {
|
|
|
563
566
|
this.runtimeOptions = makeContainerRuntimeOptions(mockContainerRuntimeOptions);
|
|
564
567
|
}
|
|
565
568
|
|
|
566
|
-
public get outstandingMessageCount() {
|
|
569
|
+
public get outstandingMessageCount(): number {
|
|
567
570
|
return this.messages.length;
|
|
568
571
|
}
|
|
569
572
|
|
|
@@ -601,11 +604,11 @@ export class MockContainerRuntimeFactory {
|
|
|
601
604
|
return containerRuntime;
|
|
602
605
|
}
|
|
603
606
|
|
|
604
|
-
public removeContainerRuntime(containerRuntime: MockContainerRuntime) {
|
|
607
|
+
public removeContainerRuntime(containerRuntime: MockContainerRuntime): void {
|
|
605
608
|
this.runtimes.delete(containerRuntime);
|
|
606
609
|
}
|
|
607
610
|
|
|
608
|
-
public pushMessage(msg: Partial<ISequencedDocumentMessage>) {
|
|
611
|
+
public pushMessage(msg: Partial<ISequencedDocumentMessage>): void {
|
|
609
612
|
deepFreeze(msg);
|
|
610
613
|
if (
|
|
611
614
|
msg.clientId &&
|
|
@@ -618,7 +621,7 @@ export class MockContainerRuntimeFactory {
|
|
|
618
621
|
}
|
|
619
622
|
|
|
620
623
|
protected lastProcessedMessage: ISequencedDocumentMessage | undefined;
|
|
621
|
-
protected getFirstMessageToProcess() {
|
|
624
|
+
protected getFirstMessageToProcess(): ISequencedDocumentMessage {
|
|
622
625
|
assert(this.messages.length > 0, "The message queue should not be empty");
|
|
623
626
|
|
|
624
627
|
// Explicitly JSON clone the value to match the behavior of going thru the wire.
|
|
@@ -640,7 +643,7 @@ export class MockContainerRuntimeFactory {
|
|
|
640
643
|
return message;
|
|
641
644
|
}
|
|
642
645
|
|
|
643
|
-
private processFirstMessage() {
|
|
646
|
+
private processFirstMessage(): void {
|
|
644
647
|
const message = this.getFirstMessageToProcess();
|
|
645
648
|
for (const runtime of this.runtimes) {
|
|
646
649
|
runtime.process(message);
|
|
@@ -650,7 +653,7 @@ export class MockContainerRuntimeFactory {
|
|
|
650
653
|
/**
|
|
651
654
|
* Process one of the queued messages. Throws if no messages are queued.
|
|
652
655
|
*/
|
|
653
|
-
public processOneMessage() {
|
|
656
|
+
public processOneMessage(): void {
|
|
654
657
|
if (this.messages.length === 0) {
|
|
655
658
|
throw new Error("Tried to process a message that did not exist");
|
|
656
659
|
}
|
|
@@ -663,7 +666,7 @@ export class MockContainerRuntimeFactory {
|
|
|
663
666
|
* Process a given number of queued messages. Throws if there are fewer messages queued than requested.
|
|
664
667
|
* @param count - the number of messages to process
|
|
665
668
|
*/
|
|
666
|
-
public processSomeMessages(count: number) {
|
|
669
|
+
public processSomeMessages(count: number): void {
|
|
667
670
|
if (count > this.messages.length) {
|
|
668
671
|
throw new Error("Tried to process more messages than exist");
|
|
669
672
|
}
|
|
@@ -678,7 +681,7 @@ export class MockContainerRuntimeFactory {
|
|
|
678
681
|
/**
|
|
679
682
|
* Process all remaining messages in the queue.
|
|
680
683
|
*/
|
|
681
|
-
public processAllMessages() {
|
|
684
|
+
public processAllMessages(): void {
|
|
682
685
|
this.lastProcessedMessage = undefined;
|
|
683
686
|
while (this.messages.length > 0) {
|
|
684
687
|
this.processFirstMessage();
|
|
@@ -697,12 +700,12 @@ export class MockQuorumClients implements IQuorumClients, EventEmitter {
|
|
|
697
700
|
this.members = new Map((members as [string, ISequencedClient][]) ?? []);
|
|
698
701
|
}
|
|
699
702
|
|
|
700
|
-
addMember(id: string, client: Partial<ISequencedClient>) {
|
|
703
|
+
addMember(id: string, client: Partial<ISequencedClient>): void {
|
|
701
704
|
this.members.set(id, client as ISequencedClient);
|
|
702
705
|
this.eventEmitter.emit("addMember", id, client);
|
|
703
706
|
}
|
|
704
707
|
|
|
705
|
-
removeMember(id: string) {
|
|
708
|
+
removeMember(id: string): void {
|
|
706
709
|
if (this.members.delete(id)) {
|
|
707
710
|
this.eventEmitter.emit("removeMember", id);
|
|
708
711
|
}
|
|
@@ -889,7 +892,7 @@ export class MockFluidDataStoreRuntime
|
|
|
889
892
|
}
|
|
890
893
|
|
|
891
894
|
private readonly: boolean = false;
|
|
892
|
-
public readonly isReadOnly = () => this.readonly;
|
|
895
|
+
public readonly isReadOnly = (): boolean => this.readonly;
|
|
893
896
|
|
|
894
897
|
public readonly entryPoint: IFluidHandleInternal<FluidObject>;
|
|
895
898
|
|
|
@@ -933,15 +936,15 @@ export class MockFluidDataStoreRuntime
|
|
|
933
936
|
|
|
934
937
|
public createDeltaConnection(): MockDeltaConnection {
|
|
935
938
|
const deltaConnection = new MockDeltaConnection(
|
|
936
|
-
(messageContent: any, localOpMetadata: unknown) =>
|
|
939
|
+
(messageContent: any, localOpMetadata: unknown): number =>
|
|
937
940
|
this.submitMessageInternal(messageContent, localOpMetadata),
|
|
938
|
-
() => this.setChannelDirty(),
|
|
941
|
+
(): void => this.setChannelDirty(),
|
|
939
942
|
);
|
|
940
943
|
this.deltaConnections.push(deltaConnection);
|
|
941
944
|
return deltaConnection;
|
|
942
945
|
}
|
|
943
946
|
|
|
944
|
-
public get absolutePath() {
|
|
947
|
+
public get absolutePath(): string {
|
|
945
948
|
return `/${this.id}`;
|
|
946
949
|
}
|
|
947
950
|
|
|
@@ -962,7 +965,7 @@ export class MockFluidDataStoreRuntime
|
|
|
962
965
|
|
|
963
966
|
private _disposed = false;
|
|
964
967
|
|
|
965
|
-
public get disposed() {
|
|
968
|
+
public get disposed(): boolean {
|
|
966
969
|
return this._disposed;
|
|
967
970
|
}
|
|
968
971
|
|
|
@@ -1028,7 +1031,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1028
1031
|
return this.audience;
|
|
1029
1032
|
}
|
|
1030
1033
|
|
|
1031
|
-
public save(message: string) {
|
|
1034
|
+
public save(message: string): void {
|
|
1032
1035
|
return;
|
|
1033
1036
|
}
|
|
1034
1037
|
|
|
@@ -1062,7 +1065,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1062
1065
|
|
|
1063
1066
|
public submitSignal: IFluidDataStoreRuntime["submitSignal"] = () => null;
|
|
1064
1067
|
|
|
1065
|
-
public processMessages(messageCollection: IRuntimeMessageCollection) {
|
|
1068
|
+
public processMessages(messageCollection: IRuntimeMessageCollection): void {
|
|
1066
1069
|
if (this.disposed) {
|
|
1067
1070
|
return;
|
|
1068
1071
|
}
|
|
@@ -1071,7 +1074,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1071
1074
|
});
|
|
1072
1075
|
}
|
|
1073
1076
|
|
|
1074
|
-
public processSignal(message: any, local: boolean) {
|
|
1077
|
+
public processSignal(message: any, local: boolean): void {
|
|
1075
1078
|
return;
|
|
1076
1079
|
}
|
|
1077
1080
|
|
|
@@ -1079,7 +1082,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1079
1082
|
return;
|
|
1080
1083
|
}
|
|
1081
1084
|
|
|
1082
|
-
public setConnectionState(connected: boolean, clientId?: string) {
|
|
1085
|
+
public setConnectionState(connected: boolean, clientId?: string): void {
|
|
1083
1086
|
if (connected && clientId !== undefined) {
|
|
1084
1087
|
this.clientId = clientId;
|
|
1085
1088
|
}
|
|
@@ -1127,7 +1130,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1127
1130
|
};
|
|
1128
1131
|
}
|
|
1129
1132
|
|
|
1130
|
-
public updateUsedRoutes(usedRoutes: string[]) {}
|
|
1133
|
+
public updateUsedRoutes(usedRoutes: string[]): void {}
|
|
1131
1134
|
|
|
1132
1135
|
public getAttachSnapshot(): ITreeEntry[] {
|
|
1133
1136
|
return [];
|
|
@@ -1188,13 +1191,13 @@ export class MockFluidDataStoreRuntime
|
|
|
1188
1191
|
return null as any as IResponse;
|
|
1189
1192
|
}
|
|
1190
1193
|
|
|
1191
|
-
public reSubmit(content: any, localOpMetadata: unknown, squash?: boolean) {
|
|
1194
|
+
public reSubmit(content: any, localOpMetadata: unknown, squash?: boolean): void {
|
|
1192
1195
|
this.deltaConnections.forEach((dc) => {
|
|
1193
1196
|
dc.reSubmit(content, localOpMetadata, squash);
|
|
1194
1197
|
});
|
|
1195
1198
|
}
|
|
1196
1199
|
|
|
1197
|
-
public async applyStashedOp(content: any) {
|
|
1200
|
+
public async applyStashedOp(content: any): Promise<unknown> {
|
|
1198
1201
|
return this.deltaConnections.map((dc) => dc.applyStashedOp(content))[0];
|
|
1199
1202
|
}
|
|
1200
1203
|
|
|
@@ -1212,7 +1215,7 @@ export class MockFluidDataStoreRuntime
|
|
|
1212
1215
|
export class MockEmptyDeltaConnection implements IDeltaConnection {
|
|
1213
1216
|
public connected = false;
|
|
1214
1217
|
|
|
1215
|
-
public attach(handler) {}
|
|
1218
|
+
public attach(handler): void {}
|
|
1216
1219
|
|
|
1217
1220
|
public submit(messageContent: any): number {
|
|
1218
1221
|
assert(false, "Throw submit error on mock empty delta connection");
|
|
@@ -1263,7 +1266,7 @@ export class MockObjectStorageService implements IChannelStorageService {
|
|
|
1263
1266
|
* @legacy @beta
|
|
1264
1267
|
*/
|
|
1265
1268
|
export class MockSharedObjectServices implements IChannelServices {
|
|
1266
|
-
public static createFromSummary(summaryTree: ISummaryTree) {
|
|
1269
|
+
public static createFromSummary(summaryTree: ISummaryTree): MockSharedObjectServices {
|
|
1267
1270
|
const contents: { [key: string]: string } = {};
|
|
1268
1271
|
setContentsFromSummaryTree(summaryTree, "", contents);
|
|
1269
1272
|
return new MockSharedObjectServices(contents);
|
|
@@ -160,7 +160,11 @@ export class MockFluidDataStoreContext implements IFluidDataStoreContext {
|
|
|
160
160
|
throw new Error("Method not implemented.");
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
public addedGCOutboundRoute(
|
|
163
|
+
public addedGCOutboundRoute(
|
|
164
|
+
fromPath: string,
|
|
165
|
+
toPath: string,
|
|
166
|
+
messageTimestampMs?: number,
|
|
167
|
+
): void {
|
|
164
168
|
throw new Error("Method not implemented.");
|
|
165
169
|
}
|
|
166
170
|
}
|
|
@@ -42,7 +42,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
42
42
|
this.setConnectedState(connected);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
protected processPendingMessages(pendingMessages: ISequencedDocumentMessage[]) {
|
|
45
|
+
protected processPendingMessages(pendingMessages: ISequencedDocumentMessage[]): void {
|
|
46
46
|
for (const remoteMessage of pendingMessages) {
|
|
47
47
|
this.process(remoteMessage);
|
|
48
48
|
}
|
|
@@ -101,7 +101,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
override process(message: ISequencedDocumentMessage) {
|
|
104
|
+
override process(message: ISequencedDocumentMessage): void {
|
|
105
105
|
if (this.connected) {
|
|
106
106
|
this.processedOps?.push(message);
|
|
107
107
|
super.process(message);
|
|
@@ -110,7 +110,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
override submit(messageContent: any, localOpMetadata: unknown) {
|
|
113
|
+
override submit(messageContent: any, localOpMetadata: unknown): number {
|
|
114
114
|
// Submit messages only if we are connection, otherwise, just add it to the pending queue.
|
|
115
115
|
if (this.connected) {
|
|
116
116
|
return super.submit(messageContent, localOpMetadata);
|
|
@@ -120,7 +120,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
120
120
|
return -1;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
override flush() {
|
|
123
|
+
override flush(): void {
|
|
124
124
|
// Flush messages only if we are connected, otherwise, just ignore it.
|
|
125
125
|
if (this.connected) {
|
|
126
126
|
super.flush();
|
|
@@ -129,7 +129,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
129
129
|
|
|
130
130
|
public async initializeWithStashedOps(
|
|
131
131
|
fromContainerRuntime: MockContainerRuntimeForReconnection,
|
|
132
|
-
) {
|
|
132
|
+
): Promise<void> {
|
|
133
133
|
if (this.pendingMessages.length !== 0 || this.deltaManager.clientSequenceNumber !== 0) {
|
|
134
134
|
throw new Error("applyStashedOps must be called first, and once.");
|
|
135
135
|
}
|
|
@@ -189,7 +189,7 @@ export class MockContainerRuntimeForReconnection extends MockContainerRuntime {
|
|
|
189
189
|
stashedOps.set(op.referenceSequenceNumber, ops);
|
|
190
190
|
});
|
|
191
191
|
|
|
192
|
-
const applyStashedOpsAtSeq = async (seq: number) => {
|
|
192
|
+
const applyStashedOpsAtSeq = async (seq: number): Promise<void> => {
|
|
193
193
|
const pendingAtSeq = stashedOps.get(seq);
|
|
194
194
|
for (const message of pendingAtSeq ?? []) {
|
|
195
195
|
// As in production, do not locally apply any stashed ID allocation messages.
|
|
@@ -238,7 +238,7 @@ export class MockContainerRuntimeFactoryForReconnection extends MockContainerRun
|
|
|
238
238
|
return containerRuntime;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
public clearOutstandingClientMessages(clientId: string) {
|
|
241
|
+
public clearOutstandingClientMessages(clientId: string): void {
|
|
242
242
|
// Delete all the messages for client with the given clientId.
|
|
243
243
|
this.messages = this.messages.filter((message: ISequencedDocumentMessage) => {
|
|
244
244
|
return message.clientId !== clientId;
|