@dreamboard-games/sdk 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (369) hide show
  1. package/LICENSE.md +96 -0
  2. package/README.md +12 -0
  3. package/dist/HandView-ncJIVLhN.d.ts +193 -0
  4. package/dist/ResourceCounter-CTREyF73.d.ts +102 -0
  5. package/dist/ThemeProvider-fy0_QzgO.d.ts +99 -0
  6. package/dist/bundle-TIZcw8LB.d.ts +281 -0
  7. package/dist/cards-Sl3b40Mv.d.ts +13 -0
  8. package/dist/chunk-7YAHLYBR.js +481 -0
  9. package/dist/chunk-7YAHLYBR.js.map +1 -0
  10. package/dist/chunk-FDNZTDD6.js +8085 -0
  11. package/dist/chunk-FDNZTDD6.js.map +1 -0
  12. package/dist/chunk-GKKBPPSW.js +598 -0
  13. package/dist/chunk-GKKBPPSW.js.map +1 -0
  14. package/dist/chunk-I46YJSOD.js +1 -0
  15. package/dist/chunk-I46YJSOD.js.map +1 -0
  16. package/dist/chunk-KAELH4KC.js +104 -0
  17. package/dist/chunk-KAELH4KC.js.map +1 -0
  18. package/dist/chunk-PZ5AY32C.js +10 -0
  19. package/dist/chunk-PZ5AY32C.js.map +1 -0
  20. package/dist/chunk-T3ZKNUZ7.js +1 -0
  21. package/dist/chunk-T3ZKNUZ7.js.map +1 -0
  22. package/dist/chunk-T52J5RMF.js +1 -0
  23. package/dist/chunk-T52J5RMF.js.map +1 -0
  24. package/dist/chunk-TDSWKVZ4.js +5401 -0
  25. package/dist/chunk-TDSWKVZ4.js.map +1 -0
  26. package/dist/chunk-U5C6BONG.js +34 -0
  27. package/dist/chunk-U5C6BONG.js.map +1 -0
  28. package/dist/chunk-VDXOF4FW.js +69 -0
  29. package/dist/chunk-VDXOF4FW.js.map +1 -0
  30. package/dist/chunk-VFTAA4WO.js +115 -0
  31. package/dist/chunk-VFTAA4WO.js.map +1 -0
  32. package/dist/chunk-WN74KVNY.js +17 -0
  33. package/dist/chunk-WN74KVNY.js.map +1 -0
  34. package/dist/chunk-WYPQ3GG5.js +10990 -0
  35. package/dist/chunk-WYPQ3GG5.js.map +1 -0
  36. package/dist/components-D5ZRE2Hl.d.ts +1451 -0
  37. package/dist/generated/runtime/primitives.d.ts +12 -0
  38. package/dist/generated/runtime/primitives.js +180 -0
  39. package/dist/generated/runtime/primitives.js.map +1 -0
  40. package/dist/generated/runtime-api.d.ts +3 -0
  41. package/dist/generated/runtime-api.js +2 -0
  42. package/dist/generated/runtime-api.js.map +1 -0
  43. package/dist/generated/runtime.d.ts +14 -0
  44. package/dist/generated/runtime.js +18 -0
  45. package/dist/generated/runtime.js.map +1 -0
  46. package/dist/generated/workspace-contract.d.ts +14 -0
  47. package/dist/generated/workspace-contract.js +14 -0
  48. package/dist/generated/workspace-contract.js.map +1 -0
  49. package/dist/hex-board-view-D_07hO6O.d.ts +933 -0
  50. package/dist/hex-color-MhOyuY-o.d.ts +8 -0
  51. package/dist/index-BwqPQtBu.d.ts +1433 -0
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.js +12 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/infrastructure/reducer-bundle-abi.d.ts +1083 -0
  56. package/dist/infrastructure/reducer-bundle-abi.js +14 -0
  57. package/dist/infrastructure/reducer-bundle-abi.js.map +1 -0
  58. package/dist/infrastructure/workspace-codegen.d.ts +53 -0
  59. package/dist/infrastructure/workspace-codegen.js +44 -0
  60. package/dist/infrastructure/workspace-codegen.js.map +1 -0
  61. package/dist/manifest-contract-BNHVGFtU.d.ts +9 -0
  62. package/dist/package-set.d.ts +13 -0
  63. package/dist/package-set.js +12 -0
  64. package/dist/package-set.js.map +1 -0
  65. package/dist/primitive-props-DpKs-GCr.d.ts +11 -0
  66. package/dist/reducer.d.ts +3786 -0
  67. package/dist/reducer.js +8131 -0
  68. package/dist/reducer.js.map +1 -0
  69. package/dist/runtime/primitives.d.ts +226 -0
  70. package/dist/runtime/primitives.js +180 -0
  71. package/dist/runtime/primitives.js.map +1 -0
  72. package/dist/runtime/types/runtime-api.d.ts +1 -0
  73. package/dist/runtime/types/runtime-api.js +2 -0
  74. package/dist/runtime/types/runtime-api.js.map +1 -0
  75. package/dist/runtime/workspace-contract.d.ts +172 -0
  76. package/dist/runtime/workspace-contract.js +14 -0
  77. package/dist/runtime/workspace-contract.js.map +1 -0
  78. package/dist/runtime-api-3dshj6kK.d.ts +101 -0
  79. package/dist/runtime-api-DWxvTr-O.d.ts +379 -0
  80. package/dist/runtime.d.ts +58 -0
  81. package/dist/runtime.js +13 -0
  82. package/dist/runtime.js.map +1 -0
  83. package/dist/slots-1GPGihk8.d.ts +8 -0
  84. package/dist/testing.d.ts +149 -0
  85. package/dist/testing.js +513 -0
  86. package/dist/testing.js.map +1 -0
  87. package/dist/types.d.ts +496 -0
  88. package/dist/types.js +28 -0
  89. package/dist/types.js.map +1 -0
  90. package/dist/ui/components.d.ts +16 -0
  91. package/dist/ui/components.js +192 -0
  92. package/dist/ui/components.js.map +1 -0
  93. package/dist/ui/defaults.d.ts +19 -0
  94. package/dist/ui/defaults.js +104 -0
  95. package/dist/ui/defaults.js.map +1 -0
  96. package/dist/ui/plugin-styles.css +250 -0
  97. package/dist/ui/types/player-state.d.ts +365 -0
  98. package/dist/ui/types/player-state.js +1 -0
  99. package/dist/ui/types/player-state.js.map +1 -0
  100. package/dist/ui-contract-iQfTtUSL.d.ts +1161 -0
  101. package/dist/ui.d.ts +320 -0
  102. package/dist/ui.js +253 -0
  103. package/dist/ui.js.map +1 -0
  104. package/package.json +199 -0
  105. package/src/generated/reducer-contract/builders.ts +90 -0
  106. package/src/generated/reducer-contract/version.ts +9 -0
  107. package/src/generated/reducer-contract/wire.ts +100 -0
  108. package/src/generated/reducer-contract/zod.ts +101 -0
  109. package/src/generated/runtime/primitives.ts +2 -0
  110. package/src/generated/runtime-api.ts +5 -0
  111. package/src/generated/runtime.ts +35 -0
  112. package/src/generated/workspace-contract.ts +2 -0
  113. package/src/index.ts +7 -0
  114. package/src/infrastructure/reducer-bundle-abi.ts +8 -0
  115. package/src/infrastructure/reducer-contract/bundle.ts +37 -0
  116. package/src/infrastructure/workspace-codegen/hex-geometry.ts +69 -0
  117. package/src/infrastructure/workspace-codegen/index.ts +64 -0
  118. package/src/infrastructure/workspace-codegen/manifest-contract.ts +6632 -0
  119. package/src/infrastructure/workspace-codegen/manifest-validation.ts +795 -0
  120. package/src/infrastructure/workspace-codegen/ownership.ts +131 -0
  121. package/src/infrastructure/workspace-codegen/preset-card-sets.ts +169 -0
  122. package/src/infrastructure/workspace-codegen/seeds.ts +1705 -0
  123. package/src/infrastructure/workspace-codegen.ts +1 -0
  124. package/src/package-set.ts +19 -0
  125. package/src/reducer/authoring/contract.ts +157 -0
  126. package/src/reducer/authoring/effect.ts +224 -0
  127. package/src/reducer/authoring/game.ts +23 -0
  128. package/src/reducer/authoring/interaction.ts +98 -0
  129. package/src/reducer/authoring/phase.ts +300 -0
  130. package/src/reducer/authoring/types.ts +70 -0
  131. package/src/reducer/authoring/validation.ts +382 -0
  132. package/src/reducer/authoring/view-stage.ts +68 -0
  133. package/src/reducer/authoring.ts +29 -0
  134. package/src/reducer/bundle/ingress-bundle.ts +491 -0
  135. package/src/reducer/bundle/trusted/engine-instruction-resolver.ts +254 -0
  136. package/src/reducer/bundle/trusted/flow-instruction-resolver.ts +73 -0
  137. package/src/reducer/bundle/trusted/instruction-runner.ts +414 -0
  138. package/src/reducer/bundle/trusted/interaction-authorization.ts +137 -0
  139. package/src/reducer/bundle/trusted/interaction-collectors.ts +859 -0
  140. package/src/reducer/bundle/trusted/interaction-decision.ts +747 -0
  141. package/src/reducer/bundle/trusted/interaction-resolver.ts +95 -0
  142. package/src/reducer/bundle/trusted/interaction-types.ts +171 -0
  143. package/src/reducer/bundle/trusted/lifecycle-runner.ts +427 -0
  144. package/src/reducer/bundle/trusted/projection-builder.ts +356 -0
  145. package/src/reducer/bundle/trusted/projection-context.ts +39 -0
  146. package/src/reducer/bundle/trusted/rng-sampler.ts +150 -0
  147. package/src/reducer/bundle/trusted/runtime-registry.ts +120 -0
  148. package/src/reducer/bundle/trusted/runtime-scope.ts +336 -0
  149. package/src/reducer/bundle/trusted/simultaneous-player.ts +97 -0
  150. package/src/reducer/bundle/trusted/stage-resolver.ts +87 -0
  151. package/src/reducer/bundle/trusted/static-projection.ts +116 -0
  152. package/src/reducer/bundle/trusted/trusted-runtime-args.ts +97 -0
  153. package/src/reducer/bundle/trusted/trusted-runtime-result.ts +39 -0
  154. package/src/reducer/bundle/trusted/trusted-setup-profiles.ts +43 -0
  155. package/src/reducer/bundle/trusted/trusted-state-codec.ts +48 -0
  156. package/src/reducer/bundle/trusted-bundle.ts +97 -0
  157. package/src/reducer/bundle/types.ts +171 -0
  158. package/src/reducer/bundle.ts +2 -0
  159. package/src/reducer/client-param-schemas.ts +57 -0
  160. package/src/reducer/compose.ts +34 -0
  161. package/src/reducer/core/runtime-input.ts +30 -0
  162. package/src/reducer/core/runtime-instruction.ts +59 -0
  163. package/src/reducer/core/types.ts +62 -0
  164. package/src/reducer/definition-index.ts +277 -0
  165. package/src/reducer/derived.ts +106 -0
  166. package/src/reducer/effects.ts +92 -0
  167. package/src/reducer/engine/runtime-instruction-engine.ts +155 -0
  168. package/src/reducer/ingress/decode-runtime-input.ts +7 -0
  169. package/src/reducer/ingress/decode-session-state.ts +9 -0
  170. package/src/reducer/ingress/encode-session-state.ts +6 -0
  171. package/src/reducer/ingress/input-codec.ts +18 -0
  172. package/src/reducer/ingress/phase-schemas.ts +62 -0
  173. package/src/reducer/ingress/raw-types.ts +107 -0
  174. package/src/reducer/ingress/runtime-codec.ts +14 -0
  175. package/src/reducer/ingress/runtime-payload.ts +13 -0
  176. package/src/reducer/ingress/session-codec.ts +392 -0
  177. package/src/reducer/ingress/types.ts +6 -0
  178. package/src/reducer/inputs/boardInput.ts +217 -0
  179. package/src/reducer/inputs/boardTarget.ts +190 -0
  180. package/src/reducer/inputs/cardInput.ts +86 -0
  181. package/src/reducer/inputs/cardTarget.ts +101 -0
  182. package/src/reducer/inputs/choiceTarget.ts +104 -0
  183. package/src/reducer/inputs/defineInputs.ts +71 -0
  184. package/src/reducer/inputs/formInput.ts +809 -0
  185. package/src/reducer/inputs/many.ts +120 -0
  186. package/src/reducer/inputs/promptInput.ts +87 -0
  187. package/src/reducer/inputs/rngInput.ts +58 -0
  188. package/src/reducer/inputs/targetRule.ts +123 -0
  189. package/src/reducer/inputs.ts +41 -0
  190. package/src/reducer/model/definition.ts +1072 -0
  191. package/src/reducer/model/extract.ts +745 -0
  192. package/src/reducer/model/manifest.ts +570 -0
  193. package/src/reducer/model/queries.ts +641 -0
  194. package/src/reducer/model/runtime.ts +264 -0
  195. package/src/reducer/model/spec.ts +1386 -0
  196. package/src/reducer/model/table.ts +260 -0
  197. package/src/reducer/model.ts +7 -0
  198. package/src/reducer/ops.ts +1034 -0
  199. package/src/reducer/parse-utils.ts +28 -0
  200. package/src/reducer/per-player.ts +422 -0
  201. package/src/reducer/rng.ts +69 -0
  202. package/src/reducer/schema-helpers.ts +185 -0
  203. package/src/reducer/setup-bootstrap-helpers.ts +171 -0
  204. package/src/reducer/setup-bootstrap.ts +481 -0
  205. package/src/reducer/table-ops.ts +2671 -0
  206. package/src/reducer/table-queries.ts +372 -0
  207. package/src/reducer/transaction.ts +120 -0
  208. package/src/reducer.ts +314 -0
  209. package/src/runtime/primitives.ts +1 -0
  210. package/src/runtime/types/runtime-api.ts +1 -0
  211. package/src/runtime/workspace-contract.ts +32 -0
  212. package/src/runtime-internal/components/InteractionForm.tsx +1309 -0
  213. package/src/runtime-internal/components/PluginRuntime.tsx +103 -0
  214. package/src/runtime-internal/components/board/target-layer.ts +70 -0
  215. package/src/runtime-internal/context/ClientParamSchemaContext.tsx +44 -0
  216. package/src/runtime-internal/context/InteractionDraftContext.tsx +279 -0
  217. package/src/runtime-internal/context/PluginSessionContext.tsx +47 -0
  218. package/src/runtime-internal/context/PluginStateContext.tsx +262 -0
  219. package/src/runtime-internal/context/RuntimeContext.tsx +96 -0
  220. package/src/runtime-internal/defaults/components.tsx +409 -0
  221. package/src/runtime-internal/defaults/index.ts +11 -0
  222. package/src/runtime-internal/errors/ValidationError.ts +29 -0
  223. package/src/runtime-internal/hooks/useActivePlayers.ts +33 -0
  224. package/src/runtime-internal/hooks/useBoardInteractions.ts +665 -0
  225. package/src/runtime-internal/hooks/useGameSelector.ts +105 -0
  226. package/src/runtime-internal/hooks/useGameView.ts +9 -0
  227. package/src/runtime-internal/hooks/useInteractionByKey.ts +354 -0
  228. package/src/runtime-internal/hooks/useInteractionHandle.ts +438 -0
  229. package/src/runtime-internal/hooks/useIsMyTurn.ts +20 -0
  230. package/src/runtime-internal/hooks/useLobby.ts +76 -0
  231. package/src/runtime-internal/hooks/useMe.ts +48 -0
  232. package/src/runtime-internal/hooks/usePlayerInfo.ts +28 -0
  233. package/src/runtime-internal/hooks/usePlayerTurnOrder.ts +23 -0
  234. package/src/runtime-internal/hooks/usePluginRuntime.ts +147 -0
  235. package/src/runtime-internal/hooks/useSeatInbox.ts +61 -0
  236. package/src/runtime-internal/hooks/useSimultaneousPhase.ts +10 -0
  237. package/src/runtime-internal/index.ts +42 -0
  238. package/src/runtime-internal/internal.ts +43 -0
  239. package/src/runtime-internal/plugin-styles.css +250 -0
  240. package/src/runtime-internal/primitives/board.tsx +459 -0
  241. package/src/runtime-internal/primitives/dialog-lifecycle.ts +58 -0
  242. package/src/runtime-internal/primitives/dice.tsx +79 -0
  243. package/src/runtime-internal/primitives/game-ui-provider.tsx +35 -0
  244. package/src/runtime-internal/primitives/game.tsx +387 -0
  245. package/src/runtime-internal/primitives/hand-intent-adapter.ts +147 -0
  246. package/src/runtime-internal/primitives/hand-surface.tsx +594 -0
  247. package/src/runtime-internal/primitives/index.ts +196 -0
  248. package/src/runtime-internal/primitives/interaction-form-binding.tsx +56 -0
  249. package/src/runtime-internal/primitives/interaction-submit.ts +90 -0
  250. package/src/runtime-internal/primitives/interaction.tsx +987 -0
  251. package/src/runtime-internal/primitives/phase.tsx +43 -0
  252. package/src/runtime-internal/primitives/player-roster.tsx +302 -0
  253. package/src/runtime-internal/primitives/primitive-props.tsx +101 -0
  254. package/src/runtime-internal/primitives/prompt.tsx +255 -0
  255. package/src/runtime-internal/primitives/ui.tsx +60 -0
  256. package/src/runtime-internal/primitives/zone.tsx +791 -0
  257. package/src/runtime-internal/reducer.ts +30 -0
  258. package/src/runtime-internal/runtime/createPluginRuntimeAPI.ts +605 -0
  259. package/src/runtime-internal/types/plugin-state.ts +508 -0
  260. package/src/runtime-internal/types/reducer-state.ts +24 -0
  261. package/src/runtime-internal/types/runtime-api.ts +114 -0
  262. package/src/runtime-internal/ui-contract.ts +519 -0
  263. package/src/runtime-internal/utils/card-intent-adapter.ts +546 -0
  264. package/src/runtime-internal/utils/interaction-inputs.ts +492 -0
  265. package/src/runtime-internal/utils/interaction-labels.ts +23 -0
  266. package/src/runtime-internal/utils/interaction-router.ts +273 -0
  267. package/src/runtime-internal/utils/interaction-status.ts +74 -0
  268. package/src/runtime-internal/workspace-contract.ts +1170 -0
  269. package/src/runtime.ts +34 -0
  270. package/src/testing/create-expect-api.ts +352 -0
  271. package/src/testing/create-test-runtime.ts +381 -0
  272. package/src/testing/definitions.ts +127 -0
  273. package/src/testing/index.ts +3 -0
  274. package/src/testing.ts +1 -0
  275. package/src/type-stubs/manifest-contract.d.ts +42 -0
  276. package/src/type-stubs/manifest-contract.js +72 -0
  277. package/src/type-stubs/ui-contract.d.ts +5 -0
  278. package/src/type-stubs/ui-contract.js +1 -0
  279. package/src/types/authoring-card-properties.type-test.ts +266 -0
  280. package/src/types/authoring.ts +1282 -0
  281. package/src/types/cards.ts +19 -0
  282. package/src/types/contracts.ts +1550 -0
  283. package/src/types/generated-helpers.ts +35 -0
  284. package/src/types/index.ts +147 -0
  285. package/src/types/slots.ts +11 -0
  286. package/src/types.ts +1 -0
  287. package/src/ui/components/ActionButton.tsx +97 -0
  288. package/src/ui/components/ActionPanel.tsx +315 -0
  289. package/src/ui/components/Card.tsx +378 -0
  290. package/src/ui/components/CardDragSurface.tsx +1076 -0
  291. package/src/ui/components/ChromeSuppressionContext.tsx +70 -0
  292. package/src/ui/components/CostDisplay.tsx +145 -0
  293. package/src/ui/components/DiceRoller.tsx +581 -0
  294. package/src/ui/components/Drawer.tsx +180 -0
  295. package/src/ui/components/ErrorBoundary.tsx +275 -0
  296. package/src/ui/components/GameEndDisplay.tsx +398 -0
  297. package/src/ui/components/GameSkeleton.tsx +260 -0
  298. package/src/ui/components/Hand.tsx +468 -0
  299. package/src/ui/components/HandDock.tsx +299 -0
  300. package/src/ui/components/HandView.tsx +441 -0
  301. package/src/ui/components/MobileHandTray.tsx +381 -0
  302. package/src/ui/components/MoreActions.tsx +143 -0
  303. package/src/ui/components/PhaseIndicator.tsx +341 -0
  304. package/src/ui/components/PlayArea.tsx +146 -0
  305. package/src/ui/components/PrimaryActionButton.tsx +336 -0
  306. package/src/ui/components/PrimaryButton.tsx +45 -0
  307. package/src/ui/components/ResourceCounter.tsx +270 -0
  308. package/src/ui/components/StagingZone.tsx +134 -0
  309. package/src/ui/components/ThemedButton.tsx +113 -0
  310. package/src/ui/components/Toast.tsx +264 -0
  311. package/src/ui/components/board/HexGrid.tsx +1294 -0
  312. package/src/ui/components/board/NetworkGraph.tsx +476 -0
  313. package/src/ui/components/board/SlotSystem.tsx +388 -0
  314. package/src/ui/components/board/SquareGrid.tsx +1165 -0
  315. package/src/ui/components/board/TrackBoard.tsx +496 -0
  316. package/src/ui/components/board/ZoneMap.tsx +448 -0
  317. package/src/ui/components/board/hex-board-view.ts +123 -0
  318. package/src/ui/components/board/index.ts +142 -0
  319. package/src/ui/components/board/interaction-accessibility.ts +21 -0
  320. package/src/ui/components/board/target-layer.ts +66 -0
  321. package/src/ui/components/card-render-content.type-test.ts +27 -0
  322. package/src/ui/components/hand-layout-math.ts +163 -0
  323. package/src/ui/components/hand-pointer-engine.ts +413 -0
  324. package/src/ui/components/index.ts +245 -0
  325. package/src/ui/components.ts +1 -0
  326. package/src/ui/defaults/components.tsx +106 -0
  327. package/src/ui/defaults/index.ts +8 -0
  328. package/src/ui/defaults.ts +1 -0
  329. package/src/ui/errors/ValidationError.ts +29 -0
  330. package/src/ui/helpers/cards.ts +19 -0
  331. package/src/ui/helpers/track-board.ts +211 -0
  332. package/src/ui/hooks/useBoardTopology.ts +316 -0
  333. package/src/ui/hooks/useCards.ts +10 -0
  334. package/src/ui/hooks/useHandCardPointer.ts +381 -0
  335. package/src/ui/hooks/useHandLayout.ts +378 -0
  336. package/src/ui/hooks/useHandPresentation.ts +121 -0
  337. package/src/ui/hooks/useHexBoard.ts +74 -0
  338. package/src/ui/hooks/useHexGrid.ts +185 -0
  339. package/src/ui/hooks/useIsMobile.ts +35 -0
  340. package/src/ui/hooks/usePanZoom.ts +278 -0
  341. package/src/ui/hooks/useSquareBoard.ts +124 -0
  342. package/src/ui/hooks/useSquareGrid.ts +328 -0
  343. package/src/ui/index.ts +98 -0
  344. package/src/ui/internal/ui/alert.tsx +51 -0
  345. package/src/ui/internal/ui/button.tsx +58 -0
  346. package/src/ui/internal/ui/dialog.tsx +134 -0
  347. package/src/ui/internal/ui/input.tsx +21 -0
  348. package/src/ui/internal/ui/label.tsx +21 -0
  349. package/src/ui/internal/ui/select.tsx +129 -0
  350. package/src/ui/internal/ui/tooltip.tsx +54 -0
  351. package/src/ui/internal/ui/utils.ts +5 -0
  352. package/src/ui/plugin-styles.css +250 -0
  353. package/src/ui/primitives/dialog-lifecycle.ts +58 -0
  354. package/src/ui/primitives/dice.tsx +79 -0
  355. package/src/ui/primitives/primitive-props.tsx +101 -0
  356. package/src/ui/theme/ThemeProvider.tsx +252 -0
  357. package/src/ui/theme/board.ts +61 -0
  358. package/src/ui/theme/css-vars.ts +105 -0
  359. package/src/ui/theme/derive.ts +240 -0
  360. package/src/ui/theme/index.ts +61 -0
  361. package/src/ui/theme/presets/arcade.ts +261 -0
  362. package/src/ui/theme/presets/studio.ts +261 -0
  363. package/src/ui/theme/presets/tabletop.ts +266 -0
  364. package/src/ui/theme/tokens.ts +392 -0
  365. package/src/ui/types/hex-color.ts +20 -0
  366. package/src/ui/types/player-state.ts +463 -0
  367. package/src/ui/types/tiled-board.ts +785 -0
  368. package/src/ui/types/visual-state.ts +137 -0
  369. package/src/ui.ts +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/testing/definitions.ts","../src/testing/create-expect-api.ts","../src/testing/create-test-runtime.ts"],"sourcesContent":["export type TestRunner = \"reducer\" | \"embedded\" | \"browser\";\n\nexport type InteractionDescriptorLike = {\n interactionId?: string;\n surface?: string;\n kind?: string;\n availability?: InteractionAvailabilityLike;\n context?: {\n to?: string;\n };\n} & Record<string, unknown>;\n\nexport type InteractionAvailabilityLike =\n | { status: \"available\" }\n | { status: \"notYourTurn\"; reason: string }\n | {\n status: \"insufficientResources\";\n reason: string;\n missingResources?: Record<string, unknown>;\n }\n | { status: \"blocked\"; reason: string };\n\nexport type SnapshotMatcherHandler = (\n name: string | undefined,\n actual: unknown,\n) => void;\n\nexport type RejectionExpectation = {\n errorCode?: string;\n message?: string | RegExp;\n};\n\nexport type ExpectMatchers = {\n toBe: (expected: unknown) => void;\n toEqual: (expected: unknown) => void;\n toMatchObject: (expected: Record<string, unknown>) => void;\n toBeDefined: () => void;\n toBeUndefined: () => void;\n toBeNull: () => void;\n toContain: (expected: unknown) => void;\n toContainEqual: (expected: unknown) => void;\n toHaveLength: (expected: number) => void;\n toBeGreaterThan: (expected: number) => void;\n toBeGreaterThanOrEqual: (expected: number) => void;\n toThrow: (predicate?: string | RegExp | ((error: Error) => boolean)) => void;\n toMatchSnapshot: (filename?: string) => void;\n toRejectWith: (expected: RejectionExpectation) => Promise<void>;\n toHaveInteraction: (\n interactionId: string,\n opts?: Partial<InteractionDescriptorLike>,\n ) => void;\n toBeGatedBy: (reason: string, opts?: { interactionId?: string }) => void;\n toBeActiveFor: (playerId: string, opts?: { interactionId?: string }) => void;\n not: {\n toHaveInteraction: (interactionId: string) => void;\n };\n};\n\nexport type ExpectFn = (actual: unknown) => ExpectMatchers;\n\nexport interface BaseContext<PlayerId extends string = string> {\n game: {\n start(): Promise<void>;\n patchState?(\n mutator: (state: Record<string, unknown>) => void,\n ): Promise<void>;\n submit(\n playerId: PlayerId,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n };\n players(): readonly PlayerId[];\n seat(index: number): PlayerId;\n}\n\nexport interface SharedScenarioContext<\n PlayerId extends string = string,\n StateName extends string = string,\n View = unknown,\n Descriptor extends InteractionDescriptorLike = InteractionDescriptorLike,\n> extends BaseContext<PlayerId> {\n state(): StateName;\n view(playerId: PlayerId): View;\n interactions(playerId: PlayerId): readonly Descriptor[];\n expect: ExpectFn;\n}\n\nexport interface BaseDefinition {\n id: string;\n seed?: number;\n players?: number;\n setupProfileId?: string | null;\n extends?: string;\n setup: (ctx: BaseContext) => void | Promise<void>;\n}\n\nexport interface ScenarioDefinition<\n Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n PhaseName extends string = string,\n StageName extends string = string,\n> {\n id: string;\n description?: string;\n from: string;\n runners?: Runners;\n phase?: PhaseName;\n stage?: StageName;\n when: (ctx: SharedScenarioContext) => void | Promise<void>;\n then: (ctx: SharedScenarioContext) => void | Promise<void>;\n}\n\nexport function defineBase<const Definition extends BaseDefinition>(\n definition: Definition,\n): Definition {\n return definition;\n}\n\nexport function defineScenario<\n const Runners extends readonly TestRunner[] = readonly [\"reducer\"],\n const PhaseName extends string = string,\n const StageName extends string = string,\n>(\n definition: ScenarioDefinition<Runners, PhaseName, StageName>,\n): ScenarioDefinition<Runners, PhaseName, StageName> {\n return definition;\n}\n","import { isDeepStrictEqual } from \"node:util\";\nimport type {\n ExpectFn,\n ExpectMatchers,\n InteractionDescriptorLike,\n RejectionExpectation,\n SnapshotMatcherHandler,\n} from \"./definitions.js\";\n\ntype CreateExpectApiOptions = {\n matchSnapshot?: SnapshotMatcherHandler;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction matchPartial(\n actual: unknown,\n expected: unknown,\n path: string = \"value\",\n): string | null {\n if (!isRecord(expected)) {\n return isDeepStrictEqual(actual, expected)\n ? null\n : `${path} does not match`;\n }\n if (!isRecord(actual)) {\n return `${path} is not an object`;\n }\n for (const [key, expectedValue] of Object.entries(expected)) {\n const actualValue = actual[key];\n if (!(key in actual)) {\n return `${path}.${key} is missing`;\n }\n const mismatch = matchPartial(actualValue, expectedValue, `${path}.${key}`);\n if (mismatch) {\n return mismatch;\n }\n }\n return null;\n}\n\nfunction asDescriptorList(actual: unknown): InteractionDescriptorLike[] {\n if (!Array.isArray(actual)) {\n throw new Error(\"Expected interaction descriptor array.\");\n }\n return actual as InteractionDescriptorLike[];\n}\n\nfunction findInteraction(\n descriptors: readonly InteractionDescriptorLike[],\n interactionId: string,\n): InteractionDescriptorLike | null {\n return (\n descriptors.find(\n (descriptor) => descriptor.interactionId === interactionId,\n ) ?? null\n );\n}\n\nfunction assertDescriptorMatches(\n descriptor: InteractionDescriptorLike,\n opts: Partial<InteractionDescriptorLike> | undefined,\n): void {\n if (!opts) {\n return;\n }\n const mismatch = matchPartial(descriptor, opts, \"interaction\");\n if (mismatch) {\n throw new Error(mismatch);\n }\n}\n\nfunction createSubmissionErrorMatcher(\n actual: unknown,\n expected: RejectionExpectation,\n): 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 }'.`,\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}'.`,\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(expected.message)}.`,\n );\n }\n });\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 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) => createSubmissionErrorMatcher(actual, expected),\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 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 { ReducerBundleContract } from \"../infrastructure/reducer-contract/bundle.js\";\nimport type * as Wire from \"../generated/reducer-contract/wire.js\";\nimport type {\n InteractionDescriptor,\n PluginStateSnapshot,\n ZoneHandlesSnapshot,\n} from \"../runtime-internal/reducer.js\";\nimport type {\n RuntimeAPI,\n SubmissionError,\n ValidationResult,\n} from \"../runtime-internal/types/runtime-api.js\";\nimport type { PluginSessionState as RuntimePluginSessionState } from \"../runtime-internal/types/runtime-api.js\";\n\ntype ReducerBundleLike = Pick<\n ReducerBundleContract,\n \"projectSeatsDynamic\" | \"validateInput\" | \"dispatch\"\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 };\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};\n\nexport type CreatedTestRuntime = {\n runtime: RuntimeAPI & {\n getSnapshot(): PluginStateSnapshot;\n subscribeToState(\n listener: (state: PluginStateSnapshot) => void,\n ): () => void;\n _subscribeToSessionState(\n listener: (state: RuntimePluginSessionState) => void,\n ): () => void;\n };\n getSnapshot(): PluginStateSnapshot;\n players(): readonly string[];\n seat(index: number): string;\n submit(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<void>;\n validate(\n playerId: string,\n interactionId: string,\n params?: unknown,\n ): Promise<ValidationResult>;\n setControllingPlayer(playerId: string): void;\n};\n\nfunction cloneState<T>(value: T): DeepMutable<T> {\n return structuredClone(value) as DeepMutable<T>;\n}\n\nfunction createSubmissionError(\n errorCode: string | undefined,\n message: string | undefined,\n): SubmissionError {\n const error = new Error(message ?? \"Interaction rejected\") as SubmissionError;\n error.name = \"SubmissionError\";\n error.errorCode = errorCode;\n return error;\n}\n\nfunction readFlowState(state: Wire.ReducerSessionState): {\n currentPhase: string | null;\n activePlayers: string[];\n} {\n const flow = ((\n state.domain as\n | { flow?: { currentPhase?: string; activePlayers?: string[] } }\n | undefined\n )?.flow ?? {}) as {\n currentPhase?: string;\n activePlayers?: string[];\n };\n return {\n currentPhase: flow.currentPhase ?? null,\n activePlayers: Array.isArray(flow.activePlayers) ? flow.activePlayers : [],\n };\n}\n\nfunction resolvePlayerIds(options: {\n baseState: BaseStateArtifact;\n explicitPlayerIds?: readonly string[];\n}): string[] {\n if (options.explicitPlayerIds && options.explicitPlayerIds.length > 0) {\n return [...options.explicitPlayerIds];\n }\n return Array.from(\n { length: options.baseState.fingerprint.players },\n (_, index) => `player-${index + 1}`,\n );\n}\n\nfunction isWireZoneHandles(value: unknown): value is WireZoneHandles {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction buildPluginSnapshot(options: {\n state: Wire.ReducerSessionState;\n bundle: ReducerBundleLike;\n playerId: string;\n playerIds: readonly string[];\n userId: string | null;\n sessionId: string;\n version: number;\n expectedPhase: string | undefined;\n baseId: string;\n}): PluginStateSnapshot {\n const projection = options.bundle.projectSeatsDynamic({\n state: options.state,\n playerIds: [options.playerId],\n });\n\n const flow = readFlowState(options.state);\n if (options.expectedPhase && flow.currentPhase !== options.expectedPhase) {\n throw new Error(\n `Expected base '${options.baseId}' to be in phase '${options.expectedPhase}', received '${\n flow.currentPhase ?? \"null\"\n }'.`,\n );\n }\n\n const interactionsByRef =\n (projection.interactionsByRef as\n | Record<string, InteractionDescriptor>\n | undefined) ?? {};\n const hydrateRefs = (\n refs: readonly string[] | undefined,\n ): InteractionDescriptor[] =>\n (refs ?? [])\n .map((ref) => interactionsByRef[ref])\n .filter((descriptor): descriptor is InteractionDescriptor =>\n Boolean(descriptor),\n );\n\n const seat = projection.seats?.[options.playerId];\n const zones = Object.fromEntries(\n Object.entries(\n ((seat?.zones as Record<string, unknown> | undefined) ?? {}),\n ).map(([zoneId, zoneValue]) => {\n const zone = isWireZoneHandles(zoneValue) ? zoneValue : {};\n return [\n zoneId,\n {\n cardIds: [...(zone.cardIds ?? [])],\n cardViewsById: { ...(zone.cardViewsById ?? {}) },\n playableByCardId: Object.fromEntries(\n Object.entries(zone.playableByCardId ?? {}).map(\n ([cardId, refs]) => [cardId, hydrateRefs(refs)],\n ),\n ),\n } satisfies ZoneHandlesSnapshot,\n ];\n }),\n );\n\n return {\n view: (seat?.view ?? null) as PluginStateSnapshot[\"view\"],\n gameplay: {\n currentPhase: flow.currentPhase,\n currentStage: projection.currentStage ?? null,\n activePlayers: flow.activePlayers,\n simultaneousPhase: projection.simultaneousPhase ?? null,\n availableInteractions: hydrateRefs(\n seat?.availableInteractionRefs as readonly string[] | undefined,\n ),\n zones,\n },\n lobby: null,\n notifications: [],\n session: {\n sessionId: options.sessionId,\n controllablePlayerIds: [...options.playerIds],\n controllingPlayerId: options.playerId || null,\n userId: options.userId,\n },\n history: null,\n syncId: options.version,\n };\n}\n\nexport function createTestRuntime(\n options: CreateTestRuntimeOptions,\n): CreatedTestRuntime {\n const baseState = options.baseStates[options.baseId];\n if (!baseState) {\n throw new Error(`Unknown test base '${options.baseId}'.`);\n }\n\n let currentState = cloneState(baseState.snapshot);\n const playerIds = resolvePlayerIds({\n baseState,\n explicitPlayerIds: options.playerIds,\n });\n const userId = options.userId ?? \"test-user\";\n const sessionId = options.sessionId ?? \"test-session\";\n\n let version = 0;\n let currentPlayerId = playerIds[0] ?? \"\";\n const stateListeners = new Set<(state: PluginStateSnapshot) => void>();\n const sessionListeners = new Set<(state: RuntimePluginSessionState) => void>();\n\n const toReadySessionState = (\n snapshot: PluginStateSnapshot,\n ): RuntimePluginSessionState => ({\n ...snapshot.session,\n status: \"ready\",\n });\n\n let lastPluginSnapshot: PluginStateSnapshot;\n let lastSessionState: RuntimePluginSessionState;\n\n const applyCurrentState = (): void => {\n const previousSession = lastSessionState;\n version += 1;\n lastPluginSnapshot = buildPluginSnapshot({\n state: currentState,\n bundle: options.bundle,\n playerId: currentPlayerId,\n playerIds,\n userId,\n sessionId,\n version,\n expectedPhase: version === 1 ? options.phase : undefined,\n baseId: options.baseId,\n });\n lastSessionState = toReadySessionState(lastPluginSnapshot);\n\n for (const listener of stateListeners) {\n listener(lastPluginSnapshot);\n }\n\n if (\n !previousSession ||\n previousSession.controllingPlayerId !==\n lastSessionState.controllingPlayerId ||\n previousSession.controllablePlayerIds.join(\"\\0\") !==\n lastSessionState.controllablePlayerIds.join(\"\\0\")\n ) {\n for (const listener of sessionListeners) {\n listener(lastSessionState);\n }\n }\n };\n\n applyCurrentState();\n\n const validate = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<ValidationResult> => {\n const result = await options.bundle.validateInput({\n state: currentState,\n input: {\n kind: \"interaction\",\n playerId,\n interactionId,\n params: params as Wire.JsonValue,\n },\n });\n return {\n valid: result.valid,\n errorCode: result.errorCode,\n message: result.message,\n };\n };\n\n const submit = async (\n playerId: string,\n interactionId: string,\n params: unknown = {},\n ): Promise<void> => {\n const validation = await validate(playerId, interactionId, params);\n if (!validation.valid) {\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 throw createSubmissionError(result.errorCode, result.message);\n }\n currentState = cloneState(result.state);\n applyCurrentState();\n };\n\n const setControllingPlayer = (playerId: string): void => {\n if (!playerIds.includes(playerId)) {\n throw new Error(`Unknown controlling player '${playerId}'.`);\n }\n currentPlayerId = playerId;\n applyCurrentState();\n };\n\n const runtime = {\n validateInteraction: validate,\n submitInteraction: submit,\n getSessionState: (): RuntimePluginSessionState => lastSessionState,\n disconnect: () => undefined,\n switchPlayer: (playerId: string) => {\n setControllingPlayer(playerId);\n },\n getSnapshot: (): PluginStateSnapshot => lastPluginSnapshot,\n subscribeToState: (listener: (state: PluginStateSnapshot) => void) => {\n stateListeners.add(listener);\n return () => {\n stateListeners.delete(listener);\n };\n },\n _subscribeToSessionState: (\n listener: (state: RuntimePluginSessionState) => void,\n ) => {\n sessionListeners.add(listener);\n return () => {\n sessionListeners.delete(listener);\n };\n },\n };\n\n return {\n runtime,\n getSnapshot: () => lastPluginSnapshot,\n players: () => [...playerIds],\n seat: (index: number) => {\n if (!Number.isInteger(index) || index < 0 || index >= playerIds.length) {\n throw new Error(\n `seat(${index}) is out of range; base '${options.baseId}' has ${playerIds.length} player(s).`,\n );\n }\n return playerIds[index]!;\n },\n submit,\n validate,\n setControllingPlayer,\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,496 @@
