@dreamboard-games/sdk 0.4.0-alpha.6 → 0.4.0-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/REFERENCE.md +408 -8
- package/dist/authoring/index.d.ts +5 -4
- package/dist/authoring/index.js +3 -3
- package/dist/authoring/index.js.map +1 -1
- package/dist/{chunk-PAPIAMYX.js → chunk-3QIZKXJ2.js} +6 -4
- package/dist/{chunk-PAPIAMYX.js.map → chunk-3QIZKXJ2.js.map} +1 -1
- package/dist/chunk-5IHU5CUK.js +575 -0
- package/dist/chunk-5IHU5CUK.js.map +1 -0
- package/dist/chunk-IU6KGPY7.js +659 -0
- package/dist/chunk-IU6KGPY7.js.map +1 -0
- package/dist/{chunk-HK3WN4U7.js → chunk-KYEWGZ2Y.js} +2 -2
- package/dist/{chunk-HK3WN4U7.js.map → chunk-KYEWGZ2Y.js.map} +1 -1
- package/dist/{chunk-DDST4U2P.js → chunk-NO537WSS.js} +2 -2
- package/dist/{chunk-SOBNI363.js → chunk-Q322XCY2.js} +11 -6
- package/dist/{chunk-SOBNI363.js.map → chunk-Q322XCY2.js.map} +1 -1
- package/dist/{chunk-OV6JC2BM.js → chunk-RKGJ64UN.js} +19 -15
- package/dist/chunk-RKGJ64UN.js.map +1 -0
- package/dist/chunk-VLG4YST5.js +564 -0
- package/dist/chunk-VLG4YST5.js.map +1 -0
- package/dist/{stale-contract-artifact-error-BelRiIDR.d.ts → diagnostics-1BWjRo6-.d.ts} +1 -18
- package/dist/index.js +2 -2
- package/dist/package-set.d.ts +2 -2
- package/dist/package-set.js +2 -2
- package/dist/reducer.d.ts +3 -2
- package/dist/reducer.js +5 -5
- package/dist/reducer.js.map +1 -1
- package/dist/reference-games/index.d.ts +223 -0
- package/dist/reference-games/index.js +230 -0
- package/dist/reference-games/index.js.map +1 -0
- package/dist/runtime/primitives.js +4 -3
- package/dist/runtime/workspace-contract.js +5 -4
- package/dist/runtime.js +15 -205
- package/dist/runtime.js.map +1 -1
- package/dist/stale-contract-artifact-error-C5AaZPJ8.d.ts +18 -0
- package/dist/testing-runtime.d.ts +42 -0
- package/dist/testing-runtime.js +153 -0
- package/dist/testing-runtime.js.map +1 -0
- package/dist/testing.d.ts +5 -191
- package/dist/testing.js +22 -640
- package/dist/testing.js.map +1 -1
- package/dist/types-DcADVHe9.d.ts +192 -0
- package/package.json +13 -2
- package/dist/chunk-OV6JC2BM.js.map +0 -1
- package/dist/chunk-UUQNOGZV.js +0 -1266
- package/dist/chunk-UUQNOGZV.js.map +0 -1
- /package/dist/{chunk-DDST4U2P.js.map → chunk-NO537WSS.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/testing/create-expect-api.ts","../src/testing/create-test-runtime.ts"],"sourcesContent":["import 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 isDeepStrictEqual(actual: unknown, expected: unknown): boolean {\n if (Object.is(actual, expected)) return true;\n if (typeof actual !== typeof expected) return false;\n if (actual === null || expected === null) return false;\n if (typeof actual !== \"object\" || typeof expected !== \"object\") return false;\n\n if (actual instanceof Date || expected instanceof Date) {\n return (\n actual instanceof Date &&\n expected instanceof Date &&\n Object.is(actual.getTime(), expected.getTime())\n );\n }\n if (actual instanceof RegExp || expected instanceof RegExp) {\n return (\n actual instanceof RegExp &&\n expected instanceof RegExp &&\n actual.source === expected.source &&\n actual.flags === expected.flags\n );\n }\n if (Array.isArray(actual) || Array.isArray(expected)) {\n return (\n Array.isArray(actual) &&\n Array.isArray(expected) &&\n actual.length === expected.length &&\n actual.every((value, index) => isDeepStrictEqual(value, expected[index]))\n );\n }\n\n const actualPrototype = Object.getPrototypeOf(actual);\n const expectedPrototype = Object.getPrototypeOf(expected);\n if (actualPrototype !== expectedPrototype) return false;\n\n const actualRecord = actual as Record<string, unknown>;\n const expectedRecord = expected as Record<string, unknown>;\n const actualKeys = Object.keys(actualRecord);\n const expectedKeys = Object.keys(expectedRecord);\n return (\n actualKeys.length === expectedKeys.length &&\n actualKeys.every(\n (key) =>\n Object.prototype.hasOwnProperty.call(expectedRecord, key) &&\n isDeepStrictEqual(actualRecord[key], expectedRecord[key]),\n )\n );\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 recentEvents: [],\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 const 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"],"mappings":";;;;;;;;AAkBA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,kBAAkB,QAAiB,UAA4B;AACtE,MAAI,OAAO,GAAG,QAAQ,QAAQ,EAAG,QAAO;AACxC,MAAI,OAAO,WAAW,OAAO,SAAU,QAAO;AAC9C,MAAI,WAAW,QAAQ,aAAa,KAAM,QAAO;AACjD,MAAI,OAAO,WAAW,YAAY,OAAO,aAAa,SAAU,QAAO;AAEvE,MAAI,kBAAkB,QAAQ,oBAAoB,MAAM;AACtD,WACE,kBAAkB,QAClB,oBAAoB,QACpB,OAAO,GAAG,OAAO,QAAQ,GAAG,SAAS,QAAQ,CAAC;AAAA,EAElD;AACA,MAAI,kBAAkB,UAAU,oBAAoB,QAAQ;AAC1D,WACE,kBAAkB,UAClB,oBAAoB,UACpB,OAAO,WAAW,SAAS,UAC3B,OAAO,UAAU,SAAS;AAAA,EAE9B;AACA,MAAI,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,QAAQ,GAAG;AACpD,WACE,MAAM,QAAQ,MAAM,KACpB,MAAM,QAAQ,QAAQ,KACtB,OAAO,WAAW,SAAS,UAC3B,OAAO,MAAM,CAAC,OAAO,UAAU,kBAAkB,OAAO,SAAS,KAAK,CAAC,CAAC;AAAA,EAE5E;AAEA,QAAM,kBAAkB,OAAO,eAAe,MAAM;AACpD,QAAM,oBAAoB,OAAO,eAAe,QAAQ;AACxD,MAAI,oBAAoB,kBAAmB,QAAO;AAElD,QAAM,eAAe;AACrB,QAAM,iBAAiB;AACvB,QAAM,aAAa,OAAO,KAAK,YAAY;AAC3C,QAAM,eAAe,OAAO,KAAK,cAAc;AAC/C,SACE,WAAW,WAAW,aAAa,UACnC,WAAW;AAAA,IACT,CAAC,QACC,OAAO,UAAU,eAAe,KAAK,gBAAgB,GAAG,KACxD,kBAAkB,aAAa,GAAG,GAAG,eAAe,GAAG,CAAC;AAAA,EAC5D;AAEJ;AAEA,SAAS,aACP,QACA,UACA,OAAe,SACA;AACf,MAAI,CAAC,SAAS,QAAQ,GAAG;AACvB,WAAO,kBAAkB,QAAQ,QAAQ,IACrC,OACA,GAAG,IAAI;AAAA,EACb;AACA,MAAI,CAAC,SAAS,MAAM,GAAG;AACrB,WAAO,GAAG,IAAI;AAAA,EAChB;AACA,aAAW,CAAC,KAAK,aAAa,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC3D,UAAM,cAAc,OAAO,GAAG;AAC9B,QAAI,EAAE,OAAO,SAAS;AACpB,aAAO,GAAG,IAAI,IAAI,GAAG;AAAA,IACvB;AACA,UAAM,WAAW,aAAa,aAAa,eAAe,GAAG,IAAI,IAAI,GAAG,EAAE;AAC1E,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,QAA8C;AACtE,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACA,SAAO;AACT;AAEA,SAAS,gBACP,aACA,eACkC;AAClC,SACE,YAAY;AAAA,IACV,CAAC,eAAe,WAAW,kBAAkB;AAAA,EAC/C,KAAK;AAET;AAEA,SAAS,wBACP,YACA,MACM;AACN,MAAI,CAAC,MAAM;AACT;AAAA,EACF;AACA,QAAM,WAAW,aAAa,YAAY,MAAM,aAAa;AAC7D,MAAI,UAAU;AACZ,UAAM,IAAI,MAAM,QAAQ;AAAA,EAC1B;AACF;AAEA,SAAS,6BACP,QACA,UACA,SACe;AACf,QAAM,iBAAiB,MAAwB;AAC7C,QAAI,OAAO,WAAW,YAAY;AAChC,aAAO,QAAQ,QAAQ,EAAE,KAAK,MAAO,OAAyB,CAAC;AAAA,IACjE;AACA,WAAO,QAAQ,QAAQ,MAAM;AAAA,EAC/B;AAEA,SAAO,eAAe,EACnB,KAAK,MAAM;AACV,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C,CAAC,EACA,MAAM,CAAC,UAAmB;AACzB,QAAI,EAAE,iBAAiB,QAAQ;AAC7B,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,QACE,SAAS,cAAc,UACtB,MAAyC,cACxC,SAAS,WACX;AACA,YAAM,IAAI;AAAA,QACR,iCAAiC,SAAS,SAAS,gBAChD,MAAyC,aAAa,WACzD,KAAK,8BAA8B,OAAO,CAAC;AAAA,MAC7C;AAAA,IACF;AACA,QACE,OAAO,SAAS,YAAY,YAC5B,MAAM,YAAY,SAAS,SAC3B;AACA,YAAM,IAAI;AAAA,QACR,+BAA+B,SAAS,OAAO,gBAAgB,MAAM,OAAO,KAAK;AAAA,UAC/E;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,QACE,SAAS,mBAAmB,UAC5B,CAAC,SAAS,QAAQ,KAAK,MAAM,OAAO,GACpC;AACA,YAAM,IAAI;AAAA,QACR,+BAA+B,MAAM,OAAO,cAAc;AAAA,UACxD,SAAS;AAAA,QACX,CAAC,IAAI,8BAA8B,OAAO,CAAC;AAAA,MAC7C;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEA,SAAS,8BACP,SACQ;AACR,QAAM,YAAY,QAAQ,0BAA0B;AACpD,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,OAAO,UAAU,SAAS,WAAW,UAAU,MAAM,KAAK;AAChE,QAAM,UAAU,UAAU,UAAU,YAAY,UAAU,OAAO,KAAK;AACtE,SAAO;AAAA,4BAA+B,UAAU,SAAS,GAAG,IAAI,GAAG,OAAO;AAC5E;AAEA,SAAS,aAAa,QAAiB,UAAwB;AAC7D,MACE,WAAW,QACX,WAAW,UACX,OAAQ,OAAgC,WAAW,UACnD;AACA,UAAM,IAAI,MAAM,qDAAqD;AAAA,EACvE;AACA,QAAM,SAAU,OAA8B;AAC9C,MAAI,WAAW,UAAU;AACvB,UAAM,IAAI,MAAM,mBAAmB,QAAQ,cAAc,MAAM,GAAG;AAAA,EACpE;AACF;AAEA,SAAS,6BACP,aACQ;AACR,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ;AAAA,IACZ,iBAAiB,YAAY,YAAY;AAAA,IACzC,GAAG,YAAY,MAAM,IAAI,CAAC,SAAS;AACjC,YAAM,OAAO,KAAK,YAAY,KAAK,KAAK,SAAS,MAAM;AACvD,YAAM,UAAU,KAAK,UAAU,KAAK,KAAK,OAAO,KAAK;AACrD,aAAO,QAAQ,KAAK,MAAM,IAAI,KAAK,OAAO,GAAG,IAAI,GAAG,OAAO;AAAA,IAC7D,CAAC;AAAA,IACD,GAAG,YAAY,OAAO;AAAA,MACpB,CAAC,UAAU,SAAS,MAAM,GAAG,kBAAkB,MAAM,aAAa;AAAA,IACpE;AAAA,EACF;AACA,SAAO;AAAA,EAAK,MAAM,KAAK,IAAI,CAAC;AAC9B;AAEA,SAAS,aACP,QACA,WACM;AACN,MAAI,OAAO,WAAW,YAAY;AAChC,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,MAAI;AACF,IAAC,OAAyB;AAAA,EAC5B,SAAS,OAAO;AACd,QAAI,EAAE,iBAAiB,QAAQ;AAC7B,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,QAAI,cAAc,QAAW;AAC3B;AAAA,IACF;AACA,QAAI,OAAO,cAAc,YAAY,MAAM,YAAY,WAAW;AAChE,YAAM,IAAI;AAAA,QACR,4BAA4B,SAAS,gBAAgB,MAAM,OAAO;AAAA,MACpE;AAAA,IACF;AACA,QAAI,qBAAqB,UAAU,CAAC,UAAU,KAAK,MAAM,OAAO,GAAG;AACjE,YAAM,IAAI;AAAA,QACR,4BAA4B,MAAM,OAAO,cAAc,OAAO,SAAS,CAAC;AAAA,MAC1E;AAAA,IACF;AACA,QAAI,OAAO,cAAc,cAAc,CAAC,UAAU,KAAK,GAAG;AACxD,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AACA;AAAA,EACF;AACA,QAAM,IAAI,MAAM,6BAA6B;AAC/C;AAEO,SAAS,gBACd,UAAkC,CAAC,GACzB;AACV,QAAM,gBAAgB,CAAC,YAAqC;AAAA,IAC1D,MAAM,CAAC,aAAsB;AAC3B,UAAI,WAAW,UAAU;AACvB,cAAM,IAAI;AAAA,UACR,aAAa,OAAO,MAAM,CAAC,YAAY,OAAO,QAAQ,CAAC;AAAA,QACzD;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,CAAC,aAAsB;AAC9B,UAAI,CAAC,kBAAkB,QAAQ,QAAQ,GAAG;AACxC,cAAM,IAAI,MAAM,qCAAqC;AAAA,MACvD;AAAA,IACF;AAAA,IACA,eAAe,CAAC,aAAsC;AACpD,YAAM,WAAW,aAAa,QAAQ,QAAQ;AAC9C,UAAI,UAAU;AACZ,cAAM,IAAI,MAAM,QAAQ;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,aAAa,MAAM;AACjB,UAAI,WAAW,QAAW;AACxB,cAAM,IAAI,MAAM,+BAA+B;AAAA,MACjD;AAAA,IACF;AAAA,IACA,eAAe,MAAM;AACnB,UAAI,WAAW,QAAW;AACxB,cAAM,IAAI;AAAA,UACR,iDAAiD,OAAO,MAAM,CAAC;AAAA,QACjE;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,MAAM;AACd,UAAI,WAAW,MAAM;AACnB,cAAM,IAAI;AAAA,UACR,4CAA4C,OAAO,MAAM,CAAC;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAAA,IACA,WAAW,CAAC,aAAsB;AAChC,UAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,YAAI,CAAC,OAAO,SAAS,QAAQ,GAAG;AAC9B,gBAAM,IAAI,MAAM,kCAAkC;AAAA,QACpD;AACA;AAAA,MACF;AACA,UAAI,OAAO,WAAW,UAAU;AAC9B,YAAI,CAAC,OAAO,SAAS,OAAO,QAAQ,CAAC,GAAG;AACtC,gBAAM,IAAI,MAAM,mCAAmC;AAAA,QACrD;AACA;AAAA,MACF;AACA,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAAA,IACA,gBAAgB,CAAC,aAAsB;AACrC,UAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,cAAM,IAAI,MAAM,+CAA+C;AAAA,MACjE;AACA,UAAI,CAAC,OAAO,KAAK,CAAC,UAAU,kBAAkB,OAAO,QAAQ,CAAC,GAAG;AAC/D,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AAAA,IACF;AAAA,IACA,cAAc,CAAC,aAAqB;AAClC,mBAAa,QAAQ,QAAQ;AAAA,IAC/B;AAAA,IACA,iBAAiB,CAAC,aAAqB;AACrC,UAAI,OAAO,WAAW,UAAU;AAC9B,cAAM,IAAI,MAAM,gDAAgD;AAAA,MAClE;AACA,UAAI,UAAU,UAAU;AACtB,cAAM,IAAI,MAAM,YAAY,MAAM,YAAY,QAAQ,GAAG;AAAA,MAC3D;AAAA,IACF;AAAA,IACA,wBAAwB,CAAC,aAAqB;AAC5C,UAAI,OAAO,WAAW,UAAU;AAC9B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,UAAI,SAAS,UAAU;AACrB,cAAM,IAAI,MAAM,YAAY,MAAM,aAAa,QAAQ,GAAG;AAAA,MAC5D;AAAA,IACF;AAAA,IACA,SAAS,CAAC,cAAc;AACtB,mBAAa,QAAQ,SAAS;AAAA,IAChC;AAAA,IACA,iBAAiB,CAAC,aAAa;AAC7B,UAAI,CAAC,QAAQ,eAAe;AAC1B,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,cAAQ,cAAc,UAAU,MAAM;AAAA,IACxC;AAAA,IACA,cAAc,CAAC,aACb,6BAA6B,QAAQ,UAAU,OAAO;AAAA,IACxD,mBAAmB,CAAC,eAAe,SAAS;AAC1C,YAAM,cAAc,iBAAiB,MAAM;AAC3C,YAAM,aAAa,gBAAgB,aAAa,aAAa;AAC7D,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,yBAAyB,aAAa,aAAa;AAAA,MACrE;AACA,8BAAwB,YAAY,IAAI;AAAA,IAC1C;AAAA,IACA,aAAa,CAAC,QAAQ,SAAS;AAC7B,YAAM,aAAa,MAAM,QAAQ,MAAM,KAClC,MAAM;AACL,YAAI,CAAC,MAAM,eAAe;AACxB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,iBAAiB,MAAM;AAAA,UACvB,KAAK;AAAA,QACP;AAAA,MACF,GAAG,IACF;AACL,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AACA,UAAI,WAAW,cAAc,WAAW,aAAa;AACnD,cAAM,IAAI,MAAM,yCAAyC;AAAA,MAC3D;AACA,YAAM,eACJ,WAAW,cAAc,WAAW,iBACpC,WAAW,cAAc,WAAW,2BACpC,WAAW,cAAc,WAAW,YAChC,WAAW,aAAa,SACxB;AACN,UAAI,iBAAiB,QAAQ;AAC3B,cAAM,IAAI;AAAA,UACR,gCAAgC,MAAM,gBACpC,gBAAgB,WAClB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,eAAe,CAAC,gBAAgB;AAC9B,YAAM,aAAa,MAAM,QAAQ,MAAM,KAClC,MAAM;AACL,YAAI,CAAC,aAAa,eAAe;AAC/B,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,iBAAiB,MAAM;AAAA,UACvB,YAAY;AAAA,QACd;AAAA,MACF,GAAG,IACF;AACL,UAAI,CAAC,YAAY;AACf,cAAM,IAAI;AAAA,UACR,4CAA4C;AAAA,YAC1C;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,WAAW,cAAc,WAAW,aAAa;AACnD,cAAM,IAAI;AAAA,UACR,yBAAyB,WAAW,iBAAiB,SAAS,qBAAqB;AAAA,YACjF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,IACA,eAAe,CAAC,UAAU,SAAS;AACjC,YAAM,aAAa,MAAM,QAAQ,MAAM,KAClC,MAAM;AACL,YAAI,CAAC,MAAM,eAAe;AACxB,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,iBAAiB,MAAM;AAAA,UACvB,KAAK;AAAA,QACP;AAAA,MACF,GAAG,IACF;AACL,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,MAAM,2CAA2C;AAAA,MAC7D;AACA,UAAI,WAAW,SAAS,OAAO,UAAU;AACvC,cAAM,IAAI;AAAA,UACR,mCAAmC,QAAQ,gBACzC,WAAW,SAAS,MAAM,WAC5B;AAAA,QACF;AAAA,MACF;AACA,UAAI,WAAW,cAAc,WAAW,aAAa;AACnD,cAAM,IAAI,MAAM,uCAAuC;AAAA,MACzD;AAAA,IACF;AAAA,IACA,KAAK;AAAA,MACH,mBAAmB,CAAC,kBAAkB;AACpC,cAAM,cAAc,iBAAiB,MAAM;AAC3C,YAAI,gBAAgB,aAAa,aAAa,GAAG;AAC/C,gBAAM,IAAI;AAAA,YACR,yBAAyB,aAAa;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,WAAoB,cAAc,MAAM;AAClD;;;AC1WA,SAAS,WAAc,OAA0B;AAC/C,SAAO,gBAAgB,KAAK;AAC9B;AAEA,SAAS,sBACP,WACA,SACiB;AACjB,QAAM,QAAQ,IAAI,MAAM,WAAW,sBAAsB;AACzD,QAAM,OAAO;AACb,QAAM,YAAY;AAClB,SAAO;AACT;AAEA,SAAS,mBACP,OAC6B;AAC7B,UAAQ,SAAS,CAAC,GAAG,QAAQ,CAAC,UAAuC;AACnE,QAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO,CAAC;AACzD,UAAM,SAAS;AACf,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK,uBAAuB;AAC1B,cAAM,QACJ,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,OAChD,OAAO,QACR,CAAC;AACP,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,eAAe,OAAO,MAAM,iBAAiB,EAAE;AAAA,YAC/C,UAAU,OAAO,MAAM,YAAY,EAAE;AAAA,UACvC;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,cAAM,SACJ,OAAO,OAAO,WAAW,YAAY,OAAO,WAAW,OAClD,OAAO,SACR,CAAC;AACP,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,aAAa,OAAO,OAAO,QAAQ,OAAO,QAAQ,QAAQ;AAAA,UAC5D;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK;AACH,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,WAAW,OAAO,OAAO,aAAa,EAAE;AAAA,YACxC,YAAY,OAAO,OAAO,cAAc,EAAE;AAAA,UAC5C;AAAA,QACF;AAAA,MACF;AACE,eAAO,CAAC;AAAA,IACZ;AAAA,EACF,CAAC;AACH;AAEA,SAAS,cAAc,OAGrB;AACA,QAAM,OACJ,MAAM,QAGL,QAAQ,CAAC;AAIZ,SAAO;AAAA,IACL,cAAc,KAAK,gBAAgB;AAAA,IACnC,eAAe,MAAM,QAAQ,KAAK,aAAa,IAAI,KAAK,gBAAgB,CAAC;AAAA,EAC3E;AACF;AAEA,SAAS,iBAAiB,SAGb;AACX,MAAI,QAAQ,qBAAqB,QAAQ,kBAAkB,SAAS,GAAG;AACrE,WAAO,CAAC,GAAG,QAAQ,iBAAiB;AAAA,EACtC;AACA,SAAO,MAAM;AAAA,IACX,EAAE,QAAQ,QAAQ,UAAU,YAAY,QAAQ;AAAA,IAChD,CAAC,GAAG,UAAU,UAAU,QAAQ,CAAC;AAAA,EACnC;AACF;AAEA,SAAS,kBAAkB,OAA0C;AACnE,SAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,iBAAiB,SAOF;AACtB,QAAM,aAAa,QAAQ,OAAO,oBAAoB;AAAA,IACpD,OAAO,QAAQ;AAAA,IACf,WAAW,CAAC,QAAQ,QAAQ;AAAA,EAC9B,CAAC;AAED,QAAM,OAAO,cAAc,QAAQ,KAAK;AACxC,MAAI,QAAQ,iBAAiB,KAAK,iBAAiB,QAAQ,eAAe;AACxE,UAAM,IAAI;AAAA,MACR,kBAAkB,QAAQ,MAAM,qBAAqB,QAAQ,aAAa,gBACxE,KAAK,gBAAgB,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBACH,WAAW,qBAEM,CAAC;AACrB,QAAM,cAAc,CAClB,UAEC,QAAQ,CAAC,GACP,IAAI,CAAC,QAAQ,kBAAkB,GAAG,CAAC,EACnC;AAAA,IAAO,CAAC,eACP,QAAQ,UAAU;AAAA,EACpB;AAEJ,QAAM,OAAO,WAAW,QAAQ,QAAQ,QAAQ;AAChD,QAAM,QAAQ,OAAO;AAAA,IACnB,OAAO;AAAA,MACJ,MAAM,SAAiD,CAAC;AAAA,IAC3D,EAAE,IAAI,CAAC,CAAC,QAAQ,SAAS,MAAM;AAC7B,YAAM,OAAO,kBAAkB,SAAS,IAAI,YAAY,CAAC;AACzD,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,SAAS,CAAC,GAAI,KAAK,WAAW,CAAC,CAAE;AAAA,UACjC,eAAe,EAAE,GAAI,KAAK,iBAAiB,CAAC,EAAG;AAAA,UAC/C,kBAAkB,OAAO;AAAA,YACvB,OAAO,QAAQ,KAAK,oBAAoB,CAAC,CAAC,EAAE;AAAA,cAC1C,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,YAAY,IAAI,CAAC;AAAA,YAChD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,wBAAwB;AAAA,IAC5B,MAAM;AAAA,EACR;AACA,SAAO;AAAA,IACL,aAAa,QAAQ;AAAA,IACrB,kBAAkB,8BAA8B;AAAA,MAC9C,aAAa,QAAQ;AAAA,MACrB;AAAA,IACF,CAAC;AAAA,IACD,qBAAqB,QAAQ,YAAY;AAAA,IACzC,MAAM,MAAM,QAAQ;AAAA,IACpB,MAAM;AAAA,MACJ,cAAc,KAAK;AAAA,MACnB,cAAc,WAAW,gBAAgB;AAAA,MACzC,eAAe,KAAK;AAAA,MACpB,mBAAmB,WAAW,qBAAqB;AAAA,IACrD;AAAA,IACA;AAAA,IACA,cAAc,CAAC;AAAA,IACf;AAAA,EACF;AACF;AAEO,SAAS,kBACd,SACoB;AACpB,QAAM,YAAY,QAAQ,WAAW,QAAQ,MAAM;AACnD,MAAI,CAAC,WAAW;AACd,UAAM,IAAI,MAAM,sBAAsB,QAAQ,MAAM,IAAI;AAAA,EAC1D;AACA,QAAM,+BACJ,QAAQ,gCACR,UAAU,YAAY;AACxB,MACE,QAAQ,uBACR,gCACA,QAAQ,wBAAwB,8BAChC;AACA,UAAM,IAAI,2BAA2B;AAAA,MACnC,UAAU;AAAA,MACV,UAAU,QAAQ;AAAA,MAClB,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AAEA,MAAI,eAAe,WAAW,UAAU,QAAQ;AAChD,QAAM,YAAY,iBAAiB;AAAA,IACjC;AAAA,IACA,mBAAmB,QAAQ;AAAA,EAC7B,CAAC;AACD,QAAM,YAAY,QAAQ,aAAa;AACvC,QAAM,oBAA6C;AAAA,IACjD;AAAA,IACA,SAAS,UAAU,IAAI,CAAC,cAAc;AAAA,MACpC;AAAA,MACA,aAAa,QAAQ,wBAAwB,QAAQ,KAAK;AAAA,IAC5D,EAAE;AAAA,EACJ;AAEA,MAAI,UAAU;AACd,MAAI,oBAAoB;AACxB,QAAM,kBAAkB,UAAU,CAAC,KAAK;AACxC,QAAM,mBAA6C,CAAC;AACpD,MAAI,eAGO;AACX,QAAM,sBAAsB,CAC1B,WAC+B;AAAA,IAC/B,QAAQ;AAAA,IACR;AAAA,IACA,qBAAqB,MAAM;AAAA,EAC7B;AAEA,MAAI;AACJ,MAAI;AAEJ,QAAM,oBAAoB,MAAY;AACpC,eAAW;AACX,sBAAkB,iBAAiB;AAAA,MACjC,OAAO;AAAA,MACP,QAAQ,QAAQ;AAAA,MAChB,UAAU;AAAA,MACV;AAAA,MACA,eAAe,YAAY,IAAI,QAAQ,QAAQ;AAAA,MAC/C,QAAQ,QAAQ;AAAA,IAClB,CAAC;AACD,uBAAmB,oBAAoB,eAAe;AAAA,EACxD;AAEA,oBAAkB;AAElB,QAAM,WAAW,OACf,UACA,eACA,SAAkB,CAAC,MACW;AAC9B,UAAM,SAAS,MAAM,QAAQ,OAAO,cAAc;AAAA,MAChD,OAAO;AAAA,MACP,OAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO;AAAA,MACL,OAAO,OAAO;AAAA,MACd,WAAW,OAAO;AAAA,MAClB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF;AAEA,QAAM,SAAS,OACb,UACA,eACA,SAAkB,CAAC,MACD;AAClB,yBAAqB;AACrB,UAAM,eAAe,OAAO,iBAAiB;AAC7C,qBAAiB,KAAK;AAAA,MACpB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,cAAc,YAAY,EAAE,gBAAgB;AAAA,IACrD,CAAC;AACD,UAAM,aAAa,MAAM,SAAS,UAAU,eAAe,MAAM;AACjE,QAAI,CAAC,WAAW,OAAO;AACrB,uBAAiB,KAAK;AAAA,QACpB,MAAM;AAAA,QACN;AAAA,QACA,WAAW,WAAW,aAAa;AAAA,QACnC,GAAI,WAAW,UAAU,EAAE,SAAS,WAAW,QAAQ,IAAI,CAAC;AAAA,MAC9D,CAAC;AACD,YAAM,sBAAsB,WAAW,WAAW,WAAW,OAAO;AAAA,IACtE;AACA,UAAM,SAAS,MAAM,QAAQ,OAAO,SAAS;AAAA,MAC3C,OAAO;AAAA,MACP,OAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AACD,QAAI,OAAO,SAAS,UAAU;AAC5B,uBAAiB,KAAK;AAAA,QACpB,MAAM;AAAA,QACN;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,MACtD,CAAC;AACD,YAAM,sBAAsB,OAAO,WAAW,OAAO,OAAO;AAAA,IAC9D;AACA,UAAM,QAAQ,mBAAmB,OAAO,KAAK;AAC7C,mBAAe,EAAE,cAAc,MAAM;AACrC,qBAAiB,KAAK;AAAA,MACpB,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF,CAAC;AACD,mBAAe,WAAW,OAAO,KAAK;AACtC,sBAAkB;AAAA,EACpB;AAEA,QAAM,UAAU,CACd,UACA,kBAC+B;AAC/B,QAAI,CAAC,QAAQ,OAAO,oBAAoB;AACtC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO,QAAQ,OAAO,mBAAmB;AAAA,MACvC,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,UAAU;AAAA,IACd,qBAAqB,CAAC,eAAuB,WAC3C,SAAS,iBAAiB,eAAe,MAAM;AAAA,IACjD,mBAAmB,CAAC,eAAuB,WACzC,OAAO,iBAAiB,eAAe,MAAM;AAAA,IAC/C,iBAAiB,MAAiC;AAAA,IAClD,YAAY,MAAM;AAAA,EACpB;AAEA,SAAO;AAAA,IACL;AAAA,IACA,UAAU,MAAM;AAAA,IAChB,sBAAsB,MAAM;AAAA,IAC5B,SAAS,MAAM,CAAC,GAAG,SAAS;AAAA,IAC5B,MAAM,CAAC,UAAkB;AACvB,UAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,KAAK,SAAS,UAAU,QAAQ;AACtE,cAAM,IAAI;AAAA,UACR,QAAQ,KAAK,4BAA4B,QAAQ,MAAM,SAAS,UAAU,MAAM;AAAA,QAClF;AAAA,MACF;AACA,aAAO,UAAU,KAAK;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,MACX,IAAI,SAAS;AACX,eAAO;AAAA,MACT;AAAA,MACA,IAAI,eAAe;AACjB,eAAO;AAAA,MACT;AAAA,MACA,QAAQ;AACN,yBAAiB,SAAS;AAC1B,uBAAe;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/authoring/generated-metadata.ts
|
|
2
2
|
var GENERATED_AUTHORING_METADATA = {
|
|
3
|
-
sdkVersion: "0.4.0-alpha.
|
|
3
|
+
sdkVersion: "0.4.0-alpha.7",
|
|
4
4
|
codegenVersion: "0.3.0-alpha.0",
|
|
5
5
|
manifestSchemaVersion: 2,
|
|
6
6
|
generatedArtifactSchemaVersion: 1
|
|
@@ -9,4 +9,4 @@ var GENERATED_AUTHORING_METADATA = {
|
|
|
9
9
|
export {
|
|
10
10
|
GENERATED_AUTHORING_METADATA
|
|
11
11
|
};
|
|
12
|
-
//# sourceMappingURL=chunk-
|
|
12
|
+
//# sourceMappingURL=chunk-KYEWGZ2Y.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/authoring/generated-metadata.ts"],"sourcesContent":["// Generated by scripts/generate-authoring-metadata.mjs. Do not edit by hand.\nimport type { GeneratedAuthoringMetadataV1 } from \"./types.js\";\n\nexport const GENERATED_AUTHORING_METADATA = {\n sdkVersion: \"0.4.0-alpha.
|
|
1
|
+
{"version":3,"sources":["../src/authoring/generated-metadata.ts"],"sourcesContent":["// Generated by scripts/generate-authoring-metadata.mjs. Do not edit by hand.\nimport type { GeneratedAuthoringMetadataV1 } from \"./types.js\";\n\nexport const GENERATED_AUTHORING_METADATA = {\n sdkVersion: \"0.4.0-alpha.7\",\n codegenVersion: \"0.3.0-alpha.0\",\n manifestSchemaVersion: 2,\n generatedArtifactSchemaVersion: 1,\n} as const satisfies GeneratedAuthoringMetadataV1;\n"],"mappings":";AAGO,IAAM,+BAA+B;AAAA,EAC1C,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,uBAAuB;AAAA,EACvB,gCAAgC;AAClC;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GENERATED_AUTHORING_METADATA
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-KYEWGZ2Y.js";
|
|
4
4
|
|
|
5
5
|
// src/package-set.ts
|
|
6
6
|
var DREAMBOARD_SDK_VERSION = GENERATED_AUTHORING_METADATA.sdkVersion;
|
|
@@ -18,4 +18,4 @@ export {
|
|
|
18
18
|
DREAMBOARD_SDK_PACKAGES,
|
|
19
19
|
DREAMBOARD_SDK_PACKAGE_SET
|
|
20
20
|
};
|
|
21
|
-
//# sourceMappingURL=chunk-
|
|
21
|
+
//# sourceMappingURL=chunk-NO537WSS.js.map
|
|
@@ -16,7 +16,10 @@ import {
|
|
|
16
16
|
isInteractionAvailable,
|
|
17
17
|
useResolvedCardTargetValue,
|
|
18
18
|
useZoneCards
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-RKGJ64UN.js";
|
|
20
|
+
import {
|
|
21
|
+
useAuthoredPluginGameplayFrameSelector
|
|
22
|
+
} from "./chunk-VLG4YST5.js";
|
|
20
23
|
import {
|
|
21
24
|
CardFace,
|
|
22
25
|
Dialog,
|
|
@@ -31,9 +34,6 @@ import {
|
|
|
31
34
|
useIsMobile,
|
|
32
35
|
useRegisterMobileHand
|
|
33
36
|
} from "./chunk-2TRZSZGD.js";
|
|
34
|
-
import {
|
|
35
|
-
useAuthoredPluginGameplayFrameSelector
|
|
36
|
-
} from "./chunk-UUQNOGZV.js";
|
|
37
37
|
|
|
38
38
|
// src/runtime/workspace-contract/index.ts
|
|
39
39
|
import { Fragment, createElement as createElement6 } from "react";
|
|
@@ -666,7 +666,12 @@ function createZoneCardComponent(ctx) {
|
|
|
666
666
|
});
|
|
667
667
|
const match = useAuthoredPluginGameplayFrameSelector((frame) => {
|
|
668
668
|
const candidates = frame.zones[zone]?.playableByCardId[cardId] ?? [];
|
|
669
|
-
|
|
669
|
+
const orderedCandidates = [...candidates].sort((left, right) => {
|
|
670
|
+
const leftAvailable = left.availability.status === "available";
|
|
671
|
+
const rightAvailable = right.availability.status === "available";
|
|
672
|
+
return leftAvailable === rightAvailable ? 0 : leftAvailable ? -1 : 1;
|
|
673
|
+
});
|
|
674
|
+
for (const descriptor of orderedCandidates) {
|
|
670
675
|
const input = descriptor.inputs.find(
|
|
671
676
|
(candidateInput) => candidateInput.domain.type === "cardTarget" && candidateInput.domain.projection === "resolved" && candidateInput.domain.eligibleTargets.includes(cardId)
|
|
672
677
|
);
|
|
@@ -869,4 +874,4 @@ function createWorkspaceUIContract(options) {
|
|
|
869
874
|
export {
|
|
870
875
|
createWorkspaceUIContract
|
|
871
876
|
};
|
|
872
|
-
//# sourceMappingURL=chunk-
|
|
877
|
+
//# sourceMappingURL=chunk-Q322XCY2.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/workspace-contract/index.ts","../src/runtime/ui-contract.ts","../src/runtime/workspace-contract/board.ts","../src/runtime/workspace-contract/slots.ts","../src/runtime/workspace-contract/forms.ts","../src/runtime/workspace-contract/surfaces.ts","../src/runtime/workspace-contract/zones.ts","../src/runtime/workspace-contract/hand.ts"],"sourcesContent":["import { Fragment, createElement } from \"react\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport {\n ClientParamSchemaProvider,\n type ClientParamSchemaMap,\n} from \"../context/ClientParamSchemaContext.js\";\nimport {\n createResourceCounter,\n type ResourceCounterComponents,\n type ResourceDisplayConfig,\n} from \"../../ui.js\";\nimport { MobileHandTrayProvider } from \"../../ui/components.js\";\nimport { ToastProvider } from \"../../ui.js\";\nimport {\n createDreamboardUI,\n type DreamboardUI,\n type TypedGame,\n type UIContract,\n} from \"../ui-contract.js\";\nimport type {\n BoardGridInteractionFilter,\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridInteractionFilter,\n BoardSquareGridProps,\n InteractionDialogProps,\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n GameMeState,\n GamePlayersState,\n GameRenderState,\n GameTurnState,\n UIRootProps,\n ZoneCardRenderItem,\n} from \"../primitives/index.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport type {\n RuntimeBoard,\n RuntimeInteraction,\n RuntimeZone,\n WorkspaceContractContext,\n WorkspaceContractOptions,\n} from \"./types.js\";\nimport { createBoardNamespace } from \"./board.js\";\nimport { createInteractionForms } from \"./forms.js\";\nexport type { WorkspaceInteractionFormDialogProps } from \"./forms.js\";\nimport { createSurfaceResolvers } from \"./surfaces.js\";\nimport { createZoneNamespace } from \"./zones.js\";\n\nexport type { BoardSpaceTargetProps } from \"../primitives/board.js\";\nexport type { HandRole } from \"../../ui/components.js\";\nexport type {\n WorkspaceInteractionSlotComponent,\n WorkspaceFormInputSlot,\n WorkspaceCardInputSlot,\n WorkspaceBoardTargetInputSlot,\n WorkspaceBoardSurface,\n WorkspaceZoneCardsComponent,\n WorkspaceZoneCardComponent,\n WorkspaceZoneStagingComponent,\n WorkspaceHandSurface,\n WorkspaceHandOptions,\n WorkspacePileSurface,\n WorkspaceCardCollectionSurface,\n WorkspaceBoardSurfaceDescriptor,\n WorkspaceHandSurfaceDescriptor,\n WorkspacePileSurfaceDescriptor,\n WorkspacePilesSurfaceDescriptor,\n WorkspaceCardCollectionSurfaceDescriptor,\n WorkspaceInteractionFormsDescriptor,\n WorkspaceInteractionFormDescriptor,\n WorkspaceSurfaceDescriptor,\n WorkspaceSurfaceSpec,\n WorkspaceContractOptions,\n} from \"./types.js\";\n\nexport interface DefineGameUIConfig<GameState, Surfaces> {\n useSurfaces: () => Surfaces;\n interactionRoutes?: (context: {\n game: GameState;\n surfaces: Surfaces;\n }) => Record<string, { collect: Record<string, unknown> }>;\n phases: Record<\n string,\n (context: { game: GameState; surfaces: Surfaces }) => ReactNode\n >;\n renderInteractions?: (context: {\n game: GameState;\n surfaces: Surfaces;\n }) => ReactNode;\n fallback?: ReactNode | ((phase: string | null) => ReactNode);\n includeUnavailableInteractions?: boolean | null;\n}\n\nexport function createWorkspaceUIContract<\n WorkspaceUI,\n Contract extends UIContract,\n Resource extends string,\n Card,\n HexBoards extends Record<string, unknown>,\n SquareBoards extends Record<string, unknown> = Record<string, unknown>,\n>(\n options: WorkspaceContractOptions<\n Contract,\n Resource,\n Card,\n HexBoards,\n SquareBoards\n >,\n): WorkspaceUI {\n const baseUI = createDreamboardUI(options.uiContract);\n const runtimeInteraction = baseUI.Interaction as RuntimeInteraction;\n const runtimeBoard = baseUI.Board as RuntimeBoard;\n const runtimeZone = baseUI.Zone as RuntimeZone<Card>;\n const runtimeGameRoot = baseUI.Game.Root as ComponentType<{\n children: (game: unknown) => ReactNode;\n }>;\n const runtimePhaseSwitch = baseUI.Phase.Switch as ComponentType<{\n routes: Record<string, () => ReactNode>;\n fallback?: ReactNode | ((phase: string | null) => ReactNode);\n }>;\n\n const ctx: WorkspaceContractContext<Card> = {\n options,\n // The context carries the contract-erased view of the UI: every consumer\n // already neutralizes key genericity (`as never` inputs/zones), exactly as\n // the original single-file factory did with its `Runtime*` casts.\n baseUI: baseUI as unknown as DreamboardUI,\n runtimeInteraction,\n runtimeBoard,\n runtimeZone,\n withInteractionRoot: (interaction: string, children: ReactNode) =>\n createElement(runtimeInteraction.Root, {\n interaction,\n children,\n }),\n };\n\n const resourceDisplayConfig = options.resourceIds.map((resource) => {\n const presentation = options.resourcePresentationById?.[resource];\n return {\n type: resource,\n label: presentation?.label ?? resource,\n icon: presentation?.icon ?? resource,\n };\n }) satisfies ReadonlyArray<ResourceDisplayConfig<Resource>>;\n const resourceCounter = createResourceCounter<Resource>(\n resourceDisplayConfig,\n );\n\n const { Interaction, useInteractionFormSurface } =\n createInteractionForms(ctx);\n const Board = createBoardNamespace(ctx);\n const Zone = createZoneNamespace(ctx);\n const { defineSurfaces } = createSurfaceResolvers({\n Board,\n Zone,\n useInteractionFormSurface,\n });\n\n const UI = {\n ...baseUI,\n Root: ({ children, ...props }: UIRootProps) =>\n createElement(ClientParamSchemaProvider, {\n schemas: options.clientParamSchemasByPhase,\n children: createElement(ToastProvider, {\n children: createElement(MobileHandTrayProvider, {\n children: createElement(baseUI.Root, { ...props, children }),\n }),\n }),\n }),\n defineSurfaces,\n defineGameUI<GameState, Surfaces>({\n useSurfaces,\n interactionRoutes,\n phases,\n renderInteractions,\n fallback,\n includeUnavailableInteractions,\n }: DefineGameUIConfig<GameState, Surfaces>) {\n function DefinedGameUIFrame({ game }: { game: GameState }) {\n const surfaces = useSurfaces();\n const phaseRoutes = Object.fromEntries(\n Object.entries(phases).map(([phase, render]) => [\n phase,\n () => render({ game, surfaces }),\n ]),\n );\n const routeMap = interactionRoutes?.({ game, surfaces });\n return createElement(\n Fragment,\n null,\n routeMap\n ? createElement(runtimeInteraction.Routes, {\n routes: routeMap,\n includeUnavailable: includeUnavailableInteractions,\n })\n : null,\n createElement(runtimePhaseSwitch, {\n routes: phaseRoutes,\n fallback,\n }),\n renderInteractions?.({ game, surfaces }) ?? null,\n );\n }\n\n return function DefinedGameUI(props: Omit<UIRootProps, \"children\">) {\n return createElement(UI.Root, {\n ...props,\n children: createElement(runtimeGameRoot, {\n children: (rawGame: unknown) =>\n createElement(DefinedGameUIFrame, {\n game: rawGame as GameState,\n }),\n }),\n });\n };\n },\n Interaction,\n Board,\n Zone,\n ResourceCounter: resourceCounter,\n };\n\n return UI as WorkspaceUI;\n}\n\nexport type {\n BoardGridInteractionFilter,\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridInteractionFilter,\n BoardSquareGridProps,\n ClientParamSchemaMap,\n DreamboardUI,\n GameMeState,\n GamePlayersState,\n GameRenderState,\n GameTurnState,\n InteractionDialogProps,\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n ResourceCounterComponents,\n TypedGame,\n UIContract,\n UIRootProps,\n ZoneCardRenderItem,\n ZoneListProps,\n};\n","import type {\n ButtonHTMLAttributes,\n ComponentType,\n ReactElement,\n ReactNode,\n} from \"react\";\nimport {\n Board as BoardPrimitive,\n Dice as DicePrimitive,\n Game as GamePrimitive,\n Interaction as InteractionPrimitive,\n Phase as PhasePrimitive,\n PlayerRoster as PlayerRosterPrimitive,\n Prompt as PromptPrimitive,\n PromptInbox as PromptInboxPrimitive,\n UI as UIPrimitive,\n Zone as ZonePrimitive,\n type BoardHexGridProps,\n type BoardHexGridInteractionFilter,\n type BoardSquareGridProps,\n type BoardSquareGridInteractionFilter,\n type BoardTargetProps,\n type BoardSpaceTargetProps,\n type BoardEdgeTargetProps,\n type BoardVertexTargetProps,\n type GameChromeProps,\n type DiceComponents,\n type GameRootProps,\n type InteractionCardInputProps,\n type InteractionDialogProps,\n type InteractionFieldPrimitiveProps,\n type InteractionFormPrimitiveProps,\n type InteractionRoutesMap,\n type InteractionRoutesProps,\n type InteractionRootProps,\n type InteractionSwitchRouteMap,\n type InteractionSwitchProps,\n type PhaseSwitchProps,\n type PlayerRosterComponents,\n type PlayerRosterBadge,\n type PlayerRosterEntry,\n type PlayerRosterListProps,\n type PlayerRosterPartProps,\n type PlayerRosterRootProps,\n type PromptDialogProps,\n type PromptInboxItemsProps,\n type PromptOptionRenderItem,\n type PromptOptionProps,\n type PromptOptionsProps,\n type PromptRootProps,\n type UIRootProps,\n type ZoneItemProps,\n type ZoneCardAtProps,\n type ZoneCardActionProps,\n type ZoneCardRenderItem,\n type ZoneListProps,\n type ZonePileCardsProps,\n type ZonePileRootProps,\n type ZoneRootProps,\n} from \"./primitives/index.js\";\nimport type { InteractionDescriptor } from \"./types/plugin-state.js\";\nimport type {\n AnyHexBoardInput,\n AnySquareBoardInput,\n BoardSpaceIdOf,\n} from \"../ui.js\";\n\n/**\n * Workspace-aware UI typing extension point.\n *\n * Generated workspaces will augment this interface with their concrete UI\n * contract. The unregistered SDK keeps all public keys string-compatible so\n * package-local tests and generic consumers can still import ui-sdk directly.\n */\nexport interface DreamboardUIRegister {\n readonly __dreamboardUIRegister?: never;\n}\n\nexport type UIContractBucket = Record<string, unknown>;\n\nexport interface UIContract {\n interactions?: UIContractBucket;\n inputs?: UIContractBucket;\n prompts?: UIContractBucket;\n promptOptions?: UIContractBucket;\n players?: UIContractBucket;\n zones?: UIContractBucket;\n cards?: UIContractBucket;\n phases?: UIContractBucket;\n boardTargets?: UIContractBucket;\n}\n\ntype RegisteredUIContract = DreamboardUIRegister extends {\n ui: infer Registered extends UIContract;\n}\n ? Registered\n : UIContract;\n\ntype BucketOf<Contract extends UIContract, Key extends keyof UIContract> =\n NonNullable<Contract[Key]> extends UIContractBucket\n ? NonNullable<Contract[Key]>\n : UIContractBucket;\n\ntype StringKeyOf<Bucket extends UIContractBucket> = Extract<\n keyof Bucket,\n string\n>;\n\ntype StringKeysOrFallback<Bucket extends UIContractBucket> = [\n StringKeyOf<Bucket>,\n] extends [never]\n ? string\n : string extends StringKeyOf<Bucket>\n ? string\n : StringKeyOf<Bucket>;\n\nexport type RegisteredUI = RegisteredUIContract;\n\nexport type InteractionKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"interactions\">>;\n\nexport type InteractionInputKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"inputs\">>;\n\nexport type PromptKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"prompts\">>;\n\nexport type PromptOptionKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"promptOptions\">>;\n\nexport type PlayerKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"players\">>;\n\nexport type ZoneKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"zones\">>;\n\nexport type CardKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"cards\">>;\n\nexport type PhaseKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"phases\">>;\n\nexport type BoardTargetKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"boardTargets\">>;\n\ntype TypedZoneCardRenderItem<Contract extends UIContract> =\n ZoneCardRenderItem<CardKey<Contract> & string> extends infer Item\n ? Item extends { id: string; zone: string }\n ? Omit<Item, \"id\" | \"zone\"> & {\n id: CardKey<Contract>;\n zone: ZoneKey<Contract>;\n }\n : never\n : never;\n\nexport type TypedInteraction<Contract extends UIContract> = Omit<\n typeof InteractionPrimitive,\n \"Root\" | \"CardInput\" | \"Dialog\" | \"Field\" | \"Form\" | \"Switch\"\n> & {\n Root<Interaction extends InteractionKey<Contract>>(\n props: InteractionRootProps<Interaction>,\n ): ReactElement | null;\n Switch(\n props: Omit<InteractionSwitchProps<InteractionKey<Contract>>, \"routes\"> & {\n routes: InteractionSwitchRouteMap<InteractionKey<Contract>>;\n },\n ): ReactElement;\n Routes(\n props: Omit<InteractionRoutesProps<InteractionKey<Contract>>, \"routes\"> & {\n routes: InteractionRoutesMap<InteractionKey<Contract>>;\n },\n ): ReactElement;\n CardInput<Input extends InteractionInputKey<Contract>>(\n props: Omit<InteractionCardInputProps, \"input\" | \"unsafeCardId\"> & {\n input: Input;\n unsafeCardId?: CardKey<Contract>;\n },\n ): ReactElement;\n Dialog<Interaction extends InteractionKey<Contract>>(\n props: InteractionDialogProps<Interaction>,\n ): ReactElement;\n Field<Input extends InteractionInputKey<Contract>>(\n props: Omit<InteractionFieldPrimitiveProps, \"input\"> & { input: Input },\n ): ReactElement | null;\n Form(props: InteractionFormPrimitiveProps): ReactElement | null;\n};\n\nexport type InteractionSlotComponent<Props = object> = ComponentType<\n Props extends { children: unknown } ? Props : Props & { children?: ReactNode }\n>;\n\nexport interface InteractionDefaultInputSlot {\n readonly Default: InteractionSlotComponent;\n}\n\nexport interface InteractionValueInputSlot<Value = unknown> {\n readonly Value: InteractionSlotComponent<{\n children: (value: Value | undefined) => ReactNode;\n }>;\n}\n\nexport interface InteractionChoiceInputSlot<Value = unknown> {\n readonly Field: InteractionSlotComponent;\n readonly Options: InteractionSlotComponent<{\n children: (option: { value: Value; label: string }) => ReactNode;\n }>;\n}\n\nexport interface InteractionChoiceListInputSlot<Value = unknown> {\n readonly Field: InteractionSlotComponent;\n readonly Options: InteractionSlotComponent<{\n children: (option: { value: Value; label: string }) => ReactNode;\n }>;\n}\n\nexport interface InteractionNumberInputSlot {\n readonly Field: InteractionSlotComponent;\n}\n\nexport interface InteractionResourceMapInputSlot<\n Resource extends string = string,\n> {\n readonly Field: InteractionSlotComponent;\n readonly Resource: InteractionSlotComponent<{ value: Resource }>;\n}\n\nexport type InteractionFormInputSlot<Value = unknown> =\n | InteractionChoiceInputSlot<Value>\n | InteractionChoiceListInputSlot<Value>\n | InteractionNumberInputSlot\n | InteractionResourceMapInputSlot;\n\nexport interface InteractionCardTargetInputSlot<Card extends string = string> {\n readonly Card: InteractionSlotComponent<\n { value: Card } & Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | \"children\"\n | \"disabled\"\n | \"aria-disabled\"\n | \"aria-pressed\"\n | \"onClick\"\n | \"type\"\n | \"value\"\n >\n >;\n readonly Cards: InteractionSlotComponent<{\n children: (card: { id: Card }) => ReactNode;\n }>;\n}\n\nexport interface InteractionBoardTargetInputSlot<\n Target extends string = string,\n> {\n readonly Target: InteractionSlotComponent<\n { value: Target } & Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | \"children\"\n | \"disabled\"\n | \"aria-disabled\"\n | \"aria-pressed\"\n | \"onClick\"\n | \"type\"\n | \"value\"\n >\n >;\n}\n\nexport type InteractionBoardSpaceTargetInputSlot<\n Space extends string = string,\n> = InteractionBoardTargetInputSlot<Space>;\n\nexport type InteractionBoardEdgeTargetInputSlot<Edge extends string = string> =\n InteractionBoardTargetInputSlot<Edge>;\n\nexport type InteractionBoardVertexTargetInputSlot<\n Vertex extends string = string,\n> = InteractionBoardTargetInputSlot<Vertex>;\n\nexport type InteractionBoardTileTargetInputSlot<Tile extends string = string> =\n InteractionBoardTargetInputSlot<Tile>;\n\nexport interface InteractionSubmitSlot {\n readonly Button: InteractionSlotComponent<\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"disabled\" | \"type\" | \"value\"\n >\n >;\n}\n\nexport type TypedPrompt<Contract extends UIContract> = Omit<\n typeof PromptPrimitive,\n \"Root\" | \"Option\" | \"Options\" | \"Dialog\"\n> & {\n Root<Prompt extends PromptKey<Contract>>(\n props: PromptRootProps<Prompt>,\n ): ReactElement | null;\n Option<Option extends PromptOptionKey<Contract>>(\n props: Omit<PromptOptionProps, \"value\"> & { value: Option },\n ): ReactElement;\n Options(\n props: Omit<PromptOptionsProps, \"children\"> & {\n children: (\n option: Omit<PromptOptionRenderItem, \"id\"> & {\n id: PromptOptionKey<Contract>;\n },\n ) => ReactNode;\n },\n ): ReactElement;\n Dialog<Prompt extends PromptKey<Contract>>(\n props: PromptDialogProps<Prompt>,\n ): ReactElement;\n};\n\nexport type TypedPromptInbox<Contract extends UIContract> = Omit<\n typeof PromptInboxPrimitive,\n \"Items\"\n> & {\n Items(\n props: Omit<PromptInboxItemsProps, \"children\"> & {\n children: (\n prompt: Omit<InteractionDescriptor, \"interactionKey\"> & {\n interactionKey: PromptKey<Contract>;\n },\n ) => ReactNode;\n },\n ): ReactElement;\n};\n\ntype TypedPlayerRosterEntry<Player extends string> = Omit<\n PlayerRosterEntry,\n \"playerId\"\n> & {\n playerId: Player;\n};\n\ntype TypedPlayerRosterRootProps<Player extends string> = Omit<\n PlayerRosterRootProps,\n \"score\" | \"scoreLabel\" | \"badges\" | \"metadata\"\n> & {\n score?: (playerId: Player) => number | undefined;\n scoreLabel?: string | ((playerId: Player) => string | undefined);\n badges?: (\n playerId: Player,\n ) => ReadonlyArray<PlayerRosterBadge | null | false | undefined>;\n metadata?: (playerId: Player) => Record<string, unknown> | undefined;\n};\n\ntype TypedPlayerRosterListProps<Player extends string> = Omit<\n PlayerRosterListProps,\n \"children\"\n> & {\n children?: (player: TypedPlayerRosterEntry<Player>) => ReactNode;\n};\n\ntype TypedPlayerRosterPartProps<Player extends string> = Omit<\n PlayerRosterPartProps,\n \"player\"\n> & {\n player: TypedPlayerRosterEntry<Player>;\n};\n\nexport type TypedPlayerRoster<Contract extends UIContract> = Omit<\n PlayerRosterComponents,\n \"Root\" | \"List\" | \"Name\" | \"Score\" | \"Badges\"\n> & {\n Root(\n props: TypedPlayerRosterRootProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n List(props: TypedPlayerRosterListProps<PlayerKey<Contract>>): ReactElement;\n Name(props: TypedPlayerRosterPartProps<PlayerKey<Contract>>): ReactElement;\n Score(\n props: TypedPlayerRosterPartProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n Badges(\n props: TypedPlayerRosterPartProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n};\n\nexport type TypedPhase<Contract extends UIContract> = Omit<\n typeof PhasePrimitive,\n \"Switch\"\n> & {\n Switch(props: PhaseSwitchProps<PhaseKey<Contract>>): ReactElement | null;\n};\n\nexport type TypedZone<Contract extends UIContract> = Omit<\n typeof ZonePrimitive,\n | \"Root\"\n | \"Item\"\n | \"CardAt\"\n | \"TopCard\"\n | \"CardAction\"\n | \"List\"\n | \"PileRoot\"\n | \"PileCards\"\n> & {\n Root<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneRootProps, \"zone\"> & { zone: Zone },\n ): ReactElement;\n Item<Card extends CardKey<Contract>>(\n props: Omit<ZoneItemProps, \"card\"> & { card: Card },\n ): ReactElement;\n CardAction<Card extends CardKey<Contract>>(\n props: Omit<ZoneCardActionProps, \"card\"> & { card?: Card },\n ): ReactElement;\n CardAt<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneCardAtProps<Zone>, \"zone\" | \"children\"> & {\n zone?: Zone;\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement | null;\n TopCard<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneCardAtProps<Zone>, \"zone\" | \"index\" | \"children\"> & {\n zone?: Zone;\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement | null;\n List(\n props: Omit<ZoneListProps, \"children\"> & {\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement;\n PileRoot<Zone extends ZoneKey<Contract>>(\n props: Omit<ZonePileRootProps<Zone>, \"zone\"> & {\n zone: Zone;\n },\n ): ReactElement;\n PileCards(\n props: Omit<ZonePileCardsProps, \"renderCard\"> & {\n renderCard: (card: TypedZoneCardRenderItem<Contract>) => ReactNode;\n },\n ): ReactElement | null;\n};\n\nexport type TypedBoard<Contract extends UIContract> = Omit<\n typeof BoardPrimitive,\n | \"Target\"\n | \"SpaceTarget\"\n | \"EdgeTarget\"\n | \"VertexTarget\"\n | \"HexGrid\"\n | \"SquareGrid\"\n> & {\n Target<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n SpaceTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardSpaceTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n EdgeTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardEdgeTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n VertexTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardVertexTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n HexGrid<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n >(\n props: Omit<BoardHexGridProps<TBoard, TSpaceView>, \"interactions\"> & {\n interactions?:\n | Exclude<BoardHexGridInteractionFilter, object>\n | {\n edge?: ReadonlyArray<InteractionKey<Contract>>;\n vertex?: ReadonlyArray<InteractionKey<Contract>>;\n space?: ReadonlyArray<InteractionKey<Contract>>;\n };\n },\n ): ReactElement;\n SquareGrid<TBoard extends AnySquareBoardInput>(\n props: Omit<BoardSquareGridProps<TBoard>, \"interactions\"> & {\n interactions?:\n | Exclude<BoardSquareGridInteractionFilter, object>\n | {\n edge?: ReadonlyArray<InteractionKey<Contract>>;\n vertex?: ReadonlyArray<InteractionKey<Contract>>;\n space?: ReadonlyArray<InteractionKey<Contract>>;\n };\n },\n ): ReactElement;\n};\n\nexport type TypedGame<\n _Contract extends UIContract,\n View = unknown,\n Player extends string = PlayerKey<_Contract>,\n Phase extends string = PhaseKey<_Contract>,\n> = Omit<typeof GamePrimitive, \"Root\"> & {\n Root(props: GameRootProps<View, Player, Phase>): ReactElement;\n Chrome(\n props: GameChromeProps<View, Player, Phase, InteractionKey<_Contract>>,\n ): ReactElement;\n};\n\nexport interface DreamboardUI<Contract extends UIContract = RegisteredUI> {\n readonly contract: Contract;\n Root(props: UIRootProps): ReactElement;\n readonly Game: TypedGame<Contract>;\n readonly Interaction: TypedInteraction<Contract>;\n readonly Prompt: TypedPrompt<Contract>;\n readonly PromptInbox: TypedPromptInbox<Contract>;\n readonly PlayerRoster: TypedPlayerRoster<Contract>;\n readonly Dice: DiceComponents;\n readonly Phase: TypedPhase<Contract>;\n readonly Zone: TypedZone<Contract>;\n readonly Board: TypedBoard<Contract>;\n}\n\nexport function createDreamboardUI<const Contract extends UIContract>(\n contract: Contract,\n): DreamboardUI<Contract> {\n return {\n contract,\n Root: UIPrimitive.Root,\n Game: GamePrimitive,\n Interaction: InteractionPrimitive,\n Prompt: PromptPrimitive,\n PromptInbox: PromptInboxPrimitive,\n PlayerRoster: PlayerRosterPrimitive,\n Dice: DicePrimitive,\n Phase: PhasePrimitive,\n Zone: ZonePrimitive,\n Board: BoardPrimitive,\n } as DreamboardUI<Contract>;\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport type {\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridProps,\n} from \"../primitives/index.js\";\nimport type { BoardSpaceTargetProps } from \"../primitives/board.js\";\nimport { createBoardTargetInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceBoardSurfaceDescriptor,\n WorkspaceContractContext,\n} from \"./types.js\";\n\nexport function createUseBoardSurface<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { baseUI, runtimeBoard } = ctx;\n return function useBoardSurface() {\n return {\n Root: ({ children }: { children?: ReactNode }) =>\n createElement(baseUI.Board.Root, { children }),\n Space: (props: BoardSpaceTargetProps<string>) =>\n createElement(runtimeBoard.SpaceTarget, props),\n slot: {\n space: createBoardTargetInputSlot(ctx, \"space\"),\n playerSpace: createBoardTargetInputSlot(ctx, \"space\"),\n edge: createBoardTargetInputSlot(ctx, \"edge\"),\n vertex: createBoardTargetInputSlot(ctx, \"vertex\"),\n tile: createBoardTargetInputSlot(ctx, \"tile\"),\n },\n };\n };\n}\n\n/**\n * Assembles the `Board` namespace for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation so `HexView`/`HexGrid` keep stable\n * component identities.\n */\nexport function createBoardNamespace<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI } = ctx;\n const useBoardSurface = createUseBoardSurface(ctx);\n\n return {\n surface<Board extends string>(\n board: Board,\n ): WorkspaceBoardSurfaceDescriptor<Board> {\n return { kind: \"board\", board };\n },\n useSurface: useBoardSurface,\n HexView({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.HexView as never,\n {\n ...props,\n board: options.hexStaticBoards[boardId],\n } as BoardHexViewProps<never, never>,\n ) as ReactElement;\n },\n HexGrid({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.HexGrid as never,\n {\n ...props,\n board: options.hexStaticBoards[boardId],\n } as BoardHexGridProps<never, never>,\n ) as ReactElement;\n },\n SquareGrid({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.SquareGrid as never,\n {\n ...props,\n board: options.squareStaticBoards?.[boardId],\n } as BoardSquareGridProps<never>,\n ) as ReactElement;\n },\n };\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { Fragment as ReactFragment, createElement } from \"react\";\nimport { useResolvedCardTargetValue } from \"../primitives/index.js\";\nimport type {\n WorkspaceBoardTargetInputSlot,\n WorkspaceCardInputSlot,\n WorkspaceContractContext,\n WorkspaceFormInputSlot,\n} from \"./types.js\";\n\n/**\n * Render-prop body for the card surface `slot.card.Value`. Surfaces the live\n * draft value for the active interaction's card-target input — the selected\n * card-id array for `selection: \"many\"` collectors, or the single id for\n * `selection: \"one\"`. Renders nothing meaningful (`undefined`) outside an\n * `<Interaction.Root>`.\n */\nfunction CardSlotValue({\n children,\n}: {\n children: (value: unknown | undefined) => ReactNode;\n}): ReactElement {\n const value = useResolvedCardTargetValue();\n return createElement(ReactFragment, null, children(value));\n}\n\nexport function createFormInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n input: string,\n interaction?: string,\n): WorkspaceFormInputSlot {\n const { baseUI, withInteractionRoot } = ctx;\n return {\n Field: (props: { children?: ReactNode }) => {\n const field = createElement(baseUI.Interaction.Field, {\n ...props,\n input: input as never,\n });\n return interaction ? withInteractionRoot(interaction, field) : field;\n },\n Options: () => null,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(ReactFragment, null, children(undefined)),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n\nexport function createCardInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n): WorkspaceCardInputSlot {\n const { runtimeInteraction } = ctx;\n return {\n Card: ({ value, ...props }: { value: string; children?: ReactNode }) =>\n createElement(runtimeInteraction.CardInput, {\n ...props,\n input: \"cardId\",\n unsafeCardId: value,\n }),\n Cards: () => null,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(CardSlotValue, { children }),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n\nexport function createBoardTargetInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n kind: \"space\" | \"edge\" | \"vertex\" | \"tile\",\n): WorkspaceBoardTargetInputSlot<typeof kind> {\n const { runtimeBoard } = ctx;\n const Target = ({\n value,\n ...props\n }: {\n value: string;\n children?: ReactNode;\n }) => {\n if (kind === \"edge\") {\n return createElement(runtimeBoard.EdgeTarget, { ...props, value });\n }\n if (kind === \"vertex\") {\n return createElement(runtimeBoard.VertexTarget, { ...props, value });\n }\n return createElement(runtimeBoard.SpaceTarget, { ...props, value });\n };\n return {\n Target,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(ReactFragment, null, children(undefined)),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"../../ui/components.js\";\nimport type {\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n} from \"../primitives/index.js\";\nimport type { InteractionDialogProps } from \"../primitives/interaction/dialog.js\";\nimport { createFormInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceContractContext,\n WorkspaceInteractionFormDescriptor,\n WorkspaceInteractionFormsDescriptor,\n} from \"./types.js\";\n\nexport interface WorkspaceInteractionFormDialogProps extends Omit<\n InteractionDialogProps,\n \"children\"\n> {\n title: ReactNode;\n description?: ReactNode;\n trigger?: ReactNode;\n children: ReactNode;\n contentClassName?: string;\n overlayClassName?: string;\n showCloseButton?: boolean;\n}\n\n/**\n * Builds the interaction-form surface pieces and the `Interaction` namespace\n * for one workspace contract. Called once per `createWorkspaceUIContract`\n * invocation so `InteractionRoutes` keeps a stable component identity.\n */\nexport function createInteractionForms<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI, runtimeInteraction, withInteractionRoot } = ctx;\n\n function InteractionRoutes({\n routes,\n fallback,\n includeUnavailable,\n }: {\n routes: Record<\n string,\n {\n collect: Record<string, unknown>;\n }\n >;\n fallback?: ReactNode;\n includeUnavailable?: boolean | null;\n }): ReactElement {\n return createElement(runtimeInteraction.Routes, {\n routes,\n fallback,\n includeUnavailable,\n });\n }\n\n function GeneratedFormDialog({\n title,\n description,\n trigger,\n children,\n contentClassName,\n overlayClassName,\n showCloseButton,\n defaultOpen,\n onStateChange,\n }: WorkspaceInteractionFormDialogProps) {\n return createElement(baseUI.Interaction.Dialog, {\n defaultOpen,\n onStateChange,\n children: (state) =>\n createElement(\n Dialog,\n { open: state.open, onOpenChange: state.setOpen },\n trigger\n ? createElement(DialogTrigger, {\n asChild: true,\n children: trigger,\n })\n : null,\n createElement(\n DialogContent,\n {\n className: contentClassName,\n overlayClassName,\n showCloseButton,\n },\n createElement(\n DialogHeader,\n null,\n createElement(DialogTitle, null, title),\n description\n ? createElement(DialogDescription, null, description)\n : null,\n ),\n children,\n ),\n ),\n });\n }\n\n function useInteractionFormSurface(interaction: string) {\n const validInputs = options.formInputKeysForInteraction(interaction);\n const slot = Object.fromEntries(\n [...validInputs].map((input) => [\n input,\n createFormInputSlot(ctx, input, interaction),\n ]),\n );\n return {\n Root: ({ children }: { children?: ReactNode }) =>\n withInteractionRoot(interaction, children),\n Form: (props: InteractionFormPrimitiveProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Form, props),\n ),\n Dialog: (props: WorkspaceInteractionFormDialogProps) =>\n withInteractionRoot(\n interaction,\n createElement(GeneratedFormDialog, props),\n ),\n State: (props: InteractionStateProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.State, props),\n ),\n Arm: (props: InteractionTriggerProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Trigger, props),\n ),\n Submit: (props: InteractionSubmitProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Submit, props),\n ),\n Field: ({ input, ...props }: { input: string; children?: ReactNode }) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Field, {\n ...props,\n input: input as never,\n }),\n ),\n slot,\n };\n }\n\n const Interaction = {\n State: baseUI.Interaction.State,\n Dialog: baseUI.Interaction.Dialog,\n useForm: useInteractionFormSurface,\n form<const Interaction extends string>(\n interaction: Interaction,\n ): WorkspaceInteractionFormDescriptor<Interaction> {\n return { kind: \"form\", interaction };\n },\n forms<const Interactions extends Readonly<Record<string, string>>>(\n interactions: Interactions,\n ): WorkspaceInteractionFormsDescriptor<Interactions> {\n return { kind: \"forms\", interactions };\n },\n Routes: InteractionRoutes,\n };\n\n return { Interaction, useInteractionFormSurface };\n}\n","import type {\n WorkspaceHandOptions,\n WorkspaceSurfaceDescriptor,\n WorkspaceSurfaceSpec,\n} from \"./types.js\";\n\ninterface SurfaceResolverDeps {\n readonly Board: {\n useSurface(name: string): unknown;\n };\n readonly Zone: {\n useHand(name: string, zoneOptions: WorkspaceHandOptions): unknown;\n usePile(name: string, zoneOptions: { zone: string }): unknown;\n useCardCollection(\n name: string,\n zoneOptions: { zones: readonly string[]; mode?: \"all\" | \"top-card\" },\n ): unknown;\n };\n readonly useInteractionFormSurface: (interaction: string) => unknown;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isSurfaceDescriptor(\n value: unknown,\n): value is WorkspaceSurfaceDescriptor {\n return (\n isPlainObject(value) &&\n typeof (value as { kind?: unknown }).kind === \"string\"\n );\n}\n\n/**\n * Builds the surface-spec resolvers for one workspace contract.\n */\nexport function createSurfaceResolvers({\n Board,\n Zone,\n useInteractionFormSurface,\n}: SurfaceResolverDeps) {\n const boardSurface = Board.useSurface;\n const zoneHandSurface = Zone.useHand;\n const zonePileSurface = Zone.usePile;\n const zoneCardCollectionSurface = Zone.useCardCollection;\n const interactionFormSurface = useInteractionFormSurface;\n\n function resolveSurfaceDescriptor(\n name: string,\n descriptor: WorkspaceSurfaceDescriptor,\n ): unknown {\n switch (descriptor.kind) {\n case \"board\":\n return boardSurface(name);\n case \"hand\":\n return zoneHandSurface(name, {\n zone: descriptor.zone,\n role: descriptor.role,\n label: descriptor.label,\n order: descriptor.order,\n });\n case \"pile\":\n return zonePileSurface(name, { zone: descriptor.zone });\n case \"piles\":\n return Object.fromEntries(\n descriptor.zones.map((zone) => [\n zone,\n zonePileSurface(String(zone), { zone }),\n ]),\n );\n case \"cardCollection\":\n return zoneCardCollectionSurface(name, {\n zones: descriptor.zones,\n mode: descriptor.mode,\n });\n case \"form\":\n return interactionFormSurface(descriptor.interaction);\n case \"forms\":\n return Object.fromEntries(\n Object.entries(descriptor.interactions).map(([key, interaction]) => [\n key,\n interactionFormSurface(interaction),\n ]),\n );\n }\n }\n\n function resolveSurfaceSpec(spec: WorkspaceSurfaceSpec): unknown {\n return Object.fromEntries(\n Object.entries(spec).map(([key, value]) => [\n key,\n isSurfaceDescriptor(value)\n ? resolveSurfaceDescriptor(key, value)\n : resolveSurfaceSpec(value as WorkspaceSurfaceSpec),\n ]),\n );\n }\n\n function defineSurfaces<const Spec extends WorkspaceSurfaceSpec>(spec: Spec) {\n return function useDefinedSurfaces() {\n return resolveSurfaceSpec(spec);\n };\n }\n\n return { defineSurfaces, resolveSurfaceSpec, resolveSurfaceDescriptor };\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { Fragment as ReactFragment, createElement } from \"react\";\nimport { clsx } from \"clsx\";\nimport { useAuthoredPluginGameplayFrameSelector } from \"../context/PluginGameplayFrameContext.js\";\nimport { CardFace, type ViewCard } from \"../../ui.js\";\nimport type { InteractionCardInputRenderState } from \"../primitives/index.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport { createHandPieces } from \"./hand.js\";\nimport { createCardInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceCardCollectionSurfaceDescriptor,\n WorkspaceContractContext,\n WorkspaceHandOptions,\n WorkspaceHandSurfaceDescriptor,\n WorkspacePileSurfaceDescriptor,\n WorkspacePilesSurfaceDescriptor,\n} from \"./types.js\";\n\nconst DEFAULT_ZONE_CARD_CLASS =\n \"group relative border-0 bg-transparent p-0 transition-transform enabled:cursor-pointer enabled:hover:-translate-y-2 data-[selected=true]:-translate-y-3 disabled:cursor-not-allowed data-[eligible=false]:opacity-45 data-[eligible=false]:grayscale data-[eligible=false]:hover:translate-y-0 data-[card-available=false]:opacity-45 data-[card-available=false]:grayscale\";\n\nfunction cardRenderItemToViewCard(card: unknown, cardId: string): ViewCard {\n if (\n card &&\n typeof card === \"object\" &&\n \"hidden\" in card &&\n (card as { hidden?: unknown }).hidden === false\n ) {\n return card as unknown as ViewCard;\n }\n return {\n id: cardId,\n cardType: \"hidden\",\n name: \"Hidden card\",\n properties: {},\n };\n}\n\nexport function createZoneCardsComponent<Card>(\n ctx: WorkspaceContractContext<Card>,\n zones: readonly string[],\n) {\n const { baseUI, runtimeZone } = ctx;\n return ({\n empty,\n children,\n ...props\n }: {\n empty?: ReactNode;\n children: (card: Card) => ReactNode;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) =>\n createElement(\n ReactFragment,\n null,\n ...zones.map((zone) =>\n createElement(baseUI.Zone.Root, {\n key: zone,\n zone: zone as never,\n children: createElement(runtimeZone.List, {\n ...props,\n empty,\n children,\n }),\n }),\n ),\n );\n}\n\nexport function createZoneCardComponent<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI, runtimeInteraction } = ctx;\n return ({\n card,\n children,\n className,\n ...props\n }: {\n card: Card;\n children?: ReactNode;\n } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\" | \"value\">) => {\n const cardId = options.cardIdFromZoneCard(card);\n const zone = options.zoneIdFromZoneCard(card);\n const viewCard = cardRenderItemToViewCard(card, cardId);\n const faceDown =\n !!card &&\n typeof card === \"object\" &&\n \"hidden\" in card &&\n (card as { hidden?: unknown }).hidden === true;\n const renderCardFace = (state: InteractionCardInputRenderState) =>\n createElement(CardFace, {\n card: viewCard,\n selected: state.selected,\n disabled: state.disabled || !state.eligible,\n faceDown,\n size: \"sm\",\n children,\n });\n const match = useAuthoredPluginGameplayFrameSelector((frame) => {\n const candidates = frame.zones[zone]?.playableByCardId[cardId] ?? [];\n for (const descriptor of candidates) {\n const input = descriptor.inputs.find(\n (candidateInput) =>\n candidateInput.domain.type === \"cardTarget\" &&\n candidateInput.domain.projection === \"resolved\" &&\n candidateInput.domain.eligibleTargets.includes(cardId),\n );\n if (input) return { descriptor, input };\n }\n return null;\n });\n if (!match) {\n return createElement(\n \"div\",\n {\n ...props,\n className: clsx(\"relative inline-flex\", className),\n \"data-dreamboard-zone-card\": \"\",\n \"data-card-id\": cardId,\n \"data-zone\": zone,\n \"data-interactive\": false,\n },\n createElement(CardFace, {\n card: viewCard,\n faceDown,\n size: \"sm\",\n children,\n }),\n );\n }\n return createElement(baseUI.Zone.Root, {\n zone: zone as never,\n children: createElement(runtimeInteraction.Root, {\n interaction: match.descriptor.interactionKey,\n children: createElement(runtimeInteraction.CardInput, {\n ...props,\n className: clsx(DEFAULT_ZONE_CARD_CLASS, className),\n input: match.input.key,\n unsafeCardId: cardId,\n children: renderCardFace,\n }),\n }),\n });\n };\n}\n\n/**\n * Assembles the `Zone` namespace for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation.\n */\nexport function createZoneNamespace<Card>(ctx: WorkspaceContractContext<Card>) {\n const {\n createHandCardsComponent,\n createStagingComponent,\n HandCardsSlot,\n HandSummarySlot,\n HandActionsSlot,\n } = createHandPieces(ctx);\n\n return {\n hand<Zone extends string>(\n zone: Zone,\n options: Omit<WorkspaceHandSurfaceDescriptor<Zone>, \"kind\" | \"zone\">,\n ): WorkspaceHandSurfaceDescriptor<Zone> {\n return { kind: \"hand\", zone, ...options };\n },\n pile<Zone extends string>(\n zone: Zone,\n ): WorkspacePileSurfaceDescriptor<Zone> {\n return { kind: \"pile\", zone };\n },\n piles<const Zones extends readonly string[]>(\n zones: Zones,\n ): WorkspacePilesSurfaceDescriptor<Zones> {\n return { kind: \"piles\", zones };\n },\n collection<const Zones extends readonly string[]>(\n zones: Zones,\n options: { mode?: \"all\" | \"top-card\" } = {},\n ): WorkspaceCardCollectionSurfaceDescriptor<Zones> {\n return { kind: \"cardCollection\", zones, mode: options.mode };\n },\n useHand(_name: string, zoneOptions: WorkspaceHandOptions) {\n const handComponentOptions = {\n name: _name,\n zone: zoneOptions.zone,\n role: zoneOptions.role,\n label: zoneOptions.label,\n order: zoneOptions.order,\n };\n return {\n Hand: createHandCardsComponent(handComponentOptions),\n Cards: HandCardsSlot,\n Summary: HandSummarySlot,\n Actions: HandActionsSlot,\n Card: createZoneCardComponent(ctx),\n Staging: createStagingComponent(handComponentOptions),\n slot: { card: createCardInputSlot(ctx) },\n };\n },\n usePile(_name: string, zoneOptions: { zone: string }) {\n return {\n Pile: createZoneCardsComponent(ctx, [zoneOptions.zone]),\n Card: createZoneCardComponent(ctx),\n };\n },\n useCardCollection(\n _name: string,\n zoneOptions: { zones: readonly string[]; mode?: \"all\" | \"top-card\" },\n ) {\n void zoneOptions.mode;\n return {\n Collection: createZoneCardsComponent(ctx, zoneOptions.zones),\n Card: createZoneCardComponent(ctx),\n slot: { card: createCardInputSlot(ctx) },\n };\n },\n };\n}\n","import type { ReactNode } from \"react\";\nimport { Children, createElement, isValidElement, useMemo } from \"react\";\nimport { clsx } from \"clsx\";\nimport { useIsMobile } from \"../../ui.js\";\nimport { useRegisterMobileHand } from \"../../ui/components.js\";\nimport { useZoneCards } from \"../primitives/index.js\";\nimport {\n HandSurfaceView,\n HandStagingView,\n dropTargetIdFor,\n type HandSelectionSummary,\n type HandSurfaceViewProps,\n type RuntimeDropTarget,\n} from \"../primitives/hand-surface.js\";\nimport type { AuthoredCardIntent } from \"../primitives/hand-intent-adapter.js\";\nimport type {\n CardDropTargetVisualState,\n HandInteractionPolicy,\n HandLayoutKind,\n HandLayoutPolicy,\n InteractionVisualState,\n} from \"../../ui.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport { isInteractionAvailable } from \"../utils/interaction-status.js\";\nimport type {\n WorkspaceContractContext,\n WorkspaceHandComponentOptions,\n} from \"./types.js\";\n\n/**\n * Builds the hand-surface pieces for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation so `GeneratedHandCards` keeps a\n * single stable component identity per contract (its `useRegisterMobileHand`\n * registration depends on this).\n */\nexport function createHandPieces<Card>(ctx: WorkspaceContractContext<Card>) {\n const { baseUI } = ctx;\n\n function HandCardsSlot({\n children,\n }: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n }) {\n void children;\n return createElement(\"template\", { \"data-dreamboard-hand-cards-slot\": \"\" });\n }\n\n function HandSummarySlot({\n children,\n }: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n }) {\n void children;\n return createElement(\"template\", {\n \"data-dreamboard-hand-summary-slot\": \"\",\n });\n }\n\n function HandActionsSlot({\n children,\n }: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n }) {\n void children;\n return createElement(\"template\", {\n \"data-dreamboard-hand-actions-slot\": \"\",\n });\n }\n\n function renderHandSlot(\n slot: ReactNode | ((summary: HandSelectionSummary) => ReactNode),\n summary: HandSelectionSummary,\n ): ReactNode {\n return typeof slot === \"function\" ? slot(summary) : slot;\n }\n\n function createHandCardsComponent(options: WorkspaceHandComponentOptions) {\n return ({\n empty,\n children,\n className,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n onSelectionSummary,\n ...props\n }: {\n empty?: ReactNode;\n children:\n | ReactNode\n | ((card: Card, state: InteractionVisualState) => ReactNode);\n className?: string;\n layout?: HandLayoutKind | HandLayoutPolicy;\n mobileInteraction?: HandInteractionPolicy;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n dropTargets?: ReadonlyArray<{\n target:\n | { kind: \"card\"; card: string }\n | { kind: \"space\"; target: string }\n | { kind: \"edge\"; target: string }\n | { kind: \"vertex\"; target: string }\n | { kind: \"tile\"; target: string };\n label: string;\n render: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n role?: string;\n order?: number;\n }>;\n renderDropTargets?: (children: ReactNode) => ReactNode;\n onCardIntent?: (intent: AuthoredCardIntent) => void;\n onSelectionSummary?: (summary: HandSelectionSummary) => void;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) => {\n const slots = collectHandSlots(children);\n const renderCard =\n typeof children === \"function\" ? children : slots.cards?.children;\n if (!renderCard) {\n throw new Error(\n \"Generated hand surfaces require exactly one <hand.Cards> slot.\",\n );\n }\n const summaryRenderer = slots.summary\n ? (summary: HandSelectionSummary) =>\n renderHandSlot(slots.summary!.children, summary)\n : undefined;\n const actionsRenderer = slots.actions\n ? (summary: HandSelectionSummary) =>\n renderHandSlot(slots.actions!.children, summary)\n : undefined;\n return createElement(baseUI.Zone.Root, {\n zone: options.zone as never,\n // Fill the author's container instead of shrink-wrapping to the fan's\n // own measured width. Without a definite width here, a centering parent\n // sizes to the cards row, the hand measures that, recomputes a new fan\n // width, and the layout chases itself (a ResizeObserver loop). `w-full`\n // pins the outermost hand element to the available width and breaks the\n // cycle for every author layout.\n className: \"w-full min-w-0\",\n children: createElement(GeneratedHandCards, {\n ...props,\n hand: options,\n className,\n empty,\n children: renderCard,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n summarySlot: summaryRenderer,\n actionsSlot: actionsRenderer,\n onSelectionSummary,\n }),\n });\n };\n }\n\n function collectHandSlots(\n children:\n | ReactNode\n | ((card: Card, state: InteractionVisualState) => ReactNode),\n ): {\n cards?: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n summary?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n actions?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } {\n const slots: {\n cards?: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n summary?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n actions?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } = {};\n if (typeof children === \"function\") return slots;\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue;\n if (child.type === HandCardsSlot) {\n if (slots.cards) {\n throw new Error(\"Only one <hand.Cards> slot may be rendered.\");\n }\n slots.cards = child.props as {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n } else if (child.type === HandSummarySlot) {\n if (slots.summary) {\n throw new Error(\"Only one <hand.Summary> slot may be rendered.\");\n }\n slots.summary = child.props as {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } else if (child.type === HandActionsSlot) {\n if (slots.actions) {\n throw new Error(\"Only one <hand.Actions> slot may be rendered.\");\n }\n slots.actions = child.props as {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n }\n }\n return slots;\n }\n\n function GeneratedHandCards({\n hand,\n empty,\n children,\n className,\n sort,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n summarySlot,\n actionsSlot,\n onSelectionSummary,\n }: {\n hand: WorkspaceHandComponentOptions;\n empty?: ReactNode;\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n className?: string;\n layout?: HandLayoutKind | HandLayoutPolicy;\n mobileInteraction?: HandInteractionPolicy;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n dropTargets?: ReadonlyArray<{\n target:\n | { kind: \"card\"; card: string }\n | { kind: \"space\"; target: string }\n | { kind: \"edge\"; target: string }\n | { kind: \"vertex\"; target: string }\n | { kind: \"tile\"; target: string };\n label: string;\n render: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n role?: string;\n order?: number;\n }>;\n renderDropTargets?: (children: ReactNode) => ReactNode;\n onCardIntent?: (intent: AuthoredCardIntent) => void;\n summarySlot?: (summary: HandSelectionSummary) => ReactNode;\n actionsSlot?: (summary: HandSelectionSummary) => ReactNode;\n onSelectionSummary?: (summary: HandSelectionSummary) => void;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) {\n const isMobile = useIsMobile();\n const { items, count } = useZoneCards({ sort });\n // One predictable presentation for every hand: the projected surface\n // (fan on desktop, tray on mobile by default). Authors choose other shapes\n // explicitly with `layout` (e.g. layout=\"strip\"). We no longer fall back to\n // a bare scroll strip when no interaction props are passed, so the layout —\n // and the eligible/selected projection — stays consistent across phases.\n const handClassName = clsx(\"min-h-[112px]\", className);\n const resolvedDropTargets = useMemo<RuntimeDropTarget[] | undefined>(() => {\n if (!dropTargets || dropTargets.length === 0) return undefined;\n return dropTargets.map((dt) => {\n const value =\n dt.target.kind === \"card\" ? dt.target.card : dt.target.target;\n return {\n targetId: dropTargetIdFor(dt.target.kind, value),\n label: dt.label,\n render: dt.render,\n className: dt.className,\n role: dt.role,\n order: dt.order,\n };\n });\n }, [dropTargets]);\n const content = useMemo(\n () =>\n createElement(HandSurfaceView, {\n zone: hand.zone,\n cards: items,\n renderCard: (card, state) => children(card as Card, state),\n layout,\n mobileInteraction,\n dropTargets: resolvedDropTargets,\n renderDropTargets,\n cardSize,\n renderEmpty: empty !== undefined ? () => empty : undefined,\n ariaLabel,\n onIntentRouted: onCardIntent\n ? (intent) => onCardIntent(intent)\n : undefined,\n summarySlot,\n actionsSlot,\n onSelectionSummary,\n className: handClassName,\n } satisfies HandSurfaceViewProps<(typeof items)[number]>),\n [\n ariaLabel,\n cardSize,\n children,\n empty,\n hand.zone,\n handClassName,\n items,\n layout,\n mobileInteraction,\n onCardIntent,\n onSelectionSummary,\n actionsSlot,\n renderDropTargets,\n summarySlot,\n resolvedDropTargets,\n ],\n );\n const active = items.some(\n (item) =>\n !item.hidden &&\n item.interactions.some((descriptor) =>\n isInteractionAvailable(descriptor),\n ),\n );\n const autoOpen = items.some(\n (item) =>\n !item.hidden &&\n item.interactions.some(\n (descriptor) =>\n isInteractionAvailable(descriptor) &&\n descriptor.inputs.some(\n (input) =>\n input.domain.type === \"cardTarget\" &&\n input.domain.selection?.mode === \"many\",\n ),\n ),\n );\n const version = items\n .map((item) =>\n item.hidden\n ? `${item.id}:hidden`\n : `${item.id}:${item.cardType}:${JSON.stringify(item.properties)}`,\n )\n .join(\"|\");\n const registration = useMemo(\n () => ({\n id: `${hand.name}:${hand.zone}`,\n zone: hand.zone,\n label: hand.label,\n role: hand.role,\n order: hand.order,\n version,\n count,\n active,\n autoOpen,\n content: createElement(baseUI.Zone.Root, {\n zone: hand.zone as never,\n children: content,\n }),\n }),\n [\n active,\n autoOpen,\n content,\n count,\n hand.label,\n hand.name,\n hand.order,\n hand.role,\n hand.zone,\n version,\n ],\n );\n useRegisterMobileHand(registration);\n\n return isMobile ? null : content;\n }\n\n function createStagingComponent(options: WorkspaceHandComponentOptions) {\n return ({\n children,\n label,\n renderEmptySlot,\n cardSize,\n ariaLabel,\n className,\n }: {\n children: (card: Card) => ReactNode;\n label?: ReactNode;\n renderEmptySlot?: (index: number) => ReactNode;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n className?: string;\n }) =>\n createElement(HandStagingView, {\n zone: options.zone,\n renderCard: (card) => children(card as Card),\n renderEmptySlot,\n label,\n cardSize,\n ariaLabel,\n className,\n });\n }\n\n return {\n createHandCardsComponent,\n createStagingComponent,\n HandCardsSlot,\n HandSummarySlot,\n HandActionsSlot,\n };\n}\n"],"mappings":"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","names":["createElement","createElement","createElement","createElement","createElement","Interaction","Board","Zone","ReactFragment","createElement","clsx","createElement","createElement","createElement","ReactFragment","clsx","createElement","Interaction","Board","Zone","UI"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime/workspace-contract/index.ts","../src/runtime/ui-contract.ts","../src/runtime/workspace-contract/board.ts","../src/runtime/workspace-contract/slots.ts","../src/runtime/workspace-contract/forms.ts","../src/runtime/workspace-contract/surfaces.ts","../src/runtime/workspace-contract/zones.ts","../src/runtime/workspace-contract/hand.ts"],"sourcesContent":["import { Fragment, createElement } from \"react\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport {\n ClientParamSchemaProvider,\n type ClientParamSchemaMap,\n} from \"../context/ClientParamSchemaContext.js\";\nimport {\n createResourceCounter,\n type ResourceCounterComponents,\n type ResourceDisplayConfig,\n} from \"../../ui.js\";\nimport { MobileHandTrayProvider } from \"../../ui/components.js\";\nimport { ToastProvider } from \"../../ui.js\";\nimport {\n createDreamboardUI,\n type DreamboardUI,\n type TypedGame,\n type UIContract,\n} from \"../ui-contract.js\";\nimport type {\n BoardGridInteractionFilter,\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridInteractionFilter,\n BoardSquareGridProps,\n InteractionDialogProps,\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n GameMeState,\n GamePlayersState,\n GameRenderState,\n GameTurnState,\n UIRootProps,\n ZoneCardRenderItem,\n} from \"../primitives/index.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport type {\n RuntimeBoard,\n RuntimeInteraction,\n RuntimeZone,\n WorkspaceContractContext,\n WorkspaceContractOptions,\n} from \"./types.js\";\nimport { createBoardNamespace } from \"./board.js\";\nimport { createInteractionForms } from \"./forms.js\";\nexport type { WorkspaceInteractionFormDialogProps } from \"./forms.js\";\nimport { createSurfaceResolvers } from \"./surfaces.js\";\nimport { createZoneNamespace } from \"./zones.js\";\n\nexport type { BoardSpaceTargetProps } from \"../primitives/board.js\";\nexport type { HandRole } from \"../../ui/components.js\";\nexport type {\n WorkspaceInteractionSlotComponent,\n WorkspaceFormInputSlot,\n WorkspaceCardInputSlot,\n WorkspaceBoardTargetInputSlot,\n WorkspaceBoardSurface,\n WorkspaceZoneCardsComponent,\n WorkspaceZoneCardComponent,\n WorkspaceZoneStagingComponent,\n WorkspaceHandSurface,\n WorkspaceHandOptions,\n WorkspacePileSurface,\n WorkspaceCardCollectionSurface,\n WorkspaceBoardSurfaceDescriptor,\n WorkspaceHandSurfaceDescriptor,\n WorkspacePileSurfaceDescriptor,\n WorkspacePilesSurfaceDescriptor,\n WorkspaceCardCollectionSurfaceDescriptor,\n WorkspaceInteractionFormsDescriptor,\n WorkspaceInteractionFormDescriptor,\n WorkspaceSurfaceDescriptor,\n WorkspaceSurfaceSpec,\n WorkspaceContractOptions,\n} from \"./types.js\";\n\nexport interface DefineGameUIConfig<GameState, Surfaces> {\n useSurfaces: () => Surfaces;\n interactionRoutes?: (context: {\n game: GameState;\n surfaces: Surfaces;\n }) => Record<string, { collect: Record<string, unknown> }>;\n phases: Record<\n string,\n (context: { game: GameState; surfaces: Surfaces }) => ReactNode\n >;\n renderInteractions?: (context: {\n game: GameState;\n surfaces: Surfaces;\n }) => ReactNode;\n fallback?: ReactNode | ((phase: string | null) => ReactNode);\n includeUnavailableInteractions?: boolean | null;\n}\n\nexport function createWorkspaceUIContract<\n WorkspaceUI,\n Contract extends UIContract,\n Resource extends string,\n Card,\n HexBoards extends Record<string, unknown>,\n SquareBoards extends Record<string, unknown> = Record<string, unknown>,\n>(\n options: WorkspaceContractOptions<\n Contract,\n Resource,\n Card,\n HexBoards,\n SquareBoards\n >,\n): WorkspaceUI {\n const baseUI = createDreamboardUI(options.uiContract);\n const runtimeInteraction = baseUI.Interaction as RuntimeInteraction;\n const runtimeBoard = baseUI.Board as RuntimeBoard;\n const runtimeZone = baseUI.Zone as RuntimeZone<Card>;\n const runtimeGameRoot = baseUI.Game.Root as ComponentType<{\n children: (game: unknown) => ReactNode;\n }>;\n const runtimePhaseSwitch = baseUI.Phase.Switch as ComponentType<{\n routes: Record<string, () => ReactNode>;\n fallback?: ReactNode | ((phase: string | null) => ReactNode);\n }>;\n\n const ctx: WorkspaceContractContext<Card> = {\n options,\n // The context carries the contract-erased view of the UI: every consumer\n // already neutralizes key genericity (`as never` inputs/zones), exactly as\n // the original single-file factory did with its `Runtime*` casts.\n baseUI: baseUI as unknown as DreamboardUI,\n runtimeInteraction,\n runtimeBoard,\n runtimeZone,\n withInteractionRoot: (interaction: string, children: ReactNode) =>\n createElement(runtimeInteraction.Root, {\n interaction,\n children,\n }),\n };\n\n const resourceDisplayConfig = options.resourceIds.map((resource) => {\n const presentation = options.resourcePresentationById?.[resource];\n return {\n type: resource,\n label: presentation?.label ?? resource,\n icon: presentation?.icon ?? resource,\n };\n }) satisfies ReadonlyArray<ResourceDisplayConfig<Resource>>;\n const resourceCounter = createResourceCounter<Resource>(\n resourceDisplayConfig,\n );\n\n const { Interaction, useInteractionFormSurface } =\n createInteractionForms(ctx);\n const Board = createBoardNamespace(ctx);\n const Zone = createZoneNamespace(ctx);\n const { defineSurfaces } = createSurfaceResolvers({\n Board,\n Zone,\n useInteractionFormSurface,\n });\n\n const UI = {\n ...baseUI,\n Root: ({ children, ...props }: UIRootProps) =>\n createElement(ClientParamSchemaProvider, {\n schemas: options.clientParamSchemasByPhase,\n children: createElement(ToastProvider, {\n children: createElement(MobileHandTrayProvider, {\n children: createElement(baseUI.Root, { ...props, children }),\n }),\n }),\n }),\n defineSurfaces,\n defineGameUI<GameState, Surfaces>({\n useSurfaces,\n interactionRoutes,\n phases,\n renderInteractions,\n fallback,\n includeUnavailableInteractions,\n }: DefineGameUIConfig<GameState, Surfaces>) {\n function DefinedGameUIFrame({ game }: { game: GameState }) {\n const surfaces = useSurfaces();\n const phaseRoutes = Object.fromEntries(\n Object.entries(phases).map(([phase, render]) => [\n phase,\n () => render({ game, surfaces }),\n ]),\n );\n const routeMap = interactionRoutes?.({ game, surfaces });\n return createElement(\n Fragment,\n null,\n routeMap\n ? createElement(runtimeInteraction.Routes, {\n routes: routeMap,\n includeUnavailable: includeUnavailableInteractions,\n })\n : null,\n createElement(runtimePhaseSwitch, {\n routes: phaseRoutes,\n fallback,\n }),\n renderInteractions?.({ game, surfaces }) ?? null,\n );\n }\n\n return function DefinedGameUI(props: Omit<UIRootProps, \"children\">) {\n return createElement(UI.Root, {\n ...props,\n children: createElement(runtimeGameRoot, {\n children: (rawGame: unknown) =>\n createElement(DefinedGameUIFrame, {\n game: rawGame as GameState,\n }),\n }),\n });\n };\n },\n Interaction,\n Board,\n Zone,\n ResourceCounter: resourceCounter,\n };\n\n return UI as WorkspaceUI;\n}\n\nexport type {\n BoardGridInteractionFilter,\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridInteractionFilter,\n BoardSquareGridProps,\n ClientParamSchemaMap,\n DreamboardUI,\n GameMeState,\n GamePlayersState,\n GameRenderState,\n GameTurnState,\n InteractionDialogProps,\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n ResourceCounterComponents,\n TypedGame,\n UIContract,\n UIRootProps,\n ZoneCardRenderItem,\n ZoneListProps,\n};\n","import type {\n ButtonHTMLAttributes,\n ComponentType,\n ReactElement,\n ReactNode,\n} from \"react\";\nimport {\n Board as BoardPrimitive,\n Dice as DicePrimitive,\n Game as GamePrimitive,\n Interaction as InteractionPrimitive,\n Phase as PhasePrimitive,\n PlayerRoster as PlayerRosterPrimitive,\n Prompt as PromptPrimitive,\n PromptInbox as PromptInboxPrimitive,\n UI as UIPrimitive,\n Zone as ZonePrimitive,\n type BoardHexGridProps,\n type BoardHexGridInteractionFilter,\n type BoardSquareGridProps,\n type BoardSquareGridInteractionFilter,\n type BoardTargetProps,\n type BoardSpaceTargetProps,\n type BoardEdgeTargetProps,\n type BoardVertexTargetProps,\n type GameChromeProps,\n type DiceComponents,\n type GameRootProps,\n type InteractionCardInputProps,\n type InteractionDialogProps,\n type InteractionFieldPrimitiveProps,\n type InteractionFormPrimitiveProps,\n type InteractionRoutesMap,\n type InteractionRoutesProps,\n type InteractionRootProps,\n type InteractionSwitchRouteMap,\n type InteractionSwitchProps,\n type PhaseSwitchProps,\n type PlayerRosterComponents,\n type PlayerRosterBadge,\n type PlayerRosterEntry,\n type PlayerRosterListProps,\n type PlayerRosterPartProps,\n type PlayerRosterRootProps,\n type PromptDialogProps,\n type PromptInboxItemsProps,\n type PromptOptionRenderItem,\n type PromptOptionProps,\n type PromptOptionsProps,\n type PromptRootProps,\n type UIRootProps,\n type ZoneItemProps,\n type ZoneCardAtProps,\n type ZoneCardActionProps,\n type ZoneCardRenderItem,\n type ZoneListProps,\n type ZonePileCardsProps,\n type ZonePileRootProps,\n type ZoneRootProps,\n} from \"./primitives/index.js\";\nimport type { InteractionDescriptor } from \"./types/plugin-state.js\";\nimport type {\n AnyHexBoardInput,\n AnySquareBoardInput,\n BoardSpaceIdOf,\n} from \"../ui.js\";\n\n/**\n * Workspace-aware UI typing extension point.\n *\n * Generated workspaces will augment this interface with their concrete UI\n * contract. The unregistered SDK keeps all public keys string-compatible so\n * package-local tests and generic consumers can still import ui-sdk directly.\n */\nexport interface DreamboardUIRegister {\n readonly __dreamboardUIRegister?: never;\n}\n\nexport type UIContractBucket = Record<string, unknown>;\n\nexport interface UIContract {\n interactions?: UIContractBucket;\n inputs?: UIContractBucket;\n prompts?: UIContractBucket;\n promptOptions?: UIContractBucket;\n players?: UIContractBucket;\n zones?: UIContractBucket;\n cards?: UIContractBucket;\n phases?: UIContractBucket;\n boardTargets?: UIContractBucket;\n}\n\ntype RegisteredUIContract = DreamboardUIRegister extends {\n ui: infer Registered extends UIContract;\n}\n ? Registered\n : UIContract;\n\ntype BucketOf<Contract extends UIContract, Key extends keyof UIContract> =\n NonNullable<Contract[Key]> extends UIContractBucket\n ? NonNullable<Contract[Key]>\n : UIContractBucket;\n\ntype StringKeyOf<Bucket extends UIContractBucket> = Extract<\n keyof Bucket,\n string\n>;\n\ntype StringKeysOrFallback<Bucket extends UIContractBucket> = [\n StringKeyOf<Bucket>,\n] extends [never]\n ? string\n : string extends StringKeyOf<Bucket>\n ? string\n : StringKeyOf<Bucket>;\n\nexport type RegisteredUI = RegisteredUIContract;\n\nexport type InteractionKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"interactions\">>;\n\nexport type InteractionInputKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"inputs\">>;\n\nexport type PromptKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"prompts\">>;\n\nexport type PromptOptionKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"promptOptions\">>;\n\nexport type PlayerKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"players\">>;\n\nexport type ZoneKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"zones\">>;\n\nexport type CardKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"cards\">>;\n\nexport type PhaseKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"phases\">>;\n\nexport type BoardTargetKey<Contract extends UIContract = RegisteredUI> =\n StringKeysOrFallback<BucketOf<Contract, \"boardTargets\">>;\n\ntype TypedZoneCardRenderItem<Contract extends UIContract> =\n ZoneCardRenderItem<CardKey<Contract> & string> extends infer Item\n ? Item extends { id: string; zone: string }\n ? Omit<Item, \"id\" | \"zone\"> & {\n id: CardKey<Contract>;\n zone: ZoneKey<Contract>;\n }\n : never\n : never;\n\nexport type TypedInteraction<Contract extends UIContract> = Omit<\n typeof InteractionPrimitive,\n \"Root\" | \"CardInput\" | \"Dialog\" | \"Field\" | \"Form\" | \"Switch\"\n> & {\n Root<Interaction extends InteractionKey<Contract>>(\n props: InteractionRootProps<Interaction>,\n ): ReactElement | null;\n Switch(\n props: Omit<InteractionSwitchProps<InteractionKey<Contract>>, \"routes\"> & {\n routes: InteractionSwitchRouteMap<InteractionKey<Contract>>;\n },\n ): ReactElement;\n Routes(\n props: Omit<InteractionRoutesProps<InteractionKey<Contract>>, \"routes\"> & {\n routes: InteractionRoutesMap<InteractionKey<Contract>>;\n },\n ): ReactElement;\n CardInput<Input extends InteractionInputKey<Contract>>(\n props: Omit<InteractionCardInputProps, \"input\" | \"unsafeCardId\"> & {\n input: Input;\n unsafeCardId?: CardKey<Contract>;\n },\n ): ReactElement;\n Dialog<Interaction extends InteractionKey<Contract>>(\n props: InteractionDialogProps<Interaction>,\n ): ReactElement;\n Field<Input extends InteractionInputKey<Contract>>(\n props: Omit<InteractionFieldPrimitiveProps, \"input\"> & { input: Input },\n ): ReactElement | null;\n Form(props: InteractionFormPrimitiveProps): ReactElement | null;\n};\n\nexport type InteractionSlotComponent<Props = object> = ComponentType<\n Props extends { children: unknown } ? Props : Props & { children?: ReactNode }\n>;\n\nexport interface InteractionDefaultInputSlot {\n readonly Default: InteractionSlotComponent;\n}\n\nexport interface InteractionValueInputSlot<Value = unknown> {\n readonly Value: InteractionSlotComponent<{\n children: (value: Value | undefined) => ReactNode;\n }>;\n}\n\nexport interface InteractionChoiceInputSlot<Value = unknown> {\n readonly Field: InteractionSlotComponent;\n readonly Options: InteractionSlotComponent<{\n children: (option: { value: Value; label: string }) => ReactNode;\n }>;\n}\n\nexport interface InteractionChoiceListInputSlot<Value = unknown> {\n readonly Field: InteractionSlotComponent;\n readonly Options: InteractionSlotComponent<{\n children: (option: { value: Value; label: string }) => ReactNode;\n }>;\n}\n\nexport interface InteractionNumberInputSlot {\n readonly Field: InteractionSlotComponent;\n}\n\nexport interface InteractionResourceMapInputSlot<\n Resource extends string = string,\n> {\n readonly Field: InteractionSlotComponent;\n readonly Resource: InteractionSlotComponent<{ value: Resource }>;\n}\n\nexport type InteractionFormInputSlot<Value = unknown> =\n | InteractionChoiceInputSlot<Value>\n | InteractionChoiceListInputSlot<Value>\n | InteractionNumberInputSlot\n | InteractionResourceMapInputSlot;\n\nexport interface InteractionCardTargetInputSlot<Card extends string = string> {\n readonly Card: InteractionSlotComponent<\n { value: Card } & Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | \"children\"\n | \"disabled\"\n | \"aria-disabled\"\n | \"aria-pressed\"\n | \"onClick\"\n | \"type\"\n | \"value\"\n >\n >;\n readonly Cards: InteractionSlotComponent<{\n children: (card: { id: Card }) => ReactNode;\n }>;\n}\n\nexport interface InteractionBoardTargetInputSlot<\n Target extends string = string,\n> {\n readonly Target: InteractionSlotComponent<\n { value: Target } & Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n | \"children\"\n | \"disabled\"\n | \"aria-disabled\"\n | \"aria-pressed\"\n | \"onClick\"\n | \"type\"\n | \"value\"\n >\n >;\n}\n\nexport type InteractionBoardSpaceTargetInputSlot<\n Space extends string = string,\n> = InteractionBoardTargetInputSlot<Space>;\n\nexport type InteractionBoardEdgeTargetInputSlot<Edge extends string = string> =\n InteractionBoardTargetInputSlot<Edge>;\n\nexport type InteractionBoardVertexTargetInputSlot<\n Vertex extends string = string,\n> = InteractionBoardTargetInputSlot<Vertex>;\n\nexport type InteractionBoardTileTargetInputSlot<Tile extends string = string> =\n InteractionBoardTargetInputSlot<Tile>;\n\nexport interface InteractionSubmitSlot {\n readonly Button: InteractionSlotComponent<\n Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\" | \"disabled\" | \"type\" | \"value\"\n >\n >;\n}\n\nexport type TypedPrompt<Contract extends UIContract> = Omit<\n typeof PromptPrimitive,\n \"Root\" | \"Option\" | \"Options\" | \"Dialog\"\n> & {\n Root<Prompt extends PromptKey<Contract>>(\n props: PromptRootProps<Prompt>,\n ): ReactElement | null;\n Option<Option extends PromptOptionKey<Contract>>(\n props: Omit<PromptOptionProps, \"value\"> & { value: Option },\n ): ReactElement;\n Options(\n props: Omit<PromptOptionsProps, \"children\"> & {\n children: (\n option: Omit<PromptOptionRenderItem, \"id\"> & {\n id: PromptOptionKey<Contract>;\n },\n ) => ReactNode;\n },\n ): ReactElement;\n Dialog<Prompt extends PromptKey<Contract>>(\n props: PromptDialogProps<Prompt>,\n ): ReactElement;\n};\n\nexport type TypedPromptInbox<Contract extends UIContract> = Omit<\n typeof PromptInboxPrimitive,\n \"Items\"\n> & {\n Items(\n props: Omit<PromptInboxItemsProps, \"children\"> & {\n children: (\n prompt: Omit<InteractionDescriptor, \"interactionKey\"> & {\n interactionKey: PromptKey<Contract>;\n },\n ) => ReactNode;\n },\n ): ReactElement;\n};\n\ntype TypedPlayerRosterEntry<Player extends string> = Omit<\n PlayerRosterEntry,\n \"playerId\"\n> & {\n playerId: Player;\n};\n\ntype TypedPlayerRosterRootProps<Player extends string> = Omit<\n PlayerRosterRootProps,\n \"score\" | \"scoreLabel\" | \"badges\" | \"metadata\"\n> & {\n score?: (playerId: Player) => number | undefined;\n scoreLabel?: string | ((playerId: Player) => string | undefined);\n badges?: (\n playerId: Player,\n ) => ReadonlyArray<PlayerRosterBadge | null | false | undefined>;\n metadata?: (playerId: Player) => Record<string, unknown> | undefined;\n};\n\ntype TypedPlayerRosterListProps<Player extends string> = Omit<\n PlayerRosterListProps,\n \"children\"\n> & {\n children?: (player: TypedPlayerRosterEntry<Player>) => ReactNode;\n};\n\ntype TypedPlayerRosterPartProps<Player extends string> = Omit<\n PlayerRosterPartProps,\n \"player\"\n> & {\n player: TypedPlayerRosterEntry<Player>;\n};\n\nexport type TypedPlayerRoster<Contract extends UIContract> = Omit<\n PlayerRosterComponents,\n \"Root\" | \"List\" | \"Name\" | \"Score\" | \"Badges\"\n> & {\n Root(\n props: TypedPlayerRosterRootProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n List(props: TypedPlayerRosterListProps<PlayerKey<Contract>>): ReactElement;\n Name(props: TypedPlayerRosterPartProps<PlayerKey<Contract>>): ReactElement;\n Score(\n props: TypedPlayerRosterPartProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n Badges(\n props: TypedPlayerRosterPartProps<PlayerKey<Contract>>,\n ): ReactElement | null;\n};\n\nexport type TypedPhase<Contract extends UIContract> = Omit<\n typeof PhasePrimitive,\n \"Switch\"\n> & {\n Switch(props: PhaseSwitchProps<PhaseKey<Contract>>): ReactElement | null;\n};\n\nexport type TypedZone<Contract extends UIContract> = Omit<\n typeof ZonePrimitive,\n | \"Root\"\n | \"Item\"\n | \"CardAt\"\n | \"TopCard\"\n | \"CardAction\"\n | \"List\"\n | \"PileRoot\"\n | \"PileCards\"\n> & {\n Root<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneRootProps, \"zone\"> & { zone: Zone },\n ): ReactElement;\n Item<Card extends CardKey<Contract>>(\n props: Omit<ZoneItemProps, \"card\"> & { card: Card },\n ): ReactElement;\n CardAction<Card extends CardKey<Contract>>(\n props: Omit<ZoneCardActionProps, \"card\"> & { card?: Card },\n ): ReactElement;\n CardAt<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneCardAtProps<Zone>, \"zone\" | \"children\"> & {\n zone?: Zone;\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement | null;\n TopCard<Zone extends ZoneKey<Contract>>(\n props: Omit<ZoneCardAtProps<Zone>, \"zone\" | \"index\" | \"children\"> & {\n zone?: Zone;\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement | null;\n List(\n props: Omit<ZoneListProps, \"children\"> & {\n children?:\n | ReactNode\n | ((card: TypedZoneCardRenderItem<Contract>) => ReactNode);\n },\n ): ReactElement;\n PileRoot<Zone extends ZoneKey<Contract>>(\n props: Omit<ZonePileRootProps<Zone>, \"zone\"> & {\n zone: Zone;\n },\n ): ReactElement;\n PileCards(\n props: Omit<ZonePileCardsProps, \"renderCard\"> & {\n renderCard: (card: TypedZoneCardRenderItem<Contract>) => ReactNode;\n },\n ): ReactElement | null;\n};\n\nexport type TypedBoard<Contract extends UIContract> = Omit<\n typeof BoardPrimitive,\n | \"Target\"\n | \"SpaceTarget\"\n | \"EdgeTarget\"\n | \"VertexTarget\"\n | \"HexGrid\"\n | \"SquareGrid\"\n> & {\n Target<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n SpaceTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardSpaceTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n EdgeTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardEdgeTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n VertexTarget<Target extends BoardTargetKey<Contract>>(\n props: Omit<BoardVertexTargetProps, \"value\"> & { value: Target },\n ): ReactElement;\n HexGrid<\n TBoard extends AnyHexBoardInput,\n TSpaceView extends { id: BoardSpaceIdOf<TBoard> },\n >(\n props: Omit<BoardHexGridProps<TBoard, TSpaceView>, \"interactions\"> & {\n interactions?:\n | Exclude<BoardHexGridInteractionFilter, object>\n | {\n edge?: ReadonlyArray<InteractionKey<Contract>>;\n vertex?: ReadonlyArray<InteractionKey<Contract>>;\n space?: ReadonlyArray<InteractionKey<Contract>>;\n };\n },\n ): ReactElement;\n SquareGrid<TBoard extends AnySquareBoardInput>(\n props: Omit<BoardSquareGridProps<TBoard>, \"interactions\"> & {\n interactions?:\n | Exclude<BoardSquareGridInteractionFilter, object>\n | {\n edge?: ReadonlyArray<InteractionKey<Contract>>;\n vertex?: ReadonlyArray<InteractionKey<Contract>>;\n space?: ReadonlyArray<InteractionKey<Contract>>;\n };\n },\n ): ReactElement;\n};\n\nexport type TypedGame<\n _Contract extends UIContract,\n View = unknown,\n Player extends string = PlayerKey<_Contract>,\n Phase extends string = PhaseKey<_Contract>,\n> = Omit<typeof GamePrimitive, \"Root\"> & {\n Root(props: GameRootProps<View, Player, Phase>): ReactElement;\n Chrome(\n props: GameChromeProps<View, Player, Phase, InteractionKey<_Contract>>,\n ): ReactElement;\n};\n\nexport interface DreamboardUI<Contract extends UIContract = RegisteredUI> {\n readonly contract: Contract;\n Root(props: UIRootProps): ReactElement;\n readonly Game: TypedGame<Contract>;\n readonly Interaction: TypedInteraction<Contract>;\n readonly Prompt: TypedPrompt<Contract>;\n readonly PromptInbox: TypedPromptInbox<Contract>;\n readonly PlayerRoster: TypedPlayerRoster<Contract>;\n readonly Dice: DiceComponents;\n readonly Phase: TypedPhase<Contract>;\n readonly Zone: TypedZone<Contract>;\n readonly Board: TypedBoard<Contract>;\n}\n\nexport function createDreamboardUI<const Contract extends UIContract>(\n contract: Contract,\n): DreamboardUI<Contract> {\n return {\n contract,\n Root: UIPrimitive.Root,\n Game: GamePrimitive,\n Interaction: InteractionPrimitive,\n Prompt: PromptPrimitive,\n PromptInbox: PromptInboxPrimitive,\n PlayerRoster: PlayerRosterPrimitive,\n Dice: DicePrimitive,\n Phase: PhasePrimitive,\n Zone: ZonePrimitive,\n Board: BoardPrimitive,\n } as DreamboardUI<Contract>;\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport type {\n BoardHexGridProps,\n BoardHexViewProps,\n BoardSquareGridProps,\n} from \"../primitives/index.js\";\nimport type { BoardSpaceTargetProps } from \"../primitives/board.js\";\nimport { createBoardTargetInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceBoardSurfaceDescriptor,\n WorkspaceContractContext,\n} from \"./types.js\";\n\nexport function createUseBoardSurface<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { baseUI, runtimeBoard } = ctx;\n return function useBoardSurface() {\n return {\n Root: ({ children }: { children?: ReactNode }) =>\n createElement(baseUI.Board.Root, { children }),\n Space: (props: BoardSpaceTargetProps<string>) =>\n createElement(runtimeBoard.SpaceTarget, props),\n slot: {\n space: createBoardTargetInputSlot(ctx, \"space\"),\n playerSpace: createBoardTargetInputSlot(ctx, \"space\"),\n edge: createBoardTargetInputSlot(ctx, \"edge\"),\n vertex: createBoardTargetInputSlot(ctx, \"vertex\"),\n tile: createBoardTargetInputSlot(ctx, \"tile\"),\n },\n };\n };\n}\n\n/**\n * Assembles the `Board` namespace for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation so `HexView`/`HexGrid` keep stable\n * component identities.\n */\nexport function createBoardNamespace<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI } = ctx;\n const useBoardSurface = createUseBoardSurface(ctx);\n\n return {\n surface<Board extends string>(\n board: Board,\n ): WorkspaceBoardSurfaceDescriptor<Board> {\n return { kind: \"board\", board };\n },\n useSurface: useBoardSurface,\n HexView({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.HexView as never,\n {\n ...props,\n board: options.hexStaticBoards[boardId],\n } as BoardHexViewProps<never, never>,\n ) as ReactElement;\n },\n HexGrid({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.HexGrid as never,\n {\n ...props,\n board: options.hexStaticBoards[boardId],\n } as BoardHexGridProps<never, never>,\n ) as ReactElement;\n },\n SquareGrid({ board: boardId, ...props }: { board: string }) {\n return createElement(\n baseUI.Board.SquareGrid as never,\n {\n ...props,\n board: options.squareStaticBoards?.[boardId],\n } as BoardSquareGridProps<never>,\n ) as ReactElement;\n },\n };\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { Fragment as ReactFragment, createElement } from \"react\";\nimport { useResolvedCardTargetValue } from \"../primitives/index.js\";\nimport type {\n WorkspaceBoardTargetInputSlot,\n WorkspaceCardInputSlot,\n WorkspaceContractContext,\n WorkspaceFormInputSlot,\n} from \"./types.js\";\n\n/**\n * Render-prop body for the card surface `slot.card.Value`. Surfaces the live\n * draft value for the active interaction's card-target input — the selected\n * card-id array for `selection: \"many\"` collectors, or the single id for\n * `selection: \"one\"`. Renders nothing meaningful (`undefined`) outside an\n * `<Interaction.Root>`.\n */\nfunction CardSlotValue({\n children,\n}: {\n children: (value: unknown | undefined) => ReactNode;\n}): ReactElement {\n const value = useResolvedCardTargetValue();\n return createElement(ReactFragment, null, children(value));\n}\n\nexport function createFormInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n input: string,\n interaction?: string,\n): WorkspaceFormInputSlot {\n const { baseUI, withInteractionRoot } = ctx;\n return {\n Field: (props: { children?: ReactNode }) => {\n const field = createElement(baseUI.Interaction.Field, {\n ...props,\n input: input as never,\n });\n return interaction ? withInteractionRoot(interaction, field) : field;\n },\n Options: () => null,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(ReactFragment, null, children(undefined)),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n\nexport function createCardInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n): WorkspaceCardInputSlot {\n const { runtimeInteraction } = ctx;\n return {\n Card: ({ value, ...props }: { value: string; children?: ReactNode }) =>\n createElement(runtimeInteraction.CardInput, {\n ...props,\n input: \"cardId\",\n unsafeCardId: value,\n }),\n Cards: () => null,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(CardSlotValue, { children }),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n\nexport function createBoardTargetInputSlot<Card>(\n ctx: WorkspaceContractContext<Card>,\n kind: \"space\" | \"edge\" | \"vertex\" | \"tile\",\n): WorkspaceBoardTargetInputSlot<typeof kind> {\n const { runtimeBoard } = ctx;\n const Target = ({\n value,\n ...props\n }: {\n value: string;\n children?: ReactNode;\n }) => {\n if (kind === \"edge\") {\n return createElement(runtimeBoard.EdgeTarget, { ...props, value });\n }\n if (kind === \"vertex\") {\n return createElement(runtimeBoard.VertexTarget, { ...props, value });\n }\n return createElement(runtimeBoard.SpaceTarget, { ...props, value });\n };\n return {\n Target,\n Value: ({\n children,\n }: {\n children: (value: unknown | undefined) => ReactNode;\n }) => createElement(ReactFragment, null, children(undefined)),\n Default: ({ children }: { children?: ReactNode }) =>\n createElement(ReactFragment, null, children),\n };\n}\n","import type { ReactElement, ReactNode } from \"react\";\nimport { createElement } from \"react\";\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"../../ui/components.js\";\nimport type {\n InteractionFormPrimitiveProps,\n InteractionStateProps,\n InteractionSubmitProps,\n InteractionTriggerProps,\n} from \"../primitives/index.js\";\nimport type { InteractionDialogProps } from \"../primitives/interaction/dialog.js\";\nimport { createFormInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceContractContext,\n WorkspaceInteractionFormDescriptor,\n WorkspaceInteractionFormsDescriptor,\n} from \"./types.js\";\n\nexport interface WorkspaceInteractionFormDialogProps extends Omit<\n InteractionDialogProps,\n \"children\"\n> {\n title: ReactNode;\n description?: ReactNode;\n trigger?: ReactNode;\n children: ReactNode;\n contentClassName?: string;\n overlayClassName?: string;\n showCloseButton?: boolean;\n}\n\n/**\n * Builds the interaction-form surface pieces and the `Interaction` namespace\n * for one workspace contract. Called once per `createWorkspaceUIContract`\n * invocation so `InteractionRoutes` keeps a stable component identity.\n */\nexport function createInteractionForms<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI, runtimeInteraction, withInteractionRoot } = ctx;\n\n function InteractionRoutes({\n routes,\n fallback,\n includeUnavailable,\n }: {\n routes: Record<\n string,\n {\n collect: Record<string, unknown>;\n }\n >;\n fallback?: ReactNode;\n includeUnavailable?: boolean | null;\n }): ReactElement {\n return createElement(runtimeInteraction.Routes, {\n routes,\n fallback,\n includeUnavailable,\n });\n }\n\n function GeneratedFormDialog({\n title,\n description,\n trigger,\n children,\n contentClassName,\n overlayClassName,\n showCloseButton,\n defaultOpen,\n onStateChange,\n }: WorkspaceInteractionFormDialogProps) {\n return createElement(baseUI.Interaction.Dialog, {\n defaultOpen,\n onStateChange,\n children: (state) =>\n createElement(\n Dialog,\n { open: state.open, onOpenChange: state.setOpen },\n trigger\n ? createElement(DialogTrigger, {\n asChild: true,\n children: trigger,\n })\n : null,\n createElement(\n DialogContent,\n {\n className: contentClassName,\n overlayClassName,\n showCloseButton,\n },\n createElement(\n DialogHeader,\n null,\n createElement(DialogTitle, null, title),\n description\n ? createElement(DialogDescription, null, description)\n : null,\n ),\n children,\n ),\n ),\n });\n }\n\n function useInteractionFormSurface(interaction: string) {\n const validInputs = options.formInputKeysForInteraction(interaction);\n const slot = Object.fromEntries(\n [...validInputs].map((input) => [\n input,\n createFormInputSlot(ctx, input, interaction),\n ]),\n );\n return {\n Root: ({ children }: { children?: ReactNode }) =>\n withInteractionRoot(interaction, children),\n Form: (props: InteractionFormPrimitiveProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Form, props),\n ),\n Dialog: (props: WorkspaceInteractionFormDialogProps) =>\n withInteractionRoot(\n interaction,\n createElement(GeneratedFormDialog, props),\n ),\n State: (props: InteractionStateProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.State, props),\n ),\n Arm: (props: InteractionTriggerProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Trigger, props),\n ),\n Submit: (props: InteractionSubmitProps) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Submit, props),\n ),\n Field: ({ input, ...props }: { input: string; children?: ReactNode }) =>\n withInteractionRoot(\n interaction,\n createElement(baseUI.Interaction.Field, {\n ...props,\n input: input as never,\n }),\n ),\n slot,\n };\n }\n\n const Interaction = {\n State: baseUI.Interaction.State,\n Dialog: baseUI.Interaction.Dialog,\n useForm: useInteractionFormSurface,\n form<const Interaction extends string>(\n interaction: Interaction,\n ): WorkspaceInteractionFormDescriptor<Interaction> {\n return { kind: \"form\", interaction };\n },\n forms<const Interactions extends Readonly<Record<string, string>>>(\n interactions: Interactions,\n ): WorkspaceInteractionFormsDescriptor<Interactions> {\n return { kind: \"forms\", interactions };\n },\n Routes: InteractionRoutes,\n };\n\n return { Interaction, useInteractionFormSurface };\n}\n","import type {\n WorkspaceHandOptions,\n WorkspaceSurfaceDescriptor,\n WorkspaceSurfaceSpec,\n} from \"./types.js\";\n\ninterface SurfaceResolverDeps {\n readonly Board: {\n useSurface(name: string): unknown;\n };\n readonly Zone: {\n useHand(name: string, zoneOptions: WorkspaceHandOptions): unknown;\n usePile(name: string, zoneOptions: { zone: string }): unknown;\n useCardCollection(\n name: string,\n zoneOptions: { zones: readonly string[]; mode?: \"all\" | \"top-card\" },\n ): unknown;\n };\n readonly useInteractionFormSurface: (interaction: string) => unknown;\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isSurfaceDescriptor(\n value: unknown,\n): value is WorkspaceSurfaceDescriptor {\n return (\n isPlainObject(value) &&\n typeof (value as { kind?: unknown }).kind === \"string\"\n );\n}\n\n/**\n * Builds the surface-spec resolvers for one workspace contract.\n */\nexport function createSurfaceResolvers({\n Board,\n Zone,\n useInteractionFormSurface,\n}: SurfaceResolverDeps) {\n const boardSurface = Board.useSurface;\n const zoneHandSurface = Zone.useHand;\n const zonePileSurface = Zone.usePile;\n const zoneCardCollectionSurface = Zone.useCardCollection;\n const interactionFormSurface = useInteractionFormSurface;\n\n function resolveSurfaceDescriptor(\n name: string,\n descriptor: WorkspaceSurfaceDescriptor,\n ): unknown {\n switch (descriptor.kind) {\n case \"board\":\n return boardSurface(name);\n case \"hand\":\n return zoneHandSurface(name, {\n zone: descriptor.zone,\n role: descriptor.role,\n label: descriptor.label,\n order: descriptor.order,\n });\n case \"pile\":\n return zonePileSurface(name, { zone: descriptor.zone });\n case \"piles\":\n return Object.fromEntries(\n descriptor.zones.map((zone) => [\n zone,\n zonePileSurface(String(zone), { zone }),\n ]),\n );\n case \"cardCollection\":\n return zoneCardCollectionSurface(name, {\n zones: descriptor.zones,\n mode: descriptor.mode,\n });\n case \"form\":\n return interactionFormSurface(descriptor.interaction);\n case \"forms\":\n return Object.fromEntries(\n Object.entries(descriptor.interactions).map(([key, interaction]) => [\n key,\n interactionFormSurface(interaction),\n ]),\n );\n }\n }\n\n function resolveSurfaceSpec(spec: WorkspaceSurfaceSpec): unknown {\n return Object.fromEntries(\n Object.entries(spec).map(([key, value]) => [\n key,\n isSurfaceDescriptor(value)\n ? resolveSurfaceDescriptor(key, value)\n : resolveSurfaceSpec(value as WorkspaceSurfaceSpec),\n ]),\n );\n }\n\n function defineSurfaces<const Spec extends WorkspaceSurfaceSpec>(spec: Spec) {\n return function useDefinedSurfaces() {\n return resolveSurfaceSpec(spec);\n };\n }\n\n return { defineSurfaces, resolveSurfaceSpec, resolveSurfaceDescriptor };\n}\n","import type { ButtonHTMLAttributes, ReactNode } from \"react\";\nimport { Fragment as ReactFragment, createElement } from \"react\";\nimport { clsx } from \"clsx\";\nimport { useAuthoredPluginGameplayFrameSelector } from \"../context/PluginGameplayFrameContext.js\";\nimport { CardFace, type ViewCard } from \"../../ui.js\";\nimport type { InteractionCardInputRenderState } from \"../primitives/index.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport { createHandPieces } from \"./hand.js\";\nimport { createCardInputSlot } from \"./slots.js\";\nimport type {\n WorkspaceCardCollectionSurfaceDescriptor,\n WorkspaceContractContext,\n WorkspaceHandOptions,\n WorkspaceHandSurfaceDescriptor,\n WorkspacePileSurfaceDescriptor,\n WorkspacePilesSurfaceDescriptor,\n} from \"./types.js\";\n\nconst DEFAULT_ZONE_CARD_CLASS =\n \"group relative border-0 bg-transparent p-0 transition-transform enabled:cursor-pointer enabled:hover:-translate-y-2 data-[selected=true]:-translate-y-3 disabled:cursor-not-allowed data-[eligible=false]:opacity-45 data-[eligible=false]:grayscale data-[eligible=false]:hover:translate-y-0 data-[card-available=false]:opacity-45 data-[card-available=false]:grayscale\";\n\nfunction cardRenderItemToViewCard(card: unknown, cardId: string): ViewCard {\n if (\n card &&\n typeof card === \"object\" &&\n \"hidden\" in card &&\n (card as { hidden?: unknown }).hidden === false\n ) {\n return card as unknown as ViewCard;\n }\n return {\n id: cardId,\n cardType: \"hidden\",\n name: \"Hidden card\",\n properties: {},\n };\n}\n\nexport function createZoneCardsComponent<Card>(\n ctx: WorkspaceContractContext<Card>,\n zones: readonly string[],\n) {\n const { baseUI, runtimeZone } = ctx;\n return ({\n empty,\n children,\n ...props\n }: {\n empty?: ReactNode;\n children: (card: Card) => ReactNode;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) =>\n createElement(\n ReactFragment,\n null,\n ...zones.map((zone) =>\n createElement(baseUI.Zone.Root, {\n key: zone,\n zone: zone as never,\n children: createElement(runtimeZone.List, {\n ...props,\n empty,\n children,\n }),\n }),\n ),\n );\n}\n\nexport function createZoneCardComponent<Card>(\n ctx: WorkspaceContractContext<Card>,\n) {\n const { options, baseUI, runtimeInteraction } = ctx;\n return ({\n card,\n children,\n className,\n ...props\n }: {\n card: Card;\n children?: ReactNode;\n } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, \"type\" | \"value\">) => {\n const cardId = options.cardIdFromZoneCard(card);\n const zone = options.zoneIdFromZoneCard(card);\n const viewCard = cardRenderItemToViewCard(card, cardId);\n const faceDown =\n !!card &&\n typeof card === \"object\" &&\n \"hidden\" in card &&\n (card as { hidden?: unknown }).hidden === true;\n const renderCardFace = (state: InteractionCardInputRenderState) =>\n createElement(CardFace, {\n card: viewCard,\n selected: state.selected,\n disabled: state.disabled || !state.eligible,\n faceDown,\n size: \"sm\",\n children,\n });\n const match = useAuthoredPluginGameplayFrameSelector((frame) => {\n const candidates = frame.zones[zone]?.playableByCardId[cardId] ?? [];\n const orderedCandidates = [...candidates].sort((left, right) => {\n const leftAvailable = left.availability.status === \"available\";\n const rightAvailable = right.availability.status === \"available\";\n return leftAvailable === rightAvailable ? 0 : leftAvailable ? -1 : 1;\n });\n for (const descriptor of orderedCandidates) {\n const input = descriptor.inputs.find(\n (candidateInput) =>\n candidateInput.domain.type === \"cardTarget\" &&\n candidateInput.domain.projection === \"resolved\" &&\n candidateInput.domain.eligibleTargets.includes(cardId),\n );\n if (input) return { descriptor, input };\n }\n return null;\n });\n if (!match) {\n return createElement(\n \"div\",\n {\n ...props,\n className: clsx(\"relative inline-flex\", className),\n \"data-dreamboard-zone-card\": \"\",\n \"data-card-id\": cardId,\n \"data-zone\": zone,\n \"data-interactive\": false,\n },\n createElement(CardFace, {\n card: viewCard,\n faceDown,\n size: \"sm\",\n children,\n }),\n );\n }\n return createElement(baseUI.Zone.Root, {\n zone: zone as never,\n children: createElement(runtimeInteraction.Root, {\n interaction: match.descriptor.interactionKey,\n children: createElement(runtimeInteraction.CardInput, {\n ...props,\n className: clsx(DEFAULT_ZONE_CARD_CLASS, className),\n input: match.input.key,\n unsafeCardId: cardId,\n children: renderCardFace,\n }),\n }),\n });\n };\n}\n\n/**\n * Assembles the `Zone` namespace for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation.\n */\nexport function createZoneNamespace<Card>(ctx: WorkspaceContractContext<Card>) {\n const {\n createHandCardsComponent,\n createStagingComponent,\n HandCardsSlot,\n HandSummarySlot,\n HandActionsSlot,\n } = createHandPieces(ctx);\n\n return {\n hand<Zone extends string>(\n zone: Zone,\n options: Omit<WorkspaceHandSurfaceDescriptor<Zone>, \"kind\" | \"zone\">,\n ): WorkspaceHandSurfaceDescriptor<Zone> {\n return { kind: \"hand\", zone, ...options };\n },\n pile<Zone extends string>(\n zone: Zone,\n ): WorkspacePileSurfaceDescriptor<Zone> {\n return { kind: \"pile\", zone };\n },\n piles<const Zones extends readonly string[]>(\n zones: Zones,\n ): WorkspacePilesSurfaceDescriptor<Zones> {\n return { kind: \"piles\", zones };\n },\n collection<const Zones extends readonly string[]>(\n zones: Zones,\n options: { mode?: \"all\" | \"top-card\" } = {},\n ): WorkspaceCardCollectionSurfaceDescriptor<Zones> {\n return { kind: \"cardCollection\", zones, mode: options.mode };\n },\n useHand(_name: string, zoneOptions: WorkspaceHandOptions) {\n const handComponentOptions = {\n name: _name,\n zone: zoneOptions.zone,\n role: zoneOptions.role,\n label: zoneOptions.label,\n order: zoneOptions.order,\n };\n return {\n Hand: createHandCardsComponent(handComponentOptions),\n Cards: HandCardsSlot,\n Summary: HandSummarySlot,\n Actions: HandActionsSlot,\n Card: createZoneCardComponent(ctx),\n Staging: createStagingComponent(handComponentOptions),\n slot: { card: createCardInputSlot(ctx) },\n };\n },\n usePile(_name: string, zoneOptions: { zone: string }) {\n return {\n Pile: createZoneCardsComponent(ctx, [zoneOptions.zone]),\n Card: createZoneCardComponent(ctx),\n };\n },\n useCardCollection(\n _name: string,\n zoneOptions: { zones: readonly string[]; mode?: \"all\" | \"top-card\" },\n ) {\n void zoneOptions.mode;\n return {\n Collection: createZoneCardsComponent(ctx, zoneOptions.zones),\n Card: createZoneCardComponent(ctx),\n slot: { card: createCardInputSlot(ctx) },\n };\n },\n };\n}\n","import type { ReactNode } from \"react\";\nimport { Children, createElement, isValidElement, useMemo } from \"react\";\nimport { clsx } from \"clsx\";\nimport { useIsMobile } from \"../../ui.js\";\nimport { useRegisterMobileHand } from \"../../ui/components.js\";\nimport { useZoneCards } from \"../primitives/index.js\";\nimport {\n HandSurfaceView,\n HandStagingView,\n dropTargetIdFor,\n type HandSelectionSummary,\n type HandSurfaceViewProps,\n type RuntimeDropTarget,\n} from \"../primitives/hand-surface.js\";\nimport type { AuthoredCardIntent } from \"../primitives/hand-intent-adapter.js\";\nimport type {\n CardDropTargetVisualState,\n HandInteractionPolicy,\n HandLayoutKind,\n HandLayoutPolicy,\n InteractionVisualState,\n} from \"../../ui.js\";\nimport type { ZoneListProps } from \"../primitives/zone.js\";\nimport { isInteractionAvailable } from \"../utils/interaction-status.js\";\nimport type {\n WorkspaceContractContext,\n WorkspaceHandComponentOptions,\n} from \"./types.js\";\n\n/**\n * Builds the hand-surface pieces for one workspace contract. Called once per\n * `createWorkspaceUIContract` invocation so `GeneratedHandCards` keeps a\n * single stable component identity per contract (its `useRegisterMobileHand`\n * registration depends on this).\n */\nexport function createHandPieces<Card>(ctx: WorkspaceContractContext<Card>) {\n const { baseUI } = ctx;\n\n function HandCardsSlot({\n children,\n }: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n }) {\n void children;\n return createElement(\"template\", { \"data-dreamboard-hand-cards-slot\": \"\" });\n }\n\n function HandSummarySlot({\n children,\n }: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n }) {\n void children;\n return createElement(\"template\", {\n \"data-dreamboard-hand-summary-slot\": \"\",\n });\n }\n\n function HandActionsSlot({\n children,\n }: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n }) {\n void children;\n return createElement(\"template\", {\n \"data-dreamboard-hand-actions-slot\": \"\",\n });\n }\n\n function renderHandSlot(\n slot: ReactNode | ((summary: HandSelectionSummary) => ReactNode),\n summary: HandSelectionSummary,\n ): ReactNode {\n return typeof slot === \"function\" ? slot(summary) : slot;\n }\n\n function createHandCardsComponent(options: WorkspaceHandComponentOptions) {\n return ({\n empty,\n children,\n className,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n onSelectionSummary,\n ...props\n }: {\n empty?: ReactNode;\n children:\n | ReactNode\n | ((card: Card, state: InteractionVisualState) => ReactNode);\n className?: string;\n layout?: HandLayoutKind | HandLayoutPolicy;\n mobileInteraction?: HandInteractionPolicy;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n dropTargets?: ReadonlyArray<{\n target:\n | { kind: \"card\"; card: string }\n | { kind: \"space\"; target: string }\n | { kind: \"edge\"; target: string }\n | { kind: \"vertex\"; target: string }\n | { kind: \"tile\"; target: string };\n label: string;\n render: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n role?: string;\n order?: number;\n }>;\n renderDropTargets?: (children: ReactNode) => ReactNode;\n onCardIntent?: (intent: AuthoredCardIntent) => void;\n onSelectionSummary?: (summary: HandSelectionSummary) => void;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) => {\n const slots = collectHandSlots(children);\n const renderCard =\n typeof children === \"function\" ? children : slots.cards?.children;\n if (!renderCard) {\n throw new Error(\n \"Generated hand surfaces require exactly one <hand.Cards> slot.\",\n );\n }\n const summaryRenderer = slots.summary\n ? (summary: HandSelectionSummary) =>\n renderHandSlot(slots.summary!.children, summary)\n : undefined;\n const actionsRenderer = slots.actions\n ? (summary: HandSelectionSummary) =>\n renderHandSlot(slots.actions!.children, summary)\n : undefined;\n return createElement(baseUI.Zone.Root, {\n zone: options.zone as never,\n // Fill the author's container instead of shrink-wrapping to the fan's\n // own measured width. Without a definite width here, a centering parent\n // sizes to the cards row, the hand measures that, recomputes a new fan\n // width, and the layout chases itself (a ResizeObserver loop). `w-full`\n // pins the outermost hand element to the available width and breaks the\n // cycle for every author layout.\n className: \"w-full min-w-0\",\n children: createElement(GeneratedHandCards, {\n ...props,\n hand: options,\n className,\n empty,\n children: renderCard,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n summarySlot: summaryRenderer,\n actionsSlot: actionsRenderer,\n onSelectionSummary,\n }),\n });\n };\n }\n\n function collectHandSlots(\n children:\n | ReactNode\n | ((card: Card, state: InteractionVisualState) => ReactNode),\n ): {\n cards?: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n summary?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n actions?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } {\n const slots: {\n cards?: {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n summary?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n actions?: {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } = {};\n if (typeof children === \"function\") return slots;\n for (const child of Children.toArray(children)) {\n if (!isValidElement(child)) continue;\n if (child.type === HandCardsSlot) {\n if (slots.cards) {\n throw new Error(\"Only one <hand.Cards> slot may be rendered.\");\n }\n slots.cards = child.props as {\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n };\n } else if (child.type === HandSummarySlot) {\n if (slots.summary) {\n throw new Error(\"Only one <hand.Summary> slot may be rendered.\");\n }\n slots.summary = child.props as {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n } else if (child.type === HandActionsSlot) {\n if (slots.actions) {\n throw new Error(\"Only one <hand.Actions> slot may be rendered.\");\n }\n slots.actions = child.props as {\n children: ReactNode | ((summary: HandSelectionSummary) => ReactNode);\n };\n }\n }\n return slots;\n }\n\n function GeneratedHandCards({\n hand,\n empty,\n children,\n className,\n sort,\n layout,\n mobileInteraction,\n cardSize,\n ariaLabel,\n dropTargets,\n renderDropTargets,\n onCardIntent,\n summarySlot,\n actionsSlot,\n onSelectionSummary,\n }: {\n hand: WorkspaceHandComponentOptions;\n empty?: ReactNode;\n children: (card: Card, state: InteractionVisualState) => ReactNode;\n className?: string;\n layout?: HandLayoutKind | HandLayoutPolicy;\n mobileInteraction?: HandInteractionPolicy;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n dropTargets?: ReadonlyArray<{\n target:\n | { kind: \"card\"; card: string }\n | { kind: \"space\"; target: string }\n | { kind: \"edge\"; target: string }\n | { kind: \"vertex\"; target: string }\n | { kind: \"tile\"; target: string };\n label: string;\n render: (state: CardDropTargetVisualState) => ReactNode;\n className?: string;\n role?: string;\n order?: number;\n }>;\n renderDropTargets?: (children: ReactNode) => ReactNode;\n onCardIntent?: (intent: AuthoredCardIntent) => void;\n summarySlot?: (summary: HandSelectionSummary) => ReactNode;\n actionsSlot?: (summary: HandSelectionSummary) => ReactNode;\n onSelectionSummary?: (summary: HandSelectionSummary) => void;\n } & Omit<ZoneListProps, \"children\" | \"empty\">) {\n const isMobile = useIsMobile();\n const { items, count } = useZoneCards({ sort });\n // One predictable presentation for every hand: the projected surface\n // (fan on desktop, tray on mobile by default). Authors choose other shapes\n // explicitly with `layout` (e.g. layout=\"strip\"). We no longer fall back to\n // a bare scroll strip when no interaction props are passed, so the layout —\n // and the eligible/selected projection — stays consistent across phases.\n const handClassName = clsx(\"min-h-[112px]\", className);\n const resolvedDropTargets = useMemo<RuntimeDropTarget[] | undefined>(() => {\n if (!dropTargets || dropTargets.length === 0) return undefined;\n return dropTargets.map((dt) => {\n const value =\n dt.target.kind === \"card\" ? dt.target.card : dt.target.target;\n return {\n targetId: dropTargetIdFor(dt.target.kind, value),\n label: dt.label,\n render: dt.render,\n className: dt.className,\n role: dt.role,\n order: dt.order,\n };\n });\n }, [dropTargets]);\n const content = useMemo(\n () =>\n createElement(HandSurfaceView, {\n zone: hand.zone,\n cards: items,\n renderCard: (card, state) => children(card as Card, state),\n layout,\n mobileInteraction,\n dropTargets: resolvedDropTargets,\n renderDropTargets,\n cardSize,\n renderEmpty: empty !== undefined ? () => empty : undefined,\n ariaLabel,\n onIntentRouted: onCardIntent\n ? (intent) => onCardIntent(intent)\n : undefined,\n summarySlot,\n actionsSlot,\n onSelectionSummary,\n className: handClassName,\n } satisfies HandSurfaceViewProps<(typeof items)[number]>),\n [\n ariaLabel,\n cardSize,\n children,\n empty,\n hand.zone,\n handClassName,\n items,\n layout,\n mobileInteraction,\n onCardIntent,\n onSelectionSummary,\n actionsSlot,\n renderDropTargets,\n summarySlot,\n resolvedDropTargets,\n ],\n );\n const active = items.some(\n (item) =>\n !item.hidden &&\n item.interactions.some((descriptor) =>\n isInteractionAvailable(descriptor),\n ),\n );\n const autoOpen = items.some(\n (item) =>\n !item.hidden &&\n item.interactions.some(\n (descriptor) =>\n isInteractionAvailable(descriptor) &&\n descriptor.inputs.some(\n (input) =>\n input.domain.type === \"cardTarget\" &&\n input.domain.selection?.mode === \"many\",\n ),\n ),\n );\n const version = items\n .map((item) =>\n item.hidden\n ? `${item.id}:hidden`\n : `${item.id}:${item.cardType}:${JSON.stringify(item.properties)}`,\n )\n .join(\"|\");\n const registration = useMemo(\n () => ({\n id: `${hand.name}:${hand.zone}`,\n zone: hand.zone,\n label: hand.label,\n role: hand.role,\n order: hand.order,\n version,\n count,\n active,\n autoOpen,\n content: createElement(baseUI.Zone.Root, {\n zone: hand.zone as never,\n children: content,\n }),\n }),\n [\n active,\n autoOpen,\n content,\n count,\n hand.label,\n hand.name,\n hand.order,\n hand.role,\n hand.zone,\n version,\n ],\n );\n useRegisterMobileHand(registration);\n\n return isMobile ? null : content;\n }\n\n function createStagingComponent(options: WorkspaceHandComponentOptions) {\n return ({\n children,\n label,\n renderEmptySlot,\n cardSize,\n ariaLabel,\n className,\n }: {\n children: (card: Card) => ReactNode;\n label?: ReactNode;\n renderEmptySlot?: (index: number) => ReactNode;\n cardSize?: \"sm\" | \"md\" | \"lg\";\n ariaLabel?: string;\n className?: string;\n }) =>\n createElement(HandStagingView, {\n zone: options.zone,\n renderCard: (card) => children(card as Card),\n renderEmptySlot,\n label,\n cardSize,\n ariaLabel,\n className,\n });\n }\n\n return {\n createHandCardsComponent,\n createStagingComponent,\n HandCardsSlot,\n HandSummarySlot,\n HandActionsSlot,\n };\n}\n"],"mappings":"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","names":["createElement","createElement","createElement","createElement","createElement","Interaction","Board","Zone","ReactFragment","createElement","clsx","createElement","createElement","createElement","ReactFragment","clsx","createElement","Interaction","Board","Zone","UI"]}
|