@fluidframework/azure-end-to-end-tests 2.93.0 → 2.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @fluidframework/azure-end-to-end-tests
2
2
 
3
+ ## 2.100.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Node 22 is now the minimum supported Node.js version ([#27116](https://github.com/microsoft/FluidFramework/pull/27116)) [e8214d29663](https://github.com/microsoft/FluidFramework/commit/e8214d29663f5ee98d737daed82506a25d8de8d0)
8
+
9
+ All Fluid Framework client packages now require Node.js 22 or later. This aligns with the standing Node upgrade policy as Node 20 reaches end-of-life on April 30, 2026.
10
+
3
11
  ## 2.93.0
4
12
 
5
13
  Dependency updates only.
@@ -6,7 +6,6 @@ import { strict as assert } from "node:assert";
6
6
  import { AzureClient, } from "@fluidframework/azure-client";
7
7
  import { AttachState } from "@fluidframework/container-definitions";
8
8
  import { ConnectionState } from "@fluidframework/container-loader";
9
- import { LogLevel } from "@fluidframework/core-interfaces";
10
9
  import { getPresence } from "@fluidframework/fluid-static";
11
10
  import { StateFactory, } from "@fluidframework/presence";
12
11
  import { InsecureTokenProvider } from "@fluidframework/test-runtime-utils/internal";
@@ -55,7 +54,7 @@ function selectiveVerboseLog(event, logLevel) {
55
54
  if (interest === "details") {
56
55
  content.details = event.details;
57
56
  }
58
- log(`[${logLevel ?? LogLevel.default}]`, content);
57
+ log(`[${logLevel ?? "unspecified"}]`, content);
59
58
  }