1
+ import { M as GameTopologyManifest$1, H as DieTypeSpec$1, g as BoardEdgeRef, o as BoardVertexRef, al as JsonValue } from './index-BwqPQtBu.js';
2
+ export { A as ActionDefinition, a as ActionInteractionDescriptor, b as ActionParameterDefinition, c as AvailableInteractionAvailability, B as BlockedInteractionAvailability, d as BoardCard, e as BoardContainerHostSpec, f as BoardContainerSpec, h as BoardHostSpec, i as BoardLayout, j as BoardRelationSpec, k as BoardSpaceSpec, l as BoardSpec, m as BoardTargetDomain, n as BoardTemplateSpec, p as BoundedNumberDomain, C as CardPropertySchema, q as CardPropertySchemaVariants, r as CardSetDefinition, s as CardSetSourceType, t as CardTargetDomain, u as ChoiceDomain, v as ChoiceDomainOption, w as ChoiceListDomain, x as ComponentHomeSpec, y as ComponentSlotSpec, z as ComponentVisibilitySpec, D as ContainerHomeSpec, E as DetachedHomeSpec, F as DieSeedSpec, G as DieSlotHostRef, I as DieTypeSpec, J as EagerInputDomainDependencies, K as EdgeHomeSpec, L as GameTopologyManifest, N as GenericBoardSpec, O as GenericBoardTemplateSpec, P as HexBoardSpec, Q as HexBoardTemplateSpec, R as HexEdgeRef, S as HexEdgeSpec, T as HexOrientation, U as HexSpaceSpec, V as HexVertexRef, W as HexVertexSpec, X as HistoryEntrySummary, Y as HostActionSubmitResponse, Z as HostEndedSessionSnapshot, _ as HostGameplaySeatView, $ as HostGameplaySessionSnapshot, a0 as HostGameplaySharedView, a1 as HostLobbySessionSnapshot, a2 as HostLobbyView, a3 as HostPlayerGameplayView, a4 as HostSessionContext, a5 as HostSessionEventCausation, a6 as HostSessionGameplayUpdatedEvent, a7 as HostSessionSnapshot, a8 as HostSessionStatus, a9 as InputDomain, aa as InputDomainDependencyCase, ab as InputDomainResolver, ac as InputSelection, ad as InsufficientResourcesInteractionAvailability, ae as InteractionAvailability, af as InteractionCommitPolicy, ag as InteractionContext, ah as InteractionContextOption, ai as InteractionDescriptor, aj as InteractionDescriptorBase, ak as InteractionInputDescriptor, am as LazyBoardTargetDomain, an as LazyCardTargetDomain, ao as LazyInputDomainDependencies, ap as ManualCardSetDefinition, aq as ManyInputSelection, ar as NotYourTurnInteractionAvailability, as as ObjectSchema, at as ParameterType, au as PieceSeedSpec, av as PieceSlotHostRef, aw as PieceTypeSpec, ax as PlayerId, ay as PlayersDefinition, az as PresetCardSetDefinition, aA as PromptInteractionDescriptor, aB as PropertySchema, aC as ResolvedBoardTargetDomain, aD as ResolvedCardTargetDomain, aE as ResourceDefinition, aF as ResourceMapDomain, aG as ResourceMapDomainEntry, aH as SeatAssignment, aI as SessionActor, aJ as SessionActorAuthUser, aK as SessionActorDemoGuest, aL as SessionGameSource, aM as SessionGameSourceDemoRevision, aN as SessionGameSourceUserCompiled, aO as SessionSnapshotHistory, aP as SessionSnapshotPhase, aQ as SetupOptionChoiceSpec, aR as SetupOptionSpec, aS as SetupProfileSpec, aT as SimultaneousPhaseSnapshot, aU as SingleInputSelection, aV as SlotHomeSpec, aW as SlotHostRef, aX as SpaceHomeSpec, aY as SpaceHostSpec, aZ as SquareBoardSpec, a_ as SquareBoardTemplateSpec, a$ as SquareEdgeSpec, b0 as SquareSpaceSpec, b1 as SquareVertexSpec, b2 as TopologyScope, b3 as VertexHomeSpec, b4 as ZoneHandles, b5 as ZoneHomeSpec, b6 as ZoneSpec, b7 as ZoneVisibility } from './index-BwqPQtBu.js';
3
+ export { C as CardCollection, V as ViewCard } from './cards-Sl3b40Mv.js';
4
+ export { V as ViewSlotOccupant } from './slots-1GPGihk8.js';
5
+
6
+ type DieTypeSpec = Omit<DieTypeSpec$1, "sides"> & {
7
+ sides?: DieTypeSpec$1["sides"];
8
+ };
9
+ type DeepReadonly<T> = T extends (...args: readonly unknown[]) => unknown ? T : T extends readonly (infer Item)[] ? ReadonlyArray<DeepReadonly<Item>> : T extends object ? {
10
+ readonly [Key in keyof T]: DeepReadonly<T[Key]>;
11
+ } : T;
12
+ type GameTopologyManifest = DeepReadonly<Omit<GameTopologyManifest$1, "dieTypes"> & {
13
+ dieTypes?: readonly DieTypeSpec[];
14
+ }>;
15
+ type ArrayItem<T> = T extends readonly (infer Item)[] ? Item : never;
16
+ type EntryId<T> = T extends {
17
+ id: infer Id extends string;
18
+ } ? Id : never;
19
+ type IdsOf<T> = EntryId<ArrayItem<NonNullable<T>>>;
20
+ type RuntimeRecord = Record<string, JsonValue>;
21
+ type CardSetId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["cardSets"]>;
22
+ type ZoneId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["zones"]>;
23
+ type BoardId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["boards"]>;
24
+ type PerPlayerZoneId<Manifest extends GameTopologyManifest> = EntryId<Extract<ArrayItem<NonNullable<Manifest["zones"]>>, {
25
+ scope: "perPlayer";
26
+ }>>;
27
+ type SharedZoneId<Manifest extends GameTopologyManifest> = Exclude<ZoneId<Manifest>, PerPlayerZoneId<Manifest>>;
28
+ type PerPlayerBoardId<Manifest extends GameTopologyManifest> = EntryId<Extract<ArrayItem<NonNullable<Manifest["boards"]>>, {
29
+ scope: "perPlayer";
30
+ }>>;
31
+ type SharedBoardId<Manifest extends GameTopologyManifest> = Exclude<BoardId<Manifest>, PerPlayerBoardId<Manifest>>;
32
+ type ResourceId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["resources"]>;
33
+ type PieceTypeId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["pieceTypes"]>;
34
+ type DieTypeId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["dieTypes"]>;
35
+ type PieceSeedOf<Manifest extends GameTopologyManifest> = ArrayItem<NonNullable<Manifest["pieceSeeds"]>>;
36
+ type DieSeedOf<Manifest extends GameTopologyManifest> = ArrayItem<NonNullable<Manifest["dieSeeds"]>>;
37
+ type SetupOptionId<Manifest extends GameTopologyManifest> = IdsOf<Manifest["setupOptions"]>;
38
+ type ManualCardSetOf<Manifest extends GameTopologyManifest> = Extract<ArrayItem<NonNullable<Manifest["cardSets"]>>, {
39
+ type: "manual";
40
+ }>;
41
+ type CardOf<Manifest extends GameTopologyManifest> = ManualCardSetOf<Manifest> extends infer CardSet ? CardSet extends {
42
+ cards: infer Cards extends readonly unknown[];
43
+ } ? ArrayItem<Cards> : never : never;
44
+ type BoardOf<Manifest extends GameTopologyManifest, CurrentBoardId extends BoardId<Manifest>> = Extract<ArrayItem<NonNullable<Manifest["boards"]>>, {
45
+ id: CurrentBoardId;
46
+ }>;
47
+ type BoardTemplateOf<Manifest extends GameTopologyManifest, CurrentTemplateId extends string> = Extract<ArrayItem<NonNullable<Manifest["boardTemplates"]>>, {
48
+ id: CurrentTemplateId;
49
+ }>;
50
+ type ResolvedBoardLikeOf<Manifest extends GameTopologyManifest, CurrentBoardId extends BoardId<Manifest>> = BoardOf<Manifest, CurrentBoardId> | (BoardOf<Manifest, CurrentBoardId> extends {
51
+ templateId: infer CurrentTemplateId extends string;
52
+ } ? BoardTemplateOf<Manifest, CurrentTemplateId> : never);
53
+ type SpaceIdOf<BoardLike> = IdsOf<BoardLike extends {
54
+ spaces?: infer Spaces;
55
+ } ? Spaces : never>;
56
+ type ContainerIdOf<BoardLike> = IdsOf<BoardLike extends {
57
+ containers?: infer Containers;
58
+ } ? Containers : never>;
59
+ type SpaceOf<BoardLike> = ArrayItem<NonNullable<BoardLike extends {
60
+ spaces?: infer Spaces;
61
+ } ? Spaces : never>>;
62
+ type SquareSpaceOf<BoardLike> = Extract<SpaceOf<BoardLike>, {
63
+ row: number;
64
+ col: number;
65
+ }>;
66
+ type HexSpaceOf<BoardLike> = Extract<SpaceOf<BoardLike>, {
67
+ q: number;
68
+ r: number;
69
+ }>;
70
+ type BoardEntryOf<Manifest extends GameTopologyManifest> = ArrayItem<NonNullable<Manifest["boards"]>>;
71
+ type TemplateForBoardEntry<Manifest extends GameTopologyManifest, Entry> = Entry extends {
72
+ templateId: infer TemplateId extends string;
73
+ layout: infer Layout;
74
+ } ? Extract<BoardTemplateOf<Manifest, TemplateId>, {
75
+ layout: Layout;
76
+ }> : never;
77
+ type BoardLikeForEntry<Manifest extends GameTopologyManifest, Entry> = Entry extends BoardEntryOf<Manifest> ? Entry extends {
78
+ id: infer CurrentBoardId extends BoardId<Manifest>;
79
+ } ? ResolvedBoardLikeOf<Manifest, CurrentBoardId> : Entry : Entry;
80
+ type SpaceIdForBoard<Manifest extends GameTopologyManifest, CurrentBoardId extends BoardId<Manifest>> = SpaceIdOf<ResolvedBoardLikeOf<Manifest, CurrentBoardId>>;
81
+ type ContainerIdForBoard<Manifest extends GameTopologyManifest, CurrentBoardId extends BoardId<Manifest>> = ContainerIdOf<ResolvedBoardLikeOf<Manifest, CurrentBoardId>>;
82
+ type RuntimeIdsFromCount<BaseId extends string, Count> = Count extends number ? number extends Count ? BaseId | `${BaseId}-${number}` : Count extends 1 ? BaseId : `${BaseId}-${OneTo<Count>}` : BaseId;
83
+ type CardRuntimeId<Card> = Card extends {
84
+ type: infer TypeId extends string;
85
+ } ? RuntimeIdsFromCount<TypeId, Card extends {
86
+ count: infer Count extends number;
87
+ } ? Count : never> : never;
88
+ type SeedRuntimeId<Seed> = Seed extends {
89
+ typeId: infer TypeId extends string;
90
+ } ? RuntimeIdsFromCount<Seed extends {
91
+ id: infer Id extends string;
92
+ } ? Id : TypeId, Seed extends {
93
+ count: infer Count extends number;
94
+ } ? Count : never> : never;
95
+ type CardId<Manifest extends GameTopologyManifest> = CardRuntimeId<CardOf<Manifest>>;
96
+ type PieceId<Manifest extends GameTopologyManifest> = SeedRuntimeId<PieceSeedOf<Manifest>>;
97
+ type DieId<Manifest extends GameTopologyManifest> = SeedRuntimeId<DieSeedOf<Manifest>>;
98
+ type PieceTypeOf<Manifest extends GameTopologyManifest, CurrentTypeId extends PieceTypeId<Manifest>> = Extract<ArrayItem<NonNullable<Manifest["pieceTypes"]>>, {
99
+ id: CurrentTypeId;
100
+ }>;
101
+ type DieTypeOf<Manifest extends GameTopologyManifest, CurrentTypeId extends DieTypeId<Manifest>> = Extract<ArrayItem<NonNullable<Manifest["dieTypes"]>>, {
102
+ id: CurrentTypeId;
103
+ }>;
104
+ type SlotIdOf<TypeSpec> = IdsOf<TypeSpec extends {
105
+ slots?: infer Slots;
106
+ } ? Slots : never>;
107
+ type SlotIdForPieceType<Manifest extends GameTopologyManifest, CurrentTypeId extends PieceTypeId<Manifest>> = SlotIdOf<PieceTypeOf<Manifest, CurrentTypeId>>;
108
+ type SlotIdForDieType<Manifest extends GameTopologyManifest, CurrentTypeId extends DieTypeId<Manifest>> = SlotIdOf<DieTypeOf<Manifest, CurrentTypeId>>;
109
+ type SingletonExplicitSeed<Seed> = Seed extends {
110
+ id: infer _Id extends string;
111
+ } ? Seed extends {
112
+ count: infer Count extends number;
113
+ } ? Count extends 1 ? Seed : never : Seed : never;
114
+ type TypedPieceSlotHostSeed<Manifest extends GameTopologyManifest> = SingletonExplicitSeed<PieceSeedOf<Manifest>> extends infer Seed ? Seed extends {
115
+ typeId: infer CurrentTypeId extends PieceTypeId<Manifest>;
116
+ } ? [SlotIdForPieceType<Manifest, CurrentTypeId>] extends [never] ? never : Seed : never : never;
117
+ type TypedDieSlotHostSeed<Manifest extends GameTopologyManifest> = SingletonExplicitSeed<DieSeedOf<Manifest>> extends infer Seed ? Seed extends {
118
+ typeId: infer CurrentTypeId extends DieTypeId<Manifest>;
119
+ } ? [SlotIdForDieType<Manifest, CurrentTypeId>] extends [never] ? never : Seed : never : never;
120
+ type TypedPieceSlotHomeSpec<Manifest extends GameTopologyManifest> = TypedPieceSlotHostSeed<Manifest> extends infer Seed ? Seed extends {
121
+ id: infer HostId extends string;
122
+ typeId: infer CurrentTypeId extends PieceTypeId<Manifest>;
123
+ } ? {
124
+ type: "slot";
125
+ host: {
126
+ kind: "piece";
127
+ id: HostId;
128
+ };
129
+ slotId: SlotIdForPieceType<Manifest, CurrentTypeId>;
130
+ } : never : never;
131
+ type TypedDieSlotHomeSpec<Manifest extends GameTopologyManifest> = TypedDieSlotHostSeed<Manifest> extends infer Seed ? Seed extends {
132
+ id: infer HostId extends string;
133
+ typeId: infer CurrentTypeId extends DieTypeId<Manifest>;
134
+ } ? {
135
+ type: "slot";
136
+ host: {
137
+ kind: "die";
138
+ id: HostId;
139
+ };
140
+ slotId: SlotIdForDieType<Manifest, CurrentTypeId>;
141
+ } : never : never;
142
+ type RequiredSchemaKeys<Properties extends Readonly<Record<string, unknown>>> = {
143
+ [Key in keyof Properties]: Properties[Key] extends {
144
+ optional: true;
145
+ } ? never : Properties[Key] extends {
146
+ default: unknown;
147
+ } ? never : Key;
148
+ }[keyof Properties];
149
+ type OptionalSchemaKeys<Properties extends Readonly<Record<string, unknown>>> = {
150
+ [Key in keyof Properties]: Properties[Key] extends {
151
+ optional: true;
152
+ } ? Key : Properties[Key] extends {
153
+ default: unknown;
154
+ } ? Key : never;
155
+ }[keyof Properties];
156
+ type SchemaValueFromObjectProperties<Properties extends Readonly<Record<string, unknown>>, Manifest extends GameTopologyManifest, BoardLike = never> = keyof Properties extends never ? RuntimeRecord : {
157
+ [Key in RequiredSchemaKeys<Properties>]: SchemaValueForProperty<Properties[Key], Manifest, BoardLike>;
158
+ } & {
159
+ [Key in OptionalSchemaKeys<Properties>]?: SchemaValueForProperty<Properties[Key], Manifest, BoardLike>;
160
+ };
161
+ type SchemaValueForObjectSchema<Schema, Manifest extends GameTopologyManifest, BoardLike = never> = Schema extends {
162
+ properties: infer Properties extends Readonly<Record<string, unknown>>;
163
+ } ? SchemaValueFromObjectProperties<Properties, Manifest, BoardLike> : RuntimeRecord;
164
+ type MergeSharedProperties<Variant, Shared> = Variant extends {
165
+ properties: infer VariantProperties extends Readonly<Record<string, unknown>>;
166
+ } ? {
167
+ properties: Shared extends Readonly<Record<string, unknown>> ? Omit<Shared, keyof VariantProperties> & VariantProperties : VariantProperties;
168
+ } : Variant;
169
+ type BaseSchemaValueForProperty<Schema, Manifest extends GameTopologyManifest, BoardLike = never> = Schema extends {
170
+ type: "string";
171
+ } ? string : Schema extends {
172
+ type: "integer" | "number";
173
+ } ? number : Schema extends {
174
+ type: "boolean";
175
+ } ? boolean : Schema extends {
176
+ type: "zoneId";
177
+ } ? ZoneId<Manifest> : Schema extends {
178
+ type: "cardId";
179
+ } ? CardId<Manifest> : Schema extends {
180
+ type: "playerId";
181
+ } ? PlayerId<Manifest> : Schema extends {
182
+ type: "boardId";
183
+ } ? BoardId<Manifest> : Schema extends {
184
+ type: "spaceId";
185
+ } ? [BoardLike] extends [never] ? string : SpaceIdOf<BoardLike> : Schema extends {
186
+ type: "edgeId";
187
+ } ? [BoardLike] extends [never] ? string : DerivedEdgeIdOf<BoardLike> : Schema extends {
188
+ type: "vertexId";
189
+ } ? [BoardLike] extends [never] ? string : DerivedVertexIdOf<BoardLike> : Schema extends {
190
+ type: "pieceId";
191
+ } ? PieceId<Manifest> : Schema extends {
192
+ type: "dieId";
193
+ } ? DieId<Manifest> : Schema extends {
194
+ type: "resourceId";
195
+ } ? ResourceId<Manifest> : Schema extends {
196
+ type: "enum";
197
+ } ? Schema extends {
198
+ enums: infer Values extends readonly string[];
199
+ } ? Values[number] : string : Schema extends {
200
+ type: "array";
201
+ } ? ReadonlyArray<SchemaValueForProperty<Schema extends {
202
+ items?: infer Items;
203
+ } ? Items : undefined, Manifest, BoardLike>> : Schema extends {
204
+ type: "object";
205
+ } ? SchemaValueForObjectSchema<Schema extends {
206
+ properties?: infer Properties extends Record<string, unknown>;
207
+ } ? {
208
+ properties: Properties;
209
+ } : undefined, Manifest, BoardLike> : Schema extends {
210
+ type: "record";
211
+ } ? Record<string, SchemaValueForProperty<Schema extends {
212
+ values?: infer Values;
213
+ } ? Values : undefined, Manifest, BoardLike>> : RuntimeRecord;
214
+ type SchemaValueForProperty<Schema, Manifest extends GameTopologyManifest, BoardLike = never> = Schema extends {
215
+ nullable: true;
216
+ } ? BaseSchemaValueForProperty<Schema, Manifest, BoardLike> | null : BaseSchemaValueForProperty<Schema, Manifest, BoardLike>;
217
+ type BuildTuple<Length extends number, Accumulator extends unknown[] = []> = Accumulator["length"] extends Length ? Accumulator : BuildTuple<Length, [...Accumulator, unknown]>;
218
+ type EnumerateInternal<Length extends number, Accumulator extends number[] = []> = Accumulator["length"] extends Length ? Accumulator[number] : EnumerateInternal<Length, [...Accumulator, Accumulator["length"]]>;
219
+ type AddOne<Count extends number> = [...BuildTuple<Count>, unknown]["length"] & number;
220
+ type OneTo<Count extends number> = Exclude<EnumerateInternal<AddOne<Count>>, 0>;
221
+ type PlayerId<Manifest extends GameTopologyManifest> = Manifest["players"]["maxPlayers"] extends infer MaxPlayers extends number ? `player-${OneTo<MaxPlayers>}` : `player-${number}`;
222
+ type ToNumber<Input extends string> = Input extends `${infer Value extends number}` ? Value : never;
223
+ type AbsoluteNumber<Count extends number> = `${Count}` extends `-${infer Value extends number}` ? Value : Count;
224
+ type IsNegative<Count extends number> = `${Count}` extends `-${string}` ? true : false;
225
+ type Negate<Count extends number> = Count extends 0 ? 0 : ToNumber<`${`${Count}` extends `-${infer Value extends number}` ? Value : `-${Count}`}`>;
226
+ type AddPositive<Left extends number, Right extends number> = number extends Left | Right ? number : [...BuildTuple<Left>, ...BuildTuple<Right>]["length"] & number;
227
+ type ComparePositive<Left extends number, Right extends number> = Left extends Right ? "equal" : number extends Left | Right ? "unknown" : BuildTuple<Left> extends [...BuildTuple<Right>, ...infer Rest] ? Rest extends [] ? "equal" : "greater" : "less";
228
+ type SubtractPositive<Left extends number, Right extends number> = number extends Left | Right ? number : BuildTuple<Left> extends [...BuildTuple<Right>, ...infer Rest] ? Rest["length"] & number : never;
229
+ type AddSigned<Left extends number, Right extends number> = number extends Left | Right ? number : IsNegative<Left> extends IsNegative<Right> ? IsNegative<Left> extends true ? Negate<AddPositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>>> : AddPositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>> : ComparePositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>> extends "equal" ? 0 : ComparePositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>> extends "greater" ? IsNegative<Left> extends true ? Negate<SubtractPositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>>> : SubtractPositive<AbsoluteNumber<Left>, AbsoluteNumber<Right>> : IsNegative<Right> extends true ? Negate<SubtractPositive<AbsoluteNumber<Right>, AbsoluteNumber<Left>>> : SubtractPositive<AbsoluteNumber<Right>, AbsoluteNumber<Left>>;
230
+ type MultiplyByThree<Count extends number> = AddSigned<Count, AddSigned<Count, Count>>;
231
+ type CharRank<Character extends string> = Character extends "," ? 0 : Character extends "-" ? 1 : Character extends "0" ? 2 : Character extends "1" ? 3 : Character extends "2" ? 4 : Character extends "3" ? 5 : Character extends "4" ? 6 : Character extends "5" ? 7 : Character extends "6" ? 8 : Character extends "7" ? 9 : Character extends "8" ? 10 : Character extends "9" ? 11 : never;
232
+ type CompareCharacters<Left extends string, Right extends string> = Left extends Right ? "equal" : ComparePositive<CharRank<Left>, CharRank<Right>> extends "less" ? "less" : "greater";
233
+ type CompareStrings<Left extends string, Right extends string> = Left extends `${infer LeftHead}${infer LeftTail}` ? Right extends `${infer RightHead}${infer RightTail}` ? LeftHead extends RightHead ? CompareStrings<LeftTail, RightTail> : CompareCharacters<LeftHead, RightHead> : "greater" : Right extends "" ? "equal" : "less";
234
+ type SortPair<Left extends string, Right extends string> = CompareStrings<Left, Right> extends "greater" ? `${Right}::${Left}` : `${Left}::${Right}`;
235
+ type SquareCornerGeometryKey<Space extends {
236
+ row: number;
237
+ col: number;
238
+ }, Corner extends "nw" | "ne" | "se" | "sw"> = Corner extends "nw" ? `${Space["col"]},${Space["row"]}` : Corner extends "ne" ? `${AddSigned<Space["col"], 1>},${Space["row"]}` : Corner extends "se" ? `${AddSigned<Space["col"], 1>},${AddSigned<Space["row"], 1>}` : `${Space["col"]},${AddSigned<Space["row"], 1>}`;
239
+ type SquareEdgeGeometryKey<Space extends {
240
+ row: number;
241
+ col: number;
242
+ }, Side extends "north" | "east" | "south" | "west"> = Side extends "north" ? `${Space["col"]},${Space["row"]}::${AddSigned<Space["col"], 1>},${Space["row"]}` : Side extends "east" ? `${AddSigned<Space["col"], 1>},${Space["row"]}::${AddSigned<Space["col"], 1>},${AddSigned<Space["row"], 1>}` : Side extends "south" ? `${Space["col"]},${AddSigned<Space["row"], 1>}::${AddSigned<Space["col"], 1>},${AddSigned<Space["row"], 1>}` : `${Space["col"]},${Space["row"]}::${Space["col"]},${AddSigned<Space["row"], 1>}`;
243
+ type HexCornerGeometryKey<Space extends {
244
+ q: number;
245
+ r: number;
246
+ }, Corner extends "ne-e" | "e-se" | "se-sw" | "sw-w" | "w-nw" | "nw-ne"> = `${AddSigned<MultiplyByThree<Space["q"]>, Corner extends "ne-e" ? 2 : Corner extends "e-se" ? 1 : Corner extends "se-sw" ? -1 : Corner extends "sw-w" ? -2 : Corner extends "w-nw" ? -1 : 1>},${AddSigned<MultiplyByThree<Negate<AddSigned<Space["q"], Space["r"]>>>, Corner extends "ne-e" ? -1 : Corner extends "e-se" ? -2 : Corner extends "se-sw" ? -1 : Corner extends "sw-w" ? 1 : Corner extends "w-nw" ? 2 : 1>},${AddSigned<MultiplyByThree<Space["r"]>, Corner extends "ne-e" ? -1 : Corner extends "e-se" ? 1 : Corner extends "se-sw" ? 2 : Corner extends "sw-w" ? 1 : Corner extends "w-nw" ? -1 : -2>}`;
247
+ type HexEdgeGeometryKey<Space extends {
248
+ q: number;
249
+ r: number;
250
+ }, Side extends "e" | "ne" | "nw" | "w" | "sw" | "se"> = SortPair<HexCornerGeometryKey<Space, Side extends "e" ? "ne-e" : Side extends "ne" ? "nw-ne" : Side extends "nw" ? "w-nw" : Side extends "w" ? "sw-w" : Side extends "sw" ? "se-sw" : "e-se">, HexCornerGeometryKey<Space, Side extends "e" ? "e-se" : Side extends "ne" ? "ne-e" : Side extends "nw" ? "nw-ne" : Side extends "w" ? "w-nw" : Side extends "sw" ? "sw-w" : "se-sw">>;
251
+ type DerivedSquareEdgeIdOf<BoardLike> = SquareSpaceOf<BoardLike> extends infer Space ? Space extends {
252
+ row: number;
253
+ col: number;
254
+ } ? `square-edge:${SquareEdgeGeometryKey<Space, "north">}` | `square-edge:${SquareEdgeGeometryKey<Space, "east">}` | `square-edge:${SquareEdgeGeometryKey<Space, "south">}` | `square-edge:${SquareEdgeGeometryKey<Space, "west">}` : never : never;
255
+ type DerivedSquareVertexIdOf<BoardLike> = SquareSpaceOf<BoardLike> extends infer Space ? Space extends {
256
+ row: number;
257
+ col: number;
258
+ } ? `square-vertex:${SquareCornerGeometryKey<Space, "nw">}` | `square-vertex:${SquareCornerGeometryKey<Space, "ne">}` | `square-vertex:${SquareCornerGeometryKey<Space, "se">}` | `square-vertex:${SquareCornerGeometryKey<Space, "sw">}` : never : never;
259
+ type DerivedHexEdgeIdOf<BoardLike> = HexSpaceOf<BoardLike> extends infer Space ? Space extends {
260
+ q: number;
261
+ r: number;
262
+ } ? `hex-edge:${HexEdgeGeometryKey<Space, "e">}` | `hex-edge:${HexEdgeGeometryKey<Space, "ne">}` | `hex-edge:${HexEdgeGeometryKey<Space, "nw">}` | `hex-edge:${HexEdgeGeometryKey<Space, "w">}` | `hex-edge:${HexEdgeGeometryKey<Space, "sw">}` | `hex-edge:${HexEdgeGeometryKey<Space, "se">}` : never : never;
263
+ type DerivedHexVertexIdOf<BoardLike> = HexSpaceOf<BoardLike> extends infer Space ? Space extends {
264
+ q: number;
265
+ r: number;
266
+ } ? `hex-vertex:${HexCornerGeometryKey<Space, "ne-e">}` | `hex-vertex:${HexCornerGeometryKey<Space, "e-se">}` | `hex-vertex:${HexCornerGeometryKey<Space, "se-sw">}` | `hex-vertex:${HexCornerGeometryKey<Space, "sw-w">}` | `hex-vertex:${HexCornerGeometryKey<Space, "w-nw">}` | `hex-vertex:${HexCornerGeometryKey<Space, "nw-ne">}` : never : never;
267
+ type DerivedEdgeIdOf<BoardLike> = BoardLike extends {
268
+ layout: "square";
269
+ } ? DerivedSquareEdgeIdOf<BoardLike> : BoardLike extends {
270
+ layout: "hex";
271
+ } ? DerivedHexEdgeIdOf<BoardLike> : never;
272
+ type DerivedVertexIdOf<BoardLike> = BoardLike extends {
273
+ layout: "square";
274
+ } ? DerivedSquareVertexIdOf<BoardLike> : BoardLike extends {
275
+ layout: "hex";
276
+ } ? DerivedHexVertexIdOf<BoardLike> : never;
277
+ type SetupOptionChoiceId<Option> = IdsOf<Option extends {
278
+ choices?: infer Choices;
279
+ } ? Choices : never>;
280
+ type SetupOptionOf<Manifest extends GameTopologyManifest> = ArrayItem<NonNullable<Manifest["setupOptions"]>>;
281
+ type SetupOptionChoiceIdFor<Manifest extends GameTopologyManifest, OptionId extends SetupOptionId<Manifest>> = SetupOptionChoiceId<Extract<SetupOptionOf<Manifest>, {
282
+ id: OptionId;
283
+ }>>;
284
+ type TypedSharedSpaceHomeSpec<Manifest extends GameTopologyManifest> = {
285
+ [CurrentBoardId in SharedBoardId<Manifest>]: {
286
+ type: "space";
287
+ boardId: CurrentBoardId;
288
+ spaceId: SpaceIdForBoard<Manifest, CurrentBoardId>;
289
+ };
290
+ }[SharedBoardId<Manifest>];
291
+ type TypedPerPlayerSpaceHomeSpec<Manifest extends GameTopologyManifest> = {
292
+ [CurrentBoardId in PerPlayerBoardId<Manifest>]: {
293
+ type: "space";
294
+ boardId: CurrentBoardId;
295
+ spaceId: SpaceIdForBoard<Manifest, CurrentBoardId>;
296
+ };
297
+ }[PerPlayerBoardId<Manifest>];
298
+ type TypedSharedContainerHomeSpec<Manifest extends GameTopologyManifest> = {
299
+ [CurrentBoardId in SharedBoardId<Manifest>]: {
300
+ type: "container";
301
+ boardId: CurrentBoardId;
302
+ containerId: ContainerIdForBoard<Manifest, CurrentBoardId>;
303
+ };
304
+ }[SharedBoardId<Manifest>];
305
+ type TypedPerPlayerContainerHomeSpec<Manifest extends GameTopologyManifest> = {
306
+ [CurrentBoardId in PerPlayerBoardId<Manifest>]: {
307
+ type: "container";
308
+ boardId: CurrentBoardId;
309
+ containerId: ContainerIdForBoard<Manifest, CurrentBoardId>;
310
+ };
311
+ }[PerPlayerBoardId<Manifest>];
312
+ type TypedSharedEdgeHomeSpec<Manifest extends GameTopologyManifest> = {
313
+ [CurrentBoardId in SharedBoardId<Manifest>]: {
314
+ type: "edge";
315
+ boardId: CurrentBoardId;
316
+ ref: BoardEdgeRef;
317
+ };
318
+ }[SharedBoardId<Manifest>];
319
+ type TypedPerPlayerEdgeHomeSpec<Manifest extends GameTopologyManifest> = {
320
+ [CurrentBoardId in PerPlayerBoardId<Manifest>]: {
321
+ type: "edge";
322
+ boardId: CurrentBoardId;
323
+ ref: BoardEdgeRef;
324
+ };
325
+ }[PerPlayerBoardId<Manifest>];
326
+ type TypedSharedVertexHomeSpec<Manifest extends GameTopologyManifest> = {
327
+ [CurrentBoardId in SharedBoardId<Manifest>]: {
328
+ type: "vertex";
329
+ boardId: CurrentBoardId;
330
+ ref: BoardVertexRef;
331
+ };
332
+ }[SharedBoardId<Manifest>];
333
+ type TypedPerPlayerVertexHomeSpec<Manifest extends GameTopologyManifest> = {
334
+ [CurrentBoardId in PerPlayerBoardId<Manifest>]: {
335
+ type: "vertex";
336
+ boardId: CurrentBoardId;
337
+ ref: BoardVertexRef;
338
+ };
339
+ }[PerPlayerBoardId<Manifest>];
340
+ type TypedSharedZoneHomeSpec<Manifest extends GameTopologyManifest> = {
341
+ type: "zone";
342
+ zoneId: SharedZoneId<Manifest>;
343
+ };
344
+ type TypedPerPlayerZoneHomeSpec<Manifest extends GameTopologyManifest> = {
345
+ type: "zone";
346
+ zoneId: PerPlayerZoneId<Manifest>;
347
+ };
348
+ type TypedPlayerScopedComponentHomeSpec<Manifest extends GameTopologyManifest> = TypedPerPlayerZoneHomeSpec<Manifest> | TypedPerPlayerSpaceHomeSpec<Manifest> | TypedPerPlayerContainerHomeSpec<Manifest> | TypedPerPlayerEdgeHomeSpec<Manifest> | TypedPerPlayerVertexHomeSpec<Manifest>;
349
+ type TypedSharedComponentHomeSpec<Manifest extends GameTopologyManifest> = {
350
+ type: "detached";
351
+ } | TypedSharedZoneHomeSpec<Manifest> | TypedSharedSpaceHomeSpec<Manifest> | TypedSharedContainerHomeSpec<Manifest> | TypedSharedEdgeHomeSpec<Manifest> | TypedSharedVertexHomeSpec<Manifest> | TypedPieceSlotHomeSpec<Manifest> | TypedDieSlotHomeSpec<Manifest>;
352
+ type TypedComponentHomeSpec<Manifest extends GameTopologyManifest> = TypedSharedComponentHomeSpec<Manifest> | TypedPlayerScopedComponentHomeSpec<Manifest>;
353
+ type TypedSeedLocationSpec<Seed, Manifest extends GameTopologyManifest> = Seed extends {
354
+ home: infer Home;
355
+ } ? Home extends TypedPlayerScopedComponentHomeSpec<Manifest> ? Omit<Seed, "ownerId" | "home"> & {
356
+ ownerId: PlayerId<Manifest>;
357
+ home: TypedPlayerScopedComponentHomeSpec<Manifest>;
358
+ } : Omit<Seed, "ownerId" | "home"> & {
359
+ ownerId?: PlayerId<Manifest>;
360
+ home?: TypedComponentHomeSpec<Manifest>;
361
+ } : Omit<Seed, "ownerId" | "home"> & {
362
+ ownerId?: PlayerId<Manifest>;
363
+ home?: TypedComponentHomeSpec<Manifest>;
364
+ };
365
+ type TypedVisibilitySpec<Manifest extends GameTopologyManifest> = {
366
+ faceUp?: boolean;
367
+ visibleTo?: readonly PlayerId<Manifest>[];
368
+ };
369
+ type TypedVisibility<T, Manifest extends GameTopologyManifest> = T extends {
370
+ visibility?: unknown;
371
+ } ? Omit<T, "visibility"> & {
372
+ visibility?: TypedVisibilitySpec<Manifest>;
373
+ } : T;
374
+ type TypedFields<T, Schema, Manifest extends GameTopologyManifest, BoardLike = never> = T extends {
375
+ fields?: unknown;
376
+ } ? Omit<T, "fields"> & {
377
+ fields?: SchemaValueForObjectSchema<Schema, Manifest, BoardLike>;
378
+ } : T;
379
+ type TypedBoardContainerHost<Host, BoardLike> = Host extends {
380
+ type: "space";
381
+ spaceId: string;
382
+ } ? Omit<Host, "spaceId"> & {
383
+ spaceId: SpaceIdOf<BoardLike>;
384
+ } : Host;
385
+ type TypedBoardContainer<Container, Manifest extends GameTopologyManifest, BoardLike, ContainerSchema> = Container extends {
386
+ host: infer Host;
387
+ } ? Omit<TypedFields<TypedAllowedCardSetIds<Container, Manifest>, ContainerSchema, Manifest, BoardLike>, "host"> & {
388
+ host: TypedBoardContainerHost<Host, BoardLike>;
389
+ } : TypedFields<TypedAllowedCardSetIds<Container, Manifest>, ContainerSchema, Manifest, BoardLike>;
390
+ type TypedBoardRelation<Relation, Manifest extends GameTopologyManifest, BoardLike, RelationSchema> = Relation extends object ? Omit<TypedFields<Relation, RelationSchema, Manifest, BoardLike>, "fromSpaceId" | "toSpaceId"> & {
391
+ fromSpaceId: SpaceIdOf<BoardLike>;
392
+ toSpaceId: SpaceIdOf<BoardLike>;
393
+ } : Relation;
394
+ type TypedOptionalArray<Base, Source, Key extends string, Item> = Source extends {
395
+ [Property in Key]?: readonly unknown[];
396
+ } ? Base & {
397
+ [Property in Key]?: ReadonlyArray<Item>;
398
+ } : Base;
399
+ type EffectiveSchemaForEntry<Manifest extends GameTopologyManifest, Entry, Key extends string> = Key extends keyof Entry ? Entry[Key] : TemplateForBoardEntry<Manifest, Entry> extends infer Template ? Key extends keyof Template ? Template[Key] : undefined : undefined;
400
+ type TypedGenericBoardLike<Entry, Manifest extends GameTopologyManifest, BoardLike> = TypedOptionalArray<TypedOptionalArray<TypedOptionalArray<TypedFields<Omit<Entry, "spaces" | "relations" | "containers">, EffectiveSchemaForEntry<Manifest, Entry, "boardFieldsSchema">, Manifest, BoardLike>, Entry, "spaces", TypedFields<ArrayItem<NonNullable<Entry extends {
401
+ spaces?: infer Spaces;
402
+ } ? Spaces : never>>, EffectiveSchemaForEntry<Manifest, Entry, "spaceFieldsSchema">, Manifest, BoardLike>>, Entry, "relations", TypedBoardRelation<ArrayItem<NonNullable<Entry extends {
403
+ relations?: infer Relations;
404
+ } ? Relations : never>>, Manifest, BoardLike, EffectiveSchemaForEntry<Manifest, Entry, "relationFieldsSchema">>>, Entry, "containers", TypedBoardContainer<ArrayItem<NonNullable<Entry extends {
405
+ containers?: infer Containers;
406
+ } ? Containers : never>>, Manifest, BoardLike, EffectiveSchemaForEntry<Manifest, Entry, "containerFieldsSchema">>>;
407
+ type TypedHexBoardLike<Entry, Manifest extends GameTopologyManifest, BoardLike> = TypedOptionalArray<TypedOptionalArray<TypedOptionalArray<TypedFields<Omit<Entry, "spaces" | "edges" | "vertices">, EffectiveSchemaForEntry<Manifest, Entry, "boardFieldsSchema">, Manifest, BoardLike>, Entry, "spaces", TypedFields<ArrayItem<NonNullable<Entry extends {
408
+ spaces?: infer Spaces;
409
+ } ? Spaces : never>>, EffectiveSchemaForEntry<Manifest, Entry, "spaceFieldsSchema">, Manifest, BoardLike>>, Entry, "edges", TypedFields<ArrayItem<NonNullable<Entry extends {
410
+ edges?: infer Edges;
411
+ } ? Edges : never>>, EffectiveSchemaForEntry<Manifest, Entry, "edgeFieldsSchema">, Manifest, BoardLike>>, Entry, "vertices", TypedFields<ArrayItem<NonNullable<Entry extends {
412
+ vertices?: infer Vertices;
413
+ } ? Vertices : never>>, EffectiveSchemaForEntry<Manifest, Entry, "vertexFieldsSchema">, Manifest, BoardLike>>;
414
+ type TypedSquareBoardLike<Entry, Manifest extends GameTopologyManifest, BoardLike> = TypedOptionalArray<TypedOptionalArray<TypedOptionalArray<TypedOptionalArray<TypedOptionalArray<TypedFields<Omit<Entry, "spaces" | "relations" | "containers" | "edges" | "vertices">, EffectiveSchemaForEntry<Manifest, Entry, "boardFieldsSchema">, Manifest, BoardLike>, Entry, "spaces", TypedFields<ArrayItem<NonNullable<Entry extends {
415
+ spaces?: infer Spaces;
416
+ } ? Spaces : never>>, EffectiveSchemaForEntry<Manifest, Entry, "spaceFieldsSchema">, Manifest, BoardLike>>, Entry, "relations", TypedBoardRelation<ArrayItem<NonNullable<Entry extends {
417
+ relations?: infer Relations;
418
+ } ? Relations : never>>, Manifest, BoardLike, EffectiveSchemaForEntry<Manifest, Entry, "relationFieldsSchema">>>, Entry, "containers", TypedBoardContainer<ArrayItem<NonNullable<Entry extends {
419
+ containers?: infer Containers;
420
+ } ? Containers : never>>, Manifest, BoardLike, EffectiveSchemaForEntry<Manifest, Entry, "containerFieldsSchema">>>, Entry, "edges", TypedFields<ArrayItem<NonNullable<Entry extends {
421
+ edges?: infer Edges;
422
+ } ? Edges : never>>, EffectiveSchemaForEntry<Manifest, Entry, "edgeFieldsSchema">, Manifest, BoardLike>>, Entry, "vertices", TypedFields<ArrayItem<NonNullable<Entry extends {
423
+ vertices?: infer Vertices;
424
+ } ? Vertices : never>>, EffectiveSchemaForEntry<Manifest, Entry, "vertexFieldsSchema">, Manifest, BoardLike>>;
425
+ type TypedBoardLikeEntry<Entry, Manifest extends GameTopologyManifest> = Entry extends {
426
+ layout: "generic";
427
+ } ? TypedGenericBoardLike<Entry, Manifest, BoardLikeForEntry<Manifest, Entry>> : Entry extends {
428
+ layout: "hex";
429
+ } ? TypedHexBoardLike<Entry, Manifest, BoardLikeForEntry<Manifest, Entry>> : Entry extends {
430
+ layout: "square";
431
+ } ? TypedSquareBoardLike<Entry, Manifest, BoardLikeForEntry<Manifest, Entry>> : Entry;
432
+ type TypedCard<Card, Manifest extends GameTopologyManifest, CardSchema> = Card extends {
433
+ type: infer CardType extends string;
434
+ } ? Omit<TypedVisibility<Card, Manifest>, "home" | "properties"> & {
435
+ home?: TypedComponentHomeSpec<Manifest>;
436
+ properties: CardSchema extends {
437
+ variants: infer Variants extends Record<string, unknown>;
438
+ shared?: infer Shared;
439
+ } ? CardType extends keyof Variants ? SchemaValueForObjectSchema<MergeSharedProperties<Variants[CardType], Shared>, Manifest> : never : SchemaValueForObjectSchema<CardSchema, Manifest>;
440
+ } : Card;
441
+ type TypedCardSet<CardSet, Manifest extends GameTopologyManifest> = CardSet extends {
442
+ type: "manual";
443
+ cardSchema: infer CardSchema;
444
+ cards: infer Cards extends readonly unknown[];
445
+ } ? Omit<CardSet, "cards"> & {
446
+ cards: ReadonlyArray<TypedCard<ArrayItem<Cards>, Manifest, CardSchema>>;
447
+ } : CardSet;
448
+ type TypedAllowedCardSetIds<T, Manifest extends GameTopologyManifest> = T extends object ? Omit<T, "allowedCardSetIds"> & {
449
+ allowedCardSetIds?: readonly CardSetId<Manifest>[];
450
+ } : T;
451
+ type TypedZone<Zone, Manifest extends GameTopologyManifest> = TypedAllowedCardSetIds<Zone, Manifest>;
452
+ type TypedPieceSeed<Seed, Manifest extends GameTopologyManifest> = Seed extends {
453
+ typeId: infer CurrentTypeId;
454
+ } ? CurrentTypeId extends PieceTypeId<Manifest> ? Omit<TypedSeedLocationSpec<TypedVisibility<Seed, Manifest>, Manifest>, "typeId" | "ownerId" | "home" | "fields"> & {
455
+ typeId: CurrentTypeId;
456
+ fields?: SchemaValueForObjectSchema<PieceTypeOf<Manifest, CurrentTypeId> extends {
457
+ fieldsSchema?: infer FieldsSchema;
458
+ } ? FieldsSchema : undefined, Manifest>;
459
+ } & Pick<TypedSeedLocationSpec<TypedVisibility<Seed, Manifest>, Manifest>, "ownerId" | "home"> : Omit<Seed, "typeId"> & {
460
+ typeId: PieceTypeId<Manifest>;
461
+ } : never;
462
+ type TypedDieSeed<Seed, Manifest extends GameTopologyManifest> = Seed extends {
463
+ typeId: infer CurrentTypeId;
464
+ } ? CurrentTypeId extends DieTypeId<Manifest> ? Omit<TypedSeedLocationSpec<TypedVisibility<Seed, Manifest>, Manifest>, "typeId" | "ownerId" | "home" | "fields"> & {
465
+ typeId: CurrentTypeId;
466
+ fields?: SchemaValueForObjectSchema<DieTypeOf<Manifest, CurrentTypeId> extends {
467
+ fieldsSchema?: infer FieldsSchema;
468
+ } ? FieldsSchema : undefined, Manifest>;
469
+ } & Pick<TypedSeedLocationSpec<TypedVisibility<Seed, Manifest>, Manifest>, "ownerId" | "home"> : Omit<Seed, "typeId"> & {
470
+ typeId: DieTypeId<Manifest>;
471
+ } : never;
472
+ type TypedSetupOptionValues<Manifest extends GameTopologyManifest> = Partial<{
473
+ [OptionId in SetupOptionId<Manifest>]: SetupOptionChoiceIdFor<Manifest, OptionId>;
474
+ }>;
475
+ type TypedSetupProfile<Profile, Manifest extends GameTopologyManifest> = Profile extends object ? Omit<Profile, "optionValues"> & {
476
+ optionValues?: TypedSetupOptionValues<Manifest>;
477
+ } : Profile;
478
+ type TypedTopologyManifest<Manifest extends GameTopologyManifest> = Omit<Manifest, "cardSets" | "zones" | "boardTemplates" | "boards" | "pieceSeeds" | "dieSeeds" | "setupProfiles"> & {
479
+ cardSets: ReadonlyArray<TypedCardSet<ArrayItem<Manifest["cardSets"]>, Manifest>>;
480
+ zones?: Manifest["zones"] extends readonly unknown[] ? ReadonlyArray<TypedZone<ArrayItem<Manifest["zones"]>, Manifest>> : Manifest["zones"];
481
+ boardTemplates?: Manifest["boardTemplates"] extends readonly unknown[] ? ReadonlyArray<TypedBoardLikeEntry<ArrayItem<Manifest["boardTemplates"]>, Manifest>> : Manifest["boardTemplates"];
482
+ boards: Manifest["boards"] extends readonly unknown[] ? ReadonlyArray<TypedBoardLikeEntry<ArrayItem<Manifest["boards"]>, Manifest>> : Manifest["boards"];
483
+ pieceSeeds?: Manifest["pieceSeeds"] extends readonly unknown[] ? ReadonlyArray<TypedPieceSeed<ArrayItem<Manifest["pieceSeeds"]>, Manifest>> : Manifest["pieceSeeds"];
484
+ dieSeeds?: Manifest["dieSeeds"] extends readonly unknown[] ? ReadonlyArray<TypedDieSeed<ArrayItem<Manifest["dieSeeds"]>, Manifest>> : Manifest["dieSeeds"];
485
+ setupProfiles?: Manifest["setupProfiles"] extends readonly unknown[] ? ReadonlyArray<TypedSetupProfile<ArrayItem<Manifest["setupProfiles"]>, Manifest>> : Manifest["setupProfiles"];
486
+ };
487
+ type TopologyManifestValidation<Manifest> = Manifest extends GameTopologyManifest ? TypedTopologyManifest<Manifest> : GameTopologyManifest;
488
+ type DefinedTopologyManifest<Manifest> = Manifest extends GameTopologyManifest ? Manifest : GameTopologyManifest;
489
+ declare function defineTopologyManifest<const Manifest>(manifest: Manifest & TopologyManifestValidation<NoInfer<Manifest>>): DefinedTopologyManifest<Manifest>;
490
+
491
+ type RecordInitializer<Id extends string, Value> = Value | ((id: Id) => Value);
492
+ declare function buildTypedRecord<Id extends string, Value>(ids: readonly Id[], initial: RecordInitializer<Id, Value>): Record<Id, Value>;
493
+ declare function isTypedId<Id extends string>(ids: readonly Id[], value: string): value is Id;
494
+ declare function expectTypedId<Id extends string>(ids: readonly Id[], value: string, description: string): Id;
495
+
496
+ export { BoardEdgeRef, BoardVertexRef, JsonValue, type TypedTopologyManifest, buildTypedRecord, defineTopologyManifest, expectTypedId, isTypedId };
package/dist/types.js ADDED
@@ -0,0 +1,28 @@
1
+ import "./chunk-PZ5AY32C.js";
2
+
3
+ // src/types/authoring.ts
4
+ function defineTopologyManifest(manifest) {
5
+ return manifest;
6
+ }
7
+
8
+ // src/types/generated-helpers.ts
9
+ function buildTypedRecord(ids, initial) {
10
+ const createValue = typeof initial === "function" ? initial : () => initial;
11
+ return Object.fromEntries(ids.map((id) => [id, createValue(id)]));
12
+ }
13
+ function isTypedId(ids, value) {
14
+ return ids.includes(value);
15
+ }
16
+ function expectTypedId(ids, value, description) {
17
+ if (isTypedId(ids, value)) {
18
+ return value;
19
+ }
20
+ throw new Error(`Unknown ${description} '${value}'.`);
21
+ }
22
+ export {
23
+ buildTypedRecord,
24
+ defineTopologyManifest,
25
+ expectTypedId,
26
+ isTypedId
27
+ };
28
+ //# sourceMappingURL=types.js.map