@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,382 @@
1
+ import {
2
+ isManifestScopedSchema,
3
+ type ManifestContract,
4
+ type RuntimeTableRecord,
5
+ type SchemaLike,
6
+ } from "../model";
7
+ import type { InputCollector } from "../model";
8
+ import {
9
+ getObjectShape,
10
+ getZodDef,
11
+ isEnumKeyedRecordSchema,
12
+ isPlainZodString,
13
+ isSparseMapSchema,
14
+ isZodArray,
15
+ unwrapWrappers,
16
+ } from "../schema-helpers";
17
+ import type { AnyReducerGameContract } from "./types";
18
+
19
+ /**
20
+ * Canonical set of manifest-scoped id field names. `defineGameContract`
21
+ * uses this list to reject state schemas that describe one of these fields
22
+ * with a raw `z.string()` instead of the corresponding branded enum from
23
+ * `manifest.ids.*` (or `gameContract.schemas.*`).
24
+ *
25
+ * The rule of thumb is "one way to do things": if a field *is* a player id,
26
+ * card id, zone id, etc. in the manifest, the authored state schema must
27
+ * reuse the same literal/branded schema so generated types line up with the
28
+ * runtime checks, instead of silently widening to `string`.
29
+ */
30
+ const MANIFEST_SCOPED_ID_NAMES = [
31
+ "playerId",
32
+ "cardId",
33
+ "deckId",
34
+ "handId",
35
+ "zoneId",
36
+ "sharedZoneId",
37
+ "playerZoneId",
38
+ "boardId",
39
+ "boardContainerId",
40
+ "boardTypeId",
41
+ "boardBaseId",
42
+ "edgeId",
43
+ "edgeTypeId",
44
+ "vertexId",
45
+ "vertexTypeId",
46
+ "spaceId",
47
+ "spaceTypeId",
48
+ "relationTypeId",
49
+ "resourceId",
50
+ "pieceId",
51
+ "pieceTypeId",
52
+ "dieId",
53
+ "dieTypeId",
54
+ "setupOptionId",
55
+ "setupProfileId",
56
+ "cardSetId",
57
+ "cardType",
58
+ ] as const;
59
+
60
+ type ManifestScopedIdName = (typeof MANIFEST_SCOPED_ID_NAMES)[number];
61
+
62
+ function matchManifestScopedIdName(
63
+ key: string,
64
+ ): { name: ManifestScopedIdName; kind: "singular" | "plural" } | null {
65
+ for (const name of MANIFEST_SCOPED_ID_NAMES) {
66
+ const capitalized = `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
67
+ if (key === name || key.endsWith(capitalized)) {
68
+ return { name, kind: "singular" };
69
+ }
70
+ const plural = `${name}s`;
71
+ const capitalizedPlural = `${capitalized}s`;
72
+ if (key === plural || key.endsWith(capitalizedPlural)) {
73
+ return { name, kind: "plural" };
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+
79
+ export function validateInteractionParamsSchema(
80
+ schema: unknown,
81
+ context: "defineInteraction" | "defineCardAction",
82
+ path: string,
83
+ ): void {
84
+ const inner = unwrapWrappers(schema);
85
+ if (isEnumKeyedRecordSchema(inner) && !isSparseMapSchema(inner)) {
86
+ throw new Error(
87
+ `${context}: ${path} uses an enum-keyed z.record(...), which parses as a total map at runtime. ` +
88
+ `Use sparseMap(...) or sparseCounts(...) from @dreamboard-games/sdk/reducer instead so interaction params stay sparse and match runtime validation.`,
89
+ );
90
+ }
91
+
92
+ const shape = getObjectShape(inner);
93
+ if (shape) {
94
+ for (const [key, fieldSchema] of Object.entries(shape)) {
95
+ validateInteractionParamsSchema(fieldSchema, context, `${path}.${key}`);
96
+ }
97
+ return;
98
+ }
99
+
100
+ const def = getZodDef(inner);
101
+ if (def.type === "array" && def.element) {
102
+ validateInteractionParamsSchema(def.element, context, `${path}[]`);
103
+ return;
104
+ }
105
+
106
+ if (def.type === "record" && def.valueType) {
107
+ validateInteractionParamsSchema(def.valueType, context, `${path}.*`);
108
+ }
109
+ }
110
+
111
+ export function validateInteractionInputsSchema(
112
+ inputs: Record<string, InputCollector> | undefined,
113
+ context: "defineInteraction" | "defineCardAction",
114
+ ): void {
115
+ if (!inputs) return;
116
+ for (const [key, collector] of Object.entries(inputs)) {
117
+ validateInteractionParamsSchema(collector.schema, context, `inputs.${key}`);
118
+ }
119
+ }
120
+
121
+ export function validateManyCommitPolicy(input: {
122
+ inputs: Record<string, InputCollector> | undefined;
123
+ commit?: { mode: string };
124
+ context: string;
125
+ }): void {
126
+ if (input.commit?.mode !== "autoWhenReady") return;
127
+ if (
128
+ Object.values(input.inputs ?? {}).some(
129
+ (collector) => collector.selection?.mode === "many",
130
+ )
131
+ ) {
132
+ throw new Error(
133
+ `${input.context}: interactions with many(...) inputs must use commit: { mode: "manual" }.`,
134
+ );
135
+ }
136
+ }
137
+
138
+ export function validateInteractionLikeDefinition(
139
+ input: {
140
+ inputs?: Record<string, InputCollector>;
141
+ commit?: { mode: string };
142
+ paramsSchema?: unknown;
143
+ },
144
+ context: "defineInteraction" | "defineCardAction",
145
+ ): void {
146
+ validateInteractionInputsSchema(input.inputs, context);
147
+ validateManyCommitPolicy({
148
+ inputs: input.inputs,
149
+ commit: input.commit,
150
+ context,
151
+ });
152
+ if (input.paramsSchema) {
153
+ validateInteractionParamsSchema(
154
+ input.paramsSchema,
155
+ context,
156
+ "paramsSchema",
157
+ );
158
+ }
159
+ }
160
+
161
+ export function validateStateSchemaIdBranding(
162
+ schema: unknown,
163
+ scope: "public" | "private" | "hidden",
164
+ ): void {
165
+ const def = getZodDef(schema);
166
+ if (def.type !== "object") {
167
+ return;
168
+ }
169
+ const shape = def.shape as Record<string, unknown> | undefined;
170
+ if (!shape) {
171
+ return;
172
+ }
173
+ for (const [key, fieldSchema] of Object.entries(shape)) {
174
+ const match = matchManifestScopedIdName(key);
175
+ if (!match) {
176
+ continue;
177
+ }
178
+ const inner = unwrapWrappers(fieldSchema);
179
+ if (match.kind === "singular") {
180
+ if (isPlainZodString(inner) && !isManifestScopedSchema(inner)) {
181
+ throw new Error(
182
+ `defineGameContract: state.${scope}.${key} uses a raw z.string() ` +
183
+ `but its name identifies it as a manifest-scoped '${match.name}'. ` +
184
+ `Use gameContract.schemas.${match.name} (or manifest.ids.${match.name}) ` +
185
+ `so the branded literal union flows through state types.`,
186
+ );
187
+ }
188
+ continue;
189
+ }
190
+ if (match.kind === "plural" && isZodArray(inner)) {
191
+ const element = unwrapWrappers(getZodDef(inner).element);
192
+ if (isPlainZodString(element) && !isManifestScopedSchema(element)) {
193
+ throw new Error(
194
+ `defineGameContract: state.${scope}.${key} uses z.array(z.string()) ` +
195
+ `but its name identifies it as manifest-scoped '${match.name}' values. ` +
196
+ `Use z.array(gameContract.schemas.${match.name}) ` +
197
+ `(or manifest.ids.${match.name}) so the branded literal union flows through state types.`,
198
+ );
199
+ }
200
+ }
201
+ }
202
+ }
203
+
204
+ export function validateDefineGamePhaseNames(definition: {
205
+ contract: AnyReducerGameContract;
206
+ phases: Record<string, unknown>;
207
+ initialPhase?: string;
208
+ setupProfiles?: Record<string, { initialPhase?: string }>;
209
+ }): void {
210
+ const contractPhaseNames = (
211
+ definition.contract as AnyReducerGameContract & {
212
+ phaseNames?: readonly string[];
213
+ }
214
+ ).phaseNames;
215
+ if (!Array.isArray(contractPhaseNames)) {
216
+ return;
217
+ }
218
+ const declared = new Set(contractPhaseNames);
219
+ const actual = new Set(Object.keys(definition.phases));
220
+ const missing = [...declared].filter((name) => !actual.has(name));
221
+ const extra = [...actual].filter((name) => !declared.has(name));
222
+ if (missing.length > 0 || extra.length > 0) {
223
+ const parts: string[] = [];
224
+ if (missing.length > 0) {
225
+ parts.push(`missing: [${missing.join(", ")}]`);
226
+ }
227
+ if (extra.length > 0) {
228
+ parts.push(`extra: [${extra.join(", ")}]`);
229
+ }
230
+ throw new Error(
231
+ `defineGame: phases record does not match contract.phaseNames (${parts.join(
232
+ "; ",
233
+ )}). Update contract.phaseNames or the phases record so they agree.`,
234
+ );
235
+ }
236
+ if (
237
+ definition.initialPhase !== undefined &&
238
+ !declared.has(definition.initialPhase)
239
+ ) {
240
+ throw new Error(
241
+ `defineGame: initialPhase '${definition.initialPhase}' is not declared in contract.phaseNames.`,
242
+ );
243
+ }
244
+ if (definition.setupProfiles) {
245
+ for (const [profileId, profile] of Object.entries(
246
+ definition.setupProfiles,
247
+ )) {
248
+ const initial = profile?.initialPhase;
249
+ if (initial !== undefined && !declared.has(initial)) {
250
+ throw new Error(
251
+ `defineGame: setupProfiles.${profileId}.initialPhase '${initial}' is not declared in contract.phaseNames.`,
252
+ );
253
+ }
254
+ }
255
+ }
256
+ }
257
+
258
+ export function validateDefineGameZoneWiring(definition: {
259
+ contract: {
260
+ manifest: ManifestContract<RuntimeTableRecord>;
261
+ };
262
+ phases: Record<string, unknown>;
263
+ }): void {
264
+ const manifestPlayerZoneIds = new Set(
265
+ definition.contract.manifest.literals.playerZoneIds ?? [],
266
+ );
267
+ for (const [phaseName, phase] of Object.entries(definition.phases)) {
268
+ const phaseRecord =
269
+ typeof phase === "object" && phase !== null
270
+ ? (phase as {
271
+ zones?: Record<string, unknown>;
272
+ cardActions?: Record<string, unknown>;
273
+ })
274
+ : null;
275
+ if (!phaseRecord) continue;
276
+
277
+ if (phaseRecord.zones !== undefined && !Array.isArray(phaseRecord.zones)) {
278
+ const zonesRecord =
279
+ typeof phaseRecord.zones === "object" && phaseRecord.zones !== null
280
+ ? (phaseRecord.zones as Record<string, unknown>)
281
+ : null;
282
+ const hasRemovedZoneSpec =
283
+ zonesRecord &&
284
+ Object.values(zonesRecord).some(
285
+ (zone) =>
286
+ typeof zone === "object" &&
287
+ zone !== null &&
288
+ ("cardsFrom" in zone || "playableVia" in zone || "from" in zone),
289
+ );
290
+ if (hasRemovedZoneSpec) {
291
+ throw new Error(
292
+ `defineGame: phases.${phaseName}.zones uses removed zone spec objects. Use zones: ["manifest-player-zone-id"] and cardActions[*].playFrom instead.`,
293
+ );
294
+ }
295
+ throw new Error(
296
+ `defineGame: phases.${phaseName}.zones must be an array of manifest player zone ids.`,
297
+ );
298
+ }
299
+
300
+ for (const [index, zoneId] of (phaseRecord.zones ?? []).entries()) {
301
+ if (typeof zoneId !== "string") {
302
+ throw new Error(
303
+ `defineGame: phases.${phaseName}.zones[${index}] must be a manifest player zone id string.`,
304
+ );
305
+ }
306
+ if (!manifestPlayerZoneIds.has(zoneId)) {
307
+ throw new Error(
308
+ `defineGame: phases.${phaseName}.zones[${index}] '${zoneId}' is not declared in manifest.literals.playerZoneIds.`,
309
+ );
310
+ }
311
+ }
312
+
313
+ for (const [actionId, action] of Object.entries(
314
+ phaseRecord.cardActions ?? {},
315
+ )) {
316
+ const actionRecord =
317
+ typeof action === "object" && action !== null
318
+ ? (action as Record<string, unknown>)
319
+ : null;
320
+ const playFrom = actionRecord?.playFrom;
321
+ if (
322
+ typeof playFrom === "string" &&
323
+ !manifestPlayerZoneIds.has(playFrom)
324
+ ) {
325
+ throw new Error(
326
+ `defineGame: phases.${phaseName}.cardActions.${actionId}.playFrom '${playFrom}' is not declared in manifest.literals.playerZoneIds.`,
327
+ );
328
+ }
329
+ }
330
+ }
331
+ }
332
+
333
+ export function validateDefineGameSimultaneousPhases(definition: {
334
+ phases: Record<string, unknown>;
335
+ }): void {
336
+ for (const [phaseName, phase] of Object.entries(definition.phases)) {
337
+ const phaseRecord =
338
+ typeof phase === "object" && phase !== null
339
+ ? (phase as {
340
+ kind?: unknown;
341
+ submit?: { inputs?: Record<string, InputCollector> };
342
+ resolve?: unknown;
343
+ interactions?: Record<string, unknown>;
344
+ })
345
+ : null;
346
+ if (!phaseRecord || phaseRecord.kind !== "simultaneousPlayer") {
347
+ continue;
348
+ }
349
+ if (!phaseRecord.submit) {
350
+ throw new Error(
351
+ `defineGame: phases.${phaseName} is kind 'simultaneousPlayer' but does not declare submit.`,
352
+ );
353
+ }
354
+ if (typeof phaseRecord.resolve !== "function") {
355
+ throw new Error(
356
+ `defineGame: phases.${phaseName} is kind 'simultaneousPlayer' but does not declare resolve.`,
357
+ );
358
+ }
359
+ if (phaseRecord.interactions?.submit) {
360
+ throw new Error(
361
+ `defineGame: phases.${phaseName}.interactions.submit conflicts with the reserved simultaneous submit interaction id.`,
362
+ );
363
+ }
364
+ validateInteractionInputsSchema(
365
+ phaseRecord.submit.inputs,
366
+ "defineInteraction",
367
+ );
368
+ validateManyCommitPolicy({
369
+ inputs: phaseRecord.submit.inputs,
370
+ commit: (phaseRecord.submit as { commit?: { mode: string } }).commit,
371
+ context: `defineGame: phases.${phaseName}.submit`,
372
+ });
373
+ }
374
+ }
375
+
376
+ export type ManifestIdSchemasOf<
377
+ Ids extends Record<string, SchemaLike<unknown>>,
378
+ > = {
379
+ readonly [Key in keyof Ids]: Ids[Key] extends SchemaLike<infer Output>
380
+ ? Ids[Key] & import("../model").ManifestIdSchema<Output>
381
+ : Ids[Key];
382
+ };
@@ -0,0 +1,68 @@
1
+ import type { z } from "zod";
2
+ import type {
3
+ ExactManifestContractOf,
4
+ SchemaLike,
5
+ ScopedPhaseState,
6
+ StageSpec,
7
+ StaticViewDefinition,
8
+ ViewDefinition,
9
+ } from "../model";
10
+ import type {
11
+ AnyReducerGameContract,
12
+ ContractManifest,
13
+ ContractState,
14
+ } from "./types";
15
+
16
+ export function defineView<Contract extends AnyReducerGameContract>() {
17
+ return <Projection>(
18
+ definition: ViewDefinition<
19
+ ContractState<Contract>,
20
+ ContractManifest<Contract>,
21
+ Projection
22
+ >,
23
+ ): ViewDefinition<
24
+ ContractState<Contract>,
25
+ ContractManifest<Contract>,
26
+ Projection
27
+ > => definition;
28
+ }
29
+
30
+ /**
31
+ * Factory for the session-scoped static view (see {@link StaticViewDefinition}).
32
+ * Kept separate from {@link defineView} because the argument shape is
33
+ * structurally different: it exposes only the manifest and generated static
34
+ * queries, with no `state`, `playerId`, `runtime`, `fx`, `ops`, or
35
+ * `accept/reject`. That shape is what prevents authors from accidentally
36
+ * projecting per-tick state into the once-per-session payload.
37
+ */
38
+ export function defineStaticView<Contract extends AnyReducerGameContract>() {
39
+ return <Projection>(
40
+ definition: StaticViewDefinition<
41
+ ExactManifestContractOf<Contract>,
42
+ Projection
43
+ >,
44
+ ): StaticViewDefinition<ExactManifestContractOf<Contract>, Projection> =>
45
+ definition;
46
+ }
47
+
48
+ export function defineStage<Contract extends AnyReducerGameContract>() {
49
+ return (
50
+ definition: StageSpec<ContractState<Contract>, ContractManifest<Contract>>,
51
+ ): StageSpec<ContractState<Contract>, ContractManifest<Contract>> =>
52
+ definition;
53
+ }
54
+
55
+ export function definePhaseStage<
56
+ Contract extends AnyReducerGameContract,
57
+ PhaseStateSchema extends SchemaLike<object>,
58
+ >() {
59
+ return (
60
+ definition: StageSpec<
61
+ ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>,
62
+ ContractManifest<Contract>
63
+ >,
64
+ ): StageSpec<
65
+ ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>,
66
+ ContractManifest<Contract>
67
+ > => definition;
68
+ }
@@ -0,0 +1,29 @@
1
+ export { defineGameContract } from "./authoring/contract";
2
+ export { defineEffect } from "./authoring/effect";
3
+ export { defineGame } from "./authoring/game";
4
+ export {
5
+ defineCardAction,
6
+ defineInteraction,
7
+ defineInteractionRule,
8
+ } from "./authoring/interaction";
9
+ export { definePhase, defineStepPhase } from "./authoring/phase";
10
+ export {
11
+ definePhaseStage,
12
+ defineStage,
13
+ defineStaticView,
14
+ defineView,
15
+ } from "./authoring/view-stage";
16
+
17
+ export type {
18
+ ReducerPhaseDefinition,
19
+ ReducerViewDefinition,
20
+ } from "./authoring/types";
21
+
22
+ export type {
23
+ GameStateOf,
24
+ InitialStateCallbacks,
25
+ ManifestOf,
26
+ PhaseMapOf,
27
+ ReducerGameContract,
28
+ ReducerGameDefinition,
29
+ } from "./model";