@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,409 @@
1
+ import type {
2
+ CSSProperties,
3
+ HTMLAttributes,
4
+ ReactNode,
5
+ SelectHTMLAttributes,
6
+ } from "react";
7
+ import {
8
+ Interaction,
9
+ Zone,
10
+ renderPrimitive,
11
+ useInteractionPrimitiveContext,
12
+ useZonePrimitiveContext,
13
+ type InteractionRootProps,
14
+ type PrimitiveCommonProps,
15
+ } from "../primitives/index.js";
16
+ import type {
17
+ InteractionDescriptor,
18
+ InteractionInputDescriptor,
19
+ } from "../types/plugin-state.js";
20
+ import type {
21
+ InteractionInputKey,
22
+ InteractionKey,
23
+ ZoneKey,
24
+ } from "../ui-contract.js";
25
+ import { useSeatInbox } from "../hooks/useSeatInbox.js";
26
+ import { isInteractionAvailable } from "../utils/interaction-status.js";
27
+
28
+ type LayoutPrimitiveProps = PrimitiveCommonProps & HTMLAttributes<HTMLElement>;
29
+
30
+ function layoutStyle(
31
+ base: CSSProperties,
32
+ style: CSSProperties | undefined,
33
+ ): CSSProperties {
34
+ return style ? { ...base, ...style } : base;
35
+ }
36
+
37
+ export function GameLayoutRoot({
38
+ children,
39
+ style,
40
+ ...props
41
+ }: LayoutPrimitiveProps) {
42
+ return renderPrimitive("div", {
43
+ ...props,
44
+ "data-dreamboard-game-layout": "",
45
+ style: layoutStyle(
46
+ {
47
+ display: "grid",
48
+ gridTemplateColumns: "minmax(0, 1fr) minmax(18rem, 24rem)",
49
+ gridTemplateRows: "auto minmax(0, 1fr) auto",
50
+ gridTemplateAreas: `"header header" "board sidebar" "bottom sidebar"`,
51
+ minHeight: "100%",
52
+ gap: "1rem",
53
+ },
54
+ style,
55
+ ),
56
+ children,
57
+ });
58
+ }
59
+
60
+ export function GameLayoutHeader({
61
+ children,
62
+ style,
63
+ ...props
64
+ }: LayoutPrimitiveProps) {
65
+ return renderPrimitive("header", {
66
+ ...props,
67
+ "data-dreamboard-game-layout-header": "",
68
+ style: layoutStyle({ gridArea: "header" }, style),
69
+ children,
70
+ });
71
+ }
72
+
73
+ export function GameLayoutBoard({
74
+ children,
75
+ style,
76
+ ...props
77
+ }: LayoutPrimitiveProps) {
78
+ return renderPrimitive("section", {
79
+ ...props,
80
+ "data-dreamboard-game-layout-board": "",
81
+ style: layoutStyle({ gridArea: "board", minWidth: 0 }, style),
82
+ children,
83
+ });
84
+ }
85
+
86
+ export function GameLayoutSidebar({
87
+ children,
88
+ style,
89
+ ...props
90
+ }: LayoutPrimitiveProps) {
91
+ return renderPrimitive("aside", {
92
+ ...props,
93
+ "data-dreamboard-game-layout-sidebar": "",
94
+ style: layoutStyle(
95
+ {
96
+ gridArea: "sidebar",
97
+ minWidth: 0,
98
+ display: "flex",
99
+ flexDirection: "column",
100
+ gap: "0.75rem",
101
+ },
102
+ style,
103
+ ),
104
+ children,
105
+ });
106
+ }
107
+
108
+ export function GameLayoutBottom({
109
+ children,
110
+ style,
111
+ ...props
112
+ }: LayoutPrimitiveProps) {
113
+ return renderPrimitive("section", {
114
+ ...props,
115
+ "data-dreamboard-game-layout-bottom": "",
116
+ style: layoutStyle({ gridArea: "bottom", minWidth: 0 }, style),
117
+ children,
118
+ });
119
+ }
120
+
121
+ export const GameLayout = {
122
+ Root: GameLayoutRoot,
123
+ Header: GameLayoutHeader,
124
+ Board: GameLayoutBoard,
125
+ Sidebar: GameLayoutSidebar,
126
+ Bottom: GameLayoutBottom,
127
+ };
128
+
129
+ export interface DefaultInteractionListProps extends PrimitiveCommonProps {
130
+ empty?: ReactNode;
131
+ includeUnavailable?: boolean;
132
+ renderInteraction?: (interaction: InteractionDescriptor) => ReactNode;
133
+ }
134
+
135
+ export function DefaultInteractionList({
136
+ empty = null,
137
+ includeUnavailable = false,
138
+ renderInteraction,
139
+ ...props
140
+ }: DefaultInteractionListProps) {
141
+ const inbox = useSeatInbox();
142
+ const interactions = (inbox.bySurface.panel ?? []).filter(
143
+ (descriptor) => includeUnavailable || isInteractionAvailable(descriptor),
144
+ );
145
+ if (interactions.length === 0) return <>{empty}</>;
146
+
147
+ return renderPrimitive("section", {
148
+ ...props,
149
+ "data-dreamboard-default-interaction-list": "",
150
+ children: interactions.map((descriptor) =>
151
+ renderInteraction ? (
152
+ renderInteraction(descriptor)
153
+ ) : (
154
+ <DefaultInteractionItem
155
+ key={descriptor.interactionKey}
156
+ interaction={descriptor.interactionKey}
157
+ />
158
+ ),
159
+ ),
160
+ });
161
+ }
162
+
163
+ export type DefaultInteractionItemProps<
164
+ InteractionKeyValue extends string = InteractionKey,
165
+ > = Omit<InteractionRootProps<InteractionKeyValue>, "children"> &
166
+ PrimitiveCommonProps;
167
+
168
+ export function DefaultInteractionItem<
169
+ InteractionKeyValue extends string = InteractionKey,
170
+ >({
171
+ interaction,
172
+ unavailable,
173
+ ...props
174
+ }: DefaultInteractionItemProps<InteractionKeyValue>) {
175
+ return (
176
+ <Interaction.Root interaction={interaction} unavailable={unavailable}>
177
+ {renderPrimitive("article", {
178
+ ...props,
179
+ "data-dreamboard-default-interaction-item": "",
180
+ children: (
181
+ <>
182
+ <Interaction.Label />
183
+ <Interaction.UnavailableMessage />
184
+ <DefaultInteractionForm />
185
+ </>
186
+ ),
187
+ })}
188
+ </Interaction.Root>
189
+ );
190
+ }
191
+
192
+ export interface DefaultInteractionFormProps extends PrimitiveCommonProps {
193
+ submitLabel?: ReactNode;
194
+ renderField?: (input: InteractionInputDescriptor) => ReactNode;
195
+ }
196
+
197
+ export function DefaultInteractionForm({
198
+ submitLabel = "Submit",
199
+ renderField,
200
+ ...props
201
+ }: DefaultInteractionFormProps) {
202
+ const { descriptor } = useInteractionPrimitiveContext();
203
+ const fields = descriptor?.inputs ?? [];
204
+ return renderPrimitive("div", {
205
+ ...props,
206
+ "data-dreamboard-default-interaction-form": "",
207
+ children: (
208
+ <>
209
+ {fields.map((input) =>
210
+ renderField ? (
211
+ renderField(input)
212
+ ) : (
213
+ <DefaultInteractionField key={input.key} input={input} />
214
+ ),
215
+ )}
216
+ <Interaction.ValidationMessage />
217
+ <Interaction.Submit>{submitLabel}</Interaction.Submit>
218
+ </>
219
+ ),
220
+ });
221
+ }
222
+
223
+ function DefaultInteractionField({
224
+ input,
225
+ }: {
226
+ input: InteractionInputDescriptor;
227
+ }) {
228
+ if (input.domain.type === "choice") {
229
+ return <DefaultChoiceField input={input} />;
230
+ }
231
+ if (input.domain.type === "boundedNumber") {
232
+ return (
233
+ <label data-dreamboard-default-interaction-field="">
234
+ {input.key}
235
+ <Interaction.Input
236
+ name={input.key}
237
+ type="number"
238
+ min={input.domain.min}
239
+ max={input.domain.max}
240
+ step={input.domain.step}
241
+ parse={(value) => Number(value)}
242
+ />
243
+ </label>
244
+ );
245
+ }
246
+ return (
247
+ <label data-dreamboard-default-interaction-field="">
248
+ {input.key}
249
+ <Interaction.Input name={input.key} />
250
+ </label>
251
+ );
252
+ }
253
+
254
+ function DefaultChoiceField({ input }: { input: InteractionInputDescriptor }) {
255
+ const { handle } = useInteractionPrimitiveContext();
256
+ const value = handle?.draft[input.key] ?? handle?.values[input.key];
257
+ const encodeValue = (candidate: unknown) =>
258
+ candidate === null ? "__dreamboard_null_choice__" : String(candidate);
259
+ return (
260
+ <label data-dreamboard-default-interaction-field="">
261
+ {input.key}
262
+ <select
263
+ name={input.key}
264
+ value={value === undefined ? "" : encodeValue(value)}
265
+ data-dreamboard-default-choice-input=""
266
+ disabled={!handle?.available}
267
+ onChange={(event) =>
268
+ handle?.setInput(
269
+ input.key,
270
+ event.currentTarget.value === "__dreamboard_null_choice__"
271
+ ? null
272
+ : event.currentTarget.value,
273
+ )
274
+ }
275
+ >
276
+ <option value="" />
277
+ {(input.domain.type === "choice"
278
+ ? (input.domain.choices ?? [])
279
+ : []
280
+ ).map((choice) => (
281
+ <option
282
+ key={encodeValue(choice.value)}
283
+ value={encodeValue(choice.value)}
284
+ disabled={choice.disabled}
285
+ >
286
+ {choice.label}
287
+ </option>
288
+ ))}
289
+ </select>
290
+ </label>
291
+ );
292
+ }
293
+
294
+ export interface DefaultZoneProps<
295
+ ZoneValue extends string = ZoneKey,
296
+ > extends PrimitiveCommonProps {
297
+ zone: ZoneValue;
298
+ empty?: ReactNode;
299
+ layout?: "row" | "column" | "grid" | "fan";
300
+ interaction?: InteractionKey;
301
+ input?: InteractionInputKey;
302
+ renderCard?: (card: DefaultZoneCard) => ReactNode;
303
+ }
304
+
305
+ export interface DefaultZoneCard {
306
+ id: string;
307
+ serialized: string;
308
+ data: unknown;
309
+ }
310
+
311
+ export function DefaultZone<ZoneValue extends string = ZoneKey>({
312
+ zone,
313
+ empty = null,
314
+ layout = "row",
315
+ interaction,
316
+ input,
317
+ renderCard,
318
+ ...props
319
+ }: DefaultZoneProps<ZoneValue>) {
320
+ const content = (
321
+ <Zone.Root zone={zone}>
322
+ <DefaultZoneList
323
+ empty={empty}
324
+ input={input}
325
+ layout={layout}
326
+ renderCard={renderCard}
327
+ {...props}
328
+ />
329
+ </Zone.Root>
330
+ );
331
+
332
+ return interaction ? (
333
+ <Interaction.Root interaction={interaction}>{content}</Interaction.Root>
334
+ ) : (
335
+ content
336
+ );
337
+ }
338
+
339
+ function DefaultZoneList({
340
+ empty,
341
+ input,
342
+ layout = "row",
343
+ renderCard,
344
+ style,
345
+ ...props
346
+ }: Omit<DefaultZoneProps<string>, "zone" | "interaction">) {
347
+ const { snapshot } = useZonePrimitiveContext();
348
+ const cardIds = snapshot?.cardIds ?? [];
349
+ if (cardIds.length === 0) return <>{empty}</>;
350
+
351
+ return (
352
+ <Zone.List
353
+ {...props}
354
+ data-dreamboard-default-zone=""
355
+ data-layout={layout}
356
+ style={layoutStyle(defaultZoneLayoutStyle(layout), style)}
357
+ >
358
+ {cardIds.map((cardId) => {
359
+ const serialized = snapshot?.cardViewsById[cardId] ?? "";
360
+ const card: DefaultZoneCard = {
361
+ id: cardId,
362
+ serialized,
363
+ data: parseCardData(serialized),
364
+ };
365
+ const body = renderCard ? renderCard(card) : card.id;
366
+ return (
367
+ <Zone.Item key={cardId} card={cardId}>
368
+ {input ? (
369
+ <Interaction.CardInput input={input}>
370
+ {body}
371
+ </Interaction.CardInput>
372
+ ) : (
373
+ body
374
+ )}
375
+ </Zone.Item>
376
+ );
377
+ })}
378
+ </Zone.List>
379
+ );
380
+ }
381
+
382
+ function defaultZoneLayoutStyle(
383
+ layout: NonNullable<DefaultZoneProps["layout"]>,
384
+ ): CSSProperties {
385
+ if (layout === "grid") {
386
+ return {
387
+ display: "grid",
388
+ gridTemplateColumns: "repeat(auto-fit, minmax(5rem, 1fr))",
389
+ gap: "0.5rem",
390
+ };
391
+ }
392
+ return {
393
+ display: "flex",
394
+ flexDirection: layout === "column" ? "column" : "row",
395
+ flexWrap: layout === "fan" ? "nowrap" : "wrap",
396
+ gap: "0.5rem",
397
+ };
398
+ }
399
+
400
+ function parseCardData(serialized: string): unknown {
401
+ if (!serialized) return null;
402
+ try {
403
+ return JSON.parse(serialized);
404
+ } catch {
405
+ return serialized;
406
+ }
407
+ }
408
+
409
+ export type DefaultChoiceInputProps = SelectHTMLAttributes<HTMLSelectElement>;
@@ -0,0 +1,11 @@
1
+ export {
2
+ GameLayout,
3
+ GameLayoutBoard,
4
+ GameLayoutBottom,
5
+ GameLayoutHeader,
6
+ GameLayoutRoot,
7
+ GameLayoutSidebar,
8
+ DefaultZone,
9
+ type DefaultZoneCard,
10
+ type DefaultZoneProps,
11
+ } from "./components.js";
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Error thrown when action validation fails.
3
+ * Contains the error code and optional message from the validation result.
4
+ */
5
+ export class ValidationError extends Error {
6
+ constructor(
7
+ public readonly errorCode?: string,
8
+ message?: string,
9
+ ) {
10
+ super(message || errorCode || "Validation failed");
11
+ this.name = "ValidationError";
12
+ }
13
+ }
14
+
15
+ export function validationErrorFromUnknown(
16
+ error: unknown,
17
+ fallbackMessage = "Interaction submission failed",
18
+ ): ValidationError {
19
+ if (error instanceof ValidationError) return error;
20
+ const errorCode =
21
+ typeof error === "object" &&
22
+ error !== null &&
23
+ "errorCode" in error &&
24
+ typeof error.errorCode === "string"
25
+ ? error.errorCode
26
+ : undefined;
27
+ const message = error instanceof Error ? error.message : fallbackMessage;
28
+ return new ValidationError(errorCode, message);
29
+ }
@@ -0,0 +1,33 @@
1
+ import type { PlayerId } from "@dreamboard/manifest-contract";
2
+ import { usePluginState } from "../context/PluginStateContext.js";
3
+
4
+ /**
5
+ * Returns the list of players the engine currently considers active, as
6
+ * reported by the most recent gameplay snapshot.
7
+ *
8
+ * - For single-active-player phases, this has one entry.
9
+ * - For multi-active-player phases (e.g. "all players discard at once"), it
10
+ * includes every seat that is expected to act.
11
+ * - Returns an empty array before the first gameplay snapshot arrives.
12
+ *
13
+ * Prefer this hook over re-projecting `currentPlayerId` / `turnOrder` into
14
+ * the view: flow state belongs to the engine, and `useActivePlayers()` is
15
+ * always in lock-step with server-authoritative state.
16
+ */
17
+ export function useActivePlayers(): readonly PlayerId[] {
18
+ return usePluginState((state) => {
19
+ // During a `simultaneousPlayer` phase the engine reports
20
+ // `flow.activePlayers` as `[]` (there is no single turn) and tracks
21
+ // per-seat progress in `simultaneousPhase` instead. Surface the seats that
22
+ // still owe an action so this hook keeps its documented "every seat
23
+ // expected to act" contract — otherwise `canAct`, `useIsMyTurn`, and roster
24
+ // `isActive` would be false for everyone mid-simultaneous-phase. Both
25
+ // branches return references owned by the snapshot, so the selector stays
26
+ // referentially stable for `useSyncExternalStore`.
27
+ const simultaneous = state.gameplay.simultaneousPhase;
28
+ if (simultaneous && simultaneous.pendingPlayerIds.length > 0) {
29
+ return simultaneous.pendingPlayerIds;
30
+ }
31
+ return state.gameplay.activePlayers;
32
+ });
33
+ }