@dreamboard-games/sdk 0.4.0-alpha.0 → 0.4.0-alpha.2

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.
Files changed (84) hide show
  1. package/README.md +8 -1
  2. package/REFERENCE.md +1849 -379
  3. package/dist/{ResourceCounter-BTXklCEZ.d.ts → ResourceCounter-BuiNstXs.d.ts} +5 -1
  4. package/dist/{ThemeProvider-DvMl17Ny.d.ts → ThemeProvider-B1sIoBlX.d.ts} +1 -1
  5. package/dist/attributes-DbvyMbXw.d.ts +68 -0
  6. package/dist/authoring/index.d.ts +66 -0
  7. package/dist/authoring/index.js +560 -0
  8. package/dist/authoring/index.js.map +1 -0
  9. package/dist/browser-interaction.d.ts +246 -44
  10. package/dist/browser-interaction.js +14 -1
  11. package/dist/{chunk-Q5O7GPVY.js → chunk-45FI6XII.js} +630 -375
  12. package/dist/chunk-45FI6XII.js.map +1 -0
  13. package/dist/{chunk-4G7552LO.js → chunk-6JQFGSLD.js} +216 -47
  14. package/dist/chunk-6JQFGSLD.js.map +1 -0
  15. package/dist/{chunk-NBAEEHAU.js → chunk-CP35NPPY.js} +5926 -5266
  16. package/dist/chunk-CP35NPPY.js.map +1 -0
  17. package/dist/{chunk-2LDZ5C3T.js → chunk-FWVV2X74.js} +2 -2
  18. package/dist/{chunk-MNKDSGIA.js → chunk-HWJS3VOJ.js} +6 -2
  19. package/dist/chunk-HWJS3VOJ.js.map +1 -0
  20. package/dist/chunk-K5ZRJTZZ.js +328 -0
  21. package/dist/chunk-K5ZRJTZZ.js.map +1 -0
  22. package/dist/{chunk-U5KBV2BA.js → chunk-N6ZDIMRB.js} +444 -223
  23. package/dist/chunk-N6ZDIMRB.js.map +1 -0
  24. package/dist/chunk-O6M6PN4E.js +1225 -0
  25. package/dist/chunk-O6M6PN4E.js.map +1 -0
  26. package/dist/chunk-PF7L4BMG.js +117 -0
  27. package/dist/chunk-PF7L4BMG.js.map +1 -0
  28. package/dist/{chunk-P7F4L2FF.js → chunk-WOWFONLZ.js} +609 -1287
  29. package/dist/chunk-WOWFONLZ.js.map +1 -0
  30. package/dist/{chunk-QLG6VEMW.js → chunk-WUIVY2KE.js} +318 -21
  31. package/dist/chunk-WUIVY2KE.js.map +1 -0
  32. package/dist/chunk-ZAS2SENW.js +12 -0
  33. package/dist/chunk-ZAS2SENW.js.map +1 -0
  34. package/dist/codegen.d.ts +11 -1
  35. package/dist/codegen.js +1 -1
  36. package/dist/{components-DaIqi9QM.d.ts → components-BbWPnZCF.d.ts} +37 -70
  37. package/dist/{hex-board-view-UCUjMALd.d.ts → hex-board-view-Kz9Q_zsv.d.ts} +1 -1
  38. package/dist/index.js +2 -1
  39. package/dist/package-set.d.ts +2 -2
  40. package/dist/package-set.js +2 -1
  41. package/dist/player-state-Cqpyeql0.d.ts +371 -0
  42. package/dist/protocol-BP193lva.d.ts +267 -0
  43. package/dist/reducer/advanced.d.ts +2 -2
  44. package/dist/reducer/advanced.js +1 -1
  45. package/dist/reducer-contract.js +1 -1
  46. package/dist/reducer.d.ts +7 -7
  47. package/dist/reducer.js +190 -183
  48. package/dist/reducer.js.map +1 -1
  49. package/dist/runtime/primitives.d.ts +10 -9
  50. package/dist/runtime/primitives.js +9 -6
  51. package/dist/runtime/runtime-api.d.ts +2 -2
  52. package/dist/runtime/workspace-contract.d.ts +28 -76
  53. package/dist/runtime/workspace-contract.js +7 -5
  54. package/dist/runtime-api-BJharVaj.d.ts +198 -0
  55. package/dist/runtime-api-C6aWo9c0.d.ts +95 -0
  56. package/dist/runtime-json-CQ9QbLZ5.d.ts +5 -0
  57. package/dist/runtime.d.ts +80 -11
  58. package/dist/runtime.js +89 -445
  59. package/dist/runtime.js.map +1 -1
  60. package/dist/testing.d.ts +643 -22
  61. package/dist/testing.js +1371 -76
  62. package/dist/testing.js.map +1 -1
  63. package/dist/types-CYeN0wLK.d.ts +29 -0
  64. package/dist/{attributes-BeRyboMS.d.ts → types-DJj5MJkl.d.ts} +32 -55
  65. package/dist/types.d.ts +14 -7
  66. package/dist/ui/components.d.ts +4 -5
  67. package/dist/ui/components.js +19 -1
  68. package/dist/ui/player-state.d.ts +2 -365
  69. package/dist/ui/plugin-styles.css +1 -1
  70. package/dist/{ui-contract-BUC6iS3s.d.ts → ui-contract-CY7cxsCC.d.ts} +17 -26
  71. package/dist/ui.d.ts +8 -13
  72. package/dist/ui.js +20 -2
  73. package/dist/{views-B0hlW6IT.d.ts → views-fn2RuXOx.d.ts} +59 -44
  74. package/package.json +28 -4
  75. package/dist/chunk-4G7552LO.js.map +0 -1
  76. package/dist/chunk-MNKDSGIA.js.map +0 -1
  77. package/dist/chunk-NBAEEHAU.js.map +0 -1
  78. package/dist/chunk-P7F4L2FF.js.map +0 -1
  79. package/dist/chunk-Q5O7GPVY.js.map +0 -1
  80. package/dist/chunk-QLG6VEMW.js.map +0 -1
  81. package/dist/chunk-U5KBV2BA.js.map +0 -1
  82. package/dist/hex-color-MhOyuY-o.d.ts +0 -8
  83. package/dist/runtime-api-BXd70c2e.d.ts +0 -490
  84. /package/dist/{chunk-2LDZ5C3T.js.map → chunk-FWVV2X74.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/testing/definitions.ts","../src/testing/create-expect-api.ts","../src/testing/create-test-runtime.ts"],"sourcesContent":["import type {\n DispatchTraceSummaryEntry,\n ReducerDiagnosticEvent,\n} from \"../reducer/diagnostics.js\";\n\nexport type TestRunner = \"reducer\" | \"remote\" | \"browser\";\n\nexport type InteractionDescriptorLike = {\n interactionId?: string;\n surface?: string;\n kind?: string;\n availability?: InteractionAvailabilityLike;\n context?: {\n to?: string;\n };\n} & Record<string, unknown>;\n\nexport type InteractionAvailabilityLike =\n | { status: \"available\" }\n | { status: \"notYourTurn\"; reason: string }\n | {\n status: \"insufficientResources\";\n reason: string;\n missingResources?: Record<string, unknown>;\n }\n | { status: \"blocked\"; reason: string };\n\nexport type InteractionExplanationLike = {\n interactionId: string;\n phase: string;\n step: string | null;\n availability:\n | \"available\"\n | \"notYourTurn\"\n | \"wrongPhase\"\n | \"wrongStep\"\n | \"blocked\";\n rules: ReadonlyArray<{\n ruleId: string;\n outcome: \"passed\" | \"failed\" | \"notEvaluated\";\n errorCode?: string;\n message?: string;\n }>;\n actor: { required: readonly string[]; playerIsActor: boolean };\n inputs: ReadonlyArray<{\n key: string;\n kind: string;\n eligibleCount: number | \"lazy\";\n }>;\n};\n\nexport type SnapshotMatcherHandler = (\n name: string | undefined,\n actual: unknown,\n) => void;\n\nexport type RejectionExpectation = {\n errorCode?: string;\n message?: string | RegExp;\n};\n\nexport type ExpectMatchers = {\n toBe: (expected: unknown) => void;\n toEqual: (expected: unknown) => void;\n toMatchObject: (expected: Record<string, unknown>) => void;\n toBeDefined: () => void;\n toBeUndefined: () => void;\n toBeNull: () => void;\n toContain: (expected: unknown) => void;\n toContainEqual: (expected: unknown) => void;\n toHaveLength: (expected: number) => void;\n toBeGreaterThan: (expected: number) => void;\n toBeGreaterThanOrEqual: (expected: number) => void;\n toThrow: (predicate?: string | RegExp | ((error: Error) => boolean)) => void;\n toMatchSnapshot: (filename?: string) => void;\n toRejectWith: (expected: RejectionExpectation) => Promise<void>;\n toHaveInteraction: (\n interactionId: string,\n opts?: Partial<InteractionDescriptorLike>,\n ) => void;\n toBeGatedBy: (reason: string, opts?: { interactionId?: string }) => void;\n toBeAvailable: (explanation?: InteractionExplanationLike) => void;\n toBeActiveFor: (playerId: string, opts?: { interactionId?: string }) => void;\n not: {\n toHaveInteraction: (interactionId: string) => void;\n };\n};\n\nexport type ExpectFn = (actual: unknown) => ExpectMatchers;\n\nexport interface BaseContext<PlayerId extends string = string> {\n game: {\n start(): Promise<void>;\n patchState?(\n mutator: (state: Record<string, unknown>) => void,\n ): Promise<void>;\n submit(\n playerId: PlayerId,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n };\n players(): readonly PlayerId[];\n seat(index: number): PlayerId;\n}\n\nexport interface SharedScenarioContext<\n PlayerId extends string = string,\n StateName extends string = string,\n View = unknown,\n Descriptor extends InteractionDescriptorLike = InteractionDescriptorLike,\n> extends BaseContext<PlayerId> {\n state(): StateName;\n view(playerId: PlayerId): View;\n interactions(playerId: PlayerId): readonly Descriptor[];\n explain(\n playerId: PlayerId,\n interactionId: string,\n ): InteractionExplanationLike;\n diagnostics: {\n readonly events: readonly ReducerDiagnosticEvent[];\n readonly lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null;\n clear(): void;\n };\n expect: ExpectFn;\n}\n\nexport interface BaseDefinition {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: string | null;\n extends?: string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n}\n\nexport interface ScenarioDefinition<\n Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n PhaseName extends string = string,\n StageName extends string = string,\n> {\n id: string;\n description?: string;\n from: string;\n runners?: Runners;\n phase?: PhaseName;\n stage?: StageName;\n when: (ctx: SharedScenarioContext) => void | Promise<void>;\n then: (ctx: SharedScenarioContext) => void | Promise<void>;\n}\n\nexport function defineBase<const Definition extends BaseDefinition>(\n definition: Definition,\n): Definition {\n return definition;\n}\n\nexport function defineScenario<\n const Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n const PhaseName extends string = string,\n const StageName extends string = string,\n>(\n definition: ScenarioDefinition<Runners, PhaseName, StageName>,\n): ScenarioDefinition<Runners, PhaseName, StageName> {\n return definition;\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n ExpectFn,\n ExpectMatchers,\n InteractionDescriptorLike,\n RejectionExpectation,\n InteractionExplanationLike,\n SnapshotMatcherHandler,\n} from \"./definitions.js\";\nimport type { ReducerDiagnosticEvent } from \"../reducer/diagnostics.js\";\n\ntype CreateExpectApiOptions = {\n matchSnapshot?: SnapshotMatcherHandler;\n lastDiagnosticRejection?: () =>\n | Extract<ReducerDiagnosticEvent, { type: \"submitRejected\" }>\n | null\n | undefined;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction matchPartial(\n actual: unknown,\n expected: unknown,\n path: string = \"value\",\n): string | null {\n if (!isRecord(expected)) {\n return isDeepStrictEqual(actual, expected)\n ? null\n : `${path} does not match`;\n }\n if (!isRecord(actual)) {\n return `${path} is not an object`;\n }\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actualValue = actual[key];\n if (!(key in actual)) {\n return `${path}.${key} is missing`;\n }\n const mismatch = matchPartial(actualValue, expectedValue, `${path}.${key}`);\n if (mismatch) {\n return mismatch;\n }\n }\n return null;\n}\n\nfunction asDescriptorList(actual: unknown): InteractionDescriptorLike[] {\n if (!Array.isArray(actual)) {\n throw new Error(\"Expected interaction descriptor array.\");\n }\n return actual as InteractionDescriptorLike[];\n}\n\nfunction findInteraction(\n descriptors: readonly InteractionDescriptorLike[],\n interactionId: string,\n): InteractionDescriptorLike | null {\n return (\n descriptors.find(\n (descriptor) => descriptor.interactionId === interactionId,\n ) ?? null\n );\n}\n\nfunction assertDescriptorMatches(\n descriptor: InteractionDescriptorLike,\n opts: Partial<InteractionDescriptorLike> | undefined,\n): void {\n if (!opts) {\n return;\n }\n const mismatch = matchPartial(descriptor, opts, \"interaction\");\n if (mismatch) {\n throw new Error(mismatch);\n }\n}\n\nfunction createSubmissionErrorMatcher(\n actual: unknown,\n expected: RejectionExpectation,\n options: CreateExpectApiOptions,\n): Promise<void> {\n const resolvePromise = (): Promise<unknown> => {\n if (typeof actual === \"function\") {\n return Promise.resolve().then(() => (actual as () => unknown)());\n }\n return Promise.resolve(actual);\n };\n\n return resolvePromise()\n .then(() => {\n throw new Error(\"Expected promise to reject.\");\n })\n .catch((error: unknown) => {\n if (!(error instanceof Error)) {\n throw new Error(\"Expected rejection to be an Error.\");\n }\n if (\n expected.errorCode !== undefined &&\n (error as Error & { errorCode?: string }).errorCode !==\n expected.errorCode\n ) {\n throw new Error(\n `Expected rejection errorCode '${expected.errorCode}', received '${\n (error as Error & { errorCode?: string }).errorCode ?? \"undefined\"\n }'.${formatLastDiagnosticRejection(options)}`,\n );\n }\n if (\n typeof expected.message === \"string\" &&\n error.message !== expected.message\n ) {\n throw new Error(\n `Expected rejection message '${expected.message}', received '${error.message}'.${formatLastDiagnosticRejection(\n options,\n )}`,\n );\n }\n if (\n expected.message instanceof RegExp &&\n !expected.message.test(error.message)\n ) {\n throw new Error(\n `Expected rejection message '${error.message}' to match ${String(\n expected.message,\n )}.${formatLastDiagnosticRejection(options)}`,\n );\n }\n });\n}\n\nfunction formatLastDiagnosticRejection(\n options: CreateExpectApiOptions,\n): string {\n const rejection = options.lastDiagnosticRejection?.();\n if (!rejection) return \"\";\n const rule = rejection.ruleId ? ` ruleId=${rejection.ruleId}` : \"\";\n const message = rejection.message ? ` message=${rejection.message}` : \"\";\n return `\\nlast rejection: errorCode=${rejection.errorCode}${rule}${message}`;\n}\n\nfunction assertLength(actual: unknown, expected: number): void {\n if (\n actual === null ||\n actual === undefined ||\n typeof (actual as { length?: unknown }).length !== \"number\"\n ) {\n throw new Error(\"toHaveLength expects a value with a numeric length.\");\n }\n const length = (actual as { length: number }).length;\n if (length !== expected) {\n throw new Error(`Expected length ${expected}, received ${length}.`);\n }\n}\n\nfunction formatInteractionExplanation(\n explanation: InteractionExplanationLike | undefined,\n): string {\n if (!explanation) {\n return \"\";\n }\n const lines = [\n `availability: ${explanation.availability}`,\n ...explanation.rules.map((rule) => {\n const code = rule.errorCode ? ` (${rule.errorCode})` : \"\";\n const message = rule.message ? `: ${rule.message}` : \"\";\n return `rule ${rule.ruleId} ${rule.outcome}${code}${message}`;\n }),\n ...explanation.inputs.map(\n (input) => `input ${input.key} eligibleCount=${input.eligibleCount}`,\n ),\n ];\n return `\\n${lines.join(\"\\n\")}`;\n}\n\nfunction assertThrown(\n actual: unknown,\n predicate?: string | RegExp | ((error: Error) => boolean),\n): void {\n if (typeof actual !== \"function\") {\n throw new Error(\"toThrow expects a function.\");\n }\n try {\n (actual as () => unknown)();\n } catch (error) {\n if (!(error instanceof Error)) {\n throw new Error(\"Thrown value is not an Error.\");\n }\n if (predicate === undefined) {\n return;\n }\n if (typeof predicate === \"string\" && error.message !== predicate) {\n throw new Error(\n `Expected thrown message '${predicate}', received '${error.message}'.`,\n );\n }\n if (predicate instanceof RegExp && !predicate.test(error.message)) {\n throw new Error(\n `Expected thrown message '${error.message}' to match ${String(predicate)}.`,\n );\n }\n if (typeof predicate === \"function\" && !predicate(error)) {\n throw new Error(\"Thrown error did not satisfy predicate.\");\n }\n return;\n }\n throw new Error(\"Expected function to throw.\");\n}\n\nexport function createExpectApi(\n options: CreateExpectApiOptions = {},\n): ExpectFn {\n const buildMatchers = (actual: unknown): ExpectMatchers => ({\n toBe: (expected: unknown) => {\n if (actual !== expected) {\n throw new Error(\n `Expected '${String(actual)}' to be '${String(expected)}'.`,\n );\n }\n },\n toEqual: (expected: unknown) => {\n if (!isDeepStrictEqual(actual, expected)) {\n throw new Error(\"Expected values to be deeply equal.\");\n }\n },\n toMatchObject: (expected: Record<string, unknown>) => {\n const mismatch = matchPartial(actual, expected);\n if (mismatch) {\n throw new Error(mismatch);\n }\n },\n toBeDefined: () => {\n if (actual === undefined) {\n throw new Error(\"Expected value to be defined.\");\n }\n },\n toBeUndefined: () => {\n if (actual !== undefined) {\n throw new Error(\n `Expected value to be undefined, but received '${String(actual)}'.`,\n );\n }\n },\n toBeNull: () => {\n if (actual !== null) {\n throw new Error(\n `Expected value to be null, but received '${String(actual)}'.`,\n );\n }\n },\n toContain: (expected: unknown) => {\n if (Array.isArray(actual)) {\n if (!actual.includes(expected)) {\n throw new Error(\"Expected array to contain value.\");\n }\n return;\n }\n if (typeof actual === \"string\") {\n if (!actual.includes(String(expected))) {\n throw new Error(\"Expected string to contain value.\");\n }\n return;\n }\n throw new Error(\"toContain expects an array or string actual value.\");\n },\n toContainEqual: (expected: unknown) => {\n if (!Array.isArray(actual)) {\n throw new Error(\"toContainEqual expects an array actual value.\");\n }\n if (!actual.some((value) => isDeepStrictEqual(value, expected))) {\n throw new Error(\"Expected array to contain an equal value.\");\n }\n },\n toHaveLength: (expected: number) => {\n assertLength(actual, expected);\n },\n toBeGreaterThan: (expected: number) => {\n if (typeof actual !== \"number\") {\n throw new Error(\"toBeGreaterThan expects a number actual value.\");\n }\n if (actual <= expected) {\n throw new Error(`Expected ${actual} to be > ${expected}.`);\n }\n },\n toBeGreaterThanOrEqual: (expected: number) => {\n if (typeof actual !== \"number\") {\n throw new Error(\n \"toBeGreaterThanOrEqual expects a number actual value.\",\n );\n }\n if (actual < expected) {\n throw new Error(`Expected ${actual} to be >= ${expected}.`);\n }\n },\n toThrow: (predicate) => {\n assertThrown(actual, predicate);\n },\n toMatchSnapshot: (filename) => {\n if (!options.matchSnapshot) {\n throw new Error(\n \"Snapshot matching is not configured for this expect API.\",\n );\n }\n options.matchSnapshot(filename, actual);\n },\n toRejectWith: (expected) =>\n createSubmissionErrorMatcher(actual, expected, options),\n toHaveInteraction: (interactionId, opts) => {\n const descriptors = asDescriptorList(actual);\n const descriptor = findInteraction(descriptors, interactionId);\n if (!descriptor) {\n throw new Error(`Expected interaction '${interactionId}' to exist.`);\n }\n assertDescriptorMatches(descriptor, opts);\n },\n toBeGatedBy: (reason, opts) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!opts?.interactionId) {\n throw new Error(\n \"toBeGatedBy on a descriptor array requires opts.interactionId.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n opts.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\"Expected interaction descriptor to exist.\");\n }\n if (descriptor.availability?.status === \"available\") {\n throw new Error(\"Expected interaction to be unavailable.\");\n }\n const actualReason =\n descriptor.availability?.status === \"notYourTurn\" ||\n descriptor.availability?.status === \"insufficientResources\" ||\n descriptor.availability?.status === \"blocked\"\n ? descriptor.availability.reason\n : undefined;\n if (actualReason !== reason) {\n throw new Error(\n `Expected unavailable reason '${reason}', received '${\n actualReason ?? \"undefined\"\n }'.`,\n );\n }\n },\n toBeAvailable: (explanation) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!explanation?.interactionId) {\n throw new Error(\n \"toBeAvailable on a descriptor array requires an explanation.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n explanation.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\n `Expected interaction descriptor to exist.${formatInteractionExplanation(\n explanation,\n )}`,\n );\n }\n if (descriptor.availability?.status !== \"available\") {\n throw new Error(\n `Expected interaction '${descriptor.interactionId ?? \"unknown\"}' to be available.${formatInteractionExplanation(\n explanation,\n )}`,\n );\n }\n },\n toBeActiveFor: (playerId, opts) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!opts?.interactionId) {\n throw new Error(\n \"toBeActiveFor on a descriptor array requires opts.interactionId.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n opts.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\"Expected interaction descriptor to exist.\");\n }\n if (descriptor.context?.to !== playerId) {\n throw new Error(\n `Expected interaction to target '${playerId}', received '${\n descriptor.context?.to ?? \"undefined\"\n }'.`,\n );\n }\n if (descriptor.availability?.status !== \"available\") {\n throw new Error(\"Expected interaction to be available.\");\n }\n },\n not: {\n toHaveInteraction: (interactionId) => {\n const descriptors = asDescriptorList(actual);\n if (findInteraction(descriptors, interactionId)) {\n throw new Error(\n `Expected interaction '${interactionId}' to be absent.`,\n );\n }\n },\n },\n });\n\n return (actual: unknown) => buildMatchers(actual);\n}\n","import type {\n ReducerBundleContract,\n Wire,\n} from \"@dreamboard-games/reducer-contract\";\nimport type {\n InteractionDescriptor,\n PluginStateSnapshot,\n ZoneHandlesSnapshot,\n} from \"../runtime/reducer.js\";\nimport type {\n RuntimeAPI,\n SubmissionError,\n ValidationResult,\n} from \"../runtime/types/runtime-api.js\";\nimport type { PluginSessionState as RuntimePluginSessionState } from \"../runtime/types/runtime-api.js\";\nimport type {\n DispatchTraceSummaryEntry,\n ReducerDiagnosticEvent,\n} from \"../reducer/diagnostics.js\";\nimport { StaleContractArtifactError } from \"../reducer/stale-contract-artifact-error.js\";\nimport type { InteractionExplanationLike } from \"./definitions.js\";\n\ntype ReducerBundleLike = Pick<\n ReducerBundleContract,\n \"projectSeatsDynamic\" | \"validateInput\" | \"dispatch\"\n> & {\n explainInteraction?: (input: {\n state: Wire.ReducerSessionState;\n playerId: string;\n interactionId: string;\n }) => InteractionExplanationLike;\n};\n\ntype DeepReadonly<T> = T extends (...args: readonly unknown[]) => unknown\n ? T\n : T extends readonly (infer Item)[]\n ? readonly DeepReadonly<Item>[]\n : T extends object\n ? { readonly [Key in keyof T]: DeepReadonly<T[Key]> }\n : T;\n\ntype DeepMutable<T> = T extends (...args: readonly unknown[]) => unknown\n ? T\n : T extends readonly (infer Item)[]\n ? DeepMutable<Item>[]\n : T extends object\n ? { -readonly [Key in keyof T]: DeepMutable<T[Key]> }\n : T;\n\ntype BaseStateArtifact = {\n snapshot: DeepReadonly<Wire.ReducerSessionState>;\n fingerprint: {\n players: number;\n contractFingerprint?: string;\n };\n};\n\ntype WireZoneHandles = {\n cardIds?: readonly string[];\n cardViewsById?: Readonly<Record<string, string>>;\n playableByCardId?: Readonly<Record<string, readonly string[]>>;\n};\n\nexport type CreateTestRuntimeOptions = {\n baseId: string;\n baseStates: Record<string, BaseStateArtifact>;\n bundle: ReducerBundleLike;\n phase?: string;\n playerIds?: readonly string[];\n sessionId?: string;\n userId?: string | null;\n gameId?: string;\n displayNameByPlayerId?: Record<string, string>;\n contractFingerprint?: string;\n expectedBaseStateFingerprint?: string;\n};\n\nexport type CreatedTestRuntime = {\n runtime: RuntimeAPI & {\n getSnapshot(): PluginStateSnapshot;\n subscribeToState(\n listener: (state: PluginStateSnapshot) => void,\n ): () => void;\n _subscribeToSessionState(\n listener: (state: RuntimePluginSessionState) => void,\n ): () => void;\n };\n getSnapshot(): PluginStateSnapshot;\n players(): readonly string[];\n seat(index: number): string;\n submit(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n validate(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<ValidationResult>;\n explain(playerId: string, interactionId: string): InteractionExplanationLike;\n diagnostics: {\n readonly events: readonly ReducerDiagnosticEvent[];\n readonly lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null;\n clear(): void;\n };\n setControllingPlayer(playerId: string): void;\n};\n\nfunction cloneState<T>(value: T): DeepMutable<T> {\n return structuredClone(value) as DeepMutable<T>;\n}\n\nfunction createSubmissionError(\n errorCode: string | undefined,\n message: string | undefined,\n): SubmissionError {\n const error = new Error(message ?? \"Interaction rejected\") as SubmissionError;\n error.name = \"SubmissionError\";\n error.errorCode = errorCode;\n return error;\n}\n\nfunction summarizeWireTrace(\n trace: readonly unknown[] | undefined,\n): DispatchTraceSummaryEntry[] {\n return (trace ?? []).flatMap((entry): DispatchTraceSummaryEntry[] => {\n if (typeof entry !== \"object\" || entry === null) return [];\n const record = entry as Record<string, unknown>;\n switch (record.kind) {\n case \"acceptedClientInput\": {\n const input =\n typeof record.input === \"object\" && record.input !== null\n ? (record.input as Record<string, unknown>)\n : {};\n return [\n {\n kind: \"acceptedClientInput\",\n interactionId: String(input.interactionId ?? \"\"),\n playerId: String(input.playerId ?? \"\"),\n },\n ];\n }\n case \"appliedEffect\": {\n const effect =\n typeof record.effect === \"object\" && record.effect !== null\n ? (record.effect as Record<string, unknown>)\n : {};\n return [\n {\n kind: \"appliedInstruction\",\n instruction: String(effect.kind ?? effect.type ?? \"effect\"),\n },\n ];\n }\n case \"rngConsumption\":\n return [\n {\n kind: \"rngConsumption\",\n operation: String(record.operation ?? \"\"),\n traceEntry: String(record.traceEntry ?? \"\"),\n },\n ];\n default:\n return [];\n }\n });\n}\n\nfunction readFlowState(state: Wire.ReducerSessionState): {\n currentPhase: string | null;\n activePlayers: string[];\n} {\n const flow = ((\n state.domain as\n | { flow?: { currentPhase?: string; activePlayers?: string[] } }\n | undefined\n )?.flow ?? {}) as {\n currentPhase?: string;\n activePlayers?: string[];\n };\n return {\n currentPhase: flow.currentPhase ?? null,\n activePlayers: Array.isArray(flow.activePlayers) ? flow.activePlayers : [],\n };\n}\n\nfunction resolvePlayerIds(options: {\n baseState: BaseStateArtifact;\n explicitPlayerIds?: readonly string[];\n}): string[] {\n if (options.explicitPlayerIds && options.explicitPlayerIds.length > 0) {\n return [...options.explicitPlayerIds];\n }\n return Array.from(\n { length: options.baseState.fingerprint.players },\n (_, index) => `player-${index + 1}`,\n );\n}\n\nfunction isWireZoneHandles(value: unknown): value is WireZoneHandles {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction buildPluginSnapshot(options: {\n state: Wire.ReducerSessionState;\n bundle: ReducerBundleLike;\n playerId: string;\n playerIds: readonly string[];\n userId: string | null;\n sessionId: string;\n version: number;\n expectedPhase: string | undefined;\n baseId: string;\n}): PluginStateSnapshot {\n const projection = options.bundle.projectSeatsDynamic({\n state: options.state,\n playerIds: [options.playerId],\n });\n\n const flow = readFlowState(options.state);\n if (options.expectedPhase && flow.currentPhase !== options.expectedPhase) {\n throw new Error(\n `Expected base '${options.baseId}' to be in phase '${options.expectedPhase}', received '${\n flow.currentPhase ?? \"null\"\n }'.`,\n );\n }\n\n const interactionsByRef =\n (projection.interactionsByRef as\n | Record<string, InteractionDescriptor>\n | undefined) ?? {};\n const hydrateRefs = (\n refs: readonly string[] | undefined,\n ): InteractionDescriptor[] =>\n (refs ?? [])\n .map((ref) => interactionsByRef[ref])\n .filter((descriptor): descriptor is InteractionDescriptor =>\n Boolean(descriptor),\n );\n\n const seat = projection.seats?.[options.playerId];\n const zones = Object.fromEntries(\n Object.entries(\n (seat?.zones as Record<string, unknown> | undefined) ?? {},\n ).map(([zoneId, zoneValue]) => {\n const zone = isWireZoneHandles(zoneValue) ? zoneValue : {};\n return [\n zoneId,\n {\n cardIds: [...(zone.cardIds ?? [])],\n cardViewsById: { ...(zone.cardViewsById ?? {}) },\n playableByCardId: Object.fromEntries(\n Object.entries(zone.playableByCardId ?? {}).map(\n ([cardId, refs]) => [cardId, hydrateRefs(refs)],\n ),\n ),\n } satisfies ZoneHandlesSnapshot,\n ];\n }),\n );\n\n return {\n view: (seat?.view ?? null) as PluginStateSnapshot[\"view\"],\n gameplay: {\n currentPhase: flow.currentPhase,\n currentStage: projection.currentStage ?? null,\n activePlayers: flow.activePlayers,\n simultaneousPhase: projection.simultaneousPhase ?? null,\n availableInteractions: hydrateRefs(\n seat?.availableInteractionRefs as readonly string[] | undefined,\n ),\n zones,\n },\n lobby: null,\n notifications: [],\n session: {\n sessionId: options.sessionId,\n controllablePlayerIds: [...options.playerIds],\n controllingPlayerId: options.playerId || null,\n userId: options.userId,\n },\n history: null,\n syncId: options.version,\n };\n}\n\nexport function createTestRuntime(\n options: CreateTestRuntimeOptions,\n): CreatedTestRuntime {\n const baseState = options.baseStates[options.baseId];\n if (!baseState) {\n throw new Error(`Unknown test base '${options.baseId}'.`);\n }\n const expectedBaseStateFingerprint =\n options.expectedBaseStateFingerprint ??\n baseState.fingerprint.contractFingerprint;\n if (\n options.contractFingerprint &&\n expectedBaseStateFingerprint &&\n options.contractFingerprint !== expectedBaseStateFingerprint\n ) {\n throw new StaleContractArtifactError({\n artifact: \"base-states\",\n expected: options.contractFingerprint,\n found: expectedBaseStateFingerprint,\n });\n }\n\n let currentState = cloneState(baseState.snapshot);\n const playerIds = resolvePlayerIds({\n baseState,\n explicitPlayerIds: options.playerIds,\n });\n const userId = options.userId ?? \"test-user\";\n const sessionId = options.sessionId ?? \"test-session\";\n\n let version = 0;\n let submissionCounter = 0;\n let currentPlayerId = playerIds[0] ?? \"\";\n const diagnosticEvents: ReducerDiagnosticEvent[] = [];\n let lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null = null;\n const stateListeners = new Set<(state: PluginStateSnapshot) => void>();\n const sessionListeners = new Set<\n (state: RuntimePluginSessionState) => void\n >();\n\n const toReadySessionState = (\n snapshot: PluginStateSnapshot,\n ): RuntimePluginSessionState => ({\n ...snapshot.session,\n status: \"ready\",\n });\n\n let lastPluginSnapshot: PluginStateSnapshot;\n let lastSessionState: RuntimePluginSessionState;\n\n const applyCurrentState = (): void => {\n const previousSession = lastSessionState;\n version += 1;\n lastPluginSnapshot = buildPluginSnapshot({\n state: currentState,\n bundle: options.bundle,\n playerId: currentPlayerId,\n playerIds,\n userId,\n sessionId,\n version,\n expectedPhase: version === 1 ? options.phase : undefined,\n baseId: options.baseId,\n });\n lastSessionState = toReadySessionState(lastPluginSnapshot);\n\n for (const listener of stateListeners) {\n listener(lastPluginSnapshot);\n }\n\n if (\n !previousSession ||\n previousSession.controllingPlayerId !==\n lastSessionState.controllingPlayerId ||\n previousSession.controllablePlayerIds.join(\"\\0\") !==\n lastSessionState.controllablePlayerIds.join(\"\\0\")\n ) {\n for (const listener of sessionListeners) {\n listener(lastSessionState);\n }\n }\n };\n\n applyCurrentState();\n\n const validate = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<ValidationResult> => {\n const result = await options.bundle.validateInput({\n state: currentState,\n input: {\n kind: \"interaction\",\n playerId,\n interactionId,\n params: params as Wire.JsonValue,\n },\n });\n return {\n valid: result.valid,\n errorCode: result.errorCode,\n message: result.message,\n };\n };\n\n const submit = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<void> => {\n submissionCounter += 1;\n const submissionId = `sub-${submissionCounter}`;\n diagnosticEvents.push({\n type: \"submitReceived\",\n submissionId,\n playerId,\n interactionId,\n phase: readFlowState(currentState).currentPhase ?? \"\",\n });\n const validation = await validate(playerId, interactionId, params);\n if (!validation.valid) {\n diagnosticEvents.push({\n type: \"submitRejected\",\n submissionId,\n errorCode: validation.errorCode ?? \"invalid-action\",\n ...(validation.message ? { message: validation.message } : {}),\n });\n throw createSubmissionError(validation.errorCode, validation.message);\n }\n const result = await options.bundle.dispatch({\n state: currentState,\n input: {\n kind: \"interaction\",\n playerId,\n interactionId,\n params: params as Wire.JsonValue,\n },\n });\n if (result.kind === \"reject\") {\n diagnosticEvents.push({\n type: \"submitRejected\",\n submissionId,\n errorCode: result.errorCode,\n ...(result.message ? { message: result.message } : {}),\n });\n throw createSubmissionError(result.errorCode, result.message);\n }\n const trace = summarizeWireTrace(result.trace);\n lastDispatch = { submissionId, trace };\n diagnosticEvents.push({\n type: \"submitAccepted\",\n submissionId,\n trace,\n });\n currentState = cloneState(result.state);\n applyCurrentState();\n };\n\n const explain = (\n playerId: string,\n interactionId: string,\n ): InteractionExplanationLike => {\n if (!options.bundle.explainInteraction) {\n throw new Error(\n \"This reducer bundle does not expose explainInteraction().\",\n );\n }\n return options.bundle.explainInteraction({\n state: currentState,\n playerId,\n interactionId,\n });\n };\n\n const setControllingPlayer = (playerId: string): void => {\n if (!playerIds.includes(playerId)) {\n throw new Error(`Unknown controlling player '${playerId}'.`);\n }\n currentPlayerId = playerId;\n applyCurrentState();\n };\n\n const runtime = {\n validateInteraction: validate,\n submitInteraction: submit,\n getSessionState: (): RuntimePluginSessionState => lastSessionState,\n disconnect: () => undefined,\n switchPlayer: (playerId: string) => {\n setControllingPlayer(playerId);\n },\n getSnapshot: (): PluginStateSnapshot => lastPluginSnapshot,\n subscribeToState: (listener: (state: PluginStateSnapshot) => void) => {\n stateListeners.add(listener);\n return () => {\n stateListeners.delete(listener);\n };\n },\n _subscribeToSessionState: (\n listener: (state: RuntimePluginSessionState) => void,\n ) => {\n sessionListeners.add(listener);\n return () => {\n sessionListeners.delete(listener);\n };\n },\n };\n\n return {\n runtime,\n getSnapshot: () => lastPluginSnapshot,\n players: () => [...playerIds],\n seat: (index: number) => {\n if (!Number.isInteger(index) || index < 0 || index >= playerIds.length) {\n throw new Error(\n `seat(${index}) is out of range; base '${options.baseId}' has ${playerIds.length} player(s).`,\n );\n }\n return playerIds[index]!;\n },\n submit,\n validate,\n explain,\n diagnostics: {\n get events() {\n return diagnosticEvents;\n },\n get lastDispatch() {\n return lastDispatch;\n },\n clear() {\n diagnosticEvents.length = 0;\n lastDispatch = null;\n },\n },\n setControllingPlayer,\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/testing/definitions.ts","../src/testing/create-expect-api.ts","../src/testing/create-test-runtime.ts","../src/testing/ui-fixture/canonical.ts","../src/testing/reducer-scenario/create-reducer-scenario-runner.ts","../src/testing/ui-fixture/parity.ts","../src/testing/ui-fixture/create-fixture-host-harness.ts","../src/testing/ui-fixture/FixturePluginRuntime.tsx","../src/testing/ui-fixture/compile-plugin-protocol-tape.ts","../src/testing/ui-fixture/deterministic-environment.ts","../src/testing/ui-fixture/schema.ts","../src/testing/ui-fixture/compiler.ts"],"sourcesContent":["import type {\n DispatchTraceSummaryEntry,\n ReducerDiagnosticEvent,\n} from \"../reducer/diagnostics.js\";\n\nexport type TestRunner = \"reducer\" | \"remote\" | \"browser\";\n\nexport type InteractionDescriptorLike = {\n interactionId?: string;\n surface?: string;\n kind?: string;\n availability?: InteractionAvailabilityLike;\n context?: {\n to?: string;\n };\n} & Record<string, unknown>;\n\nexport type InteractionAvailabilityLike =\n | { status: \"available\" }\n | { status: \"notYourTurn\"; reason: string }\n | {\n status: \"insufficientResources\";\n reason: string;\n missingResources?: Record<string, unknown>;\n }\n | { status: \"blocked\"; reason: string };\n\nexport type InteractionExplanationLike = {\n interactionId: string;\n phase: string;\n step: string | null;\n availability:\n | \"available\"\n | \"notYourTurn\"\n | \"wrongPhase\"\n | \"wrongStep\"\n | \"blocked\";\n rules: ReadonlyArray<{\n ruleId: string;\n outcome: \"passed\" | \"failed\" | \"notEvaluated\";\n errorCode?: string;\n message?: string;\n }>;\n actor: { required: readonly string[]; playerIsActor: boolean };\n inputs: ReadonlyArray<{\n key: string;\n kind: string;\n eligibleCount: number | \"lazy\";\n }>;\n};\n\nexport type SnapshotMatcherHandler = (\n name: string | undefined,\n actual: unknown,\n) => void;\n\nexport type RejectionExpectation = {\n errorCode?: string;\n message?: string | RegExp;\n};\n\nexport type ExpectMatchers = {\n toBe: (expected: unknown) => void;\n toEqual: (expected: unknown) => void;\n toMatchObject: (expected: Record<string, unknown>) => void;\n toBeDefined: () => void;\n toBeUndefined: () => void;\n toBeNull: () => void;\n toContain: (expected: unknown) => void;\n toContainEqual: (expected: unknown) => void;\n toHaveLength: (expected: number) => void;\n toBeGreaterThan: (expected: number) => void;\n toBeGreaterThanOrEqual: (expected: number) => void;\n toThrow: (predicate?: string | RegExp | ((error: Error) => boolean)) => void;\n toMatchSnapshot: (filename?: string) => void;\n toRejectWith: (expected: RejectionExpectation) => Promise<void>;\n toHaveInteraction: (\n interactionId: string,\n opts?: Partial<InteractionDescriptorLike>,\n ) => void;\n toBeGatedBy: (reason: string, opts?: { interactionId?: string }) => void;\n toBeAvailable: (explanation?: InteractionExplanationLike) => void;\n toBeActiveFor: (playerId: string, opts?: { interactionId?: string }) => void;\n not: {\n toHaveInteraction: (interactionId: string) => void;\n };\n};\n\nexport type ExpectFn = (actual: unknown) => ExpectMatchers;\n\nexport interface BaseContext<PlayerId extends string = string> {\n game: {\n start(): Promise<void>;\n patchState?(\n mutator: (state: Record<string, unknown>) => void,\n ): Promise<void>;\n submit(\n playerId: PlayerId,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n };\n players(): readonly PlayerId[];\n seat(index: number): PlayerId;\n}\n\nexport interface SharedScenarioContext<\n PlayerId extends string = string,\n StateName extends string = string,\n View = unknown,\n Descriptor extends InteractionDescriptorLike = InteractionDescriptorLike,\n> extends BaseContext<PlayerId> {\n state(): StateName;\n view(playerId: PlayerId): View;\n interactions(playerId: PlayerId): readonly Descriptor[];\n explain(\n playerId: PlayerId,\n interactionId: string,\n ): InteractionExplanationLike;\n diagnostics: {\n readonly events: readonly ReducerDiagnosticEvent[];\n readonly lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null;\n clear(): void;\n };\n expect: ExpectFn;\n}\n\nexport interface BaseDefinition {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: string | null;\n extends?: string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n}\n\nexport interface ScenarioDefinition<\n Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n PhaseName extends string = string,\n StageName extends string = string,\n> {\n id: string;\n description?: string;\n from: string;\n runners?: Runners;\n phase?: PhaseName;\n stage?: StageName;\n when: (ctx: SharedScenarioContext) => void | Promise<void>;\n then: (ctx: SharedScenarioContext) => void | Promise<void>;\n}\n\nexport function defineBase<const Definition extends BaseDefinition>(\n definition: Definition,\n): Definition {\n return definition;\n}\n\nexport function defineScenario<\n const Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n const PhaseName extends string = string,\n const StageName extends string = string,\n>(\n definition: ScenarioDefinition<Runners, PhaseName, StageName>,\n): ScenarioDefinition<Runners, PhaseName, StageName> {\n return definition;\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n ExpectFn,\n ExpectMatchers,\n InteractionDescriptorLike,\n RejectionExpectation,\n InteractionExplanationLike,\n SnapshotMatcherHandler,\n} from \"./definitions.js\";\nimport type { ReducerDiagnosticEvent } from \"../reducer/diagnostics.js\";\n\ntype CreateExpectApiOptions = {\n matchSnapshot?: SnapshotMatcherHandler;\n lastDiagnosticRejection?: () =>\n | Extract<ReducerDiagnosticEvent, { type: \"submitRejected\" }>\n | null\n | undefined;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction matchPartial(\n actual: unknown,\n expected: unknown,\n path: string = \"value\",\n): string | null {\n if (!isRecord(expected)) {\n return isDeepStrictEqual(actual, expected)\n ? null\n : `${path} does not match`;\n }\n if (!isRecord(actual)) {\n return `${path} is not an object`;\n }\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actualValue = actual[key];\n if (!(key in actual)) {\n return `${path}.${key} is missing`;\n }\n const mismatch = matchPartial(actualValue, expectedValue, `${path}.${key}`);\n if (mismatch) {\n return mismatch;\n }\n }\n return null;\n}\n\nfunction asDescriptorList(actual: unknown): InteractionDescriptorLike[] {\n if (!Array.isArray(actual)) {\n throw new Error(\"Expected interaction descriptor array.\");\n }\n return actual as InteractionDescriptorLike[];\n}\n\nfunction findInteraction(\n descriptors: readonly InteractionDescriptorLike[],\n interactionId: string,\n): InteractionDescriptorLike | null {\n return (\n descriptors.find(\n (descriptor) => descriptor.interactionId === interactionId,\n ) ?? null\n );\n}\n\nfunction assertDescriptorMatches(\n descriptor: InteractionDescriptorLike,\n opts: Partial<InteractionDescriptorLike> | undefined,\n): void {\n if (!opts) {\n return;\n }\n const mismatch = matchPartial(descriptor, opts, \"interaction\");\n if (mismatch) {\n throw new Error(mismatch);\n }\n}\n\nfunction createSubmissionErrorMatcher(\n actual: unknown,\n expected: RejectionExpectation,\n options: CreateExpectApiOptions,\n): Promise<void> {\n const resolvePromise = (): Promise<unknown> => {\n if (typeof actual === \"function\") {\n return Promise.resolve().then(() => (actual as () => unknown)());\n }\n return Promise.resolve(actual);\n };\n\n return resolvePromise()\n .then(() => {\n throw new Error(\"Expected promise to reject.\");\n })\n .catch((error: unknown) => {\n if (!(error instanceof Error)) {\n throw new Error(\"Expected rejection to be an Error.\");\n }\n if (\n expected.errorCode !== undefined &&\n (error as Error & { errorCode?: string }).errorCode !==\n expected.errorCode\n ) {\n throw new Error(\n `Expected rejection errorCode '${expected.errorCode}', received '${\n (error as Error & { errorCode?: string }).errorCode ?? \"undefined\"\n }'.${formatLastDiagnosticRejection(options)}`,\n );\n }\n if (\n typeof expected.message === \"string\" &&\n error.message !== expected.message\n ) {\n throw new Error(\n `Expected rejection message '${expected.message}', received '${error.message}'.${formatLastDiagnosticRejection(\n options,\n )}`,\n );\n }\n if (\n expected.message instanceof RegExp &&\n !expected.message.test(error.message)\n ) {\n throw new Error(\n `Expected rejection message '${error.message}' to match ${String(\n expected.message,\n )}.${formatLastDiagnosticRejection(options)}`,\n );\n }\n });\n}\n\nfunction formatLastDiagnosticRejection(\n options: CreateExpectApiOptions,\n): string {\n const rejection = options.lastDiagnosticRejection?.();\n if (!rejection) return \"\";\n const rule = rejection.ruleId ? ` ruleId=${rejection.ruleId}` : \"\";\n const message = rejection.message ? ` message=${rejection.message}` : \"\";\n return `\\nlast rejection: errorCode=${rejection.errorCode}${rule}${message}`;\n}\n\nfunction assertLength(actual: unknown, expected: number): void {\n if (\n actual === null ||\n actual === undefined ||\n typeof (actual as { length?: unknown }).length !== \"number\"\n ) {\n throw new Error(\"toHaveLength expects a value with a numeric length.\");\n }\n const length = (actual as { length: number }).length;\n if (length !== expected) {\n throw new Error(`Expected length ${expected}, received ${length}.`);\n }\n}\n\nfunction formatInteractionExplanation(\n explanation: InteractionExplanationLike | undefined,\n): string {\n if (!explanation) {\n return \"\";\n }\n const lines = [\n `availability: ${explanation.availability}`,\n ...explanation.rules.map((rule) => {\n const code = rule.errorCode ? ` (${rule.errorCode})` : \"\";\n const message = rule.message ? `: ${rule.message}` : \"\";\n return `rule ${rule.ruleId} ${rule.outcome}${code}${message}`;\n }),\n ...explanation.inputs.map(\n (input) => `input ${input.key} eligibleCount=${input.eligibleCount}`,\n ),\n ];\n return `\\n${lines.join(\"\\n\")}`;\n}\n\nfunction assertThrown(\n actual: unknown,\n predicate?: string | RegExp | ((error: Error) => boolean),\n): void {\n if (typeof actual !== \"function\") {\n throw new Error(\"toThrow expects a function.\");\n }\n try {\n (actual as () => unknown)();\n } catch (error) {\n if (!(error instanceof Error)) {\n throw new Error(\"Thrown value is not an Error.\");\n }\n if (predicate === undefined) {\n return;\n }\n if (typeof predicate === \"string\" && error.message !== predicate) {\n throw new Error(\n `Expected thrown message '${predicate}', received '${error.message}'.`,\n );\n }\n if (predicate instanceof RegExp && !predicate.test(error.message)) {\n throw new Error(\n `Expected thrown message '${error.message}' to match ${String(predicate)}.`,\n );\n }\n if (typeof predicate === \"function\" && !predicate(error)) {\n throw new Error(\"Thrown error did not satisfy predicate.\");\n }\n return;\n }\n throw new Error(\"Expected function to throw.\");\n}\n\nexport function createExpectApi(\n options: CreateExpectApiOptions = {},\n): ExpectFn {\n const buildMatchers = (actual: unknown): ExpectMatchers => ({\n toBe: (expected: unknown) => {\n if (actual !== expected) {\n throw new Error(\n `Expected '${String(actual)}' to be '${String(expected)}'.`,\n );\n }\n },\n toEqual: (expected: unknown) => {\n if (!isDeepStrictEqual(actual, expected)) {\n throw new Error(\"Expected values to be deeply equal.\");\n }\n },\n toMatchObject: (expected: Record<string, unknown>) => {\n const mismatch = matchPartial(actual, expected);\n if (mismatch) {\n throw new Error(mismatch);\n }\n },\n toBeDefined: () => {\n if (actual === undefined) {\n throw new Error(\"Expected value to be defined.\");\n }\n },\n toBeUndefined: () => {\n if (actual !== undefined) {\n throw new Error(\n `Expected value to be undefined, but received '${String(actual)}'.`,\n );\n }\n },\n toBeNull: () => {\n if (actual !== null) {\n throw new Error(\n `Expected value to be null, but received '${String(actual)}'.`,\n );\n }\n },\n toContain: (expected: unknown) => {\n if (Array.isArray(actual)) {\n if (!actual.includes(expected)) {\n throw new Error(\"Expected array to contain value.\");\n }\n return;\n }\n if (typeof actual === \"string\") {\n if (!actual.includes(String(expected))) {\n throw new Error(\"Expected string to contain value.\");\n }\n return;\n }\n throw new Error(\"toContain expects an array or string actual value.\");\n },\n toContainEqual: (expected: unknown) => {\n if (!Array.isArray(actual)) {\n throw new Error(\"toContainEqual expects an array actual value.\");\n }\n if (!actual.some((value) => isDeepStrictEqual(value, expected))) {\n throw new Error(\"Expected array to contain an equal value.\");\n }\n },\n toHaveLength: (expected: number) => {\n assertLength(actual, expected);\n },\n toBeGreaterThan: (expected: number) => {\n if (typeof actual !== \"number\") {\n throw new Error(\"toBeGreaterThan expects a number actual value.\");\n }\n if (actual <= expected) {\n throw new Error(`Expected ${actual} to be > ${expected}.`);\n }\n },\n toBeGreaterThanOrEqual: (expected: number) => {\n if (typeof actual !== \"number\") {\n throw new Error(\n \"toBeGreaterThanOrEqual expects a number actual value.\",\n );\n }\n if (actual < expected) {\n throw new Error(`Expected ${actual} to be >= ${expected}.`);\n }\n },\n toThrow: (predicate) => {\n assertThrown(actual, predicate);\n },\n toMatchSnapshot: (filename) => {\n if (!options.matchSnapshot) {\n throw new Error(\n \"Snapshot matching is not configured for this expect API.\",\n );\n }\n options.matchSnapshot(filename, actual);\n },\n toRejectWith: (expected) =>\n createSubmissionErrorMatcher(actual, expected, options),\n toHaveInteraction: (interactionId, opts) => {\n const descriptors = asDescriptorList(actual);\n const descriptor = findInteraction(descriptors, interactionId);\n if (!descriptor) {\n throw new Error(`Expected interaction '${interactionId}' to exist.`);\n }\n assertDescriptorMatches(descriptor, opts);\n },\n toBeGatedBy: (reason, opts) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!opts?.interactionId) {\n throw new Error(\n \"toBeGatedBy on a descriptor array requires opts.interactionId.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n opts.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\"Expected interaction descriptor to exist.\");\n }\n if (descriptor.availability?.status === \"available\") {\n throw new Error(\"Expected interaction to be unavailable.\");\n }\n const actualReason =\n descriptor.availability?.status === \"notYourTurn\" ||\n descriptor.availability?.status === \"insufficientResources\" ||\n descriptor.availability?.status === \"blocked\"\n ? descriptor.availability.reason\n : undefined;\n if (actualReason !== reason) {\n throw new Error(\n `Expected unavailable reason '${reason}', received '${\n actualReason ?? \"undefined\"\n }'.`,\n );\n }\n },\n toBeAvailable: (explanation) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!explanation?.interactionId) {\n throw new Error(\n \"toBeAvailable on a descriptor array requires an explanation.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n explanation.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\n `Expected interaction descriptor to exist.${formatInteractionExplanation(\n explanation,\n )}`,\n );\n }\n if (descriptor.availability?.status !== \"available\") {\n throw new Error(\n `Expected interaction '${descriptor.interactionId ?? \"unknown\"}' to be available.${formatInteractionExplanation(\n explanation,\n )}`,\n );\n }\n },\n toBeActiveFor: (playerId, opts) => {\n const descriptor = Array.isArray(actual)\n ? (() => {\n if (!opts?.interactionId) {\n throw new Error(\n \"toBeActiveFor on a descriptor array requires opts.interactionId.\",\n );\n }\n return findInteraction(\n asDescriptorList(actual),\n opts.interactionId,\n );\n })()\n : (actual as InteractionDescriptorLike | null);\n if (!descriptor) {\n throw new Error(\"Expected interaction descriptor to exist.\");\n }\n if (descriptor.context?.to !== playerId) {\n throw new Error(\n `Expected interaction to target '${playerId}', received '${\n descriptor.context?.to ?? \"undefined\"\n }'.`,\n );\n }\n if (descriptor.availability?.status !== \"available\") {\n throw new Error(\"Expected interaction to be available.\");\n }\n },\n not: {\n toHaveInteraction: (interactionId) => {\n const descriptors = asDescriptorList(actual);\n if (findInteraction(descriptors, interactionId)) {\n throw new Error(\n `Expected interaction '${interactionId}' to be absent.`,\n );\n }\n },\n },\n });\n\n return (actual: unknown) => buildMatchers(actual);\n}\n","import type {\n ReducerBundleContract,\n Wire,\n} from \"@dreamboard-games/reducer-contract\";\nimport type { InteractionDescriptor } from \"../runtime/reducer.js\";\nimport {\n computePluginActionSetVersion,\n type InteractionDescriptor as ContractInteractionDescriptor,\n type ZoneHandlesSnapshot as ContractZoneHandlesSnapshot,\n type PluginGameplayFrame,\n type PluginSessionDescriptor,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport type {\n RuntimeAPI,\n SubmissionError,\n ValidationResult,\n} from \"../runtime/types/runtime-api.js\";\nimport type { PluginSessionState as RuntimePluginSessionState } from \"../runtime/types/runtime-api.js\";\nimport type {\n DispatchTraceSummaryEntry,\n ReducerDiagnosticEvent,\n} from \"../reducer/diagnostics.js\";\nimport { StaleContractArtifactError } from \"../reducer/stale-contract-artifact-error.js\";\nimport type { InteractionExplanationLike } from \"./definitions.js\";\n\ntype ReducerBundleLike = Pick<\n ReducerBundleContract,\n \"projectSeatsDynamic\" | \"validateInput\" | \"dispatch\"\n> & {\n explainInteraction?: (input: {\n state: Wire.ReducerSessionState;\n playerId: string;\n interactionId: string;\n }) => InteractionExplanationLike;\n};\n\ntype DeepReadonly<T> = T extends (...args: readonly unknown[]) => unknown\n ? T\n : T extends readonly (infer Item)[]\n ? readonly DeepReadonly<Item>[]\n : T extends object\n ? { readonly [Key in keyof T]: DeepReadonly<T[Key]> }\n : T;\n\ntype DeepMutable<T> = T extends (...args: readonly unknown[]) => unknown\n ? T\n : T extends readonly (infer Item)[]\n ? DeepMutable<Item>[]\n : T extends object\n ? { -readonly [Key in keyof T]: DeepMutable<T[Key]> }\n : T;\n\ntype BaseStateArtifact = {\n snapshot: DeepReadonly<Wire.ReducerSessionState>;\n fingerprint: {\n players: number;\n contractFingerprint?: string;\n };\n};\n\ntype WireZoneHandles = {\n cardIds?: readonly string[];\n cardViewsById?: Readonly<Record<string, string>>;\n playableByCardId?: Readonly<Record<string, readonly string[]>>;\n};\n\nexport type CreateTestRuntimeOptions = {\n baseId: string;\n baseStates: Record<string, BaseStateArtifact>;\n bundle: ReducerBundleLike;\n phase?: string;\n playerIds?: readonly string[];\n sessionId?: string;\n userId?: string | null;\n gameId?: string;\n displayNameByPlayerId?: Record<string, string>;\n contractFingerprint?: string;\n expectedBaseStateFingerprint?: string;\n};\n\nexport type CreatedTestRuntime = {\n runtime: RuntimeAPI;\n getFrame(): PluginGameplayFrame;\n getSessionDescriptor(): PluginSessionDescriptor;\n players(): readonly string[];\n seat(index: number): string;\n submit(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n validate(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<ValidationResult>;\n explain(playerId: string, interactionId: string): InteractionExplanationLike;\n diagnostics: {\n readonly events: readonly ReducerDiagnosticEvent[];\n readonly lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null;\n clear(): void;\n };\n};\n\nfunction cloneState<T>(value: T): DeepMutable<T> {\n return structuredClone(value) as DeepMutable<T>;\n}\n\nfunction createSubmissionError(\n errorCode: string | undefined,\n message: string | undefined,\n): SubmissionError {\n const error = new Error(message ?? \"Interaction rejected\") as SubmissionError;\n error.name = \"SubmissionError\";\n error.errorCode = errorCode;\n return error;\n}\n\nfunction summarizeWireTrace(\n trace: readonly unknown[] | undefined,\n): DispatchTraceSummaryEntry[] {\n return (trace ?? []).flatMap((entry): DispatchTraceSummaryEntry[] => {\n if (typeof entry !== \"object\" || entry === null) return [];\n const record = entry as Record<string, unknown>;\n switch (record.kind) {\n case \"acceptedClientInput\": {\n const input =\n typeof record.input === \"object\" && record.input !== null\n ? (record.input as Record<string, unknown>)\n : {};\n return [\n {\n kind: \"acceptedClientInput\",\n interactionId: String(input.interactionId ?? \"\"),\n playerId: String(input.playerId ?? \"\"),\n },\n ];\n }\n case \"appliedEffect\": {\n const effect =\n typeof record.effect === \"object\" && record.effect !== null\n ? (record.effect as Record<string, unknown>)\n : {};\n return [\n {\n kind: \"appliedInstruction\",\n instruction: String(effect.kind ?? effect.type ?? \"effect\"),\n },\n ];\n }\n case \"rngConsumption\":\n return [\n {\n kind: \"rngConsumption\",\n operation: String(record.operation ?? \"\"),\n traceEntry: String(record.traceEntry ?? \"\"),\n },\n ];\n default:\n return [];\n }\n });\n}\n\nfunction readFlowState(state: Wire.ReducerSessionState): {\n currentPhase: string | null;\n activePlayers: string[];\n} {\n const flow = ((\n state.domain as\n | { flow?: { currentPhase?: string; activePlayers?: string[] } }\n | undefined\n )?.flow ?? {}) as {\n currentPhase?: string;\n activePlayers?: string[];\n };\n return {\n currentPhase: flow.currentPhase ?? null,\n activePlayers: Array.isArray(flow.activePlayers) ? flow.activePlayers : [],\n };\n}\n\nfunction resolvePlayerIds(options: {\n baseState: BaseStateArtifact;\n explicitPlayerIds?: readonly string[];\n}): string[] {\n if (options.explicitPlayerIds && options.explicitPlayerIds.length > 0) {\n return [...options.explicitPlayerIds];\n }\n return Array.from(\n { length: options.baseState.fingerprint.players },\n (_, index) => `player-${index + 1}`,\n );\n}\n\nfunction isWireZoneHandles(value: unknown): value is WireZoneHandles {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction buildPluginFrame(options: {\n state: Wire.ReducerSessionState;\n bundle: ReducerBundleLike;\n playerId: string;\n version: number;\n expectedPhase: string | undefined;\n baseId: string;\n}): PluginGameplayFrame {\n const projection = options.bundle.projectSeatsDynamic({\n state: options.state,\n playerIds: [options.playerId],\n });\n\n const flow = readFlowState(options.state);\n if (options.expectedPhase && flow.currentPhase !== options.expectedPhase) {\n throw new Error(\n `Expected base '${options.baseId}' to be in phase '${options.expectedPhase}', received '${\n flow.currentPhase ?? \"null\"\n }'.`,\n );\n }\n\n const interactionsByRef =\n (projection.interactionsByRef as\n | Record<string, InteractionDescriptor>\n | undefined) ?? {};\n const hydrateRefs = (\n refs: readonly string[] | undefined,\n ): ContractInteractionDescriptor[] =>\n (refs ?? [])\n .map((ref) => interactionsByRef[ref])\n .filter((descriptor): descriptor is InteractionDescriptor =>\n Boolean(descriptor),\n ) as ContractInteractionDescriptor[];\n\n const seat = projection.seats?.[options.playerId];\n const zones = Object.fromEntries(\n Object.entries(\n (seat?.zones as Record<string, unknown> | undefined) ?? {},\n ).map(([zoneId, zoneValue]) => {\n const zone = isWireZoneHandles(zoneValue) ? zoneValue : {};\n return [\n zoneId,\n {\n cardIds: [...(zone.cardIds ?? [])],\n cardViewsById: { ...(zone.cardViewsById ?? {}) },\n playableByCardId: Object.fromEntries(\n Object.entries(zone.playableByCardId ?? {}).map(\n ([cardId, refs]) => [cardId, hydrateRefs(refs)],\n ),\n ),\n } satisfies ContractZoneHandlesSnapshot,\n ];\n }),\n ) as PluginGameplayFrame[\"zones\"];\n\n const availableInteractions = hydrateRefs(\n seat?.availableInteractionRefs as readonly string[] | undefined,\n );\n return {\n gameVersion: options.version,\n actionSetVersion: computePluginActionSetVersion({\n gameVersion: options.version,\n availableInteractions,\n }),\n perspectivePlayerId: options.playerId || null,\n view: seat?.view ?? null,\n flow: {\n currentPhase: flow.currentPhase,\n currentStage: projection.currentStage ?? null,\n activePlayers: flow.activePlayers,\n simultaneousPhase: projection.simultaneousPhase ?? null,\n },\n availableInteractions,\n zones,\n };\n}\n\nexport function createTestRuntime(\n options: CreateTestRuntimeOptions,\n): CreatedTestRuntime {\n const baseState = options.baseStates[options.baseId];\n if (!baseState) {\n throw new Error(`Unknown test base '${options.baseId}'.`);\n }\n const expectedBaseStateFingerprint =\n options.expectedBaseStateFingerprint ??\n baseState.fingerprint.contractFingerprint;\n if (\n options.contractFingerprint &&\n expectedBaseStateFingerprint &&\n options.contractFingerprint !== expectedBaseStateFingerprint\n ) {\n throw new StaleContractArtifactError({\n artifact: \"base-states\",\n expected: options.contractFingerprint,\n found: expectedBaseStateFingerprint,\n });\n }\n\n let currentState = cloneState(baseState.snapshot);\n const playerIds = resolvePlayerIds({\n baseState,\n explicitPlayerIds: options.playerIds,\n });\n const sessionId = options.sessionId ?? \"test-session\";\n const sessionDescriptor: PluginSessionDescriptor = {\n sessionId,\n players: playerIds.map((playerId) => ({\n playerId,\n displayName: options.displayNameByPlayerId?.[playerId] ?? playerId,\n })),\n };\n\n let version = 0;\n let submissionCounter = 0;\n let currentPlayerId = playerIds[0] ?? \"\";\n const diagnosticEvents: ReducerDiagnosticEvent[] = [];\n let lastDispatch: {\n submissionId: string;\n trace: readonly DispatchTraceSummaryEntry[];\n } | null = null;\n const toReadySessionState = (\n frame: PluginGameplayFrame,\n ): RuntimePluginSessionState => ({\n status: \"ready\",\n sessionId,\n controllingPlayerId: frame.perspectivePlayerId,\n });\n\n let lastPluginFrame: PluginGameplayFrame;\n let lastSessionState: RuntimePluginSessionState;\n\n const applyCurrentState = (): void => {\n version += 1;\n lastPluginFrame = buildPluginFrame({\n state: currentState,\n bundle: options.bundle,\n playerId: currentPlayerId,\n version,\n expectedPhase: version === 1 ? options.phase : undefined,\n baseId: options.baseId,\n });\n lastSessionState = toReadySessionState(lastPluginFrame);\n };\n\n applyCurrentState();\n\n const validate = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<ValidationResult> => {\n const result = await options.bundle.validateInput({\n state: currentState,\n input: {\n kind: \"interaction\",\n playerId,\n interactionId,\n params: params as Wire.JsonValue,\n },\n });\n return {\n valid: result.valid,\n errorCode: result.errorCode,\n message: result.message,\n };\n };\n\n const submit = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<void> => {\n submissionCounter += 1;\n const submissionId = `sub-${submissionCounter}`;\n diagnosticEvents.push({\n type: \"submitReceived\",\n submissionId,\n playerId,\n interactionId,\n phase: readFlowState(currentState).currentPhase ?? \"\",\n });\n const validation = await validate(playerId, interactionId, params);\n if (!validation.valid) {\n diagnosticEvents.push({\n type: \"submitRejected\",\n submissionId,\n errorCode: validation.errorCode ?? \"invalid-action\",\n ...(validation.message ? { message: validation.message } : {}),\n });\n throw createSubmissionError(validation.errorCode, validation.message);\n }\n const result = await options.bundle.dispatch({\n state: currentState,\n input: {\n kind: \"interaction\",\n playerId,\n interactionId,\n params: params as Wire.JsonValue,\n },\n });\n if (result.kind === \"reject\") {\n diagnosticEvents.push({\n type: \"submitRejected\",\n submissionId,\n errorCode: result.errorCode,\n ...(result.message ? { message: result.message } : {}),\n });\n throw createSubmissionError(result.errorCode, result.message);\n }\n const trace = summarizeWireTrace(result.trace);\n lastDispatch = { submissionId, trace };\n diagnosticEvents.push({\n type: \"submitAccepted\",\n submissionId,\n trace,\n });\n currentState = cloneState(result.state);\n applyCurrentState();\n };\n\n const explain = (\n playerId: string,\n interactionId: string,\n ): InteractionExplanationLike => {\n if (!options.bundle.explainInteraction) {\n throw new Error(\n \"This reducer bundle does not expose explainInteraction().\",\n );\n }\n return options.bundle.explainInteraction({\n state: currentState,\n playerId,\n interactionId,\n });\n };\n\n const runtime = {\n validateInteraction: (interactionId: string, params?: unknown) =>\n validate(currentPlayerId, interactionId, params),\n submitInteraction: (interactionId: string, params?: unknown) =>\n submit(currentPlayerId, interactionId, params),\n getSessionState: (): RuntimePluginSessionState => lastSessionState,\n disconnect: () => undefined,\n };\n\n return {\n runtime,\n getFrame: () => lastPluginFrame,\n getSessionDescriptor: () => sessionDescriptor,\n players: () => [...playerIds],\n seat: (index: number) => {\n if (!Number.isInteger(index) || index < 0 || index >= playerIds.length) {\n throw new Error(\n `seat(${index}) is out of range; base '${options.baseId}' has ${playerIds.length} player(s).`,\n );\n }\n return playerIds[index]!;\n },\n submit,\n validate,\n explain,\n diagnostics: {\n get events() {\n return diagnosticEvents;\n },\n get lastDispatch() {\n return lastDispatch;\n },\n clear() {\n diagnosticEvents.length = 0;\n lastDispatch = null;\n },\n },\n };\n}\n","import { createHash } from \"node:crypto\";\nimport type {\n PluginProtocolTape,\n UIReplayRequest,\n UIScenarioFixture,\n} from \"./schema.js\";\n\ntype CanonicalJson =\n | null\n | boolean\n | number\n | string\n | readonly CanonicalJson[]\n | { readonly [key: string]: CanonicalJson };\n\nconst sha256DigestPattern = /^sha256:[a-f0-9]{64}$/;\n\nexport function isSha256Digest(value: string): boolean {\n return sha256DigestPattern.test(value);\n}\n\nexport function canonicalizeUIFixtureJson(value: unknown): CanonicalJson {\n if (value === null) {\n return null;\n }\n switch (typeof value) {\n case \"boolean\":\n case \"string\":\n return value;\n case \"number\":\n if (Number.isFinite(value)) {\n return value;\n }\n break;\n case \"object\": {\n if (Array.isArray(value)) {\n return value.map((item) => canonicalizeUIFixtureJson(item));\n }\n if (Object.getPrototypeOf(value) !== Object.prototype) {\n break;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n return Object.fromEntries(\n entries\n .filter(([, item]) => item !== undefined)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, item]) => [key, canonicalizeUIFixtureJson(item)]),\n );\n }\n }\n throw new Error(\n `UI fixture values must be deterministic JSON. Received ${typeof value}.`,\n );\n}\n\nexport function canonicalUIFixtureJson(value: unknown): string {\n return JSON.stringify(canonicalizeUIFixtureJson(value));\n}\n\nexport function digestUIFixtureJson(value: unknown): string {\n return sha256(canonicalUIFixtureJson(value));\n}\n\nexport function digestUIFixtureRequest(request: UIReplayRequest): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-replay-request@2\",\n request,\n });\n}\n\nexport function digestUIFixtureTransportRequest(request: {\n readonly operation: \"validate\" | \"submit\";\n readonly basis?: {\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n };\n readonly interactionId?: string;\n readonly payload?: unknown;\n}): string {\n return digestUIFixtureJson({\n digestVersion: \"ui-fixture-runtime-command@2\",\n request,\n });\n}\n\nexport function digestPluginProtocolTape(tape: PluginProtocolTape): string {\n return digestUIFixtureJson({\n digestVersion: \"plugin-protocol-tape@2\",\n tape,\n });\n}\n\nexport function canonicalizeUIScenarioFixture(\n fixture: UIScenarioFixture,\n): UIScenarioFixture {\n return canonicalizeUIFixtureJson({\n ...fixture,\n tags: [...fixture.tags].sort(),\n environment: {\n ...fixture.environment,\n viewportTags: [...fixture.environment.viewportTags].sort(),\n },\n }) as unknown as UIScenarioFixture;\n}\n\nexport function serializeUIScenarioFixture(fixture: UIScenarioFixture): string {\n return `${JSON.stringify(canonicalizeUIScenarioFixture(fixture), null, 2)}\\n`;\n}\n\nexport function digestUIScenarioFixture(fixture: UIScenarioFixture): string {\n return sha256(serializeUIScenarioFixture(fixture));\n}\n\nfunction sha256(value: string): string {\n return `sha256:${createHash(\"sha256\").update(value).digest(\"hex\")}`;\n}\n","import {\n computePluginActionSetVersion,\n materializePluginGameplayFrame,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureJson } from \"../ui-fixture/canonical.js\";\nimport type {\n CreateReducerScenarioRunnerOptions,\n ReducerScenarioFrame,\n ReducerScenarioExchange,\n ReducerScenarioOperation,\n ReducerScenarioRunner,\n ReducerScenarioTrace,\n} from \"./types.js\";\n\nexport function createReducerScenarioRunner(\n options: CreateReducerScenarioRunnerOptions,\n): ReducerScenarioRunner {\n return {\n async run(\n operations: readonly ReducerScenarioOperation[],\n ): Promise<ReducerScenarioTrace> {\n let state = structuredClone(options.initialState);\n let gameVersion = options.initialGameVersion ?? 1;\n const frames: ReducerScenarioFrame[] = [];\n const exchanges: ReducerScenarioExchange[] = [];\n\n const appendFrame = (id: string): ReducerScenarioFrame => {\n const dynamicProjection = options.bundle.projectSeatsDynamic({\n state,\n playerIds: [options.viewer.playerId],\n });\n const staticProjection = options.bundle.projectStatic?.() ?? null;\n const flow = readFlowState(state);\n const materialized = materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection,\n staticProjection,\n perspectivePlayerId: options.viewer.playerId,\n gameVersion,\n actionSetVersion: \"pending\",\n });\n const actionSetVersion = computePluginActionSetVersion({\n gameVersion,\n availableInteractions: materialized.availableInteractions,\n });\n const frame = {\n id,\n reducerState: structuredClone(state),\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n projectionDigest: digestUIFixtureJson({\n digestVersion: \"reducer-scenario-frame@2\",\n scenarioId: options.scenarioId,\n frameId: id,\n dynamicProjection,\n staticProjection,\n gameVersion,\n actionSetVersion,\n }),\n } satisfies ReducerScenarioFrame;\n frames.push(frame);\n return frame;\n };\n\n appendFrame(\"frame-1\");\n\n for (const operation of operations) {\n const fromFrame = frames[frames.length - 1];\n if (!fromFrame) {\n throw new Error(\"Reducer scenario runner lost its initial frame.\");\n }\n if (operation.operation === \"validate\") {\n const result = await options.bundle.validateInput({\n state,\n input: operation.input,\n });\n exchanges.push({\n id: operation.id,\n operation: \"validate\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result,\n });\n continue;\n }\n\n const result = await options.bundle.dispatch({\n state,\n input: operation.input,\n });\n if (result.kind === \"reject\") {\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"rejected\",\n diagnostics: [\n {\n code: result.errorCode,\n message: result.message ?? result.errorCode,\n },\n ],\n },\n });\n continue;\n }\n\n state = structuredClone(result.state);\n gameVersion += 1;\n const toFrame = appendFrame(`frame-${frames.length + 1}`);\n exchanges.push({\n id: operation.id,\n operation: \"submit\",\n fromFrameId: fromFrame.id,\n input: operation.input,\n result: {\n kind: \"accepted\",\n toFrameId: toFrame.id,\n },\n });\n }\n\n return {\n scenarioId: options.scenarioId,\n gameId: options.gameId,\n viewer: options.viewer,\n frames,\n exchanges,\n };\n },\n };\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","import {\n canonicalUIFixtureJson,\n digestUIFixtureJson,\n digestUIScenarioFixture,\n} from \"./canonical.js\";\nimport type { UIScenarioFixture } from \"./schema.js\";\n\nexport interface UIParityViewport {\n readonly width: number;\n readonly height: number;\n}\n\nexport interface UIParityObservationEnvironmentV1 {\n readonly project: string;\n readonly viewport: UIParityViewport;\n}\n\nexport interface UIParityDiagnosticV1 {\n readonly code: string;\n readonly message: string;\n}\n\nexport interface UIParityObservationCheckpointV1 {\n readonly stepId: string;\n readonly interactionKey?: string;\n readonly interactionId?: string;\n readonly actuatorId?: string;\n readonly descriptorDigest?: string;\n readonly draftDigest?: string;\n readonly gameVersion: number;\n readonly actionSetVersion: string;\n readonly perspectivePlayerId: string | null;\n readonly projectionDigest: string;\n readonly semanticDigest: string;\n readonly submissionDigest?: string;\n readonly screenshot?: string;\n}\n\nexport interface UIParityObservationV1 {\n readonly schemaVersion: 1;\n readonly scenarioId: string;\n readonly fixtureDigest: string;\n readonly sdkCandidateDigest: string;\n readonly pluginRuntimeProtocol: 3;\n readonly browserInteractionProtocol: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly checkpoints: readonly UIParityObservationCheckpointV1[];\n readonly diagnostics: readonly UIParityDiagnosticV1[];\n}\n\nexport type UIParityFailureCode =\n | \"candidate-mismatch\"\n | \"fixture-source-mismatch\"\n | \"protocol-mismatch\"\n | \"interaction-resolution-mismatch\"\n | \"preparation-mismatch\"\n | \"draft-mismatch\"\n | \"submission-mismatch\"\n | \"projection-mismatch\"\n | \"semantic-snapshot-mismatch\"\n | \"visual-mismatch\"\n | \"host-setup-failure\";\n\nexport interface UIParityComparisonFailure {\n readonly code: UIParityFailureCode;\n readonly message: string;\n readonly path: string;\n readonly expected: unknown;\n readonly actual: unknown;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n}\n\nexport type UIParityComparisonResult =\n | { readonly ok: true }\n | {\n readonly ok: false;\n readonly failure: UIParityComparisonFailure;\n };\n\ntype UIParityComparisonFailureInput = Omit<\n UIParityComparisonFailure,\n \"message\"\n>;\n\nexport interface CreateUIParityObservationFromFixtureOptions {\n readonly fixture: UIScenarioFixture;\n readonly sdkCandidateDigest: string;\n readonly environment: UIParityObservationEnvironmentV1;\n readonly fixtureDigest?: string;\n readonly screenshotsByStepId?: Readonly<Record<string, string>>;\n readonly diagnostics?: readonly UIParityDiagnosticV1[];\n}\n\ntype ComparablePath = {\n readonly path: string;\n readonly code: UIParityFailureCode;\n};\n\nconst topLevelComparisons: readonly ComparablePath[] = [\n { path: \"scenarioId\", code: \"fixture-source-mismatch\" },\n { path: \"fixtureDigest\", code: \"candidate-mismatch\" },\n { path: \"sdkCandidateDigest\", code: \"candidate-mismatch\" },\n { path: \"pluginRuntimeProtocol\", code: \"protocol-mismatch\" },\n { path: \"browserInteractionProtocol\", code: \"protocol-mismatch\" },\n { path: \"environment.project\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.width\", code: \"host-setup-failure\" },\n { path: \"environment.viewport.height\", code: \"host-setup-failure\" },\n];\n\nconst checkpointComparisons: readonly ComparablePath[] = [\n { path: \"stepId\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionKey\", code: \"interaction-resolution-mismatch\" },\n { path: \"interactionId\", code: \"interaction-resolution-mismatch\" },\n { path: \"actuatorId\", code: \"interaction-resolution-mismatch\" },\n { path: \"descriptorDigest\", code: \"interaction-resolution-mismatch\" },\n { path: \"gameVersion\", code: \"projection-mismatch\" },\n { path: \"actionSetVersion\", code: \"projection-mismatch\" },\n { path: \"perspectivePlayerId\", code: \"projection-mismatch\" },\n { path: \"projectionDigest\", code: \"projection-mismatch\" },\n { path: \"semanticDigest\", code: \"semantic-snapshot-mismatch\" },\n { path: \"draftDigest\", code: \"draft-mismatch\" },\n { path: \"submissionDigest\", code: \"submission-mismatch\" },\n { path: \"screenshot\", code: \"visual-mismatch\" },\n];\n\nexport function createUIParityObservationFromFixture({\n fixture,\n sdkCandidateDigest,\n environment,\n fixtureDigest = digestUIScenarioFixture(fixture),\n screenshotsByStepId = {},\n diagnostics = [],\n}: CreateUIParityObservationFromFixtureOptions): UIParityObservationV1 {\n const frameById = new Map(\n fixture.protocol.frames.map((frame) => [frame.id, frame]),\n );\n const firstFrame = fixture.protocol.frames[0];\n if (!firstFrame) {\n throw new Error(\n `Fixture '${fixture.id}' does not contain protocol frames.`,\n );\n }\n\n const checkpoints = fixture.replay.map((step, index) => {\n const expectedFrameId = step.expect.frameId ?? firstFrame.id;\n const frame = frameById.get(expectedFrameId);\n if (!frame) {\n throw new Error(\n `Fixture '${fixture.id}' replay step '${step.stepId}' references missing frame '${expectedFrameId}'.`,\n );\n }\n const identity = \"expectedIdentity\" in step ? step.expectedIdentity : null;\n const projectionDigest =\n step.expect.projectionDigest ?? frame.projectionDigest;\n const isFinal = index === fixture.replay.length - 1;\n const semanticDigest =\n step.expect.semanticDigest ??\n (isFinal\n ? fixture.expected.finalSemanticDigest\n : digestUIFixtureJson({\n scenarioId: fixture.id,\n stepId: step.stepId,\n frameId: frame.id,\n projectionDigest,\n }));\n const submissionDigest =\n step.expect.submissionDigest ??\n (isFinal ? fixture.expected.submissionDigest : undefined);\n\n return {\n stepId: step.stepId,\n interactionKey: identity?.interactionKey,\n interactionId: identity?.interactionId,\n actuatorId: identity?.actuatorId,\n descriptorDigest: identity?.descriptorDigest,\n draftDigest: step.expect.draftDigest ?? identity?.draftDigest,\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n projectionDigest,\n semanticDigest,\n submissionDigest,\n screenshot: screenshotsByStepId[step.stepId],\n } satisfies UIParityObservationCheckpointV1;\n });\n\n return {\n schemaVersion: 1,\n scenarioId: fixture.id,\n fixtureDigest,\n sdkCandidateDigest,\n pluginRuntimeProtocol: fixture.pluginRuntimeProtocol,\n browserInteractionProtocol: fixture.browserInteractionProtocol,\n environment,\n checkpoints,\n diagnostics,\n };\n}\n\nexport function parseUIParityObservationV1(\n value: unknown,\n): UIParityObservationV1 {\n const observation = assertRecord(value, \"observation\");\n if (observation.schemaVersion !== 1) {\n throw new Error(\"UI parity observation schemaVersion must be 1.\");\n }\n assertString(observation.scenarioId, \"scenarioId\");\n assertString(observation.fixtureDigest, \"fixtureDigest\");\n assertString(observation.sdkCandidateDigest, \"sdkCandidateDigest\");\n if (observation.pluginRuntimeProtocol !== 3) {\n throw new Error(\"UI parity observation pluginRuntimeProtocol must be 3.\");\n }\n assertString(\n observation.browserInteractionProtocol,\n \"browserInteractionProtocol\",\n );\n const environment = assertRecord(observation.environment, \"environment\");\n assertString(environment.project, \"environment.project\");\n const viewport = assertRecord(environment.viewport, \"environment.viewport\");\n assertNumber(viewport.width, \"environment.viewport.width\");\n assertNumber(viewport.height, \"environment.viewport.height\");\n const checkpoints = assertArray(observation.checkpoints, \"checkpoints\");\n for (let index = 0; index < checkpoints.length; index += 1) {\n const checkpoint = assertRecord(\n checkpoints[index],\n `checkpoints[${index}]`,\n );\n assertString(checkpoint.stepId, `checkpoints[${index}].stepId`);\n assertOptionalString(\n checkpoint.interactionKey,\n `checkpoints[${index}].interactionKey`,\n );\n assertOptionalString(\n checkpoint.interactionId,\n `checkpoints[${index}].interactionId`,\n );\n assertOptionalString(\n checkpoint.actuatorId,\n `checkpoints[${index}].actuatorId`,\n );\n assertOptionalString(\n checkpoint.descriptorDigest,\n `checkpoints[${index}].descriptorDigest`,\n );\n assertOptionalString(\n checkpoint.draftDigest,\n `checkpoints[${index}].draftDigest`,\n );\n assertNumber(checkpoint.gameVersion, `checkpoints[${index}].gameVersion`);\n assertString(\n checkpoint.actionSetVersion,\n `checkpoints[${index}].actionSetVersion`,\n );\n if (\n checkpoint.perspectivePlayerId !== null &&\n typeof checkpoint.perspectivePlayerId !== \"string\"\n ) {\n throw new Error(\n `checkpoints[${index}].perspectivePlayerId must be a string or null.`,\n );\n }\n assertString(\n checkpoint.projectionDigest,\n `checkpoints[${index}].projectionDigest`,\n );\n assertString(\n checkpoint.semanticDigest,\n `checkpoints[${index}].semanticDigest`,\n );\n assertOptionalString(\n checkpoint.submissionDigest,\n `checkpoints[${index}].submissionDigest`,\n );\n assertOptionalString(\n checkpoint.screenshot,\n `checkpoints[${index}].screenshot`,\n );\n }\n const diagnostics = assertArray(observation.diagnostics, \"diagnostics\");\n for (let index = 0; index < diagnostics.length; index += 1) {\n const diagnostic = assertRecord(\n diagnostics[index],\n `diagnostics[${index}]`,\n );\n assertString(diagnostic.code, `diagnostics[${index}].code`);\n assertString(diagnostic.message, `diagnostics[${index}].message`);\n }\n return observation as unknown as UIParityObservationV1;\n}\n\nexport function compareUIParityObservations(\n expected: UIParityObservationV1,\n actual: UIParityObservationV1,\n): UIParityComparisonResult {\n for (const comparison of topLevelComparisons) {\n const result = comparePath(expected, actual, comparison);\n if (result) {\n return result;\n }\n }\n\n if (expected.checkpoints.length !== actual.checkpoints.length) {\n return mismatch({\n code: \"interaction-resolution-mismatch\",\n path: \"checkpoints.length\",\n expected: expected.checkpoints.length,\n actual: actual.checkpoints.length,\n });\n }\n\n for (let index = 0; index < expected.checkpoints.length; index += 1) {\n const expectedCheckpoint = expected.checkpoints[index]!;\n const actualCheckpoint = actual.checkpoints[index]!;\n for (const comparison of checkpointComparisons) {\n const result = comparePath(\n expectedCheckpoint,\n actualCheckpoint,\n comparison,\n {\n prefix: `checkpoints[${index}]`,\n checkpointIndex: index,\n stepId: expectedCheckpoint.stepId,\n },\n );\n if (result) {\n return result;\n }\n }\n }\n\n if (!sameValue(expected.diagnostics, actual.diagnostics)) {\n return mismatch({\n code: \"host-setup-failure\",\n path: \"diagnostics\",\n expected: expected.diagnostics,\n actual: actual.diagnostics,\n });\n }\n\n return { ok: true };\n}\n\nfunction comparePath(\n expected: unknown,\n actual: unknown,\n comparison: ComparablePath,\n options: {\n readonly prefix?: string;\n readonly checkpointIndex?: number;\n readonly stepId?: string;\n } = {},\n): UIParityComparisonResult | null {\n const expectedValue = getPath(expected, comparison.path);\n const actualValue = getPath(actual, comparison.path);\n if (sameValue(expectedValue, actualValue)) {\n return null;\n }\n const path = options.prefix\n ? `${options.prefix}.${comparison.path}`\n : comparison.path;\n return mismatch({\n code: comparison.code,\n path,\n expected: expectedValue,\n actual: actualValue,\n checkpointIndex: options.checkpointIndex,\n stepId: options.stepId,\n });\n}\n\nfunction mismatch(\n input: UIParityComparisonFailureInput,\n): UIParityComparisonResult {\n return {\n ok: false,\n failure: {\n ...input,\n message: `${input.code} at ${input.path}`,\n },\n };\n}\n\nfunction sameValue(left: unknown, right: unknown): boolean {\n if (left === undefined || right === undefined) {\n return left === right;\n }\n return canonicalUIFixtureJson(left) === canonicalUIFixtureJson(right);\n}\n\nfunction getPath(value: unknown, path: string): unknown {\n return path.split(\".\").reduce<unknown>((current, key) => {\n if (current === null || typeof current !== \"object\") {\n return undefined;\n }\n return (current as Record<string, unknown>)[key];\n }, value);\n}\n\nfunction assertRecord(value: unknown, path: string): Record<string, unknown> {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw new Error(`${path} must be an object.`);\n }\n return value as Record<string, unknown>;\n}\n\nfunction assertArray(value: unknown, path: string): readonly unknown[] {\n if (!Array.isArray(value)) {\n throw new Error(`${path} must be an array.`);\n }\n return value;\n}\n\nfunction assertString(value: unknown, path: string): void {\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(`${path} must be a non-empty string.`);\n }\n}\n\nfunction assertOptionalString(value: unknown, path: string): void {\n if (\n value !== undefined &&\n (typeof value !== \"string\" || value.length === 0)\n ) {\n throw new Error(`${path} must be a non-empty string when present.`);\n }\n}\n\nfunction assertNumber(value: unknown, path: string): void {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n throw new Error(`${path} must be a finite number.`);\n }\n}\n","import {\n DREAMBOARD_PLUGIN_PROTOCOL,\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n type HostToPluginEnvelope,\n type PluginProtocolTape,\n type PluginToHostPayload,\n type SubmitInteractionCommand,\n type ValidateInteractionCommand,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport type { PluginTransport } from \"../../runtime/core/types.js\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\n\nexport interface FixtureHostEvent {\n readonly sequence: number;\n readonly atMs: number;\n readonly kind:\n | \"frame-sent\"\n | \"validate-received\"\n | \"submit-received\"\n | \"ack-received\"\n | \"ready-received\"\n | \"diagnostic\";\n readonly requestDigest?: string;\n readonly frameId?: string;\n readonly projectionDigest?: string;\n readonly result?: \"accepted\" | \"rejected\";\n}\n\nexport interface FixtureHostHarness {\n readonly transport: PluginTransport;\n readonly tape: PluginProtocolTape;\n reset(): void;\n flush(): Promise<void>;\n advanceHost(): Promise<void>;\n getCurrentFrameId(): string;\n getEvents(): readonly FixtureHostEvent[];\n assertConsumed(): void;\n}\n\nexport interface CreateFixtureHostHarnessOptions {\n readonly tape: PluginProtocolTape;\n readonly strict?: boolean;\n readonly latencyMs?: number;\n readonly channelId?: string;\n readonly onEvent?: (event: FixtureHostEvent) => void;\n readonly nowMs?: () => number;\n}\n\nconst DEFAULT_CHANNEL_ID = \"fixture-channel\";\n\nexport function createFixtureHostHarness(\n options: CreateFixtureHostHarnessOptions,\n): FixtureHostHarness {\n const strict = options.strict ?? true;\n const latencyMs = options.latencyMs ?? 0;\n const channelId = options.channelId ?? DEFAULT_CHANNEL_ID;\n const events: FixtureHostEvent[] = [];\n const frameById = new Map(\n options.tape.frames.map((frame) => [frame.id, frame]),\n );\n let eventSequence = 0;\n let envelopeSequence = 0;\n let stepCursor = 0;\n let currentFrameId: string | null = null;\n let onMessage: ((message: HostToPluginEnvelope) => void) | null = null;\n let firstFixtureError: Error | null = null;\n const pendingHandlers = new Set<Promise<void>>();\n\n const record = (event: Omit<FixtureHostEvent, \"sequence\" | \"atMs\">) => {\n const entry = {\n sequence: ++eventSequence,\n atMs: options.nowMs?.() ?? eventSequence,\n ...event,\n };\n events.push(entry);\n options.onEvent?.(entry);\n };\n\n const createFixtureError = (code: string, message: string): Error => {\n record({ kind: \"diagnostic\" });\n const error = new Error(message);\n error.name = \"FixtureHostHarnessError\";\n Object.assign(error, { errorCode: code });\n return error;\n };\n\n const rememberFixtureError = (error: unknown) => {\n if (firstFixtureError) {\n return;\n }\n firstFixtureError =\n error instanceof Error\n ? error\n : createFixtureError(\n \"fixture-unknown-error\",\n \"Fixture host failed with an unknown error.\",\n );\n };\n\n const throwFixtureError = () => {\n if (firstFixtureError) {\n throw firstFixtureError;\n }\n };\n\n const sendHostPayload = (payload: HostToPluginEnvelope[\"payload\"]) => {\n if (!onMessage) {\n return;\n }\n onMessage({\n protocol: DREAMBOARD_PLUGIN_PROTOCOL,\n version: DREAMBOARD_PLUGIN_PROTOCOL_VERSION,\n channelId,\n sequence: ++envelopeSequence,\n payload,\n });\n };\n\n const sendInit = () => {\n sendHostPayload({\n type: \"runtime.init\",\n session: options.tape.session,\n });\n };\n\n const publishFrame = (frameId: string) => {\n const frame = frameById.get(frameId);\n if (!frame) {\n throw createFixtureError(\n \"fixture-missing-frame\",\n `Plugin protocol tape references missing frame '${frameId}'.`,\n );\n }\n currentFrameId = frame.id;\n record({\n kind: \"frame-sent\",\n frameId: frame.id,\n projectionDigest: frame.projectionDigest,\n });\n sendHostPayload({\n type: \"gameplay.frame\",\n frame: frame.frame,\n });\n };\n\n const drainHostFrames = () => {\n while (options.tape.steps[stepCursor]?.kind === \"host.frame\") {\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n }\n };\n\n const drainOneHostFrame = () => {\n if (options.tape.steps[stepCursor]?.kind !== \"host.frame\") {\n return;\n }\n const step = options.tape.steps[stepCursor] as Extract<\n PluginProtocolTape[\"steps\"][number],\n { kind: \"host.frame\" }\n >;\n stepCursor += 1;\n publishFrame(step.frameId);\n };\n\n const waitForConfiguredLatency = async () => {\n if (latencyMs <= 0) {\n await Promise.resolve();\n return;\n }\n await new Promise<void>((resolve) => setTimeout(resolve, latencyMs));\n };\n\n const consumeExpectedStep = <\n Kind extends \"client.validate\" | \"client.submit\",\n >(\n kind: Kind,\n requestDigest: string,\n ): Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }> => {\n const step = options.tape.steps[stepCursor];\n if (!step) {\n throw createFixtureError(\n \"fixture-protocol-exhausted\",\n `Plugin protocol tape has no remaining step for ${kind}.`,\n );\n }\n if (step.kind !== kind) {\n throw createFixtureError(\n \"fixture-protocol-step-mismatch\",\n `Expected protocol step '${step.kind}' but received '${kind}'.`,\n );\n }\n if (step.fromFrameId !== currentFrameId) {\n throw createFixtureError(\n \"fixture-protocol-frame-mismatch\",\n `Expected protocol from frame '${step.fromFrameId}' but current frame is '${currentFrameId ?? \"<none>\"}'.`,\n );\n }\n if (step.requestDigest !== requestDigest) {\n const mode = strict ? \"strict\" : \"compatible\";\n throw createFixtureError(\n \"fixture-protocol-digest-mismatch\",\n `${mode} fixture protocol digest mismatch for ${kind}: expected ${step.requestDigest}, received ${requestDigest}.`,\n );\n }\n stepCursor += 1;\n return step as Extract<PluginProtocolTape[\"steps\"][number], { kind: Kind }>;\n };\n\n const handleValidate = async (command: ValidateInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"validate\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.validate\", requestDigest);\n record({\n kind: \"validate-received\",\n requestDigest,\n result: step.response.valid ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.validation-result\",\n requestId: command.requestId,\n result: step.response,\n });\n };\n\n const handleSubmit = async (command: SubmitInteractionCommand) => {\n const requestDigest = digestUIFixtureTransportRequest({\n operation: \"submit\",\n basis: command.basis,\n interactionId: command.interactionId,\n payload: command.params,\n });\n const step = consumeExpectedStep(\"client.submit\", requestDigest);\n record({\n kind: \"submit-received\",\n requestDigest,\n result: step.response.accepted ? \"accepted\" : \"rejected\",\n });\n await waitForConfiguredLatency();\n sendHostPayload({\n type: \"interaction.submit-result\",\n requestId: command.requestId,\n result: step.response,\n });\n if (step.response.accepted) {\n await waitForConfiguredLatency();\n drainHostFrames();\n }\n };\n\n const handleClientPayload = (payload: PluginToHostPayload) => {\n const trackHandler = (promise: Promise<void>) => {\n pendingHandlers.add(promise);\n promise\n .catch((error) => {\n rememberFixtureError(error);\n })\n .finally(() => {\n pendingHandlers.delete(promise);\n });\n };\n\n switch (payload.type) {\n case \"runtime.ready\":\n record({ kind: \"ready-received\" });\n break;\n case \"runtime.ack\":\n record({ kind: \"ack-received\" });\n break;\n case \"interaction.validate\":\n trackHandler(handleValidate(payload));\n break;\n case \"interaction.submit\":\n trackHandler(handleSubmit(payload));\n break;\n case \"runtime.error\":\n record({ kind: \"diagnostic\" });\n break;\n default: {\n const _exhaustive: never = payload;\n return _exhaustive;\n }\n }\n };\n\n const transport: PluginTransport = {\n start(nextOnMessage) {\n onMessage = nextOnMessage;\n queueMicrotask(() => {\n sendInit();\n drainOneHostFrame();\n });\n return () => {\n onMessage = null;\n };\n },\n send(message) {\n handleClientPayload(message);\n },\n };\n\n return {\n transport,\n tape: options.tape,\n reset() {\n eventSequence = 0;\n envelopeSequence = 0;\n stepCursor = 0;\n currentFrameId = null;\n firstFixtureError = null;\n pendingHandlers.clear();\n events.length = 0;\n if (onMessage) {\n sendInit();\n drainOneHostFrame();\n }\n },\n async flush() {\n await waitForConfiguredLatency();\n await Promise.resolve();\n while (pendingHandlers.size > 0) {\n await Promise.allSettled([...pendingHandlers]);\n }\n throwFixtureError();\n },\n async advanceHost() {\n await waitForConfiguredLatency();\n drainHostFrames();\n throwFixtureError();\n },\n getCurrentFrameId() {\n if (!currentFrameId) {\n throw createFixtureError(\n \"fixture-frame-not-started\",\n \"Fixture host has not emitted a gameplay frame.\",\n );\n }\n return currentFrameId;\n },\n getEvents() {\n return events.map((event) => ({ ...event }));\n },\n assertConsumed() {\n throwFixtureError();\n if (stepCursor !== options.tape.steps.length) {\n throw createFixtureError(\n \"fixture-unconsumed-protocol-steps\",\n `Plugin protocol tape consumed ${stepCursor} of ${options.tape.steps.length} protocol step(s).`,\n );\n }\n },\n };\n}\n","import React, { useMemo } from \"react\";\nimport { createPluginRuntimeClient } from \"../../runtime/core/create-plugin-runtime-client.js\";\nimport { PluginRuntimeBoundary } from \"../../runtime/components/PluginRuntimeBoundary.js\";\nimport type { PluginRuntimeClient } from \"../../runtime/core/types.js\";\nimport type { FixtureHostHarness } from \"./create-fixture-host-harness.js\";\n\nexport function FixturePluginRuntime({\n harness,\n runtime,\n children,\n}: {\n harness: FixtureHostHarness;\n runtime?: PluginRuntimeClient;\n children: React.ReactNode;\n}) {\n const fixtureRuntime = useMemo(\n () => runtime ?? createPluginRuntimeClient({ transport: harness.transport }),\n [harness.transport, runtime],\n );\n return (\n <PluginRuntimeBoundary runtime={fixtureRuntime}>\n {children}\n </PluginRuntimeBoundary>\n );\n}\n","import {\n materializePluginGameplayFrame,\n type PluginSessionDescriptor,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport { digestUIFixtureTransportRequest } from \"./canonical.js\";\nimport type { PluginProtocolTape, UIFixtureFrame } from \"./schema.js\";\nimport type { UIFixtureProtocolStep } from \"./schema.js\";\nimport type {\n ReducerScenarioExchange,\n ReducerScenarioFrame,\n ReducerScenarioTrace,\n} from \"../reducer-scenario/types.js\";\n\nexport interface CompilePluginProtocolTapeOptions {\n readonly trace: ReducerScenarioTrace;\n readonly session: PluginSessionDescriptor;\n}\n\nexport function compilePluginProtocolTape(\n options: CompilePluginProtocolTapeOptions,\n): PluginProtocolTape {\n const frames = options.trace.frames.map((frame) =>\n materializeTraceFrame(frame, options.trace.viewer.playerId),\n );\n const frameById = new Map(frames.map((frame) => [frame.id, frame]));\n const steps: UIFixtureProtocolStep[] = [];\n\n const firstFrame = frames[0];\n if (!firstFrame) {\n throw new Error(\n `Reducer scenario '${options.trace.scenarioId}' did not record frames.`,\n );\n }\n steps.push({\n id: `${firstFrame.id}.host-frame`,\n kind: \"host.frame\",\n frameId: firstFrame.id,\n });\n\n for (const exchange of options.trace.exchanges) {\n const fromFrame = frameById.get(exchange.fromFrameId);\n if (!fromFrame) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing frame '${exchange.fromFrameId}'.`,\n );\n }\n if (exchange.operation === \"validate\") {\n steps.push({\n id: exchange.id,\n kind: \"client.validate\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response: {\n valid: exchange.result.valid,\n errorCode: exchange.result.errorCode,\n message: exchange.result.message,\n },\n });\n continue;\n }\n\n steps.push({\n id: exchange.id,\n kind: \"client.submit\",\n fromFrameId: exchange.fromFrameId,\n requestDigest: digestRuntimeCommand(exchange, fromFrame),\n response:\n exchange.result.kind === \"accepted\"\n ? { accepted: true }\n : {\n accepted: false,\n errorCode:\n exchange.result.diagnostics[0]?.code ?? \"fixture-rejected\",\n message: exchange.result.diagnostics[0]?.message,\n },\n });\n if (exchange.result.kind === \"accepted\") {\n if (!frameById.has(exchange.result.toFrameId)) {\n throw new Error(\n `Reducer exchange '${exchange.id}' references missing toFrameId '${exchange.result.toFrameId}'.`,\n );\n }\n steps.push({\n id: `${exchange.id}.host-frame`,\n kind: \"host.frame\",\n frameId: exchange.result.toFrameId,\n });\n }\n }\n\n return {\n session: options.session,\n frames,\n steps,\n };\n}\n\nfunction materializeTraceFrame(\n frame: ReducerScenarioFrame,\n perspectivePlayerId: string,\n): UIFixtureFrame {\n const flow = readFlowState(frame.reducerState);\n return {\n id: frame.id,\n frame: materializePluginGameplayFrame({\n currentPhase: flow.currentPhase,\n activePlayers: flow.activePlayers,\n dynamicProjection: frame.dynamicProjection,\n staticProjection: frame.staticProjection,\n perspectivePlayerId,\n gameVersion: frame.gameVersion,\n actionSetVersion: frame.actionSetVersion,\n }),\n projectionDigest: frame.projectionDigest,\n };\n}\n\nfunction digestRuntimeCommand(\n exchange: ReducerScenarioExchange,\n frame: UIFixtureFrame,\n): string {\n return digestUIFixtureTransportRequest({\n operation: exchange.operation === \"validate\" ? \"validate\" : \"submit\",\n basis: {\n gameVersion: frame.frame.gameVersion,\n actionSetVersion: frame.frame.actionSetVersion,\n perspectivePlayerId: frame.frame.perspectivePlayerId,\n },\n interactionId: exchange.input.interactionId,\n payload: exchange.input.params,\n });\n}\n\nfunction readFlowState(state: {\n readonly domain?: {\n readonly flow?: {\n readonly currentPhase?: string;\n readonly activePlayers?: readonly string[];\n };\n };\n}): { currentPhase: string | null; activePlayers: readonly string[] } {\n return {\n currentPhase: state.domain?.flow?.currentPhase ?? null,\n activePlayers: [...(state.domain?.flow?.activePlayers ?? [])],\n };\n}\n","export interface FixtureEnvironmentInit {\n readonly clockIso: string;\n readonly randomSeed: string;\n readonly locale: \"en-US\";\n readonly timezone: \"UTC\";\n readonly reducedMotion: true;\n readonly network: \"blocked\";\n}\n\nexport const defaultFixtureEnvironmentInit: FixtureEnvironmentInit = {\n clockIso: \"2026-01-01T00:00:00.000Z\",\n randomSeed: \"dreamboard-ui-fixture\",\n locale: \"en-US\",\n timezone: \"UTC\",\n reducedMotion: true,\n network: \"blocked\",\n};\n\nexport type DeterministicIdFactory = () => string;\n\nexport function createDeterministicIdFactory(\n seed: string,\n): DeterministicIdFactory {\n let cursor = 0;\n return () => {\n cursor += 1;\n return `fixture-${slug(seed)}-${cursor.toString(36).padStart(4, \"0\")}`;\n };\n}\n\nexport function fixtureEnvironmentInitFor(options: {\n readonly clockIso: string;\n readonly randomSeed: string;\n}): FixtureEnvironmentInit {\n return {\n ...defaultFixtureEnvironmentInit,\n clockIso: options.clockIso,\n randomSeed: options.randomSeed,\n };\n}\n\nfunction slug(value: string): string {\n return (\n value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 48) || \"seed\"\n );\n}\n","import { z } from \"zod\";\nimport {\n BROWSER_INTERACTION_ACTUATOR_KINDS,\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n browserInteractionEffectSchema,\n} from \"../../browser-interaction/index.js\";\nimport type {\n BrowserInteractionEffectRequest,\n BrowserInteractionIntentRequest,\n} from \"../../browser-interaction/index.js\";\nimport { RuntimeJsonSchema } from \"../../runtime-json.js\";\nimport { digestUIFixtureRequest, isSha256Digest } from \"./canonical.js\";\nimport {\n DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION,\n PluginProtocolFrameSchema,\n PluginProtocolStepSchema,\n PluginProtocolTapeSchema,\n type PluginProtocolFrame,\n type PluginProtocolStep,\n type PluginProtocolTape as RuntimePluginProtocolTape,\n} from \"@dreamboard-games/plugin-runtime-contract\";\n\nexport const UI_SCENARIO_FIXTURE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION = 2;\nexport const UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR = 3;\nexport const UI_SCENARIO_FIXTURE_PLUGIN_RUNTIME_PROTOCOL =\n PLUGIN_RUNTIME_PROTOCOL_VERSION;\n\nconst digestSchema = z.string().refine(isSha256Digest, {\n message: \"Expected a sha256:<64 lowercase hex> digest.\",\n});\n\nconst nonEmptyStringSchema = z.string().min(1);\nconst jsonSchema = RuntimeJsonSchema;\n\nconst environmentSchema = z\n .object({\n clockIso: nonEmptyStringSchema,\n randomSeed: nonEmptyStringSchema,\n locale: z.literal(\"en-US\"),\n timezone: z.literal(\"UTC\"),\n viewportTags: z.array(z.enum([\"desktop\", \"tablet\", \"phone\", \"touch\"])),\n })\n .strict();\n\nexport const uiFixtureFrameSchema = PluginProtocolFrameSchema;\nexport const uiFixtureProtocolStepSchema = PluginProtocolStepSchema;\nexport const pluginProtocolTapeSchema = PluginProtocolTapeSchema.refine(\n (tape) => tape.frames.length > 0,\n \"UI fixture protocol tapes require at least one gameplay frame.\",\n);\n\nconst browserInteractionIntentRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n intent: nonEmptyStringSchema,\n inputKey: nonEmptyStringSchema.optional(),\n candidateValue: jsonSchema.optional(),\n candidateValueKey: nonEmptyStringSchema.optional(),\n actuatorKind: z.enum(BROWSER_INTERACTION_ACTUATOR_KINDS).optional(),\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nconst browserInteractionEffectRequestSchema = z\n .object({\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema.optional(),\n interactionKey: nonEmptyStringSchema.optional(),\n interactionId: nonEmptyStringSchema.optional(),\n effect: browserInteractionEffectSchema,\n allowDisabled: z.boolean().optional(),\n })\n .strict();\n\nexport const uiReplayRequestSchema = z.union([\n browserInteractionIntentRequestSchema,\n browserInteractionEffectRequestSchema,\n]);\n\nexport const uiReplayExecutionSchema = z.union([\n z\n .object({\n kind: z.literal(\"activate\"),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"fill\"),\n value: z.string(),\n })\n .strict(),\n z\n .object({\n kind: z.literal(\"drag\"),\n target: browserInteractionEffectRequestSchema,\n })\n .strict(),\n]);\n\nexport const uiStepExpectationSchema = z\n .object({\n frameId: nonEmptyStringSchema.optional(),\n projectionDigest: digestSchema.optional(),\n semanticDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n submissionDigest: digestSchema.optional(),\n focusedInteractionKey: nonEmptyStringSchema.optional(),\n visibleInteractionKeys: z.array(nonEmptyStringSchema).optional(),\n })\n .strict();\n\nexport const uiResolvedReplayIdentitySchema = z\n .object({\n stepId: nonEmptyStringSchema,\n surface: nonEmptyStringSchema,\n scopeId: nonEmptyStringSchema,\n interactionKey: nonEmptyStringSchema,\n interactionId: nonEmptyStringSchema,\n actuatorId: nonEmptyStringSchema,\n descriptorDigest: digestSchema.optional(),\n draftDigest: digestSchema.optional(),\n })\n .strict();\n\nexport const portableSemanticReplayStepSchema = z\n .object({\n stepId: nonEmptyStringSchema,\n requestDigest: digestSchema,\n resolve: uiReplayRequestSchema,\n execute: uiReplayExecutionSchema,\n expectedIdentity: uiResolvedReplayIdentitySchema.optional(),\n expect: uiStepExpectationSchema,\n })\n .strict();\n\nexport const uiScenarioReplayStepSchema = z.union([\n portableSemanticReplayStepSchema,\n z\n .object({\n stepId: nonEmptyStringSchema,\n kind: z.literal(\"assert\"),\n expect: uiStepExpectationSchema,\n })\n .strict(),\n]);\n\nexport const uiScenarioFixtureSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_SCHEMA_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n id: nonEmptyStringSchema,\n title: nonEmptyStringSchema,\n gameId: nonEmptyStringSchema,\n tags: z.array(nonEmptyStringSchema),\n source: z\n .object({\n scenarioId: nonEmptyStringSchema,\n reducerFingerprint: nonEmptyStringSchema,\n uiContractFingerprint: nonEmptyStringSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleDigest: digestSchema,\n sourceDigest: digestSchema,\n })\n .strict(),\n viewer: z\n .object({\n seatId: nonEmptyStringSchema,\n playerId: nonEmptyStringSchema.optional(),\n })\n .strict(),\n environment: environmentSchema,\n protocol: pluginProtocolTapeSchema,\n replay: z.array(uiScenarioReplayStepSchema),\n expected: z\n .object({\n initialProjectionDigest: digestSchema,\n finalProjectionDigest: digestSchema,\n finalSemanticDigest: digestSchema,\n submissionDigest: digestSchema,\n })\n .strict(),\n })\n .strict();\n\nexport const uiScenarioFixtureBundleIndexSchema = z\n .object({\n schemaVersion: z.literal(UI_SCENARIO_FIXTURE_BUNDLE_SCHEMA_VERSION),\n bundleId: nonEmptyStringSchema,\n sdkCommit: nonEmptyStringSchema,\n pluginRuntimeProtocol: z.literal(PLUGIN_RUNTIME_PROTOCOL_VERSION),\n browserInteractionProtocol: z.literal(\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n ),\n fixtures: z.array(\n z\n .object({\n id: nonEmptyStringSchema,\n file: nonEmptyStringSchema,\n sha256: digestSchema,\n renderModule: nonEmptyStringSchema,\n renderModuleSha256: digestSchema,\n components: z.array(nonEmptyStringSchema),\n capabilities: z.array(nonEmptyStringSchema),\n })\n .strict(),\n ),\n })\n .strict();\n\nexport type UIReplayRequest =\n | BrowserInteractionIntentRequest\n | BrowserInteractionEffectRequest;\nexport type UIReplayExecution = z.infer<typeof uiReplayExecutionSchema>;\nexport type UIStepExpectation = z.infer<typeof uiStepExpectationSchema>;\nexport type UIResolvedReplayIdentity = z.infer<\n typeof uiResolvedReplayIdentitySchema\n>;\nexport type PortableSemanticReplayStep = z.infer<\n typeof portableSemanticReplayStepSchema\n>;\nexport type UIScenarioReplayStep = z.infer<typeof uiScenarioReplayStepSchema>;\nexport type UIFixtureFrame = PluginProtocolFrame;\nexport type UIFixtureProtocolStep = PluginProtocolStep;\nexport type PluginProtocolTape = RuntimePluginProtocolTape;\nexport type UIScenarioFixture = Omit<\n z.infer<typeof uiScenarioFixtureSchema>,\n \"protocol\" | \"replay\"\n> & {\n readonly protocol: PluginProtocolTape;\n readonly replay: readonly UIScenarioReplayStep[];\n};\nexport type UIScenarioFixtureBundleIndex = z.infer<\n typeof uiScenarioFixtureBundleIndexSchema\n>;\n\nexport function parseUIScenarioFixture(value: unknown): UIScenarioFixture {\n const fixture = uiScenarioFixtureSchema.parse(\n value,\n ) as unknown as UIScenarioFixture;\n validateUIScenarioFixtureReferences(fixture);\n return fixture;\n}\n\nexport function parseUIScenarioFixtureBundleIndex(\n value: unknown,\n): UIScenarioFixtureBundleIndex {\n const bundle = uiScenarioFixtureBundleIndexSchema.parse(value);\n assertSupportedBrowserInteractionProtocol(bundle.browserInteractionProtocol);\n const ids = new Set<string>();\n for (const entry of bundle.fixtures) {\n if (ids.has(entry.id)) {\n throw new Error(`Duplicate fixture id '${entry.id}' in bundle index.`);\n }\n ids.add(entry.id);\n }\n return bundle;\n}\n\nexport function assertSupportedBrowserInteractionProtocol(\n version: string,\n): void {\n const major = Number(version.split(\".\")[0]);\n if (major !== UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR) {\n throw new Error(\n `Unsupported browser-interaction protocol '${version}'. Expected major ${UI_SCENARIO_FIXTURE_SUPPORTED_BROWSER_PROTOCOL_MAJOR}.`,\n );\n }\n}\n\nfunction validateUIScenarioFixtureReferences(fixture: UIScenarioFixture): void {\n assertSupportedBrowserInteractionProtocol(fixture.browserInteractionProtocol);\n const frameIds = new Set<string>();\n const stepIds = new Set<string>();\n\n for (const frame of fixture.protocol.frames) {\n if (frameIds.has(frame.id)) {\n throw new Error(`Duplicate fixture frame id '${frame.id}'.`);\n }\n frameIds.add(frame.id);\n }\n\n for (const step of fixture.protocol.steps) {\n if (stepIds.has(step.id)) {\n throw new Error(`Duplicate protocol step id '${step.id}'.`);\n }\n stepIds.add(step.id);\n if (step.kind === \"host.frame\") {\n if (!frameIds.has(step.frameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing frameId '${step.frameId}'.`,\n );\n }\n continue;\n }\n if (!frameIds.has(step.fromFrameId)) {\n throw new Error(\n `Protocol step '${step.id}' references missing fromFrameId '${step.fromFrameId}'.`,\n );\n }\n }\n\n for (const step of fixture.replay) {\n if (\"resolve\" in step) {\n const actualDigest = digestUIFixtureRequest(\n step.resolve as unknown as UIReplayRequest,\n );\n if (step.requestDigest !== actualDigest) {\n throw new Error(\n `Replay step '${step.stepId}' requestDigest ${step.requestDigest} does not match ${actualDigest}.`,\n );\n }\n }\n const expectedFrameId = step.expect.frameId;\n if (expectedFrameId && !frameIds.has(expectedFrameId)) {\n throw new Error(\n `Replay step '${step.stepId}' expects missing frameId '${expectedFrameId}'.`,\n );\n }\n }\n}\n","import {\n canonicalizeUIScenarioFixture,\n digestUIFixtureJson,\n serializeUIScenarioFixture,\n} from \"./canonical.js\";\nimport { DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION } from \"../../browser-interaction/index.js\";\nimport { DREAMBOARD_PLUGIN_PROTOCOL_VERSION as PLUGIN_RUNTIME_PROTOCOL_VERSION } from \"@dreamboard-games/plugin-runtime-contract\";\nimport {\n parseUIScenarioFixture,\n type PortableSemanticReplayStep,\n type PluginProtocolTape,\n type UIResolvedReplayIdentity,\n type UIScenarioFixture,\n type UIScenarioReplayStep,\n type UIStepExpectation,\n} from \"./schema.js\";\n\nexport interface CompileUIScenarioFixtureOptions {\n readonly id: string;\n readonly title: string;\n readonly gameId: string;\n readonly tags?: readonly string[];\n readonly source: UIScenarioFixture[\"source\"];\n readonly viewer: UIScenarioFixture[\"viewer\"];\n readonly environment: UIScenarioFixture[\"environment\"];\n readonly protocol: PluginProtocolTape;\n readonly replay?: readonly UIScenarioReplayStep[];\n readonly expected?: Partial<UIScenarioFixture[\"expected\"]>;\n}\n\nexport type UIReplayIdentityCandidate = UIResolvedReplayIdentity;\n\nexport function compileUIScenarioFixture(\n options: CompileUIScenarioFixtureOptions,\n): UIScenarioFixture {\n const firstFrame = options.protocol.frames[0];\n const finalFrame = lastPublishedFrame(options.protocol);\n if (!firstFrame || !finalFrame) {\n throw new Error(\n \"compileUIScenarioFixture requires at least one protocol frame.\",\n );\n }\n\n const replay = options.replay ?? [];\n const submissionDigest =\n options.expected?.submissionDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-submission@1\",\n fixtureId: options.id,\n replay: replay.map((step) =>\n \"requestDigest\" in step ? step.requestDigest : step.stepId,\n ),\n });\n const finalSemanticDigest =\n options.expected?.finalSemanticDigest ??\n digestUIFixtureJson({\n digestVersion: \"ui-semantic@1\",\n fixtureId: options.id,\n frameId: finalFrame.id,\n projectionDigest: finalFrame.projectionDigest,\n });\n\n return parseUIScenarioFixture(\n canonicalizeUIScenarioFixture({\n schemaVersion: 2,\n browserInteractionProtocol:\n DREAMBOARD_BROWSER_INTERACTION_PROTOCOL_VERSION,\n pluginRuntimeProtocol: PLUGIN_RUNTIME_PROTOCOL_VERSION,\n id: options.id,\n title: options.title,\n gameId: options.gameId,\n tags: [...(options.tags ?? [])],\n source: options.source,\n viewer: options.viewer,\n environment: options.environment,\n protocol: options.protocol,\n replay,\n expected: {\n initialProjectionDigest:\n options.expected?.initialProjectionDigest ??\n firstFrame.projectionDigest,\n finalProjectionDigest:\n options.expected?.finalProjectionDigest ??\n finalFrame.projectionDigest,\n finalSemanticDigest,\n submissionDigest,\n },\n }),\n );\n}\n\nfunction lastPublishedFrame(\n protocol: PluginProtocolTape,\n): PluginProtocolTape[\"frames\"][number] | undefined {\n const frameById = new Map(protocol.frames.map((frame) => [frame.id, frame]));\n for (let index = protocol.steps.length - 1; index >= 0; index -= 1) {\n const step = protocol.steps[index];\n if (step?.kind === \"host.frame\") {\n return frameById.get(step.frameId);\n }\n }\n return protocol.frames[protocol.frames.length - 1];\n}\n\nexport function assertDeterministicUIScenarioFixture(\n first: UIScenarioFixture,\n second: UIScenarioFixture,\n): void {\n const firstBytes = serializeUIScenarioFixture(first);\n const secondBytes = serializeUIScenarioFixture(second);\n if (firstBytes !== secondBytes) {\n throw new Error(\n `UI scenario fixture '${first.id}' is non-deterministic across compilation runs.`,\n );\n }\n}\n\nexport function assertUniqueReplayIdentity(\n step: Pick<PortableSemanticReplayStep, \"stepId\" | \"expectedIdentity\">,\n candidates: readonly UIReplayIdentityCandidate[],\n): UIReplayIdentityCandidate {\n if (candidates.length !== 1) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${candidates.length} identities; expected exactly one.`,\n );\n }\n const candidate = candidates[0];\n if (!candidate) {\n throw new Error(`Replay step '${step.stepId}' did not resolve.`);\n }\n\n const expected = step.expectedIdentity;\n if (!expected) {\n return candidate;\n }\n for (const key of [\n \"surface\",\n \"scopeId\",\n \"interactionKey\",\n \"interactionId\",\n \"actuatorId\",\n \"descriptorDigest\",\n \"draftDigest\",\n ] as const) {\n const expectedValue = expected[key];\n if (expectedValue !== undefined && candidate[key] !== expectedValue) {\n throw new Error(\n `Replay step '${step.stepId}' resolved ${key} '${String(\n candidate[key],\n )}', expected '${expectedValue}'.`,\n );\n }\n }\n return candidate;\n}\n\nexport function assertUIStepExpectationSatisfied(\n stepId: string,\n expected: UIStepExpectation,\n actual: UIStepExpectation,\n): void {\n for (const key of [\n \"frameId\",\n \"projectionDigest\",\n \"semanticDigest\",\n \"draftDigest\",\n \"submissionDigest\",\n \"focusedInteractionKey\",\n ] as const) {\n if (expected[key] !== undefined && expected[key] !== actual[key]) {\n throw new Error(\n `Replay step '${stepId}' expected ${key} '${expected[key]}', received '${actual[key]}'.`,\n );\n }\n }\n if (expected.visibleInteractionKeys) {\n const actualKeys = new Set(actual.visibleInteractionKeys ?? []);\n const missing = expected.visibleInteractionKeys.filter(\n (key) => !actualKeys.has(key),\n );\n if (missing.length > 0) {\n throw new Error(\n `Replay step '${stepId}' missing visible interactions: ${missing.join(\n \", \",\n )}.`,\n );\n }\n }\n}\n"],"mappings":"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","names":["mismatch","readFlowState","result","readFlowState"]}