60
59
  /**
61
60
  * Get or create a Fluid container.
@@ -1 +1 @@
1
- {"version":3,"file":"childClient.tool.js","sourceRoot":"","sources":["../../../src/test/multiprocess/childClient.tool.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport {\n\tAzureClient,\n\ttype AzureContainerServices,\n\ttype AzureLocalConnectionConfig,\n\ttype AzureRemoteConnectionConfig,\n\ttype ITelemetryBaseEvent,\n} from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ITelemetryBaseLogger } from \"@fluidframework/core-interfaces\";\nimport { LogLevel } from \"@fluidframework/core-interfaces\";\nimport type { ScopeType } from \"@fluidframework/driver-definitions/legacy\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { getPresence } from \"@fluidframework/fluid-static\";\nimport {\n\ttype Attendee,\n\ttype Presence,\n\tStateFactory,\n\ttype LatestRaw,\n\ttype LatestMapRaw,\n\ttype StatesWorkspace,\n} from \"@fluidframework/presence\";\nimport { InsecureTokenProvider } from \"@fluidframework/test-runtime-utils/internal\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport { createAzureTokenProvider } from \"../AzureTokenFactory.js\";\nimport { TestDataObject } from \"../TestDataObject.js\";\n\nimport type {\n\tMessageFromChild as MessageToParent,\n\tMessageToChild as MessageFromParent,\n\tUserIdAndName,\n\tEventEntry,\n} from \"./messageTypes.js\";\n\nconst testLabel = process.argv[2];\n// Identifier given to child process\nconst process_id = process.argv[3];\nconst verbosity = process.argv[4] ?? \"\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\nconst tenantId = useAzure\n\t? (process.env.azure__fluid__relay__service__tenantId as string)\n\t: \"frs-client-tenant\";\nconst endPoint = process.env.azure__fluid__relay__service__endpoint as string;\nif (useAzure && endPoint === undefined) {\n\tthrow new Error(\"Azure Fluid Relay service endpoint is missing\");\n}\n\nconst containerSchema = {\n\tinitialObjects: {\n\t\t// A DataObject is added as otherwise fluid-static complains \"Container cannot be initialized without any DataTypes\"\n\t\t_unused: TestDataObject,\n\t},\n} as const satisfies ContainerSchema;\n\nfunction log(...data: unknown[]): void {\n\tconsole.log(`[${testLabel}] [${new Date().toISOString()}] [${process_id}]`, ...data);\n}\n\nfunction telemetryEventInterestLevel(eventName: string): \"none\" | \"basic\" | \"details\" {\n\tif (eventName.includes(\":Signal\") || eventName.includes(\":Join\")) {\n\t\treturn \"details\";\n\t} else if (eventName.includes(\":Container:\") || eventName.includes(\":Presence:\")) {\n\t\treturn \"basic\";\n\t}\n\treturn \"none\";\n}\n\nfunction selectiveVerboseLog(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {\n\tconst interest = telemetryEventInterestLevel(event.eventName);\n\tif (interest === \"none\") {\n\t\treturn;\n\t}\n\tconst content: Record<string, unknown> = {\n\t\teventName: event.eventName,\n\t\tcontainerConnectionState: event.containerConnectionState,\n\t};\n\tif (interest === \"details\") {\n\t\tcontent.details = event.details;\n\t}\n\tlog(`[${logLevel ?? LogLevel.default}]`, content);\n}\n\n/**\n * Get or create a Fluid container.\n */\nconst getOrCreateContainer = async (params: {\n\tlogger: ITelemetryBaseLogger;\n\tonDisconnected: () => void;\n\tcontainerId?: string;\n\tuser: UserIdAndName;\n\tscopes?: ScopeType[];\n\tcreateScopes?: ScopeType[];\n\tconnectTimeoutMs: number;\n}): Promise<{\n\tcontainer: IFluidContainer<typeof containerSchema>;\n\tservices: AzureContainerServices;\n\tclient: AzureClient;\n\tcontainerId: string;\n\tconnected: Promise<void>;\n}> => {\n\tlet container: IFluidContainer<typeof containerSchema>;\n\tlet { containerId } = params;\n\tconst { logger, onDisconnected, user, scopes, createScopes, connectTimeoutMs } = params;\n\tconst connectionProps: AzureRemoteConnectionConfig | AzureLocalConnectionConfig = useAzure\n\t\t? {\n\t\t\t\ttenantId,\n\t\t\t\ttokenProvider: createAzureTokenProvider(\n\t\t\t\t\tuser.id ?? \"foo\",\n\t\t\t\t\tuser.name ?? \"bar\",\n\t\t\t\t\tscopes,\n\t\t\t\t\tcreateScopes,\n\t\t\t\t),\n\t\t\t\tendpoint: endPoint,\n\t\t\t\ttype: \"remote\",\n\t\t\t}\n\t\t: {\n\t\t\t\ttokenProvider: new InsecureTokenProvider(\"fooBar\", user, scopes, createScopes),\n\t\t\t\tendpoint: \"http://localhost:7071\",\n\t\t\t\ttype: \"local\",\n\t\t\t};\n\tconst client = new AzureClient({\n\t\tconnection: connectionProps,\n\t\tlogger,\n\t\tconfigProvider: {\n\t\t\tgetRawConfig: (v: string) => {\n\t\t\t\t// At higher client counts, summarizer will get invoked, taking up resources\n\t\t\t\t// and spewing telemetry. None of current tests need summarization, so disable it.\n\t\t\t\tif (v === \"Fluid.ContainerRuntime.Test.DisableSummaries\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t});\n\tlet services: AzureContainerServices;\n\tif (containerId === undefined) {\n\t\t({ container, services } = await client.createContainer(containerSchema, \"2\"));\n\t\tcontainerId = await container.attach();\n\t} else {\n\t\t({ container, services } = await client.getContainer(containerId, containerSchema, \"2\"));\n\t}\n\tcontainer.on(\"disconnected\", onDisconnected);\n\n\tconst connected =\n\t\tcontainer.connectionState === ConnectionState.Connected\n\t\t\t? Promise.resolve()\n\t\t\t: timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\n\tassert.strictEqual(\n\t\tcontainer.attachState,\n\t\tAttachState.Attached,\n\t\t\"Container is not attached after attach is called\",\n\t);\n\n\treturn {\n\t\tclient,\n\t\tcontainer,\n\t\tservices,\n\t\tcontainerId,\n\t\tconnected,\n\t};\n};\n\nfunction createSendFunction(): (msg: MessageToParent) => void {\n\tif (process.send) {\n\t\tconst sendFn = process.send.bind(process);\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\treturn (msg: MessageToParent) => {\n\t\t\t\tlog(`Sending`, msg);\n\t\t\t\tsendFn(msg);\n\t\t\t};\n\t\t}\n\t\treturn sendFn;\n\t}\n\tthrow new Error(\"process.send is not defined\");\n}\n\nconst send = createSendFunction();\n\nfunction isStringOrNumberRecord(value: unknown): value is Record<string, string | number> {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\n\tconst stringKeys = Object.keys(value);\n\tconst allKeys = Reflect.ownKeys(value);\n\n\tif (stringKeys.length !== allKeys.length) {\n\t\t// If there are non-string/symbol keys, return false\n\t\treturn false;\n\t}\n\tfor (const key of stringKeys) {\n\t\tif (!(typeof value[key] === \"string\" || typeof value[key] === \"number\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n// NOTE:\n// - This schema intentionally uses optional keys (latest?, latestMap?) so tests can register\n// states conditionally at runtime.\n// - Optional keys are not explicitly supported in StatesWorkspace typing today, which means\n// workspace.states.<key> is typed as any. As a result, usages below require casts\n// (e.g., to LatestRaw / LatestMapRaw) to recover concrete types.\n// - Track adding proper optional-key support to Presence state workspace typing here:\n// Work item: AB#47518\n// - Fallout: Until the above is addressed, keep the casts in place and document new usages accordingly.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype WorkspaceSchema = {\n\tlatest?: ReturnType<typeof StateFactory.latest<{ value: string }, \"latest\">>;\n\tlatestMap?: ReturnType<\n\t\ttypeof StateFactory.latestMap<\n\t\t\t{ value: Record<string, string | number> },\n\t\t\tstring,\n\t\t\t\"latestMap\"\n\t\t>\n\t>;\n};\nconst WorkspaceSchema: WorkspaceSchema = {};\n\nclass MessageHandler {\n\tprivate readonly log: EventEntry[] = [];\n\tprivate msgQueue: undefined | Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>[];\n\tprivate container: IFluidContainer | undefined;\n\tprivate presence: Presence | undefined;\n\tprivate readonly workspaces = new Map<string, StatesWorkspace<WorkspaceSchema>>();\n\n\tprivate send(msg: MessageToParent): void {\n\t\tthis.log.push({\n\t\t\ttimestamp: Date.now(),\n\t\t\tagentId: process_id,\n\t\t\teventCategory: \"messageSent\",\n\t\t\teventName: msg.event,\n\t\t\tdetails:\n\t\t\t\tmsg.event === \"debugReportComplete\" && msg.log\n\t\t\t\t\t? JSON.stringify({ logLength: msg.log.length })\n\t\t\t\t\t: JSON.stringify(msg),\n\t\t});\n\t\tsend(msg);\n\t}\n\n\tprivate readonly sendAttendeeConnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeConnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\tprivate readonly sendAttendeeDisconnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeDisconnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\n\tprivate readonly logger: ITelemetryBaseLogger = {\n\t\tsend: (event: ITelemetryBaseEvent, logLevel?: LogLevel) => {\n\t\t\t// Filter out non-interactive client telemetry\n\t\t\tconst clientType = event.clientType;\n\t\t\tif (typeof clientType === \"string\" && clientType.startsWith(\"noninteractive\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Special case unexpected telemetry event\n\t\t\tif (event.eventName.endsWith(\":JoinResponseWhenAlone\")) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `Unexpected ClientJoin response. Details: ${JSON.stringify(event.details)}\\nLog: ${JSON.stringify(this.log)}`,\n\t\t\t\t});\n\t\t\t\t// Keep going\n\t\t\t}\n\n\t\t\tconst interest = telemetryEventInterestLevel(event.eventName);\n\t\t\tif (interest === \"none\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"telemetry\",\n\t\t\t\teventName: event.eventName,\n\t\t\t\tdetails:\n\t\t\t\t\ttypeof event.details === \"string\" ? event.details : JSON.stringify(event.details),\n\t\t\t});\n\t\t\tif (verbosity.includes(\"telem\")) {\n\t\t\t\tselectiveVerboseLog(event, logLevel);\n\t\t\t}\n\t\t},\n\t};\n\n\tprivate readonly onDisconnected = (): void => {\n\t\t// Test state is a bit fragile and does not account for reconnections.\n\t\tthis.send({ event: \"error\", error: `${process_id}: Container disconnected` });\n\t};\n\n\tprivate registerWorkspace(\n\t\tworkspaceId: string,\n\t\toptions: { latest?: boolean; latestMap?: boolean },\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst { latest, latestMap } = options;\n\t\tconst workspace: StatesWorkspace<WorkspaceSchema> = this.presence.states.getWorkspace(\n\t\t\t`test:${workspaceId}`,\n\t\t\tWorkspaceSchema,\n\t\t);\n\n\t\tif (latest && !workspace.states.latest) {\n\t\t\tworkspace.add(\"latest\", StateFactory.latest({ local: { value: \"initial\" } }));\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }>;\n\t\t\tlatestState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\tvalue: update.value.value,\n\t\t\t\t});\n\t\t\t});\n\t\t\tfor (const remote of latestState.getRemotes()) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\tvalue: remote.value.value,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (latestMap && !workspace.states.latestMap) {\n\t\t\tworkspace.add(\n\t\t\t\t\"latestMap\",\n\t\t\t\tStateFactory.latestMap<{ value: Record<string, string | number> }>({\n\t\t\t\t\tlocal: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestMapState = workspace.states.latestMap as LatestMapRaw<{\n\t\t\t\tvalue: Record<string, string | number>;\n\t\t\t}>;\n\t\t\tlatestMapState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tfor (const [key, valueWithMetadata] of update.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tfor (const remote of latestMapState.getRemotes()) {\n\t\t\t\tfor (const [key, valueWithMetadata] of remote.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.workspaces.set(workspaceId, workspace);\n\t\tthis.send({\n\t\t\tevent: \"workspaceRegistered\",\n\t\t\tworkspaceId,\n\t\t\tlatest: latest ?? false,\n\t\t\tlatestMap: latestMap ?? false,\n\t\t});\n\t}\n\n\tpublic async onMessage(msg: MessageFromParent): Promise<void> {\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"messageReceived\",\n\t\t\t\teventName: msg.command,\n\t\t\t});\n\t\t\tlog(`Received`, msg);\n\t\t}\n\n\t\tif (msg.command === \"ping\") {\n\t\t\tthis.handlePing();\n\t\t\treturn;\n\t\t}\n\n\t\tif (msg.command === \"connect\") {\n\t\t\tawait this.handleConnect(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// All other message must wait if connect is in progress\n\t\tif (this.msgQueue !== undefined) {\n\t\t\tthis.msgQueue.push(msg);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.processMessage(msg);\n\t}\n\n\tprivate processMessage(\n\t\tmsg: Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>,\n\t): void {\n\t\tswitch (msg.command) {\n\t\t\tcase \"debugReport\": {\n\t\t\t\tthis.handleDebugReport(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"disconnectSelf\": {\n\t\t\t\tthis.handleDisconnectSelf();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestValue\": {\n\t\t\t\tthis.handleSetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestMapValue\": {\n\t\t\t\tthis.handleSetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestValue\": {\n\t\t\t\tthis.handleGetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestMapValue\": {\n\t\t\t\tthis.handleGetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"registerWorkspace\": {\n\t\t\t\tthis.registerWorkspace(msg.workspaceId, {\n\t\t\t\t\tlatest: msg.latest,\n\t\t\t\t\tlatestMap: msg.latestMap,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(`${process_id}: Unknown command:`, msg);\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `${process_id} Unknown command: ${JSON.stringify(msg)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePing(): void {\n\t\tthis.send({ event: \"ack\" });\n\t}\n\n\tprivate async handleConnect(\n\t\tmsg: Extract<MessageFromParent, { command: \"connect\" }>,\n\t): Promise<void> {\n\t\tif (!msg.user) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: No azure user information given` });\n\t\t\treturn;\n\t\t}\n\t\tif (this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: Container already loaded` });\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent reentrance. Queue messages until after connect is fully processed.\n\t\tthis.msgQueue = [];\n\n\t\ttry {\n\t\t\tconst { container, containerId, connected } = await getOrCreateContainer({\n\t\t\t\t...msg,\n\t\t\t\tlogger: this.logger,\n\t\t\t\tonDisconnected: this.onDisconnected,\n\t\t\t});\n\t\t\tthis.container = container;\n\t\t\tconst presence = getPresence(container);\n\t\t\tthis.presence = presence;\n\n\t\t\t// wait for 'ConnectionState.Connected'\n\t\t\tawait connected.catch((error) => {\n\t\t\t\t(error as Error).message += `\\nLog: ${JSON.stringify(this.log)}`;\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\t\t// Acknowledge connection before sending current attendee information\n\t\t\tthis.send({\n\t\t\t\tevent: \"connected\",\n\t\t\t\tcontainerId,\n\t\t\t\tattendeeId: presence.attendees.getMyself().attendeeId,\n\t\t\t});\n\n\t\t\t// Send existing attendees excluding self to parent/orchestrator\n\t\t\tconst self = presence.attendees.getMyself();\n\t\t\tfor (const attendee of presence.attendees.getAttendees()) {\n\t\t\t\tif (attendee !== self && attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\tthis.sendAttendeeConnected(attendee);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Listen for presence events to notify parent/orchestrator when a new attendee joins or leaves the session.\n\t\t\tpresence.attendees.events.on(\"attendeeConnected\", this.sendAttendeeConnected);\n\t\t\tpresence.attendees.events.on(\"attendeeDisconnected\", this.sendAttendeeDisconnected);\n\t\t} finally {\n\t\t\t// Process any queued messages received while connecting\n\t\t\tfor (const queuedMsg of this.msgQueue) {\n\t\t\t\tthis.processMessage(queuedMsg);\n\t\t\t}\n\t\t\tthis.msgQueue = undefined;\n\t\t}\n\t}\n\n\tprivate handleDebugReport(\n\t\tmsg: Extract<MessageFromParent, { command: \"debugReport\" }>,\n\t): void {\n\t\tif (msg.reportAttendees) {\n\t\t\tif (this.presence) {\n\t\t\t\tconst attendees = this.presence.attendees.getAttendees();\n\t\t\t\tlet connectedCount = 0;\n\t\t\t\tfor (const attendee of attendees) {\n\t\t\t\t\tif (attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\t\tconnectedCount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog(`Report: ${attendees.size} attendees, ${connectedCount} connected`);\n\t\t\t} else {\n\t\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\t}\n\t\t}\n\n\t\tconst debugReport: Extract<MessageToParent, { event: \"debugReportComplete\" }> = {\n\t\t\tevent: \"debugReportComplete\",\n\t\t};\n\t\tif (msg.sendEventLog) {\n\t\t\tdebugReport.log = this.log;\n\t\t}\n\t\tthis.send(debugReport);\n\t}\n\n\tprivate handleDisconnectSelf(): void {\n\t\tif (!this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to container` });\n\t\t\treturn;\n\t\t}\n\t\t// There are no current scenarios where disconnect without presence is expected.\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\t// Disconnect event is treated as an error in normal handling.\n\t\t// Remove listener as this disconnect is intentional.\n\t\tthis.container.off(\"disconnected\", this.onDisconnected);\n\t\tthis.container.disconnect();\n\t\tthis.send({\n\t\t\tevent: \"disconnectedSelf\",\n\t\t\tattendeeId: this.presence.attendees.getMyself().attendeeId,\n\t\t});\n\t}\n\n\tprivate handleSetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.value !== \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tlatestState.local = { value: msg.value };\n\t}\n\n\tprivate handleSetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (!isStringOrNumberRecord(msg.value)) {\n\t\t\treturn;\n\t\t}\n\t\tlatestMapState.local.set(msg.key, { value: msg.value });\n\t}\n\n\tprivate handleGetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: string };\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestState.getRemote(attendee);\n\t\t\tvalue = remoteData.value;\n\t\t} else {\n\t\t\tvalue = latestState.local;\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tvalue: value.value,\n\t\t});\n\t}\n\n\tprivate handleGetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: Record<string, string | number> } | undefined;\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestMapState.getRemote(attendee);\n\t\t\tconst keyData = remoteData.get(msg.key);\n\t\t\tvalue = keyData?.value;\n\t\t} else {\n\t\t\tvalue = latestMapState.local.get(msg.key);\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestMapValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tkey: msg.key,\n\t\t\tvalue: value?.value,\n\t\t});\n\t}\n}\n\nfunction setupMessageHandler(): void {\n\tconst messageHandler = new MessageHandler();\n\tprocess.on(\"message\", (msg: MessageFromParent) => {\n\t\tmessageHandler.onMessage(msg).catch((error: Error) => {\n\t\t\tconsole.error(`[${testLabel}] Error in client ${process_id}`, error);\n\t\t\tsend({ event: \"error\", error: `${process_id}: ${error.message}` });\n\t\t});\n\t});\n}\n\nsetupMessageHandler();\n"]}
1
+ {"version":3,"file":"childClient.tool.js","sourceRoot":"","sources":["../../../src/test/multiprocess/childClient.tool.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport {\n\tAzureClient,\n\ttype AzureContainerServices,\n\ttype AzureLocalConnectionConfig,\n\ttype AzureRemoteConnectionConfig,\n\ttype ITelemetryBaseEvent,\n} from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ITelemetryBaseLogger, LogLevel } from \"@fluidframework/core-interfaces\";\nimport type { ScopeType } from \"@fluidframework/driver-definitions/legacy\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { getPresence } from \"@fluidframework/fluid-static\";\nimport {\n\ttype Attendee,\n\ttype Presence,\n\tStateFactory,\n\ttype LatestRaw,\n\ttype LatestMapRaw,\n\ttype StatesWorkspace,\n} from \"@fluidframework/presence\";\nimport { InsecureTokenProvider } from \"@fluidframework/test-runtime-utils/internal\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport { createAzureTokenProvider } from \"../AzureTokenFactory.js\";\nimport { TestDataObject } from \"../TestDataObject.js\";\n\nimport type {\n\tMessageFromChild as MessageToParent,\n\tMessageToChild as MessageFromParent,\n\tUserIdAndName,\n\tEventEntry,\n} from \"./messageTypes.js\";\n\nconst testLabel = process.argv[2];\n// Identifier given to child process\nconst process_id = process.argv[3];\nconst verbosity = process.argv[4] ?? \"\";\n\nconst useAzure = process.env.FLUID_CLIENT === \"azure\";\nconst tenantId = useAzure\n\t? (process.env.azure__fluid__relay__service__tenantId as string)\n\t: \"frs-client-tenant\";\nconst endPoint = process.env.azure__fluid__relay__service__endpoint as string;\nif (useAzure && endPoint === undefined) {\n\tthrow new Error(\"Azure Fluid Relay service endpoint is missing\");\n}\n\nconst containerSchema = {\n\tinitialObjects: {\n\t\t// A DataObject is added as otherwise fluid-static complains \"Container cannot be initialized without any DataTypes\"\n\t\t_unused: TestDataObject,\n\t},\n} as const satisfies ContainerSchema;\n\nfunction log(...data: unknown[]): void {\n\tconsole.log(`[${testLabel}] [${new Date().toISOString()}] [${process_id}]`, ...data);\n}\n\nfunction telemetryEventInterestLevel(eventName: string): \"none\" | \"basic\" | \"details\" {\n\tif (eventName.includes(\":Signal\") || eventName.includes(\":Join\")) {\n\t\treturn \"details\";\n\t} else if (eventName.includes(\":Container:\") || eventName.includes(\":Presence:\")) {\n\t\treturn \"basic\";\n\t}\n\treturn \"none\";\n}\n\nfunction selectiveVerboseLog(\n\tevent: ITelemetryBaseEvent,\n\tlogLevel: LogLevel | undefined,\n): void {\n\tconst interest = telemetryEventInterestLevel(event.eventName);\n\tif (interest === \"none\") {\n\t\treturn;\n\t}\n\tconst content: Record<string, unknown> = {\n\t\teventName: event.eventName,\n\t\tcontainerConnectionState: event.containerConnectionState,\n\t};\n\tif (interest === \"details\") {\n\t\tcontent.details = event.details;\n\t}\n\tlog(`[${logLevel ?? \"unspecified\"}]`, content);\n}\n\n/**\n * Get or create a Fluid container.\n */\nconst getOrCreateContainer = async (params: {\n\tlogger: ITelemetryBaseLogger;\n\tonDisconnected: () => void;\n\tcontainerId?: string;\n\tuser: UserIdAndName;\n\tscopes?: ScopeType[];\n\tcreateScopes?: ScopeType[];\n\tconnectTimeoutMs: number;\n}): Promise<{\n\tcontainer: IFluidContainer<typeof containerSchema>;\n\tservices: AzureContainerServices;\n\tclient: AzureClient;\n\tcontainerId: string;\n\tconnected: Promise<void>;\n}> => {\n\tlet container: IFluidContainer<typeof containerSchema>;\n\tlet { containerId } = params;\n\tconst { logger, onDisconnected, user, scopes, createScopes, connectTimeoutMs } = params;\n\tconst connectionProps: AzureRemoteConnectionConfig | AzureLocalConnectionConfig = useAzure\n\t\t? {\n\t\t\t\ttenantId,\n\t\t\t\ttokenProvider: createAzureTokenProvider(\n\t\t\t\t\tuser.id ?? \"foo\",\n\t\t\t\t\tuser.name ?? \"bar\",\n\t\t\t\t\tscopes,\n\t\t\t\t\tcreateScopes,\n\t\t\t\t),\n\t\t\t\tendpoint: endPoint,\n\t\t\t\ttype: \"remote\",\n\t\t\t}\n\t\t: {\n\t\t\t\ttokenProvider: new InsecureTokenProvider(\"fooBar\", user, scopes, createScopes),\n\t\t\t\tendpoint: \"http://localhost:7071\",\n\t\t\t\ttype: \"local\",\n\t\t\t};\n\tconst client = new AzureClient({\n\t\tconnection: connectionProps,\n\t\tlogger,\n\t\tconfigProvider: {\n\t\t\tgetRawConfig: (v: string) => {\n\t\t\t\t// At higher client counts, summarizer will get invoked, taking up resources\n\t\t\t\t// and spewing telemetry. None of current tests need summarization, so disable it.\n\t\t\t\tif (v === \"Fluid.ContainerRuntime.Test.DisableSummaries\") {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn undefined;\n\t\t\t},\n\t\t},\n\t});\n\tlet services: AzureContainerServices;\n\tif (containerId === undefined) {\n\t\t({ container, services } = await client.createContainer(containerSchema, \"2\"));\n\t\tcontainerId = await container.attach();\n\t} else {\n\t\t({ container, services } = await client.getContainer(containerId, containerSchema, \"2\"));\n\t}\n\tcontainer.on(\"disconnected\", onDisconnected);\n\n\tconst connected =\n\t\tcontainer.connectionState === ConnectionState.Connected\n\t\t\t? Promise.resolve()\n\t\t\t: timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\n\tassert.strictEqual(\n\t\tcontainer.attachState,\n\t\tAttachState.Attached,\n\t\t\"Container is not attached after attach is called\",\n\t);\n\n\treturn {\n\t\tclient,\n\t\tcontainer,\n\t\tservices,\n\t\tcontainerId,\n\t\tconnected,\n\t};\n};\n\nfunction createSendFunction(): (msg: MessageToParent) => void {\n\tif (process.send) {\n\t\tconst sendFn = process.send.bind(process);\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\treturn (msg: MessageToParent) => {\n\t\t\t\tlog(`Sending`, msg);\n\t\t\t\tsendFn(msg);\n\t\t\t};\n\t\t}\n\t\treturn sendFn;\n\t}\n\tthrow new Error(\"process.send is not defined\");\n}\n\nconst send = createSendFunction();\n\nfunction isStringOrNumberRecord(value: unknown): value is Record<string, string | number> {\n\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\treturn false;\n\t}\n\n\tconst stringKeys = Object.keys(value);\n\tconst allKeys = Reflect.ownKeys(value);\n\n\tif (stringKeys.length !== allKeys.length) {\n\t\t// If there are non-string/symbol keys, return false\n\t\treturn false;\n\t}\n\tfor (const key of stringKeys) {\n\t\tif (!(typeof value[key] === \"string\" || typeof value[key] === \"number\")) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n\n// NOTE:\n// - This schema intentionally uses optional keys (latest?, latestMap?) so tests can register\n// states conditionally at runtime.\n// - Optional keys are not explicitly supported in StatesWorkspace typing today, which means\n// workspace.states.<key> is typed as any. As a result, usages below require casts\n// (e.g., to LatestRaw / LatestMapRaw) to recover concrete types.\n// - Track adding proper optional-key support to Presence state workspace typing here:\n// Work item: AB#47518\n// - Fallout: Until the above is addressed, keep the casts in place and document new usages accordingly.\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ntype WorkspaceSchema = {\n\tlatest?: ReturnType<typeof StateFactory.latest<{ value: string }, \"latest\">>;\n\tlatestMap?: ReturnType<\n\t\ttypeof StateFactory.latestMap<\n\t\t\t{ value: Record<string, string | number> },\n\t\t\tstring,\n\t\t\t\"latestMap\"\n\t\t>\n\t>;\n};\nconst WorkspaceSchema: WorkspaceSchema = {};\n\nclass MessageHandler {\n\tprivate readonly log: EventEntry[] = [];\n\tprivate msgQueue: undefined | Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>[];\n\tprivate container: IFluidContainer | undefined;\n\tprivate presence: Presence | undefined;\n\tprivate readonly workspaces = new Map<string, StatesWorkspace<WorkspaceSchema>>();\n\n\tprivate send(msg: MessageToParent): void {\n\t\tthis.log.push({\n\t\t\ttimestamp: Date.now(),\n\t\t\tagentId: process_id,\n\t\t\teventCategory: \"messageSent\",\n\t\t\teventName: msg.event,\n\t\t\tdetails:\n\t\t\t\tmsg.event === \"debugReportComplete\" && msg.log\n\t\t\t\t\t? JSON.stringify({ logLength: msg.log.length })\n\t\t\t\t\t: JSON.stringify(msg),\n\t\t});\n\t\tsend(msg);\n\t}\n\n\tprivate readonly sendAttendeeConnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeConnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\tprivate readonly sendAttendeeDisconnected = (attendee: Attendee): void => {\n\t\tthis.send({\n\t\t\tevent: \"attendeeDisconnected\",\n\t\t\tattendeeId: attendee.attendeeId,\n\t\t});\n\t};\n\n\tprivate readonly logger: ITelemetryBaseLogger = {\n\t\tsend: (event: ITelemetryBaseEvent, logLevel?: LogLevel) => {\n\t\t\t// Filter out non-interactive client telemetry\n\t\t\tconst clientType = event.clientType;\n\t\t\tif (typeof clientType === \"string\" && clientType.startsWith(\"noninteractive\")) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Special case unexpected telemetry event\n\t\t\tif (event.eventName.endsWith(\":JoinResponseWhenAlone\")) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `Unexpected ClientJoin response. Details: ${JSON.stringify(event.details)}\\nLog: ${JSON.stringify(this.log)}`,\n\t\t\t\t});\n\t\t\t\t// Keep going\n\t\t\t}\n\n\t\t\tconst interest = telemetryEventInterestLevel(event.eventName);\n\t\t\tif (interest === \"none\") {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"telemetry\",\n\t\t\t\teventName: event.eventName,\n\t\t\t\tdetails:\n\t\t\t\t\ttypeof event.details === \"string\" ? event.details : JSON.stringify(event.details),\n\t\t\t});\n\t\t\tif (verbosity.includes(\"telem\")) {\n\t\t\t\tselectiveVerboseLog(event, logLevel);\n\t\t\t}\n\t\t},\n\t};\n\n\tprivate readonly onDisconnected = (): void => {\n\t\t// Test state is a bit fragile and does not account for reconnections.\n\t\tthis.send({ event: \"error\", error: `${process_id}: Container disconnected` });\n\t};\n\n\tprivate registerWorkspace(\n\t\tworkspaceId: string,\n\t\toptions: { latest?: boolean; latestMap?: boolean },\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst { latest, latestMap } = options;\n\t\tconst workspace: StatesWorkspace<WorkspaceSchema> = this.presence.states.getWorkspace(\n\t\t\t`test:${workspaceId}`,\n\t\t\tWorkspaceSchema,\n\t\t);\n\n\t\tif (latest && !workspace.states.latest) {\n\t\t\tworkspace.add(\"latest\", StateFactory.latest({ local: { value: \"initial\" } }));\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }>;\n\t\t\tlatestState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\tvalue: update.value.value,\n\t\t\t\t});\n\t\t\t});\n\t\t\tfor (const remote of latestState.getRemotes()) {\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"latestValueUpdated\",\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\tvalue: remote.value.value,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (latestMap && !workspace.states.latestMap) {\n\t\t\tworkspace.add(\n\t\t\t\t\"latestMap\",\n\t\t\t\tStateFactory.latestMap<{ value: Record<string, string | number> }>({\n\t\t\t\t\tlocal: {},\n\t\t\t\t}),\n\t\t\t);\n\t\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t\t// TODO: AB#47518\n\t\t\tconst latestMapState = workspace.states.latestMap as LatestMapRaw<{\n\t\t\t\tvalue: Record<string, string | number>;\n\t\t\t}>;\n\t\t\tlatestMapState.events.on(\"remoteUpdated\", (update) => {\n\t\t\t\tfor (const [key, valueWithMetadata] of update.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: update.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t\tfor (const remote of latestMapState.getRemotes()) {\n\t\t\t\tfor (const [key, valueWithMetadata] of remote.items) {\n\t\t\t\t\tthis.send({\n\t\t\t\t\t\tevent: \"latestMapValueUpdated\",\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tattendeeId: remote.attendee.attendeeId,\n\t\t\t\t\t\tkey: String(key),\n\t\t\t\t\t\tvalue: valueWithMetadata.value.value,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.workspaces.set(workspaceId, workspace);\n\t\tthis.send({\n\t\t\tevent: \"workspaceRegistered\",\n\t\t\tworkspaceId,\n\t\t\tlatest: latest ?? false,\n\t\t\tlatestMap: latestMap ?? false,\n\t\t});\n\t}\n\n\tpublic async onMessage(msg: MessageFromParent): Promise<void> {\n\t\tif (verbosity.includes(\"msgs\")) {\n\t\t\tthis.log.push({\n\t\t\t\ttimestamp: Date.now(),\n\t\t\t\tagentId: process_id,\n\t\t\t\teventCategory: \"messageReceived\",\n\t\t\t\teventName: msg.command,\n\t\t\t});\n\t\t\tlog(`Received`, msg);\n\t\t}\n\n\t\tif (msg.command === \"ping\") {\n\t\t\tthis.handlePing();\n\t\t\treturn;\n\t\t}\n\n\t\tif (msg.command === \"connect\") {\n\t\t\tawait this.handleConnect(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// All other message must wait if connect is in progress\n\t\tif (this.msgQueue !== undefined) {\n\t\t\tthis.msgQueue.push(msg);\n\t\t\treturn;\n\t\t}\n\n\t\tthis.processMessage(msg);\n\t}\n\n\tprivate processMessage(\n\t\tmsg: Exclude<MessageFromParent, { command: \"ping\" | \"connect\" }>,\n\t): void {\n\t\tswitch (msg.command) {\n\t\t\tcase \"debugReport\": {\n\t\t\t\tthis.handleDebugReport(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"disconnectSelf\": {\n\t\t\t\tthis.handleDisconnectSelf();\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestValue\": {\n\t\t\t\tthis.handleSetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"setLatestMapValue\": {\n\t\t\t\tthis.handleSetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestValue\": {\n\t\t\t\tthis.handleGetLatestValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"getLatestMapValue\": {\n\t\t\t\tthis.handleGetLatestMapValue(msg);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"registerWorkspace\": {\n\t\t\t\tthis.registerWorkspace(msg.workspaceId, {\n\t\t\t\t\tlatest: msg.latest,\n\t\t\t\t\tlatestMap: msg.latestMap,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconsole.error(`${process_id}: Unknown command:`, msg);\n\t\t\t\tthis.send({\n\t\t\t\t\tevent: \"error\",\n\t\t\t\t\terror: `${process_id} Unknown command: ${JSON.stringify(msg)}`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handlePing(): void {\n\t\tthis.send({ event: \"ack\" });\n\t}\n\n\tprivate async handleConnect(\n\t\tmsg: Extract<MessageFromParent, { command: \"connect\" }>,\n\t): Promise<void> {\n\t\tif (!msg.user) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: No azure user information given` });\n\t\t\treturn;\n\t\t}\n\t\tif (this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id}: Container already loaded` });\n\t\t\treturn;\n\t\t}\n\n\t\t// Prevent reentrance. Queue messages until after connect is fully processed.\n\t\tthis.msgQueue = [];\n\n\t\ttry {\n\t\t\tconst { container, containerId, connected } = await getOrCreateContainer({\n\t\t\t\t...msg,\n\t\t\t\tlogger: this.logger,\n\t\t\t\tonDisconnected: this.onDisconnected,\n\t\t\t});\n\t\t\tthis.container = container;\n\t\t\tconst presence = getPresence(container);\n\t\t\tthis.presence = presence;\n\n\t\t\t// wait for 'ConnectionState.Connected'\n\t\t\tawait connected.catch((error) => {\n\t\t\t\t(error as Error).message += `\\nLog: ${JSON.stringify(this.log)}`;\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\t\t// Acknowledge connection before sending current attendee information\n\t\t\tthis.send({\n\t\t\t\tevent: \"connected\",\n\t\t\t\tcontainerId,\n\t\t\t\tattendeeId: presence.attendees.getMyself().attendeeId,\n\t\t\t});\n\n\t\t\t// Send existing attendees excluding self to parent/orchestrator\n\t\t\tconst self = presence.attendees.getMyself();\n\t\t\tfor (const attendee of presence.attendees.getAttendees()) {\n\t\t\t\tif (attendee !== self && attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\tthis.sendAttendeeConnected(attendee);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Listen for presence events to notify parent/orchestrator when a new attendee joins or leaves the session.\n\t\t\tpresence.attendees.events.on(\"attendeeConnected\", this.sendAttendeeConnected);\n\t\t\tpresence.attendees.events.on(\"attendeeDisconnected\", this.sendAttendeeDisconnected);\n\t\t} finally {\n\t\t\t// Process any queued messages received while connecting\n\t\t\tfor (const queuedMsg of this.msgQueue) {\n\t\t\t\tthis.processMessage(queuedMsg);\n\t\t\t}\n\t\t\tthis.msgQueue = undefined;\n\t\t}\n\t}\n\n\tprivate handleDebugReport(\n\t\tmsg: Extract<MessageFromParent, { command: \"debugReport\" }>,\n\t): void {\n\t\tif (msg.reportAttendees) {\n\t\t\tif (this.presence) {\n\t\t\t\tconst attendees = this.presence.attendees.getAttendees();\n\t\t\t\tlet connectedCount = 0;\n\t\t\t\tfor (const attendee of attendees) {\n\t\t\t\t\tif (attendee.getConnectionStatus() === \"Connected\") {\n\t\t\t\t\t\tconnectedCount++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlog(`Report: ${attendees.size} attendees, ${connectedCount} connected`);\n\t\t\t} else {\n\t\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\t}\n\t\t}\n\n\t\tconst debugReport: Extract<MessageToParent, { event: \"debugReportComplete\" }> = {\n\t\t\tevent: \"debugReportComplete\",\n\t\t};\n\t\tif (msg.sendEventLog) {\n\t\t\tdebugReport.log = this.log;\n\t\t}\n\t\tthis.send(debugReport);\n\t}\n\n\tprivate handleDisconnectSelf(): void {\n\t\tif (!this.container) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to container` });\n\t\t\treturn;\n\t\t}\n\t\t// There are no current scenarios where disconnect without presence is expected.\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\t// Disconnect event is treated as an error in normal handling.\n\t\t// Remove listener as this disconnect is intentional.\n\t\tthis.container.off(\"disconnected\", this.onDisconnected);\n\t\tthis.container.disconnect();\n\t\tthis.send({\n\t\t\tevent: \"disconnectedSelf\",\n\t\t\tattendeeId: this.presence.attendees.getMyself().attendeeId,\n\t\t});\n\t}\n\n\tprivate handleSetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.value !== \"string\") {\n\t\t\treturn;\n\t\t}\n\t\tlatestState.local = { value: msg.value };\n\t}\n\n\tprivate handleSetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"setLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (!isStringOrNumberRecord(msg.value)) {\n\t\t\treturn;\n\t\t}\n\t\tlatestMapState.local.set(msg.key, { value: msg.value });\n\t}\n\n\tprivate handleGetLatestValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestState = workspace.states.latest as LatestRaw<{ value: string }> | undefined;\n\t\tif (!latestState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latest state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: string };\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestState.getRemote(attendee);\n\t\t\tvalue = remoteData.value;\n\t\t} else {\n\t\t\tvalue = latestState.local;\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tvalue: value.value,\n\t\t});\n\t}\n\n\tprivate handleGetLatestMapValue(\n\t\tmsg: Extract<MessageFromParent, { command: \"getLatestMapValue\" }>,\n\t): void {\n\t\tif (!this.presence) {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} is not connected to presence` });\n\t\t\treturn;\n\t\t}\n\t\tif (typeof msg.key !== \"string\") {\n\t\t\tthis.send({ event: \"error\", error: `${process_id} invalid key type` });\n\t\t\treturn;\n\t\t}\n\t\tconst workspace = this.workspaces.get(msg.workspaceId);\n\t\tif (!workspace) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} workspace ${msg.workspaceId} not found`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\t// Cast required due to optional keys in WorkspaceSchema\n\t\t// TODO: AB#47518\n\t\tconst latestMapState = workspace.states.latestMap as\n\t\t\t| LatestMapRaw<{ value: Record<string, string | number> }>\n\t\t\t| undefined;\n\t\tif (!latestMapState) {\n\t\t\tthis.send({\n\t\t\t\tevent: \"error\",\n\t\t\t\terror: `${process_id} latestMap state not registered for workspace ${msg.workspaceId}`,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tlet value: { value: Record<string, string | number> } | undefined;\n\t\tif (msg.attendeeId) {\n\t\t\tconst attendee = this.presence.attendees.getAttendee(msg.attendeeId);\n\t\t\tconst remoteData = latestMapState.getRemote(attendee);\n\t\t\tconst keyData = remoteData.get(msg.key);\n\t\t\tvalue = keyData?.value;\n\t\t} else {\n\t\t\tvalue = latestMapState.local.get(msg.key);\n\t\t}\n\t\tthis.send({\n\t\t\tevent: \"latestMapValueGetResponse\",\n\t\t\tworkspaceId: msg.workspaceId,\n\t\t\tattendeeId: msg.attendeeId,\n\t\t\tkey: msg.key,\n\t\t\tvalue: value?.value,\n\t\t});\n\t}\n}\n\nfunction setupMessageHandler(): void {\n\tconst messageHandler = new MessageHandler();\n\tprocess.on(\"message\", (msg: MessageFromParent) => {\n\t\tmessageHandler.onMessage(msg).catch((error: Error) => {\n\t\t\tconsole.error(`[${testLabel}] Error in client ${process_id}`, error);\n\t\t\tsend({ event: \"error\", error: `${process_id}: ${error.message}` });\n\t\t});\n\t});\n}\n\nsetupMessageHandler();\n"]}
@@ -95,7 +95,7 @@ for (const testOpts of testMatrix) {
95
95
  * Scenario: Client sends a signal and connected clients receive it.
96
96
  *
97
97
  * Expected behavior: While 2 clients are connected to a container,
98
- * a signal sent by 1 client should be recieved by both clients.
98
+ * a signal sent by 1 client should be received by both clients.
99
99
  */
100
100
  it("can send and receive signals", async () => {
101
101
  const { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);
@@ -115,7 +115,7 @@ for (const testOpts of testMatrix) {
115
115
  * Scenario: Read and Write clients send signals and connected clients receive them.
116
116
  *
117
117
  * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,
118
- * a signal sent by any 1 client should be recieved by all 3 clients, regardless of read/write permissions.
118
+ * a signal sent by any 1 client should be received by all 3 clients, regardless of read/write permissions.
119
119
  */
120
120
  it("can send and receive read-only client signals", async function () {
121
121
  const { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);
@@ -1 +1 @@
1
- {"version":3,"file":"signals.spec.js","sourceRoot":"","sources":["../../src/test/signals.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAG/C,OAAO,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE,OAAO,EACN,iBAAiB,EACjB,0BAA0B,EAC1B,iCAAiC,EACjC,SAAS,GACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,qBAAqB,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAO3D,KAAK,UAAU,2BAA2B,CACzC,QAAgC,EAChC,UAAkB,EAClB,eAAkB,EAClB,OAAe,QAAQ,EACvB,YAAoB,MAAM;IAE1B,OAAO,cAAc,CACpB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnB,QAAQ,CAAC,QAAQ,CAAI,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE;YACrE,IAAI,CAAC;gBACJ,MAAM,CAAC,eAAe,CACrB,eAAe,EACf,eAAe,EACf,kDAAkD,CAClD,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;YACD,OAAO,CAAC,eAAe,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACJ,CAAC,EACD,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,oBAAoB,EAAE,CAChE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;AACnC,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE,CAAC;IACnC,QAAQ,CAAC,kBAAkB,QAAQ,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE;QACpD,MAAM,mBAAmB,GAAsB,EAAE,CAAC;QAClD,MAAM,gBAAgB,GAAG,MAAM,CAAC;QAChC,MAAM,WAAW,GAAY,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC;QAC1D,MAAM,KAAK,GAAG;YACb,EAAE,EAAE,gBAAgB;YACpB,IAAI,EAAE,kBAAkB;SACS,CAAC;QACnC,MAAM,KAAK,GAAG;YACb,EAAE,EAAE,gBAAgB;YACpB,IAAI,EAAE,kBAAkB;SACS,CAAC;QACnC,MAAM,KAAK,GAAG;YACb,EAAE,EAAE,gBAAgB;YACpB,IAAI,EAAE,kBAAkB;SACS,CAAC;QAEnC,SAAS,CAAC,KAAK,IAAI,EAAE;YACpB,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;gBAC7C,SAAS,CAAC,UAAU,EAAE,CAAC;gBACvB,SAAS,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;YACD,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,MAAM,4BAA4B,GAAG,KAAK,EACzC,EAAsB,EACtB,IAAmB,EACnB,MAA0C,EAC1C,MAAoB,EAOlB,EAAE;YACJ,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YAChF,MAAM,MAAM,GAAoB;gBAC/B,cAAc,EAAE;oBACf,QAAQ,EAAE,sBAAsB;iBAChC;aACD,CAAC;YACF,IAAI,SAA0B,CAAC;YAC/B,IAAI,QAAgC,CAAC;YACrC,IAAI,WAAmB,CAAC;YACxB,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;gBACtB,IAAI,WAAW,EAAE,CAAC;oBACjB,MAAM,iBAAiB,GAAG,MAAM,0BAA0B,CACzD,qBAAqB,CAAC,qBAAqB,EAC3C,gBAAgB,EAChB,kBAAkB,CAClB,CAAC;oBACF,WAAW,GAAG,iCAAiC,CAAC,iBAAiB,CAAC,CAAC;oBACnE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;gBACjF,CAAC;qBAAM,CAAC;oBACP,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;oBACtE,WAAW,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,CAAC;gBACxC,CAAC;YACF,CAAC;iBAAM,CAAC;gBACP,WAAW,GAAG,EAAE,CAAC;gBACjB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;YACjF,CAAC;YAED,IAAI,SAAS,CAAC,eAAe,KAAK,eAAe,CAAC,SAAS,EAAE,CAAC;gBAC7D,MAAM,cAAc,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,EAAE;oBAC/E,UAAU,EAAE,gBAAgB;oBAC5B,QAAQ,EAAE,6BAA6B;iBACvC,CAAC,CAAC;YACJ,CAAC;YACD,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAEpC,MAAM,CAAC,WAAW,CAAC,OAAO,WAAW,EAAE,QAAQ,EAAE,mCAAmC,CAAC,CAAC;YACtF,MAAM,CAAC,WAAW,CACjB,SAAS,CAAC,WAAW,EACrB,WAAW,CAAC,QAAQ,EACpB,kDAAkD,CAClD,CAAC;YAEF,MAAM,QAAQ,GAAG,SAAS,CAAC,cAAc,CAAC,QAAkC,CAAC;YAC7E,OAAO;gBACN,MAAM;gBACN,SAAS;gBACT,QAAQ;gBACR,QAAQ;gBACR,WAAW;aACX,CAAC;QACH,CAAC,CAAC;QAEF;;;;;WAKG;QACH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;YAC7C,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,4BAA4B,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;YACvF,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,4BAA4B,CACjE,WAAW,EACX,KAAK,EACL,cAAc,CAAC;gBACd,sCAAsC,EAAE,IAAI;aAC5C,CAAC,CACF,CAAC;YAEF,MAAM,UAAU,GAAG,aAAa,CAAC;YACjC,MAAM,aAAa,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAE1C,MAAM,gBAAgB,GAAG;gBACxB,2BAA2B,CAC1B,SAAS,EACT,UAAU,EACV,aAAa,EACb,gDAAgD,CAChD;gBACD,2BAA2B,CAC1B,QAAQ,EACR,UAAU,EACV,aAAa,EACb,2CAA2C,CAC3C;aACD,CAAC;YAEF,QAAQ,CAAC,YAAY,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAEjD,MAAM,MAAM,CAAC,aAAa,CACzB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAC7B,2CAA2C,CAC3C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH;;;;;WAKG;QACH,EAAE,CAAC,+CAA+C,EAAE,KAAK;YACxD,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,GAAG,MAAM,4BAA4B,CAClF,SAAS,EACT,KAAK,CACL,CAAC;YACF,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,4BAA4B,CACpE,WAAW,EACX,KAAK,EACL,SAAS,EACT,CAAC,SAAS,CAAC,OAAO,CAAC,CACnB,CAAC;YACF,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,GAAG,MAAM,4BAA4B,CACrE,WAAW,EACX,KAAK,EACL,SAAS,EACT,CAAC,SAAS,CAAC,OAAO,CAAC,CACnB,CAAC;YAEF,MAAM,UAAU,GAAG,aAAa,CAAC;YAEjC,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;YAC3C,MAAM,iBAAiB,GAAG;gBACzB,2BAA2B,CAC1B,aAAa,EACb,UAAU,EACV,cAAc,EACd,+CAA+C,CAC/C;gBACD,2BAA2B,CAC1B,aAAa,EACb,UAAU,EACV,cAAc,EACd,gDAAgD,CAChD;gBACD,2BAA2B,CAC1B,YAAY,EACZ,UAAU,EACV,cAAc,EACd,0CAA0C,CAC1C;aACD,CAAC;YACF,YAAY,CAAC,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACtD,MAAM,MAAM,CAAC,aAAa,CACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAC9B,6DAA6D,CAC7D,CAAC;YAEF,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;YAC5C,MAAM,iBAAiB,GAAG;gBACzB,2BAA2B,CAC1B,YAAY,EACZ,UAAU,EACV,cAAc,EACd,+CAA+C,CAC/C;gBACD,2BAA2B,CAC1B,aAAa,EACb,UAAU,EACV,cAAc,EACd,iDAAiD,CACjD;gBACD,2BAA2B,CAC1B,aAAa,EACb,UAAU,EACV,cAAc,EACd,2CAA2C,CAC3C;aACD,CAAC;YACF,aAAa,CAAC,YAAY,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;YACvD,MAAM,MAAM,CAAC,aAAa,CACzB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAC9B,8DAA8D,CAC9D,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,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 type { AzureClient, AzureContainerServices } from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n\tScopeType,\n} from \"./AzureClientFactory.js\";\nimport { SignalerTestDataObject } from \"./TestDataObject.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { configProvider, getTestMatrix } from \"./utils.js\";\n\ninterface UserIdAndName {\n\treadonly id: string;\n\treadonly name: string;\n}\n\nasync function createSignalListenerPromise<T>(\n\tsignaler: SignalerTestDataObject,\n\tsignalType: string,\n\texpectedPayload: T,\n\tname: string = \"Signal\",\n\ttimeoutMs: number = 10_000,\n): Promise<T> {\n\treturn timeoutPromise(\n\t\t(resolve, reject) => {\n\t\t\tsignaler.onSignal<T>(signalType, (clientId, local, receivedPayload) => {\n\t\t\t\ttry {\n\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\treceivedPayload,\n\t\t\t\t\t\texpectedPayload,\n\t\t\t\t\t\t\"Received payload does not match expected payload\",\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn reject(error);\n\t\t\t\t}\n\t\t\t\tresolve(receivedPayload);\n\t\t\t});\n\t\t},\n\t\t{ durationMs: timeoutMs, errorMsg: `${name}: listener timeout` },\n\t);\n}\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`Fluid Signals (${testOpts.variant})`, () => {\n\t\tconst connectedContainers: IFluidContainer[] = [];\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tconst user1 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user2 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user3 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\n\t\tafterEach(async () => {\n\t\t\tfor (const container of connectedContainers) {\n\t\t\t\tcontainer.disconnect();\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t\tconnectedContainers.splice(0, connectedContainers.length);\n\t\t});\n\n\t\tconst getOrCreateSignalerContainer = async (\n\t\t\tid: string | undefined,\n\t\t\tuser: UserIdAndName,\n\t\t\tconfig?: ReturnType<typeof configProvider>,\n\t\t\tscopes?: ScopeType[],\n\t\t): Promise<{\n\t\t\tcontainer: IFluidContainer;\n\t\t\tsignaler: SignalerTestDataObject;\n\t\t\tservices: AzureContainerServices;\n\t\t\tclient: AzureClient;\n\t\t\tcontainerId: string;\n\t\t}> => {\n\t\t\tconst client = createAzureClient(user.id, user.name, undefined, config, scopes);\n\t\t\tconst schema: ContainerSchema = {\n\t\t\t\tinitialObjects: {\n\t\t\t\t\tsignaler: SignalerTestDataObject,\n\t\t\t\t},\n\t\t\t};\n\t\t\tlet container: IFluidContainer;\n\t\t\tlet services: AzureContainerServices;\n\t\t\tlet containerId: string;\n\t\t\tif (id === undefined) {\n\t\t\t\tif (isEphemeral) {\n\t\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\t\tephemeralSummaryTrees.sendAndRecieveSignals,\n\t\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t\t);\n\t\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t\t} else {\n\t\t\t\t\t({ container, services } = await client.createContainer(schema, \"2\"));\n\t\t\t\t\tcontainerId = await container.attach();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontainerId = id;\n\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t}\n\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconnectedContainers.push(container);\n\n\t\t\tassert.strictEqual(typeof containerId, \"string\", \"Attach did not return a string ID\");\n\t\t\tassert.strictEqual(\n\t\t\t\tcontainer.attachState,\n\t\t\t\tAttachState.Attached,\n\t\t\t\t\"Container is not attached after attach is called\",\n\t\t\t);\n\n\t\t\tconst signaler = container.initialObjects.signaler as SignalerTestDataObject;\n\t\t\treturn {\n\t\t\t\tclient,\n\t\t\t\tcontainer,\n\t\t\t\tsignaler,\n\t\t\t\tservices,\n\t\t\t\tcontainerId,\n\t\t\t};\n\t\t};\n\n\t\t/**\n\t\t * Scenario: Client sends a signal and connected clients receive it.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected to a container,\n\t\t * a signal sent by 1 client should be recieved by both clients.\n\t\t */\n\t\tit(\"can send and receive signals\", async () => {\n\t\t\tconst { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);\n\t\t\tconst { signaler: signaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tconfigProvider({\n\t\t\t\t\t\"Fluid.Container.ForceWriteConnection\": true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\t\t\tconst signalPayload = { test: \"payload\" };\n\n\t\t\tconst listenerPromises = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tsignaler.submitSignal(signalName, signalPayload);\n\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises),\n\t\t\t\t\"Listening clients should receive signals.\",\n\t\t\t);\n\t\t});\n\n\t\t/**\n\t\t * Scenario: Read and Write clients send signals and connected clients receive them.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,\n\t\t * a signal sent by any 1 client should be recieved by all 3 clients, regardless of read/write permissions.\n\t\t */\n\t\tit(\"can send and receive read-only client signals\", async function () {\n\t\t\tconst { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(\n\t\t\t\tundefined,\n\t\t\t\tuser1,\n\t\t\t);\n\t\t\tconst { signaler: readSignaler } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\t\t\tconst { signaler: readSignaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser3,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\n\t\t\tconst signalPayload1 = { test: \"payload\" };\n\t\t\tconst listenerPromises1 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Write client listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client 2 listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\treadSignaler.submitSignal(signalName, signalPayload1);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises1),\n\t\t\t\t\"Listening clients should receive signals from read clients.\",\n\t\t\t);\n\n\t\t\tconst signalPayload2 = { test: \"payload2\" };\n\t\t\tconst listenerPromises2 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client 2 listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\twriteSignaler.submitSignal(signalName, signalPayload2);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises2),\n\t\t\t\t\"Listening clients should receive signals from write clients.\",\n\t\t\t);\n\t\t});\n\t});\n}\n"]}
1
+ {"version":3,"file":"signals.spec.js","sourceRoot":"","sources":["../../src/test/signals.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\n\nimport type { AzureClient, AzureContainerServices } from \"@fluidframework/azure-client\";\nimport { AttachState } from \"@fluidframework/container-definitions\";\nimport { ConnectionState } from \"@fluidframework/container-loader\";\nimport type { ContainerSchema, IFluidContainer } from \"@fluidframework/fluid-static\";\nimport { timeoutPromise } from \"@fluidframework/test-utils/internal\";\n\nimport {\n\tcreateAzureClient,\n\tcreateContainerFromPayload,\n\tgetContainerIdFromPayloadResponse,\n\tScopeType,\n} from \"./AzureClientFactory.js\";\nimport { SignalerTestDataObject } from \"./TestDataObject.js\";\nimport * as ephemeralSummaryTrees from \"./ephemeralSummaryTrees.js\";\nimport { configProvider, getTestMatrix } from \"./utils.js\";\n\ninterface UserIdAndName {\n\treadonly id: string;\n\treadonly name: string;\n}\n\nasync function createSignalListenerPromise<T>(\n\tsignaler: SignalerTestDataObject,\n\tsignalType: string,\n\texpectedPayload: T,\n\tname: string = \"Signal\",\n\ttimeoutMs: number = 10_000,\n): Promise<T> {\n\treturn timeoutPromise(\n\t\t(resolve, reject) => {\n\t\t\tsignaler.onSignal<T>(signalType, (clientId, local, receivedPayload) => {\n\t\t\t\ttry {\n\t\t\t\t\tassert.deepStrictEqual(\n\t\t\t\t\t\treceivedPayload,\n\t\t\t\t\t\texpectedPayload,\n\t\t\t\t\t\t\"Received payload does not match expected payload\",\n\t\t\t\t\t);\n\t\t\t\t} catch (error) {\n\t\t\t\t\treturn reject(error);\n\t\t\t\t}\n\t\t\t\tresolve(receivedPayload);\n\t\t\t});\n\t\t},\n\t\t{ durationMs: timeoutMs, errorMsg: `${name}: listener timeout` },\n\t);\n}\n\nconst testMatrix = getTestMatrix();\nfor (const testOpts of testMatrix) {\n\tdescribe(`Fluid Signals (${testOpts.variant})`, () => {\n\t\tconst connectedContainers: IFluidContainer[] = [];\n\t\tconst connectTimeoutMs = 10_000;\n\t\tconst isEphemeral: boolean = testOpts.options.isEphemeral;\n\t\tconst user1 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user2 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\t\tconst user3 = {\n\t\t\tid: \"test-user-id-1\",\n\t\t\tname: \"test-user-name-2\",\n\t\t} as const satisfies UserIdAndName;\n\n\t\tafterEach(async () => {\n\t\t\tfor (const container of connectedContainers) {\n\t\t\t\tcontainer.disconnect();\n\t\t\t\tcontainer.dispose();\n\t\t\t}\n\t\t\tconnectedContainers.splice(0, connectedContainers.length);\n\t\t});\n\n\t\tconst getOrCreateSignalerContainer = async (\n\t\t\tid: string | undefined,\n\t\t\tuser: UserIdAndName,\n\t\t\tconfig?: ReturnType<typeof configProvider>,\n\t\t\tscopes?: ScopeType[],\n\t\t): Promise<{\n\t\t\tcontainer: IFluidContainer;\n\t\t\tsignaler: SignalerTestDataObject;\n\t\t\tservices: AzureContainerServices;\n\t\t\tclient: AzureClient;\n\t\t\tcontainerId: string;\n\t\t}> => {\n\t\t\tconst client = createAzureClient(user.id, user.name, undefined, config, scopes);\n\t\t\tconst schema: ContainerSchema = {\n\t\t\t\tinitialObjects: {\n\t\t\t\t\tsignaler: SignalerTestDataObject,\n\t\t\t\t},\n\t\t\t};\n\t\t\tlet container: IFluidContainer;\n\t\t\tlet services: AzureContainerServices;\n\t\t\tlet containerId: string;\n\t\t\tif (id === undefined) {\n\t\t\t\tif (isEphemeral) {\n\t\t\t\t\tconst containerResponse = await createContainerFromPayload(\n\t\t\t\t\t\tephemeralSummaryTrees.sendAndRecieveSignals,\n\t\t\t\t\t\t\"test-user-id-1\",\n\t\t\t\t\t\t\"test-user-name-1\",\n\t\t\t\t\t);\n\t\t\t\t\tcontainerId = getContainerIdFromPayloadResponse(containerResponse);\n\t\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t\t} else {\n\t\t\t\t\t({ container, services } = await client.createContainer(schema, \"2\"));\n\t\t\t\t\tcontainerId = await container.attach();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcontainerId = id;\n\t\t\t\t({ container, services } = await client.getContainer(containerId, schema, \"2\"));\n\t\t\t}\n\n\t\t\tif (container.connectionState !== ConnectionState.Connected) {\n\t\t\t\tawait timeoutPromise((resolve) => container.once(\"connected\", () => resolve()), {\n\t\t\t\t\tdurationMs: connectTimeoutMs,\n\t\t\t\t\terrorMsg: \"container connect() timeout\",\n\t\t\t\t});\n\t\t\t}\n\t\t\tconnectedContainers.push(container);\n\n\t\t\tassert.strictEqual(typeof containerId, \"string\", \"Attach did not return a string ID\");\n\t\t\tassert.strictEqual(\n\t\t\t\tcontainer.attachState,\n\t\t\t\tAttachState.Attached,\n\t\t\t\t\"Container is not attached after attach is called\",\n\t\t\t);\n\n\t\t\tconst signaler = container.initialObjects.signaler as SignalerTestDataObject;\n\t\t\treturn {\n\t\t\t\tclient,\n\t\t\t\tcontainer,\n\t\t\t\tsignaler,\n\t\t\t\tservices,\n\t\t\t\tcontainerId,\n\t\t\t};\n\t\t};\n\n\t\t/**\n\t\t * Scenario: Client sends a signal and connected clients receive it.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected to a container,\n\t\t * a signal sent by 1 client should be received by both clients.\n\t\t */\n\t\tit(\"can send and receive signals\", async () => {\n\t\t\tconst { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);\n\t\t\tconst { signaler: signaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tconfigProvider({\n\t\t\t\t\t\"Fluid.Container.ForceWriteConnection\": true,\n\t\t\t\t}),\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\t\t\tconst signalPayload = { test: \"payload\" };\n\n\t\t\tconst listenerPromises = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\tsignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\n\t\t\tsignaler.submitSignal(signalName, signalPayload);\n\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises),\n\t\t\t\t\"Listening clients should receive signals.\",\n\t\t\t);\n\t\t});\n\n\t\t/**\n\t\t * Scenario: Read and Write clients send signals and connected clients receive them.\n\t\t *\n\t\t * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,\n\t\t * a signal sent by any 1 client should be received by all 3 clients, regardless of read/write permissions.\n\t\t */\n\t\tit(\"can send and receive read-only client signals\", async function () {\n\t\t\tconst { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(\n\t\t\t\tundefined,\n\t\t\t\tuser1,\n\t\t\t);\n\t\t\tconst { signaler: readSignaler } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser2,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\t\t\tconst { signaler: readSignaler2 } = await getOrCreateSignalerContainer(\n\t\t\t\tcontainerId,\n\t\t\t\tuser3,\n\t\t\t\tundefined,\n\t\t\t\t[ScopeType.DocRead],\n\t\t\t);\n\n\t\t\tconst signalName = \"test-signal\";\n\n\t\t\tconst signalPayload1 = { test: \"payload\" };\n\t\t\tconst listenerPromises1 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Write client listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client 2 listening for read client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload1,\n\t\t\t\t\t\"Read client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\treadSignaler.submitSignal(signalName, signalPayload1);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises1),\n\t\t\t\t\"Listening clients should receive signals from read clients.\",\n\t\t\t);\n\n\t\t\tconst signalPayload2 = { test: \"payload2\" };\n\t\t\tconst listenerPromises2 = [\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\treadSignaler2,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Read client 2 listening for write client signal\",\n\t\t\t\t),\n\t\t\t\tcreateSignalListenerPromise(\n\t\t\t\t\twriteSignaler,\n\t\t\t\t\tsignalName,\n\t\t\t\t\tsignalPayload2,\n\t\t\t\t\t\"Write client listening for its own signal\",\n\t\t\t\t),\n\t\t\t];\n\t\t\twriteSignaler.submitSignal(signalName, signalPayload2);\n\t\t\tawait assert.doesNotReject(\n\t\t\t\tPromise.all(listenerPromises2),\n\t\t\t\t\"Listening clients should receive signals from write clients.\",\n\t\t\t);\n\t\t});\n\t});\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluidframework/azure-end-to-end-tests",
3
- "version": "2.93.0",
3
+ "version": "2.100.0",
4
4
  "description": "Azure client end to end tests",
5
5
  "homepage": "https://fluidframework.com",
6
6
  "repository": {
@@ -33,29 +33,29 @@
33
33
  "temp-directory": "nyc/.nyc_output"
34
34
  },
35
35
  "dependencies": {
36
- "@fluid-experimental/data-objects": "~2.93.0",
37
- "@fluid-internal/client-utils": "~2.93.0",
38
- "@fluid-internal/mocha-test-setup": "~2.93.0",
39
- "@fluid-private/test-version-utils": "~2.93.0",
40
- "@fluidframework/aqueduct": "~2.93.0",
41
- "@fluidframework/azure-client": "~2.93.0",
36
+ "@fluid-experimental/data-objects": "~2.100.0",
37
+ "@fluid-internal/client-utils": "~2.100.0",
38
+ "@fluid-internal/mocha-test-setup": "~2.100.0",
39
+ "@fluid-private/test-version-utils": "~2.100.0",
40
+ "@fluidframework/aqueduct": "~2.100.0",
41
+ "@fluidframework/azure-client": "~2.100.0",
42
42
  "@fluidframework/azure-client-legacy": "npm:@fluidframework/azure-client@^1.2.0",
43
- "@fluidframework/container-definitions": "~2.93.0",
44
- "@fluidframework/container-loader": "~2.93.0",
45
- "@fluidframework/core-interfaces": "~2.93.0",
46
- "@fluidframework/counter": "~2.93.0",
47
- "@fluidframework/datastore-definitions": "~2.93.0",
48
- "@fluidframework/fluid-static": "~2.93.0",
49
- "@fluidframework/map": "~2.93.0",
43
+ "@fluidframework/container-definitions": "~2.100.0",
44
+ "@fluidframework/container-loader": "~2.100.0",
45
+ "@fluidframework/core-interfaces": "~2.100.0",
46
+ "@fluidframework/counter": "~2.100.0",
47
+ "@fluidframework/datastore-definitions": "~2.100.0",
48
+ "@fluidframework/fluid-static": "~2.100.0",
49
+ "@fluidframework/map": "~2.100.0",
50
50
  "@fluidframework/map-legacy": "npm:@fluidframework/map@^1.4.0",
51
- "@fluidframework/matrix": "~2.93.0",
52
- "@fluidframework/presence": "~2.93.0",
53
- "@fluidframework/runtime-definitions": "~2.93.0",
54
- "@fluidframework/sequence": "~2.93.0",
55
- "@fluidframework/telemetry-utils": "~2.93.0",
56
- "@fluidframework/test-runtime-utils": "~2.93.0",
57
- "@fluidframework/test-utils": "~2.93.0",
58
- "@fluidframework/tree": "~2.93.0",
51
+ "@fluidframework/matrix": "~2.100.0",
52
+ "@fluidframework/presence": "~2.100.0",
53
+ "@fluidframework/runtime-definitions": "~2.100.0",
54
+ "@fluidframework/sequence": "~2.100.0",
55
+ "@fluidframework/telemetry-utils": "~2.100.0",
56
+ "@fluidframework/test-runtime-utils": "~2.100.0",
57
+ "@fluidframework/test-utils": "~2.100.0",
58
+ "@fluidframework/tree": "~2.100.0",
59
59
  "cross-env": "^10.1.0",
60
60
  "mocha": "^11.7.5",
61
61
  "mocha-multi-reporters": "^1.5.1",
@@ -67,8 +67,8 @@
67
67
  "devDependencies": {
68
68
  "@biomejs/biome": "~2.4.5",
69
69
  "@fluidframework/build-common": "^2.0.3",
70
- "@fluidframework/build-tools": "^0.64.0",
71
- "@fluidframework/driver-definitions": "~2.93.0",
70
+ "@fluidframework/build-tools": "^0.65.0",
71
+ "@fluidframework/driver-definitions": "~2.100.0",
72
72
  "@fluidframework/eslint-config-fluid": "^9.0.0",
73
73
  "@types/mocha": "^10.0.10",
74
74
  "@types/nock": "^9.3.0",
@@ -14,8 +14,7 @@ import {
14
14
  } from "@fluidframework/azure-client";
15
15
  import { AttachState } from "@fluidframework/container-definitions";
16
16
  import { ConnectionState } from "@fluidframework/container-loader";
17
- import type { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
18
- import { LogLevel } from "@fluidframework/core-interfaces";
17
+ import type { ITelemetryBaseLogger, LogLevel } from "@fluidframework/core-interfaces";
19
18
  import type { ScopeType } from "@fluidframework/driver-definitions/legacy";
20
19
  import type { ContainerSchema, IFluidContainer } from "@fluidframework/fluid-static";
21
20
  import { getPresence } from "@fluidframework/fluid-static";
@@ -74,7 +73,10 @@ function telemetryEventInterestLevel(eventName: string): "none" | "basic" | "det
74
73
  return "none";
75
74
  }
76
75
 
77
- function selectiveVerboseLog(event: ITelemetryBaseEvent, logLevel?: LogLevel): void {
76
+ function selectiveVerboseLog(
77
+ event: ITelemetryBaseEvent,
78
+ logLevel: LogLevel | undefined,
79
+ ): void {
78
80
  const interest = telemetryEventInterestLevel(event.eventName);
79
81
  if (interest === "none") {
80
82
  return;
@@ -86,7 +88,7 @@ function selectiveVerboseLog(event: ITelemetryBaseEvent, logLevel?: LogLevel): v
86
88
  if (interest === "details") {
87
89
  content.details = event.details;
88
90
  }
89
- log(`[${logLevel ?? LogLevel.default}]`, content);
91
+ log(`[${logLevel ?? "unspecified"}]`, content);
90
92
  }
91
93
 
92
94
  /**
@@ -147,7 +147,7 @@ for (const testOpts of testMatrix) {
147
147
  * Scenario: Client sends a signal and connected clients receive it.
148
148
  *
149
149
  * Expected behavior: While 2 clients are connected to a container,
150
- * a signal sent by 1 client should be recieved by both clients.
150
+ * a signal sent by 1 client should be received by both clients.
151
151
  */
152
152
  it("can send and receive signals", async () => {
153
153
  const { signaler, containerId } = await getOrCreateSignalerContainer(undefined, user1);
@@ -189,7 +189,7 @@ for (const testOpts of testMatrix) {
189
189
  * Scenario: Read and Write clients send signals and connected clients receive them.
190
190
  *
191
191
  * Expected behavior: While 2 clients are connected (1 writer, 2 readers) to a container,
192
- * a signal sent by any 1 client should be recieved by all 3 clients, regardless of read/write permissions.
192
+ * a signal sent by any 1 client should be received by all 3 clients, regardless of read/write permissions.
193
193
  */
194
194
  it("can send and receive read-only client signals", async function () {
195
195
  const { signaler: writeSignaler, containerId } = await getOrCreateSignalerContainer(