@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,356 @@
1
+ import type {
2
+ PhaseMapOf,
3
+ ReducerGameContractLike,
4
+ ViewMapOf,
5
+ } from "../../model";
6
+ import type {
7
+ InteractionDescriptorShape,
8
+ createInteractionResolver,
9
+ } from "./interaction-resolver";
10
+ import type {
11
+ TrustedDomainState,
12
+ TrustedPhaseName,
13
+ TrustedPlayerId,
14
+ TrustedRuntimeScope,
15
+ TrustedSessionState,
16
+ TrustedState,
17
+ } from "./runtime-scope";
18
+ import {
19
+ createProjectionContext,
20
+ type ProjectionContext,
21
+ } from "./projection-context";
22
+ import { collectCardZoneIds } from "./interaction-collectors";
23
+ import {
24
+ isSimultaneousPhase,
25
+ resolveSimultaneousActors,
26
+ SIMULTANEOUS_SUBMIT_INTERACTION_ID,
27
+ simultaneousSubmitInteraction,
28
+ } from "./simultaneous-player";
29
+
30
+ type ProjectionMode = "full" | "actionsOnly";
31
+ type DescriptorRegistry = {
32
+ add(descriptor: InteractionDescriptorShape): string;
33
+ entries(): Record<string, InteractionDescriptorShape>;
34
+ };
35
+
36
+ type InteractionResolverFor<
37
+ Contract extends ReducerGameContractLike,
38
+ Definitions extends PhaseMapOf<Contract>,
39
+ Views extends ViewMapOf<Contract>,
40
+ > = ReturnType<typeof createInteractionResolver<Contract, Definitions, Views>>;
41
+
42
+ export function createProjectionBuilder<
43
+ Contract extends ReducerGameContractLike,
44
+ Definitions extends PhaseMapOf<Contract>,
45
+ Views extends ViewMapOf<Contract>,
46
+ >(
47
+ scope: TrustedRuntimeScope<Contract, Definitions, Views>,
48
+ interactions: InteractionResolverFor<Contract, Definitions, Views>,
49
+ ) {
50
+ type SessionState = TrustedSessionState<Contract>;
51
+ type DomainState = TrustedDomainState<Contract>;
52
+ type State = TrustedState<Contract>;
53
+ type PhaseName = TrustedPhaseName<Contract, Definitions, Views>;
54
+ type PlayerId = TrustedPlayerId<Contract>;
55
+
56
+ function createDescriptorRegistry(): DescriptorRegistry {
57
+ const byRef: Record<string, InteractionDescriptorShape> = {};
58
+ const byHash = new Map<string, string>();
59
+ return {
60
+ add(descriptor) {
61
+ const fingerprint = stableStringify(descriptor);
62
+ const existing = byHash.get(fingerprint);
63
+ if (existing) return existing;
64
+ const base =
65
+ typeof descriptor.interactionId === "string" &&
66
+ descriptor.interactionId.length > 0
67
+ ? descriptor.interactionId
68
+ : "interaction";
69
+ const ref = `${base}:${fnv1a64(fingerprint)}`;
70
+ byHash.set(fingerprint, ref);
71
+ byRef[ref] = descriptor;
72
+ return ref;
73
+ },
74
+ entries() {
75
+ return byRef;
76
+ },
77
+ };
78
+ }
79
+
80
+ function resolveZoneHandlesFor(
81
+ combinedState: State,
82
+ playerId: PlayerId,
83
+ projection: ProjectionContext<DomainState, State>,
84
+ registry: DescriptorRegistry,
85
+ ) {
86
+ const phaseName = combinedState.flow.currentPhase as PhaseName;
87
+ const zoneIds = new Set<string>(scope.zonesForPhase(phaseName).map(String));
88
+ for (const [, interaction] of scope.interactionEntriesForPhase(phaseName)) {
89
+ for (const zoneId of collectCardZoneIds(interaction)) {
90
+ zoneIds.add(String(zoneId));
91
+ }
92
+ }
93
+ const zones = [...zoneIds];
94
+ if (zones.length === 0) return {};
95
+ const q = projection.q;
96
+ const result: Record<
97
+ string,
98
+ {
99
+ cardIds: string[];
100
+ cardViewsById: Record<string, string>;
101
+ playableByCardId: Record<string, string[]>;
102
+ }
103
+ > = {};
104
+ for (const zoneId of zones) {
105
+ const table = combinedState.table as {
106
+ decks?: Record<string, unknown>;
107
+ hands?: Record<string, unknown>;
108
+ zones?: {
109
+ shared?: Record<string, unknown>;
110
+ perPlayer?: Record<string, unknown>;
111
+ };
112
+ };
113
+ const isPlayerZone =
114
+ zoneId in (table.hands ?? {}) ||
115
+ zoneId in (table.zones?.perPlayer ?? {});
116
+ const cardIds = Array.from(
117
+ isPlayerZone
118
+ ? (q.zone.playerCards(
119
+ playerId as never,
120
+ zoneId as never,
121
+ ) as readonly string[])
122
+ : (q.zone.sharedCards(zoneId as never) as readonly string[]),
123
+ );
124
+ const cardInteractionIds = scope
125
+ .interactionEntriesForPhase(phaseName)
126
+ .filter(([, interaction]) =>
127
+ collectCardZoneIds(interaction).map(String).includes(zoneId),
128
+ )
129
+ .map(([interactionId]) => interactionId);
130
+ const cardViewsById: Record<string, string> = {};
131
+ const playableByCardId: Record<string, string[]> = {};
132
+ for (const cardId of cardIds) {
133
+ cardViewsById[cardId] = JSON.stringify(q.card.get(cardId as never));
134
+ const perCard: string[] = [];
135
+ for (const interactionId of cardInteractionIds) {
136
+ const interaction = scope.findInteractionInPhase(
137
+ phaseName,
138
+ interactionId,
139
+ );
140
+ if (!interaction) continue;
141
+ const cardKey = interactions.findCardInputKeyForZone(
142
+ interaction,
143
+ zoneId,
144
+ );
145
+ const params = cardKey ? { [cardKey]: cardId } : {};
146
+ const decision = interactions.resolveInteractionDecision({
147
+ state: combinedState,
148
+ playerId,
149
+ interactionId,
150
+ params,
151
+ mode: "card",
152
+ projection,
153
+ });
154
+ if (!decision.found || !decision.visible) continue;
155
+ const cardDomain = cardKey
156
+ ? decision.descriptor.inputs.find((input) => input.key === cardKey)
157
+ ?.domain
158
+ : undefined;
159
+ const cardTargets =
160
+ cardDomain?.type === "cardTarget" &&
161
+ cardDomain.projection === "resolved"
162
+ ? cardDomain.eligibleTargets
163
+ : undefined;
164
+ if (cardKey && !cardTargets?.includes(cardId)) {
165
+ continue;
166
+ }
167
+ perCard.push(
168
+ registry.add({
169
+ ...decision.descriptor,
170
+ zoneId,
171
+ }),
172
+ );
173
+ }
174
+ playableByCardId[cardId] = perCard;
175
+ }
176
+ result[zoneId] = {
177
+ cardIds,
178
+ cardViewsById,
179
+ playableByCardId,
180
+ };
181
+ }
182
+ return result;
183
+ }
184
+
185
+ function resolveCurrentStageFor(
186
+ combinedState: State,
187
+ projection?: ProjectionContext<DomainState, State>,
188
+ ): string {
189
+ const phaseName = combinedState.flow.currentPhase as PhaseName;
190
+ return (
191
+ interactions.resolveActiveStage(combinedState, phaseName, projection)
192
+ ?.id ?? phaseName
193
+ );
194
+ }
195
+
196
+ function resolveStageSeatsFor(state: SessionState): string[] {
197
+ const combinedState = scope.toCombinedState(state);
198
+ const phaseName = combinedState.flow.currentPhase as PhaseName;
199
+ const phase = scope.phaseByName(phaseName);
200
+ if (isSimultaneousPhase(phase)) {
201
+ return resolveSimultaneousActors(scope, combinedState, phase).map(String);
202
+ }
203
+ return [...state.domain.flow.activePlayers];
204
+ }
205
+
206
+ function resolveSimultaneousPhaseFor(state: SessionState) {
207
+ const combinedState = scope.toCombinedState(state);
208
+ const phaseName = combinedState.flow.currentPhase as PhaseName;
209
+ const phase = scope.phaseByName(phaseName);
210
+ if (!isSimultaneousPhase(phase)) return null;
211
+ const current = state.runtime.simultaneous?.current;
212
+ if (!current || current.phaseName !== phaseName) return null;
213
+ const submit = simultaneousSubmitInteraction(phase);
214
+ if (!submit) return null;
215
+ const actorIds = current.actors.map(String);
216
+ const sealedPlayerIds = actorIds.filter(
217
+ (playerId) => current.submissions[playerId as PlayerId] !== undefined,
218
+ );
219
+ const pendingPlayerIds = actorIds.filter(
220
+ (playerId) => current.submissions[playerId as PlayerId] === undefined,
221
+ );
222
+ return {
223
+ phaseName: String(current.phaseName),
224
+ interactionId: SIMULTANEOUS_SUBMIT_INTERACTION_ID,
225
+ actorIds,
226
+ sealedPlayerIds,
227
+ pendingPlayerIds,
228
+ };
229
+ }
230
+
231
+ function resolveViewFor(
232
+ combinedState: State,
233
+ playerId: PlayerId,
234
+ viewId: string,
235
+ projection: ProjectionContext<DomainState, State>,
236
+ ): unknown {
237
+ const views = scope.definition.views;
238
+ const view = views?.[viewId as keyof typeof views];
239
+ if (!view) {
240
+ return null;
241
+ }
242
+ const viewArgs = {
243
+ ...scope.buildContext(combinedState),
244
+ ...scope.runtimeHelpers,
245
+ fx: projection.fx,
246
+ q: projection.q,
247
+ derived: projection.derived,
248
+ state: projection.domainState,
249
+ playerId,
250
+ } as Parameters<typeof view.project>[0];
251
+ return view.project(viewArgs);
252
+ }
253
+
254
+ function projectSeatsDynamic({
255
+ state,
256
+ playerIds,
257
+ viewId = "player",
258
+ projectionMode = "full",
259
+ }: {
260
+ state: SessionState;
261
+ playerIds: PlayerId[];
262
+ viewId?: string;
263
+ projectionMode?: ProjectionMode;
264
+ }) {
265
+ const combinedState = scope.toCombinedState(state);
266
+ const projection = createProjectionContext({
267
+ combinedState,
268
+ domainState: scope.toDomainState(combinedState),
269
+ });
270
+ const registry = createDescriptorRegistry();
271
+ type SeatProjection = {
272
+ view?: ReturnType<typeof resolveViewFor>;
273
+ availableInteractionRefs: string[];
274
+ zones?: ReturnType<typeof resolveZoneHandlesFor>;
275
+ };
276
+ const seats: Record<string, SeatProjection> = {};
277
+ for (const playerId of playerIds) {
278
+ const availableInteractionRefs = interactions
279
+ .resolveAvailableInteractionsFor(combinedState, playerId, {
280
+ projection,
281
+ })
282
+ .map((descriptor) => registry.add(descriptor));
283
+ seats[playerId as unknown as string] = {
284
+ ...(projectionMode === "full"
285
+ ? {
286
+ view: resolveViewFor(combinedState, playerId, viewId, projection),
287
+ zones: resolveZoneHandlesFor(
288
+ combinedState,
289
+ playerId,
290
+ projection,
291
+ registry,
292
+ ),
293
+ }
294
+ : {}),
295
+ availableInteractionRefs,
296
+ };
297
+ }
298
+ return {
299
+ currentStage: resolveCurrentStageFor(combinedState, projection),
300
+ stageSeats: resolveStageSeatsFor(state),
301
+ simultaneousPhase: resolveSimultaneousPhaseFor(state),
302
+ interactionsByRef: registry.entries(),
303
+ seats,
304
+ };
305
+ }
306
+
307
+ function projectSeatViewDynamic({
308
+ state,
309
+ playerId,
310
+ viewId = "player",
311
+ }: {
312
+ state: SessionState;
313
+ playerId: PlayerId;
314
+ viewId?: string;
315
+ }) {
316
+ const combinedState = scope.toCombinedState(state);
317
+ const projection = createProjectionContext({
318
+ combinedState,
319
+ domainState: scope.toDomainState(combinedState),
320
+ });
321
+ return resolveViewFor(combinedState, playerId, viewId, projection);
322
+ }
323
+
324
+ return {
325
+ projectSeatsDynamic,
326
+ projectSeatViewDynamic,
327
+ resolveCurrentStageFor,
328
+ resolveStageSeatsFor,
329
+ resolveViewFor,
330
+ resolveZoneHandlesFor,
331
+ };
332
+ }
333
+
334
+ function stableStringify(value: unknown): string {
335
+ if (value === null || typeof value !== "object") {
336
+ return JSON.stringify(value);
337
+ }
338
+ if (Array.isArray(value)) {
339
+ return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
340
+ }
341
+ const record = value as Record<string, unknown>;
342
+ return `{${Object.keys(record)
343
+ .sort()
344
+ .map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`)
345
+ .join(",")}}`;
346
+ }
347
+
348
+ function fnv1a64(value: string): string {
349
+ let hash = 0xcbf29ce484222325n;
350
+ const prime = 0x100000001b3n;
351
+ for (let index = 0; index < value.length; index += 1) {
352
+ hash ^= BigInt(value.charCodeAt(index));
353
+ hash = BigInt.asUintN(64, hash * prime);
354
+ }
355
+ return hash.toString(16).padStart(16, "0");
356
+ }
@@ -0,0 +1,39 @@
1
+ import { createDerivedResolver, type DerivedResolver } from "../../derived";
2
+ import { createReducerFx } from "../../effects";
3
+ import { createStateQueries } from "../../table-queries";
4
+ import type { RuntimeTableRecord, TableQueriesOfState } from "../../model";
5
+
6
+ type ProjectionFxState = {
7
+ table: RuntimeTableRecord;
8
+ flow: { currentPhase: string };
9
+ };
10
+
11
+ export type ProjectionContext<
12
+ State extends { table: RuntimeTableRecord },
13
+ FxState extends ProjectionFxState = ProjectionFxState,
14
+ > = {
15
+ readonly domainState: State;
16
+ readonly q: TableQueriesOfState<State>;
17
+ readonly derived: DerivedResolver;
18
+ readonly fx: ReturnType<typeof createReducerFx<FxState>>;
19
+ readonly eligibleTargets: Map<string, string[]>;
20
+ readonly stageAllowlists: Map<string, Set<string> | null>;
21
+ };
22
+
23
+ export function createProjectionContext<
24
+ State extends { table: RuntimeTableRecord },
25
+ FxState extends ProjectionFxState,
26
+ >(options: {
27
+ domainState: State;
28
+ combinedState: FxState;
29
+ }): ProjectionContext<State, FxState> {
30
+ const q = createStateQueries(options.domainState);
31
+ return {
32
+ domainState: options.domainState,
33
+ q,
34
+ derived: createDerivedResolver(options.domainState, { q }),
35
+ fx: createReducerFx(options.combinedState),
36
+ eligibleTargets: new Map(),
37
+ stageAllowlists: new Map(),
38
+ };
39
+ }
@@ -0,0 +1,150 @@
1
+ import type {
2
+ CollectorState,
3
+ InputCollector,
4
+ RandomHelpers,
5
+ RuntimeRngState,
6
+ SchemaLike,
7
+ } from "../../model";
8
+ import { nextRandomInt } from "../../rng";
9
+
10
+ export type RngConsumption = {
11
+ operation: string;
12
+ traceEntry: string;
13
+ };
14
+
15
+ export type MutableRandomHelpers = {
16
+ random: RandomHelpers;
17
+ currentRng: () => RuntimeRngState;
18
+ };
19
+
20
+ export function sampleDieValue(
21
+ sides: number,
22
+ rng: RuntimeRngState,
23
+ ): {
24
+ value: number;
25
+ nextRng: RuntimeRngState;
26
+ consumption: RngConsumption;
27
+ } {
28
+ const [offset, nextRng] = nextRandomInt(sides, rng);
29
+ return {
30
+ value: offset + 1,
31
+ nextRng,
32
+ consumption: {
33
+ operation: "rollDie",
34
+ traceEntry: nextRng.trace[nextRng.trace.length - 1] ?? "",
35
+ },
36
+ };
37
+ }
38
+
39
+ export function shuffleWithRng<T>(
40
+ values: readonly T[],
41
+ rng: RuntimeRngState,
42
+ operation:
43
+ | "shuffleSharedZone"
44
+ | "shufflePlayerZone"
45
+ | "randomSubset" = "shuffleSharedZone",
46
+ ): {
47
+ orderedValues: T[];
48
+ nextRng: RuntimeRngState;
49
+ consumptions: RngConsumption[];
50
+ } {
51
+ const orderedValues = [...values];
52
+ let nextRng = rng;
53
+ const consumptions: RngConsumption[] = [];
54
+ for (
55
+ let lastIndex = orderedValues.length - 1;
56
+ lastIndex > 0;
57
+ lastIndex -= 1
58
+ ) {
59
+ const [swapIndex, updatedRng] = nextRandomInt(lastIndex + 1, nextRng);
60
+ consumptions.push({
61
+ operation,
62
+ traceEntry: updatedRng.trace[updatedRng.trace.length - 1] ?? "",
63
+ });
64
+ nextRng = updatedRng;
65
+ const current = orderedValues[lastIndex];
66
+ const swap = orderedValues[swapIndex];
67
+ if (current === undefined || swap === undefined) {
68
+ throw new Error(
69
+ `shuffleWithRng: invalid index (lastIndex=${lastIndex}, swapIndex=${swapIndex}, length=${orderedValues.length})`,
70
+ );
71
+ }
72
+ orderedValues[lastIndex] = swap;
73
+ orderedValues[swapIndex] = current;
74
+ }
75
+ return { orderedValues, nextRng, consumptions };
76
+ }
77
+
78
+ export function subsetWithRng<T>(
79
+ values: readonly T[],
80
+ count: number,
81
+ rng: RuntimeRngState,
82
+ ): {
83
+ values: readonly T[];
84
+ nextRng: RuntimeRngState;
85
+ consumptions: RngConsumption[];
86
+ } {
87
+ if (!Number.isInteger(count) || count < 0) {
88
+ throw new Error("random.subset count must be a non-negative integer.");
89
+ }
90
+ if (count > values.length) {
91
+ throw new Error(
92
+ `random.subset count ${count} exceeds source length ${values.length}.`,
93
+ );
94
+ }
95
+ const shuffled = shuffleWithRng(values, rng, "randomSubset");
96
+ return {
97
+ values: shuffled.orderedValues.slice(0, count),
98
+ nextRng: shuffled.nextRng,
99
+ consumptions: shuffled.consumptions,
100
+ };
101
+ }
102
+
103
+ export function createMutableRandomHelpers(
104
+ rng: RuntimeRngState,
105
+ ): MutableRandomHelpers {
106
+ let current = rng;
107
+ return {
108
+ random: {
109
+ subset(options) {
110
+ const sampled = subsetWithRng(options.from, options.count, current);
111
+ current = sampled.nextRng;
112
+ return sampled.values;
113
+ },
114
+ },
115
+ currentRng: () => current,
116
+ };
117
+ }
118
+
119
+ export function sampleRngCollectorValue(
120
+ collector: InputCollector<SchemaLike<unknown>, CollectorState, "rng">,
121
+ rng: RuntimeRngState,
122
+ ): { value: unknown; nextRng: RuntimeRngState } {
123
+ const meta = collector.meta;
124
+ switch (meta.rng) {
125
+ case "d6": {
126
+ const count = meta.count > 0 ? meta.count : 1;
127
+ const values: number[] = [];
128
+ let nextRng = rng;
129
+ for (let i = 0; i < count; i += 1) {
130
+ const sampled = sampleDieValue(6, nextRng);
131
+ values.push(sampled.value);
132
+ nextRng = sampled.nextRng;
133
+ }
134
+ return { value: { values }, nextRng };
135
+ }
136
+ case "coin": {
137
+ const [offset, nextRng] = nextRandomInt(2, rng);
138
+ return {
139
+ value: { value: offset === 0 ? "heads" : "tails" },
140
+ nextRng,
141
+ };
142
+ }
143
+ default: {
144
+ const _exhaustive: never = meta;
145
+ throw new Error(
146
+ `Unknown rngInput kind '${String(_exhaustive)}'. Register a sampler in trusted rng-sampler.`,
147
+ );
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,120 @@
1
+ import type {
2
+ AnyContinuationCallable,
3
+ BaseGameStateOfContract,
4
+ ManifestContractOf,
5
+ PhaseMapOf,
6
+ PhaseNamesOfDefinition,
7
+ ReducerGameContractLike,
8
+ ReducerGameDefinition,
9
+ ViewMapOf,
10
+ } from "../../model";
11
+ import {
12
+ collectReducerDefinitionIndex,
13
+ type ReducerDefinitionPhaseIndex,
14
+ type ReducerIndexedCardActionEntry,
15
+ type ReducerIndexedInteractionEntry,
16
+ type ReducerIndexedPhase,
17
+ type ReducerIndexedStageEntry,
18
+ type ReducerIndexedZoneEntry,
19
+ } from "../../definition-index";
20
+
21
+ export type TrustedErasedPhase<Contract extends ReducerGameContractLike> =
22
+ ReducerIndexedPhase<Contract>;
23
+
24
+ export type TrustedInteractionEntry<Contract extends ReducerGameContractLike> =
25
+ ReducerIndexedInteractionEntry<Contract>;
26
+
27
+ export type TrustedCardActionEntry<Contract extends ReducerGameContractLike> =
28
+ ReducerIndexedCardActionEntry<Contract>;
29
+
30
+ export type TrustedStageEntry<Contract extends ReducerGameContractLike> =
31
+ ReducerIndexedStageEntry<Contract>;
32
+
33
+ export type TrustedZoneEntry<Contract extends ReducerGameContractLike> =
34
+ ReducerIndexedZoneEntry<Contract>;
35
+
36
+ export type TrustedContinuationRegistry<
37
+ Contract extends ReducerGameContractLike,
38
+ > = ReadonlyMap<
39
+ string,
40
+ AnyContinuationCallable<BaseGameStateOfContract<Contract>>
41
+ >;
42
+
43
+ export interface TrustedPhaseRegistry<
44
+ Contract extends ReducerGameContractLike,
45
+ Definitions extends PhaseMapOf<Contract>,
46
+ Views extends ViewMapOf<Contract>,
47
+ > extends Omit<
48
+ ReducerDefinitionPhaseIndex<Contract, Definitions, Views>,
49
+ "effects"
50
+ > {}
51
+
52
+ export interface TrustedRuntimeRegistry<
53
+ Contract extends ReducerGameContractLike,
54
+ Definitions extends PhaseMapOf<Contract>,
55
+ Views extends ViewMapOf<Contract>,
56
+ > {
57
+ readonly phaseEntries: ReadonlyArray<
58
+ readonly [
59
+ PhaseNamesOfDefinition<
60
+ ReducerGameDefinition<Contract, Definitions, Views>
61
+ >,
62
+ TrustedErasedPhase<Contract>,
63
+ ]
64
+ >;
65
+ readonly phasesByName: ReadonlyMap<
66
+ PhaseNamesOfDefinition<ReducerGameDefinition<Contract, Definitions, Views>>,
67
+ TrustedPhaseRegistry<Contract, Definitions, Views>
68
+ >;
69
+ readonly continuationsById: TrustedContinuationRegistry<Contract>;
70
+ readonly effectsById: ReadonlyMap<
71
+ string,
72
+ { readonly id: string; readonly type: string }
73
+ >;
74
+ }
75
+
76
+ export function collectTrustedRuntimeRegistry<
77
+ Contract extends ReducerGameContractLike,
78
+ Definitions extends PhaseMapOf<Contract>,
79
+ Views extends ViewMapOf<Contract>,
80
+ >(
81
+ definition: ReducerGameDefinition<Contract, Definitions, Views>,
82
+ ): TrustedRuntimeRegistry<Contract, Definitions, Views> {
83
+ type State = BaseGameStateOfContract<Contract>;
84
+ type PhaseName = PhaseNamesOfDefinition<
85
+ ReducerGameDefinition<Contract, Definitions, Views>
86
+ >;
87
+
88
+ const index = collectReducerDefinitionIndex(definition);
89
+ const phasesByName = new Map<
90
+ PhaseName,
91
+ TrustedPhaseRegistry<Contract, Definitions, Views>
92
+ >();
93
+ const continuationsById = new Map<string, AnyContinuationCallable<State>>();
94
+ const effectsById = new Map<
95
+ string,
96
+ { readonly id: string; readonly type: string }
97
+ >();
98
+
99
+ for (const phaseIndex of index.phasesByName.values()) {
100
+ const { effects: _effects, ...trustedPhase } = phaseIndex;
101
+ phasesByName.set(phaseIndex.phaseName, trustedPhase);
102
+ for (const [, effect] of phaseIndex.effects) {
103
+ effectsById.set(effect.id, { id: effect.id, type: effect.type });
104
+ if (effect.continuation) {
105
+ const continuationId = effect.continuation.id ?? effect.id;
106
+ continuationsById.set(
107
+ continuationId,
108
+ effect.continuation as AnyContinuationCallable<State>,
109
+ );
110
+ }
111
+ }
112
+ }
113
+
114
+ return {
115
+ phaseEntries: index.phaseEntries,
116
+ phasesByName,
117
+ continuationsById,
118
+ effectsById,
119
+ };
120
+ }