@@ -0,0 +1,29 @@
1
+ import { v, o, G, H, x } from './protocol-BP193lva.js';
2
+
3
+ interface RuntimeClock {
4
+ now(): number;
5
+ }
6
+ interface RuntimeIdFactory {
7
+ nextId(prefix: string): string;
8
+ }
9
+ interface PluginTransport {
10
+ start(onMessage: (message: H) => void): () => void;
11
+ send(message: x): void;
12
+ }
13
+ interface PluginRuntimeClient {
14
+ getSession(): v | null;
15
+ subscribeSession(listener: () => void): () => void;
16
+ getFrame(): o | null;
17
+ subscribeFrame(listener: () => void): () => void;
18
+ validateInteraction(interactionId: string, params: unknown): Promise<G>;
19
+ submitInteraction(interactionId: string, params: unknown): Promise<void>;
20
+ disconnect(): void;
21
+ }
22
+ interface PluginRuntimeClientOptions {
23
+ transport: PluginTransport;
24
+ idFactory?: RuntimeIdFactory;
25
+ clock?: RuntimeClock;
26
+ requestTimeoutMs?: number;
27
+ }
28
+
29
+ export type { PluginRuntimeClient as P, RuntimeClock as R, PluginRuntimeClientOptions as a, PluginTransport as b, RuntimeIdFactory as c };