@dreamboard-games/sdk 0.5.0-alpha.2 → 0.5.0-alpha.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +462 -53
  2. package/dist/board-element-CqtxU5VZ.d.ts +13 -0
  3. package/dist/chunk-3RFGPBES.js +1792 -0
  4. package/dist/chunk-3RFGPBES.js.map +1 -0
  5. package/dist/chunk-CZRPUWCT.js +1602 -0
  6. package/dist/chunk-CZRPUWCT.js.map +1 -0
  7. package/dist/chunk-DMSXVMYY.js +7199 -0
  8. package/dist/chunk-DMSXVMYY.js.map +1 -0
  9. package/dist/chunk-U6R7FAH4.js +630 -0
  10. package/dist/chunk-U6R7FAH4.js.map +1 -0
  11. package/dist/chunk-YT3RPO5J.js +635 -0
  12. package/dist/chunk-YT3RPO5J.js.map +1 -0
  13. package/dist/diagnostics-ZAPEBlJP.d.ts +64 -0
  14. package/dist/extract-CwJWDrSD.d.ts +6850 -0
  15. package/dist/index.d.ts +5177 -1
  16. package/dist/index.js +1990 -6
  17. package/dist/index.js.map +1 -1
  18. package/dist/react.d.ts +158 -0
  19. package/dist/react.js +1119 -0
  20. package/dist/react.js.map +1 -0
  21. package/dist/reducer.d.ts +1028 -97
  22. package/dist/reducer.js +4892 -125
  23. package/dist/reducer.js.map +1 -1
  24. package/dist/shortcuts-B_RrufOM.d.ts +822 -0
  25. package/dist/testing.d.ts +529 -569
  26. package/dist/testing.js +2588 -934
  27. package/dist/testing.js.map +1 -1
  28. package/dist/types-BxXRINRF.d.ts +118 -0
  29. package/package.json +39 -144
  30. package/dist/HandView-Bi2lxzQP.d.ts +0 -79
  31. package/dist/ResourceCounter-BFxJknqp.d.ts +0 -98
  32. package/dist/ThemeProvider-CElaL2ik.d.ts +0 -99
  33. package/dist/attributes-DbvyMbXw.d.ts +0 -68
  34. package/dist/browser-interaction.d.ts +0 -910
  35. package/dist/browser-interaction.js +0 -119
  36. package/dist/browser-interaction.js.map +0 -1
  37. package/dist/chunk-32PFKDV7.js +0 -11705
  38. package/dist/chunk-32PFKDV7.js.map +0 -1
  39. package/dist/chunk-3BAD4VC2.js +0 -263
  40. package/dist/chunk-3BAD4VC2.js.map +0 -1
  41. package/dist/chunk-3SKDNDPG.js +0 -104
  42. package/dist/chunk-3SKDNDPG.js.map +0 -1
  43. package/dist/chunk-5YV2WHJ4.js +0 -25
  44. package/dist/chunk-5YV2WHJ4.js.map +0 -1
  45. package/dist/chunk-ANRB4XKA.js +0 -90
  46. package/dist/chunk-ANRB4XKA.js.map +0 -1
  47. package/dist/chunk-BI4G3PM2.js +0 -1864
  48. package/dist/chunk-BI4G3PM2.js.map +0 -1
  49. package/dist/chunk-EVCLTY4Q.js +0 -935
  50. package/dist/chunk-EVCLTY4Q.js.map +0 -1
  51. package/dist/chunk-GDPKTBUR.js +0 -564
  52. package/dist/chunk-GDPKTBUR.js.map +0 -1
  53. package/dist/chunk-H6VDGFL5.js +0 -2903
  54. package/dist/chunk-H6VDGFL5.js.map +0 -1
  55. package/dist/chunk-LR3ZTWQF.js +0 -5960
  56. package/dist/chunk-LR3ZTWQF.js.map +0 -1
  57. package/dist/chunk-PF7L4BMG.js +0 -117
  58. package/dist/chunk-PF7L4BMG.js.map +0 -1
  59. package/dist/chunk-PN5O6GG2.js +0 -32
  60. package/dist/chunk-PN5O6GG2.js.map +0 -1
  61. package/dist/chunk-PZ5AY32C.js +0 -10
  62. package/dist/chunk-PZ5AY32C.js.map +0 -1
  63. package/dist/chunk-S2JEDVWH.js +0 -7165
  64. package/dist/chunk-S2JEDVWH.js.map +0 -1
  65. package/dist/chunk-T3ZKNUZ7.js +0 -1
  66. package/dist/chunk-T3ZKNUZ7.js.map +0 -1
  67. package/dist/chunk-UGH54WZ2.js +0 -223
  68. package/dist/chunk-UGH54WZ2.js.map +0 -1
  69. package/dist/chunk-VCDWP5VL.js +0 -746
  70. package/dist/chunk-VCDWP5VL.js.map +0 -1
  71. package/dist/chunk-VDXOF4FW.js +0 -69
  72. package/dist/chunk-VDXOF4FW.js.map +0 -1
  73. package/dist/chunk-WHR5UW3F.js +0 -1988
  74. package/dist/chunk-WHR5UW3F.js.map +0 -1
  75. package/dist/chunk-Y75CFE77.js +0 -17
  76. package/dist/chunk-Y75CFE77.js.map +0 -1
  77. package/dist/chunk-Z7QCREWI.js +0 -3435
  78. package/dist/chunk-Z7QCREWI.js.map +0 -1
  79. package/dist/chunk-ZZGN2ATS.js +0 -1941
  80. package/dist/chunk-ZZGN2ATS.js.map +0 -1
  81. package/dist/components-gAbIz7hK.d.ts +0 -1284
  82. package/dist/definitions-BgmV_GhC.d.ts +0 -300
  83. package/dist/diagnostics-DIi3ina7.d.ts +0 -50
  84. package/dist/digest.d.ts +0 -8
  85. package/dist/game-CsZScpcn.d.ts +0 -763
  86. package/dist/hex-board-view-aKkblDp6.d.ts +0 -1228
  87. package/dist/index-CcT9Q7N7.d.ts +0 -193
  88. package/dist/index.d-DjzoK7zn.d.ts +0 -2101
  89. package/dist/package-set.d.ts +0 -13
  90. package/dist/package-set.js +0 -12
  91. package/dist/package-set.js.map +0 -1
  92. package/dist/player-state-Cqpyeql0.d.ts +0 -371
  93. package/dist/plugin-runtime-contract.d.ts +0 -17
  94. package/dist/plugin-runtime-contract.js +0 -92
  95. package/dist/plugin-runtime-contract.js.map +0 -1
  96. package/dist/primitive-props-BNHDkgd7.d.ts +0 -16
  97. package/dist/protocol-dYgafTYY.d.ts +0 -314
  98. package/dist/reducer/advanced.d.ts +0 -82
  99. package/dist/reducer/advanced.js +0 -51
  100. package/dist/reducer/advanced.js.map +0 -1
  101. package/dist/reducer-contract.d.ts +0 -11
  102. package/dist/reducer-contract.js +0 -16
  103. package/dist/reducer-contract.js.map +0 -1
  104. package/dist/reference-games/index.d.ts +0 -31
  105. package/dist/reference-games/index.js +0 -48
  106. package/dist/reference-games/index.js.map +0 -1
  107. package/dist/runtime/primitives.d.ts +0 -250
  108. package/dist/runtime/primitives.js +0 -189
  109. package/dist/runtime/primitives.js.map +0 -1
  110. package/dist/runtime/runtime-api.d.ts +0 -2
  111. package/dist/runtime/runtime-api.js +0 -1
  112. package/dist/runtime/runtime-api.js.map +0 -1
  113. package/dist/runtime/workspace-contract.d.ts +0 -392
  114. package/dist/runtime/workspace-contract.js +0 -28
  115. package/dist/runtime/workspace-contract.js.map +0 -1
  116. package/dist/runtime-RJ5orDJU.d.ts +0 -1699
  117. package/dist/runtime-api-Bz5pwNU_.d.ts +0 -296
  118. package/dist/runtime-json-CQ9QbLZ5.d.ts +0 -5
  119. package/dist/runtime.d.ts +0 -83
  120. package/dist/runtime.js +0 -242
  121. package/dist/runtime.js.map +0 -1
  122. package/dist/schema.d.ts +0 -379
  123. package/dist/stale-contract-artifact-error-XLaweZtF.d.ts +0 -18
  124. package/dist/testing-compiler.d.ts +0 -37
  125. package/dist/testing-compiler.js +0 -272
  126. package/dist/testing-compiler.js.map +0 -1
  127. package/dist/testing-runtime.d.ts +0 -119
  128. package/dist/testing-runtime.js +0 -212
  129. package/dist/testing-runtime.js.map +0 -1
  130. package/dist/types-DJj5MJkl.d.ts +0 -256
  131. package/dist/types-DR7DoB1x.d.ts +0 -28
  132. package/dist/types-JWCYHmu7.d.ts +0 -122
  133. package/dist/types.d.ts +0 -1958
  134. package/dist/types.js +0 -14
  135. package/dist/types.js.map +0 -1
  136. package/dist/ui/components.d.ts +0 -17
  137. package/dist/ui/components.js +0 -216
  138. package/dist/ui/components.js.map +0 -1
  139. package/dist/ui/defaults.d.ts +0 -19
  140. package/dist/ui/defaults.js +0 -104
  141. package/dist/ui/defaults.js.map +0 -1
  142. package/dist/ui/player-state.d.ts +0 -2
  143. package/dist/ui/player-state.js +0 -1
  144. package/dist/ui/player-state.js.map +0 -1
  145. package/dist/ui/plugin-styles.css +0 -2
  146. package/dist/ui-contract-GTUPkf8z.d.ts +0 -1168
  147. package/dist/ui.d.ts +0 -317
  148. package/dist/ui.js +0 -277
  149. package/dist/ui.js.map +0 -1
  150. package/dist/views-BpuWcOyN.d.ts +0 -1641
