@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,448 @@
1
+ /**
2
+ * SVG-based area control visualization for territory games (Risk, Small World, Diplomacy).
3
+ */
4
+
5
+ import { useMemo, type ReactNode } from "react";
6
+ import { clsx } from "clsx";
7
+ import { usePanZoom } from "../../hooks/usePanZoom.js";
8
+ import { handleKeyboardActivation } from "./interaction-accessibility.js";
9
+
10
+ export interface ZoneShape {
11
+ type: "polygon" | "path" | "circle";
12
+ points?: Array<{ x: number; y: number }>;
13
+ /** SVG path data */
14
+ path?: string;
15
+ center?: { x: number; y: number };
16
+ radius?: number;
17
+ }
18
+
19
+ export interface ZoneDefinition {
20
+ id: string;
21
+ name: string;
22
+ adjacentTo: string[];
23
+ shape?: ZoneShape;
24
+ value?: number;
25
+ type?: string;
26
+ data?: Record<string, unknown>;
27
+ }
28
+
29
+ export interface ZonePiece {
30
+ id: string;
31
+ zoneId: string;
32
+ type: string;
33
+ owner?: string;
34
+ /** Count for stackable pieces (armies) */
35
+ count?: number;
36
+ data?: Record<string, unknown>;
37
+ }
38
+
39
+ export interface ZoneMapProps {
40
+ zones: ZoneDefinition[];
41
+ pieces: ZonePiece[];
42
+ renderZone: (zone: ZoneDefinition, pieces: ZonePiece[]) => ReactNode;
43
+ backgroundImage?: string;
44
+ width?: number | string;
45
+ height?: number | string;
46
+ enablePanZoom?: boolean;
47
+ initialZoom?: number;
48
+ minZoom?: number;
49
+ maxZoom?: number;
50
+ className?: string;
51
+ }
52
+
53
+ // ============================================================================
54
+ // Helper Components
55
+ // ============================================================================
56
+
57
+ export type ZoneHighlightType =
58
+ | "valid"
59
+ | "selected"
60
+ | "attack"
61
+ | "defend"
62
+ | "neutral";
63
+
64
+ // Highlight colors by type
65
+ const HIGHLIGHT_COLORS: Record<ZoneHighlightType, string> = {
66
+ valid: "rgba(34, 197, 94, 0.4)", // Green
67
+ selected: "rgba(59, 130, 246, 0.4)", // Blue
68
+ attack: "rgba(239, 68, 68, 0.4)", // Red
69
+ defend: "rgba(234, 179, 8, 0.4)", // Yellow
70
+ neutral: "rgba(148, 163, 184, 0.4)", // Slate
71
+ };
72
+
73
+ const HIGHLIGHT_STROKES: Record<ZoneHighlightType, string> = {
74
+ valid: "#22c55e",
75
+ selected: "#3b82f6",
76
+ attack: "#ef4444",
77
+ defend: "#eab308",
78
+ neutral: "#94a3b8",
79
+ };
80
+
81
+ const EMPTY_PLAYER_COLORS: Record<string, string> = {};
82
+
83
+ export interface DefaultZoneProps {
84
+ zone: ZoneDefinition;
85
+ fill?: string;
86
+ stroke?: string;
87
+ strokeWidth?: number;
88
+ isHighlighted?: boolean;
89
+ highlightType?: ZoneHighlightType;
90
+ isSelected?: boolean;
91
+ showLabel?: boolean;
92
+ showValue?: boolean;
93
+ onClick?: () => void;
94
+ onHover?: (hovering: boolean) => void;
95
+ className?: string;
96
+ children?: ReactNode;
97
+ }
98
+ export function DefaultZone({
99
+ zone,
100
+ fill = "rgba(100, 116, 139, 0.2)",
101
+ stroke = "#475569",
102
+ strokeWidth = 1,
103
+ isHighlighted = false,
104
+ highlightType,
105
+ isSelected = false,
106
+ showLabel = true,
107
+ showValue = false,
108
+ onClick,
109
+ onHover,
110
+ className,
111
+ children,
112
+ }: DefaultZoneProps) {
113
+ // Calculate colors based on state
114
+ let computedFill = fill;
115
+ let computedStroke = stroke;
116
+ let computedStrokeWidth = strokeWidth;
117
+
118
+ if (isHighlighted && highlightType && HIGHLIGHT_COLORS[highlightType]) {
119
+ computedFill = HIGHLIGHT_COLORS[highlightType];
120
+ computedStroke = HIGHLIGHT_STROKES[highlightType];
121
+ computedStrokeWidth = 3;
122
+ } else if (isSelected) {
123
+ computedFill = HIGHLIGHT_COLORS.selected;
124
+ computedStroke = HIGHLIGHT_STROKES.selected;
125
+ computedStrokeWidth = 3;
126
+ }
127
+
128
+ // Render zone shape
129
+ const renderShape = () => {
130
+ if (!zone.shape) return null;
131
+
132
+ switch (zone.shape.type) {
133
+ case "polygon":
134
+ if (!zone.shape.points) return null;
135
+ return (
136
+ <polygon
137
+ points={zone.shape.points.map((p) => `${p.x},${p.y}`).join(" ")}
138
+ fill={computedFill}
139
+ stroke={computedStroke}
140
+ strokeWidth={computedStrokeWidth}
141
+ />
142
+ );
143
+
144
+ case "path":
145
+ if (!zone.shape.path) return null;
146
+ return (
147
+ <path
148
+ d={zone.shape.path}
149
+ fill={computedFill}
150
+ stroke={computedStroke}
151
+ strokeWidth={computedStrokeWidth}
152
+ />
153
+ );
154
+
155
+ case "circle":
156
+ if (!zone.shape.center) return null;
157
+ return (
158
+ <circle
159
+ cx={zone.shape.center.x}
160
+ cy={zone.shape.center.y}
161
+ r={zone.shape.radius || 30}
162
+ fill={computedFill}
163
+ stroke={computedStroke}
164
+ strokeWidth={computedStrokeWidth}
165
+ />
166
+ );
167
+
168
+ default:
169
+ return null;
170
+ }
171
+ };
172
+
173
+ return (
174
+ <g
175
+ onClick={onClick}
176
+ onMouseEnter={() => onHover?.(true)}
177
+ onMouseLeave={() => onHover?.(false)}
178
+ onKeyDown={(event) => handleKeyboardActivation(event, onClick)}
179
+ className={clsx(onClick && "cursor-pointer", className)}
180
+ role={onClick ? "button" : "listitem"}
181
+ aria-label={zone.name}
182
+ tabIndex={onClick ? 0 : undefined}
183
+ >
184
+ {/* Zone shape */}
185
+ {renderShape()}
186
+
187
+ {/* Zone label */}
188
+ {showLabel && zone.shape?.center && (
189
+ <text
190
+ x={zone.shape.center.x}
191
+ y={zone.shape.center.y - (showValue ? 8 : 0)}
192
+ textAnchor="middle"
193
+ dominantBaseline="middle"
194
+ fill="white"
195
+ fontSize={12}
196
+ fontWeight="bold"
197
+ style={{ textShadow: "1px 1px 2px rgba(0,0,0,0.8)" }}
198
+ >
199
+ {zone.name}
200
+ </text>
201
+ )}
202
+
203
+ {/* Zone value */}
204
+ {showValue && zone.value !== undefined && zone.shape?.center && (
205
+ <text
206
+ x={zone.shape.center.x}
207
+ y={zone.shape.center.y + 8}
208
+ textAnchor="middle"
209
+ dominantBaseline="middle"
210
+ fill="#fbbf24"
211
+ fontSize={10}
212
+ fontWeight="bold"
213
+ style={{ textShadow: "1px 1px 2px rgba(0,0,0,0.8)" }}
214
+ >
215
+ +{zone.value}
216
+ </text>
217
+ )}
218
+
219
+ {/* Children (pieces) */}
220
+ {children}
221
+ </g>
222
+ );
223
+ }
224
+
225
+ export interface DefaultZonePiecesProps {
226
+ pieces: ZonePiece[];
227
+ zone: ZoneDefinition;
228
+ playerColors?: Record<string, string>;
229
+ radius?: number;
230
+ spacing?: number;
231
+ yOffset?: number;
232
+ className?: string;
233
+ }
234
+ export function DefaultZonePieces({
235
+ pieces,
236
+ zone,
237
+ playerColors = EMPTY_PLAYER_COLORS,
238
+ radius = 14,
239
+ spacing = 25,
240
+ yOffset = 20,
241
+ className,
242
+ }: DefaultZonePiecesProps) {
243
+ if (pieces.length === 0 || !zone.shape?.center) return null;
244
+
245
+ const centerX = zone.shape.center.x;
246
+ const centerY = zone.shape.center.y;
247
+
248
+ // Group pieces by owner
249
+ const piecesByOwner: Record<string, ZonePiece[]> = {};
250
+ pieces.forEach((p) => {
251
+ const owner = p.owner || "neutral";
252
+ const existing = piecesByOwner[owner];
253
+ if (existing) {
254
+ existing.push(p);
255
+ } else {
256
+ piecesByOwner[owner] = [p];
257
+ }
258
+ });
259
+
260
+ const owners = Object.keys(piecesByOwner);
261
+ const startOffset = -((owners.length - 1) * spacing) / 2;
262
+
263
+ return (
264
+ <g className={clsx("zone-pieces", className)}>
265
+ {owners.map((owner, i) => {
266
+ const ownerPieces = piecesByOwner[owner] || [];
267
+ const totalCount = ownerPieces.reduce(
268
+ (sum, p) => sum + (p.count || 1),
269
+ 0,
270
+ );
271
+ const offsetX = startOffset + i * spacing;
272
+
273
+ return (
274
+ <g
275
+ key={owner}
276
+ transform={`translate(${centerX + offsetX}, ${centerY + yOffset})`}
277
+ >
278
+ {/* Piece circle */}
279
+ <circle
280
+ r={radius}
281
+ fill={playerColors[owner] || "#64748b"}
282
+ stroke="white"
283
+ strokeWidth={2}
284
+ />
285
+ {/* Count */}
286
+ <text
287
+ textAnchor="middle"
288
+ dominantBaseline="central"
289
+ fill="white"
290
+ fontSize={10}
291
+ fontWeight="bold"
292
+ >
293
+ {totalCount}
294
+ </text>
295
+ </g>
296
+ );
297
+ })}
298
+ </g>
299
+ );
300
+ }
301
+
302
+ export interface DefaultZonePieceProps {
303
+ piece: ZonePiece;
304
+ x?: number;
305
+ y?: number;
306
+ radius?: number;
307
+ color?: string;
308
+ onClick?: () => void;
309
+ className?: string;
310
+ }
311
+ export function DefaultZonePiece({
312
+ piece,
313
+ x = 0,
314
+ y = 0,
315
+ radius = 14,
316
+ color = "#64748b",
317
+ onClick,
318
+ className,
319
+ }: DefaultZonePieceProps) {
320
+ const count = piece.count || 1;
321
+
322
+ return (
323
+ <g
324
+ transform={`translate(${x}, ${y})`}
325
+ onClick={(e) => {
326
+ e.stopPropagation();
327
+ onClick?.();
328
+ }}
329
+ onKeyDown={(event) =>
330
+ handleKeyboardActivation(event, onClick, { stopPropagation: true })
331
+ }
332
+ className={clsx(onClick && "cursor-pointer", className)}
333
+ role={onClick ? "button" : undefined}
334
+ tabIndex={onClick ? 0 : undefined}
335
+ aria-label={`Piece ${piece.id}`}
336
+ >
337
+ <circle r={radius} fill={color} stroke="white" strokeWidth={2} />
338
+ <text
339
+ textAnchor="middle"
340
+ dominantBaseline="central"
341
+ fill="white"
342
+ fontSize={10}
343
+ fontWeight="bold"
344
+ >
345
+ {count}
346
+ </text>
347
+ </g>
348
+ );
349
+ }
350
+
351
+ // ============================================================================
352
+ // Main Component
353
+ // ============================================================================
354
+
355
+ export function ZoneMap({
356
+ zones,
357
+ pieces,
358
+ renderZone,
359
+ backgroundImage,
360
+ width = 800,
361
+ height = 600,
362
+ enablePanZoom = false,
363
+ initialZoom = 1,
364
+ minZoom = 0.5,
365
+ maxZoom = 3,
366
+ className,
367
+ }: ZoneMapProps) {
368
+ // Use the unified pan/zoom hook
369
+ const { transform, bind, isDragging } = usePanZoom({
370
+ enabled: enablePanZoom,
371
+ initialZoom,
372
+ minZoom,
373
+ maxZoom,
374
+ mode: "viewbox",
375
+ });
376
+
377
+ // Group pieces by zone
378
+ const piecesByZone = useMemo(() => {
379
+ const map: Record<string, ZonePiece[]> = {};
380
+ pieces.forEach((p) => {
381
+ const existing = map[p.zoneId];
382
+ if (existing) {
383
+ existing.push(p);
384
+ } else {
385
+ map[p.zoneId] = [p];
386
+ }
387
+ });
388
+ return map;
389
+ }, [pieces]);
390
+
391
+ // Calculate viewBox dimensions
392
+ const baseWidth = typeof width === "number" ? width : 800;
393
+ const baseHeight = typeof height === "number" ? height : 600;
394
+ const viewBoxWidth = baseWidth / transform.zoom;
395
+ const viewBoxHeight = baseHeight / transform.zoom;
396
+ const viewBoxX = (baseWidth - viewBoxWidth) / 2 - transform.pan.x;
397
+ const viewBoxY = (baseHeight - viewBoxHeight) / 2 - transform.pan.y;
398
+
399
+ return (
400
+ <svg
401
+ width={width}
402
+ height={height}
403
+ viewBox={`${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}`}
404
+ className={clsx(
405
+ "overflow-visible",
406
+ enablePanZoom && "touch-none",
407
+ isDragging && "cursor-grabbing",
408
+ enablePanZoom && !isDragging && "cursor-grab",
409
+ className,
410
+ )}
411
+ {...bind()}
412
+ role="img"
413
+ aria-label="Zone map"
414
+ >
415
+ {/* Background image */}
416
+ {backgroundImage && (
417
+ <image href={backgroundImage} width={width} height={height} />
418
+ )}
419
+
420
+ {/* Zones */}
421
+ <g className="zones" role="list" aria-label="Map zones">
422
+ {zones.map((zone) => {
423
+ const zonePieces = piecesByZone[zone.id] || [];
424
+ return <g key={zone.id}>{renderZone(zone, zonePieces)}</g>;
425
+ })}
426
+ </g>
427
+
428
+ {/* Zoom indicator */}
429
+ {enablePanZoom && transform.zoom !== 1 && (
430
+ <g
431
+ transform={`translate(${viewBoxX + 10}, ${viewBoxY + viewBoxHeight - 30})`}
432
+ >
433
+ <rect
434
+ x={0}
435
+ y={0}
436
+ width={60}
437
+ height={20}
438
+ rx={4}
439
+ fill="rgba(0,0,0,0.6)"
440
+ />
441
+ <text x={30} y={14} textAnchor="middle" fill="white" fontSize={12}>
442
+ {Math.round(transform.zoom * 100)}%
443
+ </text>
444
+ </g>
445
+ )}
446
+ </svg>
447
+ );
448
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Typed adapter for joining static hex-board topology with a dynamic
3
+ * per-space view overlay. Use this to feed `HexGrid` a single board
4
+ * value whose tiles carry both static geometry (`q`, `r`, `id`) and
5
+ * the projected view fields the UI cares about (e.g. `terrain`,
6
+ * `numberToken`).
7
+ *
8
+ * The runtime is intentionally strict: every static space must have
9
+ * exactly one overlay, duplicates throw, and overlays for ids that
10
+ * are not on the board throw. There is no relaxed fallback in v1 —
11
+ * silent merge bugs are far more expensive than a loud throw at
12
+ * dev/CI time.
13
+ */
14
+
15
+ import type {
16
+ AnyHexBoardInput,
17
+ BoardIdOf,
18
+ BoardSpaceIdOf,
19
+ NormalizedHexTileOf,
20
+ } from "../../types/tiled-board.js";
21
+ import { normalizeHexBoardInput } from "../../types/tiled-board.js";
22
+
23
+ /**
24
+ * Per-tile result produced by {@link createHexBoardView}. Each tile
25
+ * carries the static topology (`id`, `q`, `r`) plus the matched
26
+ * overlay row in `view`.
27
+ *
28
+ * Static board fields/properties are preserved from `TBoard`.
29
+ * Consumers should use `tile.properties` for authored static space
30
+ * fields and `tile.view` for dynamic per-space projection data.
31
+ */
32
+ export type HexBoardViewTile<
33
+ TBoard extends AnyHexBoardInput,
34
+ TSpaceView extends { id: BoardSpaceIdOf<TBoard> },
35
+ > = Omit<NormalizedHexTileOf<TBoard>, "view"> & { view: TSpaceView };
36
+
37
+ /**
38
+ * Result of {@link createHexBoardView}. Shaped like an authored hex
39
+ * board so it can be passed straight to `<HexGrid board={...} />`
40
+ * without any further adapter work.
41
+ *
42
+ * The type-level board id and space id are preserved from `TBoard`,
43
+ * so `tile.id` stays narrow inside `renderTile`. `tile.view` is the
44
+ * authored overlay row, fully typed.
45
+ */
46
+ export interface HexBoardView<
47
+ TBoard extends AnyHexBoardInput,
48
+ TSpaceView extends { id: BoardSpaceIdOf<TBoard> },
49
+ > {
50
+ id: BoardIdOf<TBoard>;
51
+ layout?: "hex";
52
+ orientation?: "pointy-top" | "flat-top";
53
+ tiles: ReadonlyArray<HexBoardViewTile<TBoard, TSpaceView>>;
54
+ edges: TBoard["edges"];
55
+ vertices: TBoard["vertices"];
56
+ }
57
+
58
+ interface CreateHexBoardViewOptions<TSpaceView> {
59
+ spaces: readonly TSpaceView[];
60
+ }
61
+
62
+ /**
63
+ * Join a static hex board topology with a dynamic per-space overlay.
64
+ *
65
+ * The result is suitable for direct use as the `board` prop on
66
+ * `<HexGrid>`. Every overlay is enforced 1-to-1 against the board's
67
+ * spaces:
68
+ *
69
+ * - missing overlay for a board space → throws
70
+ * - duplicate overlay (same `id` twice) → throws
71
+ * - overlay `id` not present on the board → throws
72
+ *
73
+ * Each tile in the result carries a `view` field with the matched
74
+ * overlay row.
75
+ */
76
+ export function createHexBoardView<
77
+ const TBoard extends AnyHexBoardInput,
78
+ const TSpaceView extends { id: BoardSpaceIdOf<TBoard> },
79
+ >(
80
+ board: TBoard,
81
+ options: CreateHexBoardViewOptions<TSpaceView>,
82
+ ): HexBoardView<TBoard, TSpaceView> {
83
+ const overlayById = new Map<string, TSpaceView>();
84
+ for (const overlay of options.spaces) {
85
+ if (overlayById.has(overlay.id)) {
86
+ throw new Error(
87
+ `createHexBoardView: duplicate overlay for space '${overlay.id}'.`,
88
+ );
89
+ }
90
+ overlayById.set(overlay.id, overlay);
91
+ }
92
+
93
+ const consumed = new Set<string>();
94
+ const normalizedBoard = normalizeHexBoardInput(board);
95
+ const tiles: Array<HexBoardViewTile<TBoard, TSpaceView>> =
96
+ normalizedBoard.tiles.map((tile) => {
97
+ const overlay = overlayById.get(tile.id);
98
+ if (!overlay) {
99
+ throw new Error(
100
+ `createHexBoardView: missing overlay for space '${tile.id}'.`,
101
+ );
102
+ }
103
+ consumed.add(tile.id);
104
+ return { ...tile, view: overlay };
105
+ });
106
+
107
+ for (const id of overlayById.keys()) {
108
+ if (!consumed.has(id)) {
109
+ throw new Error(
110
+ `createHexBoardView: overlay '${id}' is not on the board.`,
111
+ );
112
+ }
113
+ }
114
+
115
+ return {
116
+ id: normalizedBoard.id,
117
+ layout: "hex",
118
+ orientation: board.orientation,
119
+ tiles,
120
+ edges: board.edges,
121
+ vertices: board.vertices,
122
+ };
123
+ }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Board Primitives
3
+ *
4
+ * Reusable board visualization components for different game types.
5
+ *
6
+ * Components:
7
+ * - NetworkGraph: For route-building games (Ticket to Ride, Pandemic)
8
+ * - HexGrid: For hex-based games (Catan, wargames)
9
+ * - SquareGrid: For grid-based games (Chess, Go, Checkers)
10
+ * - ZoneMap: For area control games (Risk, Small World)
11
+ * - TrackBoard: For track/racing games (Monopoly, Game of Life)
12
+ * - SlotSystem: For worker placement games (Agricola, Viticulture)
13
+ */
14
+
15
+ // NetworkGraph - Route building games
16
+ export {
17
+ NetworkGraph,
18
+ // Pre-built helper components for easy customization
19
+ DefaultNetworkNode,
20
+ DefaultNetworkEdge,
21
+ DefaultNetworkPiece,
22
+ type NetworkGraphProps,
23
+ type NetworkNode,
24
+ type NetworkEdge,
25
+ type NetworkPiece,
26
+ type DefaultNetworkNodeProps,
27
+ type DefaultNetworkEdgeProps,
28
+ type DefaultNetworkPieceProps,
29
+ } from "./NetworkGraph.js";
30
+
31
+ // HexGrid - Hex-based games (Catan, wargames)
32
+ export {
33
+ HexGrid,
34
+ hexUtils,
35
+ // Pre-built helper components for easy customization
36
+ DefaultHexTile,
37
+ DefaultHexEdge,
38
+ DefaultHexVertex,
39
+ type HexGridBoardProps,
40
+ type HexGridProps,
41
+ type HexOrientation,
42
+ type HexTileGeometry,
43
+ type InteractiveHexEdge,
44
+ type InteractiveHexSpace,
45
+ type InteractiveHexVertex,
46
+ type EdgePosition,
47
+ type DefaultHexTileProps,
48
+ type DefaultHexEdgeProps,
49
+ type DefaultHexVertexProps,
50
+ } from "./HexGrid.js";
51
+
52
+ export type {
53
+ InteractiveTargetLayer,
54
+ InteractiveTargetRenderState,
55
+ } from "./target-layer.js";
56
+
57
+ export {
58
+ createHexBoardView,
59
+ type HexBoardView,
60
+ type HexBoardViewTile,
61
+ } from "./hex-board-view.js";
62
+
63
+ // SquareGrid - Grid-based games (Chess, Go, Checkers)
64
+ export {
65
+ SquareGrid,
66
+ // Pre-built helper components for easy customization
67
+ DefaultGridCell,
68
+ DefaultGridPiece,
69
+ DefaultChessPiece,
70
+ // Utility functions
71
+ toAlgebraic,
72
+ toNumeric,
73
+ type SquareGridBoardProps,
74
+ type SquareGridProps,
75
+ type InteractiveSquareEdge,
76
+ type InteractiveSquareSpace,
77
+ type InteractiveSquareVertex,
78
+ type SquareEdgePosition,
79
+ type SquareVertexPosition,
80
+ type DefaultGridCellProps,
81
+ type DefaultGridPieceProps,
82
+ type DefaultChessPieceProps,
83
+ } from "./SquareGrid.js";
84
+
85
+ // ZoneMap - Area control games
86
+ export {
87
+ ZoneMap,
88
+ // Pre-built helper components for easy customization
89
+ DefaultZone,
90
+ DefaultZonePieces,
91
+ DefaultZonePiece,
92
+ type ZoneMapProps,
93
+ type ZoneDefinition,
94
+ type ZonePiece,
95
+ type ZoneShape,
96
+ type ZoneHighlightType,
97
+ type DefaultZoneProps,
98
+ type DefaultZonePiecesProps,
99
+ type DefaultZonePieceProps,
100
+ } from "./ZoneMap.js";
101
+
102
+ // TrackBoard - Track/racing games
103
+ export {
104
+ TrackBoard,
105
+ // Pre-built helper components for easy customization
106
+ DefaultTrackSpace,
107
+ DefaultTrackPiece,
108
+ DefaultTrackConnection,
109
+ DefaultTrackJump,
110
+ type TrackBoardProps,
111
+ type TrackSpace,
112
+ type TrackPiece,
113
+ type DefaultTrackSpaceProps,
114
+ type DefaultTrackPieceProps,
115
+ type DefaultTrackConnectionProps,
116
+ type DefaultTrackJumpProps,
117
+ } from "./TrackBoard.js";
118
+
119
+ // SlotSystem - Worker placement games
120
+ export {
121
+ SlotSystem,
122
+ // Pre-built helper components for easy customization
123
+ DefaultSlotItem,
124
+ DefaultSlotOccupant,
125
+ DefaultEmptySlot,
126
+ type SlotSystemProps,
127
+ type SlotDefinition,
128
+ type SlotOccupant,
129
+ type DefaultSlotItemProps,
130
+ type DefaultSlotOccupantProps,
131
+ type DefaultEmptySlotProps,
132
+ } from "./SlotSystem.js";
133
+
134
+ export type {
135
+ HexTileState,
136
+ HexEdgeState,
137
+ HexVertexState,
138
+ SquareCellState,
139
+ SquareEdgeState,
140
+ SquarePieceState,
141
+ SquareVertexState,
142
+ } from "../../types/player-state.js";