@@ -1,263 +0,0 @@
1
- import {
2
- InteractionUiProvider,
3
- PluginGameplayFrameProvider,
4
- PluginSessionProvider,
5
- RuntimeContext,
6
- usePluginSession
7
- } from "./chunk-GDPKTBUR.js";
8
- import {
9
- HostToPluginEnvelopeSchema,
10
- RuntimeJsonSchema
11
- } from "./chunk-VCDWP5VL.js";
12
-
13
- // src/runtime/core/create-plugin-runtime-client.ts
14
- var defaultClock = {
15
- now: () => Date.now()
16
- };
17
- var defaultIdFactory = {
18
- nextId: (prefix) => {
19
- const cryptoLike = globalThis.crypto;
20
- if (cryptoLike?.randomUUID) {
21
- try {
22
- return `${prefix}-${cryptoLike.randomUUID()}`;
23
- } catch {
24
- }
25
- }
26
- return `${prefix}-${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
27
- }
28
- };
29
- function createSubmissionError(result) {
30
- const error = new Error(result.message ?? "Submission failed");
31
- error.name = "SubmissionError";
32
- error.errorCode = result.errorCode;
33
- return error;
34
- }
35
- function createPluginRuntimeClient(options) {
36
- const clock = options.clock ?? defaultClock;
37
- const idFactory = options.idFactory ?? defaultIdFactory;
38
- const requestTimeoutMs = options.requestTimeoutMs ?? 1e4;
39
- let session = null;
40
- let frame = null;
41
- let disconnected = false;
42
- let stopTransport;
43
- const sessionListeners = /* @__PURE__ */ new Set();
44
- const frameListeners = /* @__PURE__ */ new Set();
45
- const pendingSubmissions = /* @__PURE__ */ new Map();
46
- const notifySession = () => {
47
- for (const listener of sessionListeners) {
48
- listener();
49
- }
50
- };
51
- const notifyFrame = () => {
52
- for (const listener of frameListeners) {
53
- listener();
54
- }
55
- };
56
- const currentBasis = () => {
57
- if (!frame) {
58
- throw new Error("Plugin runtime has not received a gameplay frame.");
59
- }
60
- return frame.basis;
61
- };
62
- const sendRuntimeError = (message, code) => {
63
- if (disconnected) {
64
- return;
65
- }
66
- options.transport.send({
67
- type: "runtime.error",
68
- message,
69
- ...code ? { code } : {}
70
- });
71
- };
72
- const handleHostMessage = (rawMessage) => {
73
- if (disconnected) {
74
- return;
75
- }
76
- const parseResult = HostToPluginEnvelopeSchema.safeParse(rawMessage);
77
- if (!parseResult.success) {
78
- sendRuntimeError(
79
- "Invalid host-to-plugin protocol envelope.",
80
- "invalid-envelope"
81
- );
82
- return;
83
- }
84
- const message = parseResult.data;
85
- const clientReceivedAtMs = clock.now();
86
- switch (message.payload.type) {
87
- case "runtime.init": {
88
- session = message.payload.session;
89
- notifySession();
90
- options.transport.send({ type: "runtime.ready" });
91
- options.transport.send({
92
- type: "runtime.ack",
93
- sequence: message.sequence,
94
- clientReceivedAtMs
95
- });
96
- break;
97
- }
98
- case "gameplay.frame": {
99
- frame = message.payload.frame;
100
- notifyFrame();
101
- const sendRenderedAck = () => {
102
- if (disconnected) {
103
- return;
104
- }
105
- options.transport.send({
106
- type: "runtime.ack",
107
- sequence: message.sequence,
108
- clientReceivedAtMs,
109
- clientRenderedAtMs: clock.now()
110
- });
111
- };
112
- if (typeof requestAnimationFrame === "function") {
113
- requestAnimationFrame(sendRenderedAck);
114
- } else {
115
- queueMicrotask(sendRenderedAck);
116
- }
117
- break;
118
- }
119
- case "interaction.result": {
120
- const pending = pendingSubmissions.get(message.payload.clientActionId);
121
- if (!pending) {
122
- break;
123
- }
124
- pendingSubmissions.delete(message.payload.clientActionId);
125
- if (message.payload.accepted) {
126
- pending.resolve();
127
- } else {
128
- pending.reject(createSubmissionError(message.payload));
129
- }
130
- break;
131
- }
132
- default: {
133
- const _exhaustive = message.payload;
134
- return _exhaustive;
135
- }
136
- }
137
- };
138
- stopTransport = options.transport.start(handleHostMessage);
139
- const rejectPending = () => {
140
- for (const pending of pendingSubmissions.values()) {
141
- const error = new Error("Plugin runtime disconnected");
142
- error.name = "SubmissionError";
143
- error.errorCode = "runtime-disconnected";
144
- pending.reject(error);
145
- }
146
- pendingSubmissions.clear();
147
- };
148
- return {
149
- getSession: () => session,
150
- subscribeSession: (listener) => {
151
- sessionListeners.add(listener);
152
- return () => {
153
- sessionListeners.delete(listener);
154
- };
155
- },
156
- getFrame: () => frame,
157
- subscribeFrame: (listener) => {
158
- frameListeners.add(listener);
159
- return () => {
160
- frameListeners.delete(listener);
161
- };
162
- },
163
- submitInteraction: async (interactionId, params) => new Promise((resolve, reject) => {
164
- if (disconnected) {
165
- const error = new Error("Plugin runtime disconnected");
166
- error.name = "SubmissionError";
167
- error.errorCode = "runtime-disconnected";
168
- reject(error);
169
- return;
170
- }
171
- const parsedParams = RuntimeJsonSchema.safeParse(params);
172
- if (!parsedParams.success) {
173
- const error = new Error(
174
- "Interaction params must be runtime JSON."
175
- );
176
- error.name = "SubmissionError";
177
- error.errorCode = "invalid-runtime-json";
178
- reject(error);
179
- return;
180
- }
181
- let basis;
182
- try {
183
- basis = currentBasis();
184
- } catch (error) {
185
- const submissionError = new Error(
186
- error instanceof Error ? error.message : "Plugin runtime is not ready."
187
- );
188
- submissionError.name = "SubmissionError";
189
- submissionError.errorCode = "runtime-not-ready";
190
- reject(submissionError);
191
- return;
192
- }
193
- const clientActionId = idFactory.nextId("action");
194
- pendingSubmissions.set(clientActionId, { resolve, reject });
195
- options.transport.send({
196
- type: "interaction.submit",
197
- clientActionId,
198
- basis,
199
- interactionId,
200
- params: parsedParams.data
201
- });
202
- setTimeout(() => {
203
- const pending = pendingSubmissions.get(clientActionId);
204
- if (!pending) {
205
- return;
206
- }
207
- pendingSubmissions.delete(clientActionId);
208
- const error = new Error("Submission request timed out");
209
- error.name = "SubmissionError";
210
- error.errorCode = "submission-timeout";
211
- pending.reject(error);
212
- }, requestTimeoutMs);
213
- }),
214
- disconnect: () => {
215
- disconnected = true;
216
- stopTransport?.();
217
- stopTransport = void 0;
218
- sessionListeners.clear();
219
- frameListeners.clear();
220
- rejectPending();
221
- session = null;
222
- frame = null;
223
- }
224
- };
225
- }
226
-
227
- // src/runtime/components/PluginRuntimeBoundary.tsx
228
- import { useMemo } from "react";
229
- import { jsx } from "react/jsx-runtime";
230
- function runtimeApiFromClient(runtime) {
231
- return {
232
- submitInteraction: (interactionId, params) => runtime.submitInteraction(interactionId, params),
233
- getSessionState: () => {
234
- const session = runtime.getSession();
235
- const frame = runtime.getFrame();
236
- return {
237
- status: session ? "ready" : "loading",
238
- sessionId: session?.sessionId ?? null,
239
- controllingPlayerId: frame?.basis.perspectivePlayerId ?? null
240
- };
241
- },
242
- disconnect: () => runtime.disconnect()
243
- };
244
- }
245
- function PluginRuntimeBoundary({
246
- runtime,
247
- children
248
- }) {
249
- const runtimeApi = useMemo(() => runtimeApiFromClient(runtime), [runtime]);
250
- return /* @__PURE__ */ jsx(RuntimeContext.Provider, { value: runtimeApi, children: /* @__PURE__ */ jsx(PluginSessionProvider, { runtime, children: /* @__PURE__ */ jsx(PluginGameplayFrameProvider, { runtime, children: /* @__PURE__ */ jsx(SessionScopedInteractionUiProvider, { children }) }) }) });
251
- }
252
- function SessionScopedInteractionUiProvider({
253
- children
254
- }) {
255
- const { controllingPlayerId } = usePluginSession();
256
- return /* @__PURE__ */ jsx(InteractionUiProvider, { children }, controllingPlayerId ?? "__no_player__");
257
- }
258
-
259
- export {
260
- createPluginRuntimeClient,
261
- PluginRuntimeBoundary
262
- };
263
- //# sourceMappingURL=chunk-3BAD4VC2.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/runtime/core/create-plugin-runtime-client.ts","../src/runtime/components/PluginRuntimeBoundary.tsx"],"sourcesContent":["import {\n HostToPluginEnvelopeSchema,\n RuntimeJsonSchema,\n type GameplayBasis,\n type HostToPluginEnvelope,\n type InteractionResult,\n type PluginGameplayFrame,\n type PluginSessionDescriptor,\n} from \"@dreamboard-games/plugin-runtime-contract\";\nimport type {\n PluginRuntimeClient,\n PluginRuntimeClientOptions,\n RuntimeClock,\n RuntimeIdFactory,\n} from \"./types.js\";\n\nconst defaultClock: RuntimeClock = {\n now: () => Date.now(),\n};\n\nconst defaultIdFactory: RuntimeIdFactory = {\n nextId: (prefix) => {\n const cryptoLike = (\n globalThis as typeof globalThis & {\n crypto?: { randomUUID?: () => string };\n }\n ).crypto;\n if (cryptoLike?.randomUUID) {\n try {\n return `${prefix}-${cryptoLike.randomUUID()}`;\n } catch {\n // Fall through to deterministic-enough fallback for older test DOMs.\n }\n }\n return `${prefix}-${Date.now().toString(16)}-${Math.random()\n .toString(16)\n .slice(2)}`;\n },\n};\n\nfunction createSubmissionError(\n result: Extract<InteractionResult, { accepted: false }>,\n): Error & { errorCode?: string } {\n const error = new Error(result.message ?? \"Submission failed\") as Error & {\n errorCode?: string;\n };\n error.name = \"SubmissionError\";\n error.errorCode = result.errorCode;\n return error;\n}\n\nexport function createPluginRuntimeClient(\n options: PluginRuntimeClientOptions,\n): PluginRuntimeClient {\n const clock = options.clock ?? defaultClock;\n const idFactory = options.idFactory ?? defaultIdFactory;\n const requestTimeoutMs = options.requestTimeoutMs ?? 10_000;\n let session: PluginSessionDescriptor | null = null;\n let frame: PluginGameplayFrame | null = null;\n let disconnected = false;\n let stopTransport: (() => void) | undefined;\n const sessionListeners = new Set<() => void>();\n const frameListeners = new Set<() => void>();\n const pendingSubmissions = new Map<\n string,\n {\n resolve: () => void;\n reject: (error: Error & { errorCode?: string }) => void;\n }\n >();\n\n const notifySession = () => {\n for (const listener of sessionListeners) {\n listener();\n }\n };\n\n const notifyFrame = () => {\n for (const listener of frameListeners) {\n listener();\n }\n };\n\n const currentBasis = (): GameplayBasis => {\n if (!frame) {\n throw new Error(\"Plugin runtime has not received a gameplay frame.\");\n }\n return frame.basis;\n };\n\n const sendRuntimeError = (message: string, code?: string) => {\n if (disconnected) {\n return;\n }\n options.transport.send({\n type: \"runtime.error\",\n message,\n ...(code ? { code } : {}),\n });\n };\n\n const handleHostMessage = (rawMessage: HostToPluginEnvelope) => {\n if (disconnected) {\n return;\n }\n const parseResult = HostToPluginEnvelopeSchema.safeParse(rawMessage);\n if (!parseResult.success) {\n sendRuntimeError(\n \"Invalid host-to-plugin protocol envelope.\",\n \"invalid-envelope\",\n );\n return;\n }\n const message = parseResult.data;\n const clientReceivedAtMs = clock.now();\n\n switch (message.payload.type) {\n case \"runtime.init\": {\n session = message.payload.session;\n notifySession();\n options.transport.send({ type: \"runtime.ready\" });\n options.transport.send({\n type: \"runtime.ack\",\n sequence: message.sequence,\n clientReceivedAtMs,\n });\n break;\n }\n case \"gameplay.frame\": {\n frame = message.payload.frame;\n notifyFrame();\n const sendRenderedAck = () => {\n if (disconnected) {\n return;\n }\n options.transport.send({\n type: \"runtime.ack\",\n sequence: message.sequence,\n clientReceivedAtMs,\n clientRenderedAtMs: clock.now(),\n });\n };\n if (typeof requestAnimationFrame === \"function\") {\n requestAnimationFrame(sendRenderedAck);\n } else {\n queueMicrotask(sendRenderedAck);\n }\n break;\n }\n case \"interaction.result\": {\n const pending = pendingSubmissions.get(message.payload.clientActionId);\n if (!pending) {\n break;\n }\n pendingSubmissions.delete(message.payload.clientActionId);\n if (message.payload.accepted) {\n pending.resolve();\n } else {\n pending.reject(createSubmissionError(message.payload));\n }\n break;\n }\n default: {\n const _exhaustive: never = message.payload;\n return _exhaustive;\n }\n }\n };\n\n stopTransport = options.transport.start(handleHostMessage);\n\n const rejectPending = () => {\n for (const pending of pendingSubmissions.values()) {\n const error = new Error(\"Plugin runtime disconnected\") as Error & {\n errorCode?: string;\n };\n error.name = \"SubmissionError\";\n error.errorCode = \"runtime-disconnected\";\n pending.reject(error);\n }\n pendingSubmissions.clear();\n };\n\n return {\n getSession: () => session,\n subscribeSession: (listener) => {\n sessionListeners.add(listener);\n return () => {\n sessionListeners.delete(listener);\n };\n },\n getFrame: () => frame,\n subscribeFrame: (listener) => {\n frameListeners.add(listener);\n return () => {\n frameListeners.delete(listener);\n };\n },\n submitInteraction: async (interactionId, params) =>\n new Promise((resolve, reject) => {\n if (disconnected) {\n const error = new Error(\"Plugin runtime disconnected\") as Error & {\n errorCode?: string;\n };\n error.name = \"SubmissionError\";\n error.errorCode = \"runtime-disconnected\";\n reject(error);\n return;\n }\n const parsedParams = RuntimeJsonSchema.safeParse(params);\n if (!parsedParams.success) {\n const error = new Error(\n \"Interaction params must be runtime JSON.\",\n ) as Error & { errorCode?: string };\n error.name = \"SubmissionError\";\n error.errorCode = \"invalid-runtime-json\";\n reject(error);\n return;\n }\n let basis: GameplayBasis;\n try {\n basis = currentBasis();\n } catch (error) {\n const submissionError = new Error(\n error instanceof Error\n ? error.message\n : \"Plugin runtime is not ready.\",\n ) as Error & { errorCode?: string };\n submissionError.name = \"SubmissionError\";\n submissionError.errorCode = \"runtime-not-ready\";\n reject(submissionError);\n return;\n }\n const clientActionId = idFactory.nextId(\"action\");\n pendingSubmissions.set(clientActionId, { resolve, reject });\n options.transport.send({\n type: \"interaction.submit\",\n clientActionId,\n basis,\n interactionId,\n params: parsedParams.data,\n });\n setTimeout(() => {\n const pending = pendingSubmissions.get(clientActionId);\n if (!pending) {\n return;\n }\n pendingSubmissions.delete(clientActionId);\n const error = new Error(\"Submission request timed out\") as Error & {\n errorCode?: string;\n };\n error.name = \"SubmissionError\";\n error.errorCode = \"submission-timeout\";\n pending.reject(error);\n }, requestTimeoutMs);\n }),\n disconnect: () => {\n disconnected = true;\n stopTransport?.();\n stopTransport = undefined;\n sessionListeners.clear();\n frameListeners.clear();\n rejectPending();\n session = null;\n frame = null;\n },\n };\n}\n","import React, { useMemo } from \"react\";\nimport { InteractionUiProvider } from \"../context/InteractionDraftContext.js\";\nimport {\n PluginSessionProvider,\n usePluginSession,\n} from \"../context/PluginSessionContext.js\";\nimport { PluginGameplayFrameProvider } from \"../context/PluginGameplayFrameContext.js\";\nimport { RuntimeContext } from \"../context/RuntimeContext.js\";\nimport type { PluginRuntimeClient } from \"../core/types.js\";\nimport type { RuntimeAPI } from \"../types/runtime-api.js\";\n\nfunction runtimeApiFromClient(runtime: PluginRuntimeClient): RuntimeAPI {\n return {\n submitInteraction: (interactionId, params) =>\n runtime.submitInteraction(interactionId, params),\n getSessionState: () => {\n const session = runtime.getSession();\n const frame = runtime.getFrame();\n return {\n status: session ? \"ready\" : \"loading\",\n sessionId: session?.sessionId ?? null,\n controllingPlayerId: frame?.basis.perspectivePlayerId ?? null,\n };\n },\n disconnect: () => runtime.disconnect(),\n };\n}\n\nexport function PluginRuntimeBoundary({\n runtime,\n children,\n}: {\n runtime: PluginRuntimeClient;\n children: React.ReactNode;\n}) {\n const runtimeApi = useMemo(() => runtimeApiFromClient(runtime), [runtime]);\n\n return (\n <RuntimeContext.Provider value={runtimeApi}>\n <PluginSessionProvider runtime={runtime}>\n <PluginGameplayFrameProvider runtime={runtime}>\n <SessionScopedInteractionUiProvider>\n {children}\n </SessionScopedInteractionUiProvider>\n </PluginGameplayFrameProvider>\n </PluginSessionProvider>\n </RuntimeContext.Provider>\n );\n}\n\nfunction SessionScopedInteractionUiProvider({\n children,\n}: {\n children: React.ReactNode;\n}) {\n const { controllingPlayerId } = usePluginSession();\n return (\n <InteractionUiProvider key={controllingPlayerId ?? \"__no_player__\"}>\n {children}\n </InteractionUiProvider>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,104 +0,0 @@
1
- import {
2
- useTheme
3
- } from "./chunk-32PFKDV7.js";
4
-
5
- // src/ui/helpers/track-board.ts
6
- function positionForLayout(layout, index, count) {
7
- if (layout.type === "linear") {
8
- const spacing = layout.spacing ?? 72;
9
- const origin = layout.origin ?? { x: 0, y: 0 };
10
- return layout.axis === "y" ? { x: origin.x, y: origin.y + index * spacing } : { x: origin.x + index * spacing, y: origin.y };
11
- }
12
- const startAngleDeg = layout.startAngleDeg ?? -90;
13
- const clockwise = layout.clockwise ?? true;
14
- const angleStep = count === 0 ? 0 : 360 / count;
15
- const angleDeg = startAngleDeg + (clockwise ? 1 : -1) * angleStep * index;
16
- const angle = angleDeg * Math.PI / 180;
17
- return {
18
- x: layout.center.x + Math.cos(angle) * layout.radius,
19
- y: layout.center.y + Math.sin(angle) * layout.radius
20
- };
21
- }
22
- function defaultNextSpaces(board, spaceId) {
23
- const relations = board.relations ?? [];
24
- return relations.flatMap((relation) => {
25
- if (relation.fromSpaceId === spaceId) {
26
- return [relation.toSpaceId];
27
- }
28
- if (!relation.directed && relation.toSpaceId === spaceId) {
29
- return [relation.fromSpaceId];
30
- }
31
- return [];
32
- });
33
- }
34
- function toTrackBoardData(board, options) {
35
- const spaces = Object.values(board.spaces);
36
- const orderedSpaces = [...spaces].sort(
37
- (left, right) => left.id.localeCompare(right.id)
38
- );
39
- return {
40
- spaces: orderedSpaces.map((space, index, allSpaces) => ({
41
- id: space.id,
42
- index,
43
- name: space.name ?? void 0,
44
- type: space.typeId ?? void 0,
45
- nextSpaces: options.getNextSpaces?.(space, board) ?? defaultNextSpaces(board, space.id),
46
- jumpTo: options.getJumpTo?.(space, board),
47
- position: "getPosition" in options && options.getPosition ? options.getPosition(space, index, allSpaces) : positionForLayout(options.layout, index, allSpaces.length),
48
- data: space.fields
49
- })),
50
- pieces: (options.pieces ?? []).map((piece) => ({
51
- id: piece.id,
52
- spaceId: piece.spaceId,
53
- owner: piece.owner,
54
- type: piece.typeId ?? void 0,
55
- data: piece.fields
56
- }))
57
- };
58
- }
59
-
60
- // src/ui/theme/board.ts
61
- import { useMemo } from "react";
62
- function useBoardTheme() {
63
- const theme = useTheme();
64
- return useMemo(() => deriveBoardTheme(theme), [theme]);
65
- }
66
- function deriveBoardTheme(theme) {
67
- return {
68
- frameBorder: theme.component.board.frameBorder,
69
- frameBackground: theme.component.board.frameBackground,
70
- hoverRing: theme.component.board.hoverRing,
71
- eligibleHint: theme.component.board.eligibleHint,
72
- tileBorder: theme.semantic.border.default,
73
- tileBorderSubtle: theme.semantic.border.subtle,
74
- tileText: theme.semantic.text.primary,
75
- ringWidth: 3
76
- };
77
- }
78
-
79
- // src/ui/types/hex-color.ts
80
- var HEX_COLOR_PATTERN = /^#[0-9A-Fa-f]{6}$/;
81
- function isHexColor(value) {
82
- return typeof value === "string" && HEX_COLOR_PATTERN.test(value);
83
- }
84
- function parseHexColor(value) {
85
- return isHexColor(value) ? value : void 0;
86
- }
87
- function hexColor(value) {
88
- if (!isHexColor(value)) {
89
- throw new Error(
90
- `Expected a 6-digit hex color such as #E53935, received '${value}'.`
91
- );
92
- }
93
- return value;
94
- }
95
-
96
- export {
97
- toTrackBoardData,
98
- useBoardTheme,
99
- deriveBoardTheme,
100
- isHexColor,
101
- parseHexColor,
102
- hexColor
103
- };
104
- //# sourceMappingURL=chunk-3SKDNDPG.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ui/helpers/track-board.ts","../src/ui/theme/board.ts","../src/ui/types/hex-color.ts"],"sourcesContent":["import type { TrackPiece, TrackSpace } from \"../components/board/TrackBoard.js\";\n\ninterface GenericBoardSpaceLike<\n SpaceIdValue extends string = string,\n Fields = Record<string, unknown>,\n> {\n id: SpaceIdValue;\n name?: string | null;\n typeId?: string | null;\n fields: Fields;\n}\n\ninterface GenericBoardRelationLike<SpaceIdValue extends string = string> {\n fromSpaceId: SpaceIdValue;\n toSpaceId: SpaceIdValue;\n directed: boolean;\n}\n\nexport interface GenericBoardLike<\n BoardIdValue extends string = string,\n SpaceIdValue extends string = string,\n SpaceFields = Record<string, unknown>,\n> {\n id: BoardIdValue;\n spaces: Readonly<\n Record<SpaceIdValue, GenericBoardSpaceLike<SpaceIdValue, SpaceFields>>\n >;\n relations?: ReadonlyArray<GenericBoardRelationLike<SpaceIdValue>>;\n}\n\nexport interface TrackBoardPieceLike<\n PieceIdValue extends string = string,\n SpaceIdValue extends string = string,\n OwnerIdValue extends string = string,\n Fields = unknown,\n> {\n id: PieceIdValue;\n spaceId: SpaceIdValue;\n owner: OwnerIdValue;\n typeId?: string | null;\n fields?: Fields;\n}\n\ntype BoardSpaceOf<TBoard extends GenericBoardLike> =\n TBoard[\"spaces\"][keyof TBoard[\"spaces\"]];\ntype SpaceIdOf<TBoard extends GenericBoardLike> =\n BoardSpaceOf<TBoard> extends {\n id: infer Id extends string;\n }\n ? Id\n : never;\ntype SpaceFieldsOf<TBoard extends GenericBoardLike> =\n BoardSpaceOf<TBoard> extends { fields: infer Fields } ? Fields : never;\ntype PieceIdOf<TPiece extends TrackBoardPieceLike> = TPiece extends {\n id: infer Id extends string;\n}\n ? Id\n : never;\ntype PieceOwnerOf<TPiece extends TrackBoardPieceLike> = TPiece extends {\n owner: infer Owner extends string;\n}\n ? Owner\n : never;\ntype PieceFieldsOf<TPiece extends TrackBoardPieceLike> = TPiece extends {\n fields?: infer Fields;\n}\n ? Fields\n : never;\n\ntype TrackLayout =\n | {\n type: \"linear\";\n axis?: \"x\" | \"y\";\n spacing?: number;\n origin?: { x: number; y: number };\n }\n | {\n type: \"circular\";\n center: { x: number; y: number };\n radius: number;\n startAngleDeg?: number;\n clockwise?: boolean;\n };\n\ntype PositionOptions<TBoard extends GenericBoardLike> =\n | {\n getPosition: (\n space: BoardSpaceOf<TBoard>,\n index: number,\n spaces: ReadonlyArray<BoardSpaceOf<TBoard>>,\n ) => { x: number; y: number };\n layout?: never;\n }\n | {\n getPosition?: never;\n layout: TrackLayout;\n };\n\nexport type ToTrackBoardDataOptions<\n TBoard extends GenericBoardLike,\n TPiece extends TrackBoardPieceLike<\n string,\n SpaceIdOf<TBoard>,\n string,\n unknown\n >,\n> = PositionOptions<TBoard> & {\n pieces?: readonly TPiece[];\n getNextSpaces?: (\n space: BoardSpaceOf<TBoard>,\n board: TBoard,\n ) => ReadonlyArray<SpaceIdOf<TBoard>> | undefined;\n getJumpTo?: (\n space: BoardSpaceOf<TBoard>,\n board: TBoard,\n ) => SpaceIdOf<TBoard> | undefined;\n};\n\nfunction positionForLayout(\n layout: TrackLayout,\n index: number,\n count: number,\n): { x: number; y: number } {\n if (layout.type === \"linear\") {\n const spacing = layout.spacing ?? 72;\n const origin = layout.origin ?? { x: 0, y: 0 };\n return layout.axis === \"y\"\n ? { x: origin.x, y: origin.y + index * spacing }\n : { x: origin.x + index * spacing, y: origin.y };\n }\n\n const startAngleDeg = layout.startAngleDeg ?? -90;\n const clockwise = layout.clockwise ?? true;\n const angleStep = count === 0 ? 0 : 360 / count;\n const angleDeg = startAngleDeg + (clockwise ? 1 : -1) * angleStep * index;\n const angle = (angleDeg * Math.PI) / 180;\n return {\n x: layout.center.x + Math.cos(angle) * layout.radius,\n y: layout.center.y + Math.sin(angle) * layout.radius,\n };\n}\n\nfunction defaultNextSpaces<TBoard extends GenericBoardLike>(\n board: TBoard,\n spaceId: SpaceIdOf<TBoard>,\n): Array<SpaceIdOf<TBoard>> {\n const relations = board.relations ?? [];\n return relations.flatMap((relation) => {\n if (relation.fromSpaceId === spaceId) {\n return [relation.toSpaceId];\n }\n if (!relation.directed && relation.toSpaceId === spaceId) {\n return [relation.fromSpaceId];\n }\n return [];\n }) as Array<SpaceIdOf<TBoard>>;\n}\n\nexport function toTrackBoardData<\n TBoard extends GenericBoardLike,\n TPiece extends TrackBoardPieceLike<\n string,\n SpaceIdOf<TBoard>,\n string,\n unknown\n >,\n>(\n board: TBoard,\n options: ToTrackBoardDataOptions<TBoard, TPiece>,\n): {\n spaces: Array<TrackSpace<SpaceIdOf<TBoard>, SpaceFieldsOf<TBoard>>>;\n pieces: Array<\n TrackPiece<\n PieceIdOf<TPiece>,\n SpaceIdOf<TBoard>,\n PieceOwnerOf<TPiece>,\n PieceFieldsOf<TPiece>\n >\n >;\n} {\n const spaces = Object.values(board.spaces) as Array<BoardSpaceOf<TBoard>>;\n const orderedSpaces = [...spaces].sort((left, right) =>\n left.id.localeCompare(right.id),\n );\n\n return {\n spaces: orderedSpaces.map((space, index, allSpaces) => ({\n id: space.id as SpaceIdOf<TBoard>,\n index,\n name: space.name ?? undefined,\n type: space.typeId ?? undefined,\n nextSpaces: (options.getNextSpaces?.(space, board) ??\n defaultNextSpaces(board, space.id as SpaceIdOf<TBoard>)) as Array<\n SpaceIdOf<TBoard>\n >,\n jumpTo: options.getJumpTo?.(space, board),\n position:\n \"getPosition\" in options && options.getPosition\n ? options.getPosition(space, index, allSpaces)\n : positionForLayout(options.layout, index, allSpaces.length),\n data: space.fields as SpaceFieldsOf<TBoard>,\n })),\n pieces: (options.pieces ?? []).map((piece) => ({\n id: piece.id as PieceIdOf<TPiece>,\n spaceId: piece.spaceId,\n owner: piece.owner as PieceOwnerOf<TPiece>,\n type: piece.typeId ?? undefined,\n data: piece.fields as PieceFieldsOf<TPiece>,\n })),\n };\n}\n","/**\n * Board theming helpers.\n *\n * The SDK's board renderers (`<HexGrid>`, `<SquareGrid>`,\n * `<NetworkGraph>`, `<ZoneMap>`, `<TrackBoard>`, `<SlotSystem>`) need a\n * tiny but consistent set of visual tokens — frame border, frame fill,\n * eligible-target hint, and active hover ring — so authors don't have\n * to re-pick colours per board. {@link useBoardTheme} exposes those\n * tokens, derived from the active {@link Theme}.\n */\n\nimport { useMemo } from \"react\";\nimport { useTheme } from \"./ThemeProvider.js\";\nimport type { Theme } from \"./tokens.js\";\n\n/**\n * Resolved board tokens consumed by board renderers and per-tile\n * default renderers. All values are CSS-ready strings.\n */\nexport interface BoardTheme {\n /** Border drawn around the board's outer frame. */\n readonly frameBorder: string;\n /** Background painted under the tile renderer (visible at tile gaps). */\n readonly frameBackground: string;\n /** Hover-state ring drawn over an interactive target. */\n readonly hoverRing: string;\n /** Idle hint colour for an eligible-but-unhovered target. */\n readonly eligibleHint: string;\n /** Border drawn on inactive tiles (matches semantic.border.default). */\n readonly tileBorder: string;\n /** Subtle dotted border for non-interactive scaffolding (e.g. ports). */\n readonly tileBorderSubtle: string;\n /** Foreground used for board labels (numbers, port ratios). */\n readonly tileText: string;\n /** Recommended ring stroke width in px for hover/eligible markers. */\n readonly ringWidth: number;\n}\n\n/**\n * Derive a {@link BoardTheme} from the active theme. Memoised on the\n * theme reference so consumers can pass it straight to a board's\n * `defaultTileProps` / `defaultEdgeProps` slots.\n */\nexport function useBoardTheme(): BoardTheme {\n const theme = useTheme();\n return useMemo(() => deriveBoardTheme(theme), [theme]);\n}\n\n/** Standalone derivation for renderers that already hold a {@link Theme}. */\nexport function deriveBoardTheme(theme: Theme): BoardTheme {\n return {\n frameBorder: theme.component.board.frameBorder,\n frameBackground: theme.component.board.frameBackground,\n hoverRing: theme.component.board.hoverRing,\n eligibleHint: theme.component.board.eligibleHint,\n tileBorder: theme.semantic.border.default,\n tileBorderSubtle: theme.semantic.border.subtle,\n tileText: theme.semantic.text.primary,\n ringWidth: 3,\n };\n}\n","export type HexColor = string & { readonly __brand: \"HexColor\" };\n\nconst HEX_COLOR_PATTERN = /^#[0-9A-Fa-f]{6}$/;\n\nexport function isHexColor(value: unknown): value is HexColor {\n return typeof value === \"string\" && HEX_COLOR_PATTERN.test(value);\n}\n\nexport function parseHexColor(value: unknown): HexColor | undefined {\n return isHexColor(value) ? value : undefined;\n}\n\nexport function hexColor(value: string): HexColor {\n if (!isHexColor(value)) {\n throw new Error(\n `Expected a 6-digit hex color such as #E53935, received '${value}'.`,\n );\n }\n return value;\n}\n"],"mappings":"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","names":[]}
@@ -1,25 +0,0 @@
1
- // ../sdk-types/dist/index.js
2
- function defineTopologyManifest(manifest) {
3
- return manifest;
4
- }
5
- function buildTypedRecord(ids, initial) {
6
- const createValue = typeof initial === "function" ? initial : () => initial;
7
- return Object.fromEntries(ids.map((id) => [id, createValue(id)]));
8
- }
9
- function isTypedId(ids, value) {
10
- return ids.includes(value);
11
- }
12
- function expectTypedId(ids, value, description) {
13
- if (isTypedId(ids, value)) {
14
- return value;
15
- }
16
- throw new Error(`Unknown ${description} '${value}'.`);
17
- }
18
-
19
- export {
20
- defineTopologyManifest,
21
- buildTypedRecord,
22
- isTypedId,
23
- expectTypedId
24
- };
25
- //# sourceMappingURL=chunk-5YV2WHJ4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../sdk-types/dist/index.js"],"sourcesContent":["// src/authoring.ts\nfunction defineTopologyManifest(manifest) {\n return manifest;\n}\n\n// src/generated-helpers.ts\nfunction buildTypedRecord(ids, initial) {\n const createValue = typeof initial === \"function\" ? initial : () => initial;\n return Object.fromEntries(ids.map((id) => [id, createValue(id)]));\n}\nfunction isTypedId(ids, value) {\n return ids.includes(value);\n}\nfunction expectTypedId(ids, value, description) {\n if (isTypedId(ids, value)) {\n return value;\n }\n throw new Error(`Unknown ${description} '${value}'.`);\n}\nexport {\n buildTypedRecord,\n defineTopologyManifest,\n expectTypedId,\n isTypedId\n};\n"],"mappings":";AACA,SAAS,uBAAuB,UAAU;AACxC,SAAO;AACT;AAGA,SAAS,iBAAiB,KAAK,SAAS;AACtC,QAAM,cAAc,OAAO,YAAY,aAAa,UAAU,MAAM;AACpE,SAAO,OAAO,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC,CAAC;AAClE;AACA,SAAS,UAAU,KAAK,OAAO;AAC7B,SAAO,IAAI,SAAS,KAAK;AAC3B;AACA,SAAS,cAAc,KAAK,OAAO,aAAa;AAC9C,MAAI,UAAU,KAAK,KAAK,GAAG;AACzB,WAAO;AAAA,EACT;AACA,QAAM,IAAI,MAAM,WAAW,WAAW,KAAK,KAAK,IAAI;AACtD;","names":[]}
@@ -1,90 +0,0 @@
1
- // src/reducer/setup-bootstrap-helpers.ts
2
- function shuffle(container) {
3
- return {
4
- type: "shuffle",
5
- container
6
- };
7
- }
8
- function dealToPlayerZone({
9
- from,
10
- zoneId,
11
- count,
12
- playerIds
13
- }) {
14
- return {
15
- type: "deal",
16
- from,
17
- to: {
18
- type: "playerZone",
19
- zoneId
20
- },
21
- count,
22
- playerIds
23
- };
24
- }
25
- function dealToPlayerBoardContainer({
26
- from,
27
- boardId,
28
- containerId,
29
- count,
30
- playerIds
31
- }) {
32
- return {
33
- type: "deal",
34
- from,
35
- to: {
36
- type: "playerBoardContainer",
37
- boardId,
38
- containerId
39
- },
40
- count,
41
- playerIds
42
- };
43
- }
44
- function seedSharedBoardContainer({
45
- from,
46
- boardId,
47
- containerId,
48
- count,
49
- componentIds
50
- }) {
51
- return {
52
- type: "move",
53
- from,
54
- to: {
55
- type: "sharedBoardContainer",
56
- boardId,
57
- containerId
58
- },
59
- count,
60
- componentIds
61
- };
62
- }
63
- function seedSharedBoardSpace({
64
- from,
65
- boardId,
66
- spaceId,
67
- count,
68
- componentIds
69
- }) {
70
- return {
71
- type: "move",
72
- from,
73
- to: {
74
- type: "sharedBoardSpace",
75
- boardId,
76
- spaceId
77
- },
78
- count,
79
- componentIds
80
- };
81
- }
82
-
83
- export {
84
- shuffle,
85
- dealToPlayerZone,
86
- dealToPlayerBoardContainer,
87
- seedSharedBoardContainer,
88
- seedSharedBoardSpace
89
- };
90
- //# sourceMappingURL=chunk-ANRB4XKA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/reducer/setup-bootstrap-helpers.ts"],"sourcesContent":["import type {\n CardIdOfManifest,\n DieIdOfManifest,\n ReducerManifestContractLike,\n PieceIdOfManifest,\n PlayerIdOfManifest,\n SetupBootstrapContainerRef,\n SetupBootstrapPerPlayerContainerTemplateRef,\n SetupBootstrapStep,\n SetupBootstrapDestinationRef,\n} from \"./model\";\n\nexport function shuffle<\n Manifest extends ReducerManifestContractLike = ReducerManifestContractLike,\n>(\n container: SetupBootstrapContainerRef<Manifest>,\n): SetupBootstrapStep<Manifest> {\n return {\n type: \"shuffle\",\n container,\n };\n}\n\nexport function dealToPlayerZone<\n Manifest extends ReducerManifestContractLike = ReducerManifestContractLike,\n>({\n from,\n zoneId,\n count,\n playerIds,\n}: {\n from: Extract<\n SetupBootstrapContainerRef<Manifest>,\n { type: \"sharedZone\" | \"sharedBoardContainer\" }\n >;\n zoneId: Extract<\n SetupBootstrapPerPlayerContainerTemplateRef<Manifest>,\n { type: \"playerZone\" }\n >[\"zoneId\"];\n count: number;\n playerIds?: readonly PlayerIdOfManifest<Manifest>[];\n}): SetupBootstrapStep<Manifest> {\n return {\n type: \"deal\",\n from,\n to: {\n type: \"playerZone\",\n zoneId,\n } as SetupBootstrapPerPlayerContainerTemplateRef<Manifest>,\n count,\n playerIds,\n };\n}\n\nexport function dealToPlayerBoardContainer<\n Manifest extends ReducerManifestContractLike = ReducerManifestContractLike,\n>({\n from,\n boardId,\n containerId,\n count,\n playerIds,\n}: {\n from: Extract<\n SetupBootstrapContainerRef<Manifest>,\n { type: \"sharedZone\" | \"sharedBoardContainer\" }\n >;\n boardId: Extract<\n SetupBootstrapPerPlayerContainerTemplateRef<Manifest>,\n { type: \"playerBoardContainer\" }\n >[\"boardId\"];\n containerId: Extract<\n SetupBootstrapPerPlayerContainerTemplateRef<Manifest>,\n { type: \"playerBoardContainer\" }\n >[\"containerId\"];\n count: number;\n playerIds?: readonly PlayerIdOfManifest<Manifest>[];\n}): SetupBootstrapStep<Manifest> {\n return {\n type: \"deal\",\n from,\n to: {\n type: \"playerBoardContainer\",\n boardId,\n containerId,\n } as SetupBootstrapPerPlayerContainerTemplateRef<Manifest>,\n count,\n playerIds,\n };\n}\n\nexport function seedSharedBoardContainer<\n Manifest extends ReducerManifestContractLike = ReducerManifestContractLike,\n>({\n from,\n boardId,\n containerId,\n count,\n componentIds,\n}: {\n from: SetupBootstrapContainerRef<Manifest>;\n boardId: Extract<\n SetupBootstrapDestinationRef<Manifest>,\n { type: \"sharedBoardContainer\" }\n >[\"boardId\"];\n containerId: Extract<\n SetupBootstrapDestinationRef<Manifest>,\n { type: \"sharedBoardContainer\" }\n >[\"containerId\"];\n count?: number;\n componentIds?: readonly (\n | CardIdOfManifest<Manifest>\n | PieceIdOfManifest<Manifest>\n | DieIdOfManifest<Manifest>\n )[];\n}): SetupBootstrapStep<Manifest> {\n return {\n type: \"move\",\n from,\n to: {\n type: \"sharedBoardContainer\",\n boardId,\n containerId,\n } as SetupBootstrapDestinationRef<Manifest>,\n count,\n componentIds,\n };\n}\n\nexport function seedSharedBoardSpace<\n Manifest extends ReducerManifestContractLike = ReducerManifestContractLike,\n>({\n from,\n boardId,\n spaceId,\n count,\n componentIds,\n}: {\n from: SetupBootstrapContainerRef<Manifest>;\n boardId: Extract<\n SetupBootstrapDestinationRef<Manifest>,\n { type: \"sharedBoardSpace\" }\n >[\"boardId\"];\n spaceId: Extract<\n SetupBootstrapDestinationRef<Manifest>,\n { type: \"sharedBoardSpace\" }\n >[\"spaceId\"];\n count?: number;\n componentIds?: readonly (\n | CardIdOfManifest<Manifest>\n | PieceIdOfManifest<Manifest>\n | DieIdOfManifest<Manifest>\n )[];\n}): SetupBootstrapStep<Manifest> {\n return {\n type: \"move\",\n from,\n to: {\n type: \"sharedBoardSpace\",\n boardId,\n spaceId,\n } as SetupBootstrapDestinationRef<Manifest>,\n count,\n componentIds,\n };\n}\n"],"mappings":";AAYO,SAAS,QAGd,WAC8B;AAC9B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,EACF;AACF;AAEO,SAAS,iBAEd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAWiC;AAC/B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,2BAEd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAeiC;AAC/B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,yBAEd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAgBiC;AAC/B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,qBAEd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAgBiC;AAC/B,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","names":[]}