@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.
- package/LICENSE.md +96 -0
- package/README.md +12 -0
- package/dist/HandView-ncJIVLhN.d.ts +193 -0
- package/dist/ResourceCounter-CTREyF73.d.ts +102 -0
- package/dist/ThemeProvider-fy0_QzgO.d.ts +99 -0
- package/dist/bundle-TIZcw8LB.d.ts +281 -0
- package/dist/cards-Sl3b40Mv.d.ts +13 -0
- package/dist/chunk-7YAHLYBR.js +481 -0
- package/dist/chunk-7YAHLYBR.js.map +1 -0
- package/dist/chunk-FDNZTDD6.js +8085 -0
- package/dist/chunk-FDNZTDD6.js.map +1 -0
- package/dist/chunk-GKKBPPSW.js +598 -0
- package/dist/chunk-GKKBPPSW.js.map +1 -0
- package/dist/chunk-I46YJSOD.js +1 -0
- package/dist/chunk-I46YJSOD.js.map +1 -0
- package/dist/chunk-KAELH4KC.js +104 -0
- package/dist/chunk-KAELH4KC.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/chunk-T3ZKNUZ7.js +1 -0
- package/dist/chunk-T3ZKNUZ7.js.map +1 -0
- package/dist/chunk-T52J5RMF.js +1 -0
- package/dist/chunk-T52J5RMF.js.map +1 -0
- package/dist/chunk-TDSWKVZ4.js +5401 -0
- package/dist/chunk-TDSWKVZ4.js.map +1 -0
- package/dist/chunk-U5C6BONG.js +34 -0
- package/dist/chunk-U5C6BONG.js.map +1 -0
- package/dist/chunk-VDXOF4FW.js +69 -0
- package/dist/chunk-VDXOF4FW.js.map +1 -0
- package/dist/chunk-VFTAA4WO.js +115 -0
- package/dist/chunk-VFTAA4WO.js.map +1 -0
- package/dist/chunk-WN74KVNY.js +17 -0
- package/dist/chunk-WN74KVNY.js.map +1 -0
- package/dist/chunk-WYPQ3GG5.js +10990 -0
- package/dist/chunk-WYPQ3GG5.js.map +1 -0
- package/dist/components-D5ZRE2Hl.d.ts +1451 -0
- package/dist/generated/runtime/primitives.d.ts +12 -0
- package/dist/generated/runtime/primitives.js +180 -0
- package/dist/generated/runtime/primitives.js.map +1 -0
- package/dist/generated/runtime-api.d.ts +3 -0
- package/dist/generated/runtime-api.js +2 -0
- package/dist/generated/runtime-api.js.map +1 -0
- package/dist/generated/runtime.d.ts +14 -0
- package/dist/generated/runtime.js +18 -0
- package/dist/generated/runtime.js.map +1 -0
- package/dist/generated/workspace-contract.d.ts +14 -0
- package/dist/generated/workspace-contract.js +14 -0
- package/dist/generated/workspace-contract.js.map +1 -0
- package/dist/hex-board-view-D_07hO6O.d.ts +933 -0
- package/dist/hex-color-MhOyuY-o.d.ts +8 -0
- package/dist/index-BwqPQtBu.d.ts +1433 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/infrastructure/reducer-bundle-abi.d.ts +1083 -0
- package/dist/infrastructure/reducer-bundle-abi.js +14 -0
- package/dist/infrastructure/reducer-bundle-abi.js.map +1 -0
- package/dist/infrastructure/workspace-codegen.d.ts +53 -0
- package/dist/infrastructure/workspace-codegen.js +44 -0
- package/dist/infrastructure/workspace-codegen.js.map +1 -0
- package/dist/manifest-contract-BNHVGFtU.d.ts +9 -0
- package/dist/package-set.d.ts +13 -0
- package/dist/package-set.js +12 -0
- package/dist/package-set.js.map +1 -0
- package/dist/primitive-props-DpKs-GCr.d.ts +11 -0
- package/dist/reducer.d.ts +3786 -0
- package/dist/reducer.js +8131 -0
- package/dist/reducer.js.map +1 -0
- package/dist/runtime/primitives.d.ts +226 -0
- package/dist/runtime/primitives.js +180 -0
- package/dist/runtime/primitives.js.map +1 -0
- package/dist/runtime/types/runtime-api.d.ts +1 -0
- package/dist/runtime/types/runtime-api.js +2 -0
- package/dist/runtime/types/runtime-api.js.map +1 -0
- package/dist/runtime/workspace-contract.d.ts +172 -0
- package/dist/runtime/workspace-contract.js +14 -0
- package/dist/runtime/workspace-contract.js.map +1 -0
- package/dist/runtime-api-3dshj6kK.d.ts +101 -0
- package/dist/runtime-api-DWxvTr-O.d.ts +379 -0
- package/dist/runtime.d.ts +58 -0
- package/dist/runtime.js +13 -0
- package/dist/runtime.js.map +1 -0
- package/dist/slots-1GPGihk8.d.ts +8 -0
- package/dist/testing.d.ts +149 -0
- package/dist/testing.js +513 -0
- package/dist/testing.js.map +1 -0
- package/dist/types.d.ts +496 -0
- package/dist/types.js +28 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/components.d.ts +16 -0
- package/dist/ui/components.js +192 -0
- package/dist/ui/components.js.map +1 -0
- package/dist/ui/defaults.d.ts +19 -0
- package/dist/ui/defaults.js +104 -0
- package/dist/ui/defaults.js.map +1 -0
- package/dist/ui/plugin-styles.css +250 -0
- package/dist/ui/types/player-state.d.ts +365 -0
- package/dist/ui/types/player-state.js +1 -0
- package/dist/ui/types/player-state.js.map +1 -0
- package/dist/ui-contract-iQfTtUSL.d.ts +1161 -0
- package/dist/ui.d.ts +320 -0
- package/dist/ui.js +253 -0
- package/dist/ui.js.map +1 -0
- package/package.json +199 -0
- package/src/generated/reducer-contract/builders.ts +90 -0
- package/src/generated/reducer-contract/version.ts +9 -0
- package/src/generated/reducer-contract/wire.ts +100 -0
- package/src/generated/reducer-contract/zod.ts +101 -0
- package/src/generated/runtime/primitives.ts +2 -0
- package/src/generated/runtime-api.ts +5 -0
- package/src/generated/runtime.ts +35 -0
- package/src/generated/workspace-contract.ts +2 -0
- package/src/index.ts +7 -0
- package/src/infrastructure/reducer-bundle-abi.ts +8 -0
- package/src/infrastructure/reducer-contract/bundle.ts +37 -0
- package/src/infrastructure/workspace-codegen/hex-geometry.ts +69 -0
- package/src/infrastructure/workspace-codegen/index.ts +64 -0
- package/src/infrastructure/workspace-codegen/manifest-contract.ts +6632 -0
- package/src/infrastructure/workspace-codegen/manifest-validation.ts +795 -0
- package/src/infrastructure/workspace-codegen/ownership.ts +131 -0
- package/src/infrastructure/workspace-codegen/preset-card-sets.ts +169 -0
- package/src/infrastructure/workspace-codegen/seeds.ts +1705 -0
- package/src/infrastructure/workspace-codegen.ts +1 -0
- package/src/package-set.ts +19 -0
- package/src/reducer/authoring/contract.ts +157 -0
- package/src/reducer/authoring/effect.ts +224 -0
- package/src/reducer/authoring/game.ts +23 -0
- package/src/reducer/authoring/interaction.ts +98 -0
- package/src/reducer/authoring/phase.ts +300 -0
- package/src/reducer/authoring/types.ts +70 -0
- package/src/reducer/authoring/validation.ts +382 -0
- package/src/reducer/authoring/view-stage.ts +68 -0
- package/src/reducer/authoring.ts +29 -0
- package/src/reducer/bundle/ingress-bundle.ts +491 -0
- package/src/reducer/bundle/trusted/engine-instruction-resolver.ts +254 -0
- package/src/reducer/bundle/trusted/flow-instruction-resolver.ts +73 -0
- package/src/reducer/bundle/trusted/instruction-runner.ts +414 -0
- package/src/reducer/bundle/trusted/interaction-authorization.ts +137 -0
- package/src/reducer/bundle/trusted/interaction-collectors.ts +859 -0
- package/src/reducer/bundle/trusted/interaction-decision.ts +747 -0
- package/src/reducer/bundle/trusted/interaction-resolver.ts +95 -0
- package/src/reducer/bundle/trusted/interaction-types.ts +171 -0
- package/src/reducer/bundle/trusted/lifecycle-runner.ts +427 -0
- package/src/reducer/bundle/trusted/projection-builder.ts +356 -0
- package/src/reducer/bundle/trusted/projection-context.ts +39 -0
- package/src/reducer/bundle/trusted/rng-sampler.ts +150 -0
- package/src/reducer/bundle/trusted/runtime-registry.ts +120 -0
- package/src/reducer/bundle/trusted/runtime-scope.ts +336 -0
- package/src/reducer/bundle/trusted/simultaneous-player.ts +97 -0
- package/src/reducer/bundle/trusted/stage-resolver.ts +87 -0
- package/src/reducer/bundle/trusted/static-projection.ts +116 -0
- package/src/reducer/bundle/trusted/trusted-runtime-args.ts +97 -0
- package/src/reducer/bundle/trusted/trusted-runtime-result.ts +39 -0
- package/src/reducer/bundle/trusted/trusted-setup-profiles.ts +43 -0
- package/src/reducer/bundle/trusted/trusted-state-codec.ts +48 -0
- package/src/reducer/bundle/trusted-bundle.ts +97 -0
- package/src/reducer/bundle/types.ts +171 -0
- package/src/reducer/bundle.ts +2 -0
- package/src/reducer/client-param-schemas.ts +57 -0
- package/src/reducer/compose.ts +34 -0
- package/src/reducer/core/runtime-input.ts +30 -0
- package/src/reducer/core/runtime-instruction.ts +59 -0
- package/src/reducer/core/types.ts +62 -0
- package/src/reducer/definition-index.ts +277 -0
- package/src/reducer/derived.ts +106 -0
- package/src/reducer/effects.ts +92 -0
- package/src/reducer/engine/runtime-instruction-engine.ts +155 -0
- package/src/reducer/ingress/decode-runtime-input.ts +7 -0
- package/src/reducer/ingress/decode-session-state.ts +9 -0
- package/src/reducer/ingress/encode-session-state.ts +6 -0
- package/src/reducer/ingress/input-codec.ts +18 -0
- package/src/reducer/ingress/phase-schemas.ts +62 -0
- package/src/reducer/ingress/raw-types.ts +107 -0
- package/src/reducer/ingress/runtime-codec.ts +14 -0
- package/src/reducer/ingress/runtime-payload.ts +13 -0
- package/src/reducer/ingress/session-codec.ts +392 -0
- package/src/reducer/ingress/types.ts +6 -0
- package/src/reducer/inputs/boardInput.ts +217 -0
- package/src/reducer/inputs/boardTarget.ts +190 -0
- package/src/reducer/inputs/cardInput.ts +86 -0
- package/src/reducer/inputs/cardTarget.ts +101 -0
- package/src/reducer/inputs/choiceTarget.ts +104 -0
- package/src/reducer/inputs/defineInputs.ts +71 -0
- package/src/reducer/inputs/formInput.ts +809 -0
- package/src/reducer/inputs/many.ts +120 -0
- package/src/reducer/inputs/promptInput.ts +87 -0
- package/src/reducer/inputs/rngInput.ts +58 -0
- package/src/reducer/inputs/targetRule.ts +123 -0
- package/src/reducer/inputs.ts +41 -0
- package/src/reducer/model/definition.ts +1072 -0
- package/src/reducer/model/extract.ts +745 -0
- package/src/reducer/model/manifest.ts +570 -0
- package/src/reducer/model/queries.ts +641 -0
- package/src/reducer/model/runtime.ts +264 -0
- package/src/reducer/model/spec.ts +1386 -0
- package/src/reducer/model/table.ts +260 -0
- package/src/reducer/model.ts +7 -0
- package/src/reducer/ops.ts +1034 -0
- package/src/reducer/parse-utils.ts +28 -0
- package/src/reducer/per-player.ts +422 -0
- package/src/reducer/rng.ts +69 -0
- package/src/reducer/schema-helpers.ts +185 -0
- package/src/reducer/setup-bootstrap-helpers.ts +171 -0
- package/src/reducer/setup-bootstrap.ts +481 -0
- package/src/reducer/table-ops.ts +2671 -0
- package/src/reducer/table-queries.ts +372 -0
- package/src/reducer/transaction.ts +120 -0
- package/src/reducer.ts +314 -0
- package/src/runtime/primitives.ts +1 -0
- package/src/runtime/types/runtime-api.ts +1 -0
- package/src/runtime/workspace-contract.ts +32 -0
- package/src/runtime-internal/components/InteractionForm.tsx +1309 -0
- package/src/runtime-internal/components/PluginRuntime.tsx +103 -0
- package/src/runtime-internal/components/board/target-layer.ts +70 -0
- package/src/runtime-internal/context/ClientParamSchemaContext.tsx +44 -0
- package/src/runtime-internal/context/InteractionDraftContext.tsx +279 -0
- package/src/runtime-internal/context/PluginSessionContext.tsx +47 -0
- package/src/runtime-internal/context/PluginStateContext.tsx +262 -0
- package/src/runtime-internal/context/RuntimeContext.tsx +96 -0
- package/src/runtime-internal/defaults/components.tsx +409 -0
- package/src/runtime-internal/defaults/index.ts +11 -0
- package/src/runtime-internal/errors/ValidationError.ts +29 -0
- package/src/runtime-internal/hooks/useActivePlayers.ts +33 -0
- package/src/runtime-internal/hooks/useBoardInteractions.ts +665 -0
- package/src/runtime-internal/hooks/useGameSelector.ts +105 -0
- package/src/runtime-internal/hooks/useGameView.ts +9 -0
- package/src/runtime-internal/hooks/useInteractionByKey.ts +354 -0
- package/src/runtime-internal/hooks/useInteractionHandle.ts +438 -0
- package/src/runtime-internal/hooks/useIsMyTurn.ts +20 -0
- package/src/runtime-internal/hooks/useLobby.ts +76 -0
- package/src/runtime-internal/hooks/useMe.ts +48 -0
- package/src/runtime-internal/hooks/usePlayerInfo.ts +28 -0
- package/src/runtime-internal/hooks/usePlayerTurnOrder.ts +23 -0
- package/src/runtime-internal/hooks/usePluginRuntime.ts +147 -0
- package/src/runtime-internal/hooks/useSeatInbox.ts +61 -0
- package/src/runtime-internal/hooks/useSimultaneousPhase.ts +10 -0
- package/src/runtime-internal/index.ts +42 -0
- package/src/runtime-internal/internal.ts +43 -0
- package/src/runtime-internal/plugin-styles.css +250 -0
- package/src/runtime-internal/primitives/board.tsx +459 -0
- package/src/runtime-internal/primitives/dialog-lifecycle.ts +58 -0
- package/src/runtime-internal/primitives/dice.tsx +79 -0
- package/src/runtime-internal/primitives/game-ui-provider.tsx +35 -0
- package/src/runtime-internal/primitives/game.tsx +387 -0
- package/src/runtime-internal/primitives/hand-intent-adapter.ts +147 -0
- package/src/runtime-internal/primitives/hand-surface.tsx +594 -0
- package/src/runtime-internal/primitives/index.ts +196 -0
- package/src/runtime-internal/primitives/interaction-form-binding.tsx +56 -0
- package/src/runtime-internal/primitives/interaction-submit.ts +90 -0
- package/src/runtime-internal/primitives/interaction.tsx +987 -0
- package/src/runtime-internal/primitives/phase.tsx +43 -0
- package/src/runtime-internal/primitives/player-roster.tsx +302 -0
- package/src/runtime-internal/primitives/primitive-props.tsx +101 -0
- package/src/runtime-internal/primitives/prompt.tsx +255 -0
- package/src/runtime-internal/primitives/ui.tsx +60 -0
- package/src/runtime-internal/primitives/zone.tsx +791 -0
- package/src/runtime-internal/reducer.ts +30 -0
- package/src/runtime-internal/runtime/createPluginRuntimeAPI.ts +605 -0
- package/src/runtime-internal/types/plugin-state.ts +508 -0
- package/src/runtime-internal/types/reducer-state.ts +24 -0
- package/src/runtime-internal/types/runtime-api.ts +114 -0
- package/src/runtime-internal/ui-contract.ts +519 -0
- package/src/runtime-internal/utils/card-intent-adapter.ts +546 -0
- package/src/runtime-internal/utils/interaction-inputs.ts +492 -0
- package/src/runtime-internal/utils/interaction-labels.ts +23 -0
- package/src/runtime-internal/utils/interaction-router.ts +273 -0
- package/src/runtime-internal/utils/interaction-status.ts +74 -0
- package/src/runtime-internal/workspace-contract.ts +1170 -0
- package/src/runtime.ts +34 -0
- package/src/testing/create-expect-api.ts +352 -0
- package/src/testing/create-test-runtime.ts +381 -0
- package/src/testing/definitions.ts +127 -0
- package/src/testing/index.ts +3 -0
- package/src/testing.ts +1 -0
- package/src/type-stubs/manifest-contract.d.ts +42 -0
- package/src/type-stubs/manifest-contract.js +72 -0
- package/src/type-stubs/ui-contract.d.ts +5 -0
- package/src/type-stubs/ui-contract.js +1 -0
- package/src/types/authoring-card-properties.type-test.ts +266 -0
- package/src/types/authoring.ts +1282 -0
- package/src/types/cards.ts +19 -0
- package/src/types/contracts.ts +1550 -0
- package/src/types/generated-helpers.ts +35 -0
- package/src/types/index.ts +147 -0
- package/src/types/slots.ts +11 -0
- package/src/types.ts +1 -0
- package/src/ui/components/ActionButton.tsx +97 -0
- package/src/ui/components/ActionPanel.tsx +315 -0
- package/src/ui/components/Card.tsx +378 -0
- package/src/ui/components/CardDragSurface.tsx +1076 -0
- package/src/ui/components/ChromeSuppressionContext.tsx +70 -0
- package/src/ui/components/CostDisplay.tsx +145 -0
- package/src/ui/components/DiceRoller.tsx +581 -0
- package/src/ui/components/Drawer.tsx +180 -0
- package/src/ui/components/ErrorBoundary.tsx +275 -0
- package/src/ui/components/GameEndDisplay.tsx +398 -0
- package/src/ui/components/GameSkeleton.tsx +260 -0
- package/src/ui/components/Hand.tsx +468 -0
- package/src/ui/components/HandDock.tsx +299 -0
- package/src/ui/components/HandView.tsx +441 -0
- package/src/ui/components/MobileHandTray.tsx +381 -0
- package/src/ui/components/MoreActions.tsx +143 -0
- package/src/ui/components/PhaseIndicator.tsx +341 -0
- package/src/ui/components/PlayArea.tsx +146 -0
- package/src/ui/components/PrimaryActionButton.tsx +336 -0
- package/src/ui/components/PrimaryButton.tsx +45 -0
- package/src/ui/components/ResourceCounter.tsx +270 -0
- package/src/ui/components/StagingZone.tsx +134 -0
- package/src/ui/components/ThemedButton.tsx +113 -0
- package/src/ui/components/Toast.tsx +264 -0
- package/src/ui/components/board/HexGrid.tsx +1294 -0
- package/src/ui/components/board/NetworkGraph.tsx +476 -0
- package/src/ui/components/board/SlotSystem.tsx +388 -0
- package/src/ui/components/board/SquareGrid.tsx +1165 -0
- package/src/ui/components/board/TrackBoard.tsx +496 -0
- package/src/ui/components/board/ZoneMap.tsx +448 -0
- package/src/ui/components/board/hex-board-view.ts +123 -0
- package/src/ui/components/board/index.ts +142 -0
- package/src/ui/components/board/interaction-accessibility.ts +21 -0
- package/src/ui/components/board/target-layer.ts +66 -0
- package/src/ui/components/card-render-content.type-test.ts +27 -0
- package/src/ui/components/hand-layout-math.ts +163 -0
- package/src/ui/components/hand-pointer-engine.ts +413 -0
- package/src/ui/components/index.ts +245 -0
- package/src/ui/components.ts +1 -0
- package/src/ui/defaults/components.tsx +106 -0
- package/src/ui/defaults/index.ts +8 -0
- package/src/ui/defaults.ts +1 -0
- package/src/ui/errors/ValidationError.ts +29 -0
- package/src/ui/helpers/cards.ts +19 -0
- package/src/ui/helpers/track-board.ts +211 -0
- package/src/ui/hooks/useBoardTopology.ts +316 -0
- package/src/ui/hooks/useCards.ts +10 -0
- package/src/ui/hooks/useHandCardPointer.ts +381 -0
- package/src/ui/hooks/useHandLayout.ts +378 -0
- package/src/ui/hooks/useHandPresentation.ts +121 -0
- package/src/ui/hooks/useHexBoard.ts +74 -0
- package/src/ui/hooks/useHexGrid.ts +185 -0
- package/src/ui/hooks/useIsMobile.ts +35 -0
- package/src/ui/hooks/usePanZoom.ts +278 -0
- package/src/ui/hooks/useSquareBoard.ts +124 -0
- package/src/ui/hooks/useSquareGrid.ts +328 -0
- package/src/ui/index.ts +98 -0
- package/src/ui/internal/ui/alert.tsx +51 -0
- package/src/ui/internal/ui/button.tsx +58 -0
- package/src/ui/internal/ui/dialog.tsx +134 -0
- package/src/ui/internal/ui/input.tsx +21 -0
- package/src/ui/internal/ui/label.tsx +21 -0
- package/src/ui/internal/ui/select.tsx +129 -0
- package/src/ui/internal/ui/tooltip.tsx +54 -0
- package/src/ui/internal/ui/utils.ts +5 -0
- package/src/ui/plugin-styles.css +250 -0
- package/src/ui/primitives/dialog-lifecycle.ts +58 -0
- package/src/ui/primitives/dice.tsx +79 -0
- package/src/ui/primitives/primitive-props.tsx +101 -0
- package/src/ui/theme/ThemeProvider.tsx +252 -0
- package/src/ui/theme/board.ts +61 -0
- package/src/ui/theme/css-vars.ts +105 -0
- package/src/ui/theme/derive.ts +240 -0
- package/src/ui/theme/index.ts +61 -0
- package/src/ui/theme/presets/arcade.ts +261 -0
- package/src/ui/theme/presets/studio.ts +261 -0
- package/src/ui/theme/presets/tabletop.ts +266 -0
- package/src/ui/theme/tokens.ts +392 -0
- package/src/ui/types/hex-color.ts +20 -0
- package/src/ui/types/player-state.ts +463 -0
- package/src/ui/types/tiled-board.ts +785 -0
- package/src/ui/types/visual-state.ts +137 -0
- package/src/ui.ts +1 -0
|
@@ -0,0 +1,3786 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { C as CardCollection, V as ViewCard } from './cards-Sl3b40Mv.js';
|
|
3
|
+
import { V as ViewSlotOccupant } from './slots-1GPGihk8.js';
|
|
4
|
+
import { R as ReducerBundleContract } from './bundle-TIZcw8LB.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Opaque brand applied to a runtime player identifier.
|
|
8
|
+
*
|
|
9
|
+
* Generators produce a workspace-specific `PlayerId` alias (e.g.
|
|
10
|
+
* `Brand<string, "PlayerId">` in `shared/manifest-contract.ts`). Authors
|
|
11
|
+
* obtain `PlayerId` values only through:
|
|
12
|
+
* - `q.player.order()` / `q.player.current()` (reducer queries),
|
|
13
|
+
* - engine-injected callback arguments (actions, phases, prompts),
|
|
14
|
+
* - `perPlayerKeys(...)` / entries iteration,
|
|
15
|
+
* - `asPlayerId(raw)` as an explicit escape hatch (e.g. ingress parsing).
|
|
16
|
+
*
|
|
17
|
+
* The brand is a phantom type: at runtime a `PlayerId` is just a string.
|
|
18
|
+
* Do not JSON-serialize the brand marker; it exists purely at the type
|
|
19
|
+
* level to block accidental literal comparisons such as
|
|
20
|
+
* `playerId === "player-1"`.
|
|
21
|
+
*/
|
|
22
|
+
type PlayerId = Brand<string, "PlayerId">;
|
|
23
|
+
/**
|
|
24
|
+
* Explicit conversion from a raw string to a branded `PlayerId`.
|
|
25
|
+
*
|
|
26
|
+
* Use at trust boundaries only (wire ingress, tests, fixtures). Inside
|
|
27
|
+
* reducer logic, obtain `PlayerId` values from the engine instead of
|
|
28
|
+
* constructing them yourself.
|
|
29
|
+
*/
|
|
30
|
+
declare function asPlayerId(raw: string): PlayerId;
|
|
31
|
+
/**
|
|
32
|
+
* Type guard that narrows `unknown` to `PlayerId` when the value is a
|
|
33
|
+
* non-empty string. Does not validate against a specific player roster;
|
|
34
|
+
* use `perPlayerSchema`/ingress parsing for that.
|
|
35
|
+
*/
|
|
36
|
+
declare function isPlayerId(value: unknown): value is PlayerId;
|
|
37
|
+
/**
|
|
38
|
+
* A runtime-accurate per-player map.
|
|
39
|
+
*
|
|
40
|
+
* `PerPlayer<Value>` is an opaque, ordered container whose entries are
|
|
41
|
+
* exactly the players that exist at runtime (the seats passed to
|
|
42
|
+
* `initialize`).
|
|
43
|
+
*
|
|
44
|
+
* The `__perPlayer` discriminator keeps the structural type nominal-ish
|
|
45
|
+
* without depending on a symbol (symbols do not round-trip through JSON,
|
|
46
|
+
* which this shape must).
|
|
47
|
+
*
|
|
48
|
+
* Construct with `perPlayer(ids, init)` and read with the accessors in
|
|
49
|
+
* this module; do not reach into `entries` directly unless you need
|
|
50
|
+
* ordered iteration.
|
|
51
|
+
*/
|
|
52
|
+
interface PerPlayer<Value, Id extends PlayerId = PlayerId> {
|
|
53
|
+
readonly __perPlayer: true;
|
|
54
|
+
readonly entries: ReadonlyArray<readonly [Id, Value]>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Construct a `PerPlayer<Value>` with one entry per `id` in `ids`.
|
|
58
|
+
*
|
|
59
|
+
* `ids` is treated as the authoritative runtime seat list: the returned
|
|
60
|
+
* `PerPlayer` contains exactly `ids.length` entries, in the same order.
|
|
61
|
+
* Duplicate ids throw.
|
|
62
|
+
*/
|
|
63
|
+
declare function perPlayer<Value, Id extends PlayerId = PlayerId>(ids: readonly Id[], init: (id: Id, index: number) => Value): PerPlayer<Value, Id>;
|
|
64
|
+
/** Ordered list of seat ids present in the `PerPlayer`. */
|
|
65
|
+
declare function perPlayerKeys<Id extends PlayerId>(value: PerPlayer<unknown, Id>): Id[];
|
|
66
|
+
/** Ordered list of values present in the `PerPlayer`. */
|
|
67
|
+
declare function perPlayerValues<Value>(value: PerPlayer<Value, PlayerId>): Value[];
|
|
68
|
+
/**
|
|
69
|
+
* Ordered `[id, value]` pairs. Returns the backing array as-is; callers
|
|
70
|
+
* must not mutate it.
|
|
71
|
+
*/
|
|
72
|
+
declare function perPlayerEntries<Value, Id extends PlayerId>(value: PerPlayer<Value, Id>): ReadonlyArray<readonly [Id, Value]>;
|
|
73
|
+
/** Number of seats in the `PerPlayer`. */
|
|
74
|
+
declare function perPlayerSize(value: PerPlayer<unknown, PlayerId>): number;
|
|
75
|
+
/** Whether `id` has a value. */
|
|
76
|
+
declare function perPlayerHas<Id extends PlayerId>(value: PerPlayer<unknown, Id>, id: Id): boolean;
|
|
77
|
+
/** Lookup with no fallback; returns `undefined` for missing seats. */
|
|
78
|
+
declare function perPlayerGet<Value, Id extends PlayerId>(value: PerPlayer<Value, Id>, id: Id): Value | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Lookup that throws if `id` is not present.
|
|
81
|
+
*
|
|
82
|
+
* Use when the caller has already established (via `q.player.order()`,
|
|
83
|
+
* an action context, etc.) that `id` is an active runtime seat.
|
|
84
|
+
*/
|
|
85
|
+
declare function perPlayerRequire<Value, Id extends PlayerId>(value: PerPlayer<Value, Id>, id: Id): Value;
|
|
86
|
+
/**
|
|
87
|
+
* Return a new `PerPlayer` with `id`'s value replaced (or added if the
|
|
88
|
+
* id is not present). Preserves entry order; new entries are appended.
|
|
89
|
+
*/
|
|
90
|
+
declare function perPlayerSet<Value, Id extends PlayerId>(value: PerPlayer<Value, Id>, id: Id, next: Value): PerPlayer<Value, Id>;
|
|
91
|
+
/**
|
|
92
|
+
* Return a new `PerPlayer` where each value is replaced by `f(value, id)`.
|
|
93
|
+
* Seat order is preserved.
|
|
94
|
+
*/
|
|
95
|
+
declare function perPlayerMap<Value, Next, Id extends PlayerId>(value: PerPlayer<Value, Id>, f: (v: Value, id: Id, index: number) => Next): PerPlayer<Next, Id>;
|
|
96
|
+
/**
|
|
97
|
+
* Structural check for a `PerPlayer` without a Zod schema. Useful in
|
|
98
|
+
* debug paths and as a fast pre-filter before schema validation.
|
|
99
|
+
*/
|
|
100
|
+
declare function isPerPlayer(value: unknown): value is PerPlayer<unknown>;
|
|
101
|
+
/**
|
|
102
|
+
* Options accepted by `perPlayerSchema`.
|
|
103
|
+
*
|
|
104
|
+
* Setting `players` locks the schema to an exact seat list: parse fails
|
|
105
|
+
* if the input is missing any seat or has an unknown id. Leaving
|
|
106
|
+
* `players` unset yields a schema that accepts any non-empty string as
|
|
107
|
+
* a key, which is the right default for generic SDK types.
|
|
108
|
+
*
|
|
109
|
+
* `playerIdSchema` lets callers feed a manifest-scoped Zod id schema in
|
|
110
|
+
* so parse errors carry the same message as other branded ids.
|
|
111
|
+
*/
|
|
112
|
+
type PerPlayerSchemaOptions<Id extends PlayerId> = {
|
|
113
|
+
readonly playerIdSchema?: z.ZodType<Id>;
|
|
114
|
+
readonly players?: readonly Id[];
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Build a Zod schema that validates a wire-shaped `PerPlayer<Value>`.
|
|
118
|
+
*
|
|
119
|
+
* When `options.players` is supplied the schema enforces that entries
|
|
120
|
+
* match that exact set (same cardinality, same ids, any order). This is
|
|
121
|
+
* the mechanism that catches the class of bug where a 3-player session
|
|
122
|
+
* produced a view shape the old `Record<PlayerId, T>` type claimed had
|
|
123
|
+
* a `player-4` key.
|
|
124
|
+
*/
|
|
125
|
+
declare function perPlayerSchema<Value, Id extends PlayerId = PlayerId>(valueSchema: z.ZodType<Value>, options?: PerPlayerSchemaOptions<Id>): z.ZodType<PerPlayer<Value, Id>>;
|
|
126
|
+
/**
|
|
127
|
+
* Reference to a board by its authored `baseId`, plus an optional seat
|
|
128
|
+
* for per-player boards.
|
|
129
|
+
*
|
|
130
|
+
* Replaces the old generated `"ring:player-1" | "ring:player-2" | ...`
|
|
131
|
+
* flat unions whose keys pretended to be static but were actually
|
|
132
|
+
* derived from `maxPlayers` and therefore misaligned with the runtime
|
|
133
|
+
* seat list.
|
|
134
|
+
*
|
|
135
|
+
* The discriminant is the *presence* of `seat`, not a `scope` field, so
|
|
136
|
+
* authors can destructure and pass the ref directly without needing a
|
|
137
|
+
* discriminator check for shared boards.
|
|
138
|
+
*/
|
|
139
|
+
type BoardRef<BaseId extends string = string, Id extends PlayerId = PlayerId> = SharedBoardRef<BaseId> | PerPlayerBoardRef<BaseId, Id>;
|
|
140
|
+
interface SharedBoardRef<BaseId extends string = string> {
|
|
141
|
+
readonly baseId: BaseId;
|
|
142
|
+
readonly seat?: undefined;
|
|
143
|
+
}
|
|
144
|
+
interface PerPlayerBoardRef<BaseId extends string = string, Id extends PlayerId = PlayerId> {
|
|
145
|
+
readonly baseId: BaseId;
|
|
146
|
+
readonly seat: Id;
|
|
147
|
+
}
|
|
148
|
+
/** Construct a shared board ref. */
|
|
149
|
+
declare function sharedBoardRef<BaseId extends string>(baseId: BaseId): SharedBoardRef<BaseId>;
|
|
150
|
+
/** Construct a per-player board ref. */
|
|
151
|
+
declare function perPlayerBoardRef<BaseId extends string, Id extends PlayerId>(baseId: BaseId, seat: Id): PerPlayerBoardRef<BaseId, Id>;
|
|
152
|
+
/**
|
|
153
|
+
* Construct a `BoardRef` without knowing the scope ahead of time. Pass
|
|
154
|
+
* `seat` for per-player boards; omit for shared boards.
|
|
155
|
+
*/
|
|
156
|
+
declare function boardRef<BaseId extends string, Id extends PlayerId>(baseId: BaseId, seat?: Id): BoardRef<BaseId, Id>;
|
|
157
|
+
/** Stable string key for Maps/Records keyed by a `BoardRef`. */
|
|
158
|
+
declare function boardRefKey(ref: BoardRef): string;
|
|
159
|
+
/**
|
|
160
|
+
* Inverse of `boardRefKey`. Parses `"base"` as a shared ref and
|
|
161
|
+
* `"base:player-N"` as a per-player ref. Returns `null` for malformed
|
|
162
|
+
* input.
|
|
163
|
+
*/
|
|
164
|
+
declare function parseBoardRefKey(key: string): BoardRef | null;
|
|
165
|
+
/**
|
|
166
|
+
* Zod schema for a `BoardRef` with free-form base and seat ids.
|
|
167
|
+
*
|
|
168
|
+
* Feed a manifest-scoped `baseIdSchema` and `playerIdSchema` to bind
|
|
169
|
+
* the ref to a specific workspace.
|
|
170
|
+
*/
|
|
171
|
+
declare function boardRefSchema<BaseId extends string = string, Id extends PlayerId = PlayerId>(options?: {
|
|
172
|
+
readonly baseIdSchema?: z.ZodType<BaseId>;
|
|
173
|
+
readonly playerIdSchema?: z.ZodType<Id>;
|
|
174
|
+
}): z.ZodType<BoardRef<BaseId, Id>>;
|
|
175
|
+
/** True when `ref` targets a shared board (no seat). */
|
|
176
|
+
declare function isSharedBoardRef<BaseId extends string>(ref: BoardRef<BaseId, PlayerId>): ref is SharedBoardRef<BaseId>;
|
|
177
|
+
/** True when `ref` targets a per-player board (has a seat). */
|
|
178
|
+
declare function isPerPlayerBoardRef<BaseId extends string, Id extends PlayerId>(ref: BoardRef<BaseId, Id>): ref is PerPlayerBoardRef<BaseId, Id>;
|
|
179
|
+
|
|
180
|
+
type RuntimeScalar = boolean | number | string | null;
|
|
181
|
+
interface RuntimeRecord {
|
|
182
|
+
[key: string]: RuntimePayload | undefined;
|
|
183
|
+
}
|
|
184
|
+
type RuntimePayload = RuntimeScalar | RuntimePayload[] | RuntimeRecord;
|
|
185
|
+
type SchemaLike<Output> = z.ZodType<Output>;
|
|
186
|
+
type AnySchema = z.ZodTypeAny;
|
|
187
|
+
type StringKeyOf<T> = Extract<keyof T, string>;
|
|
188
|
+
type Brand<Value, Name extends string> = Value & {
|
|
189
|
+
readonly __brand: Name;
|
|
190
|
+
};
|
|
191
|
+
type RuntimeHandVisibilityMode = "all" | "ownerOnly" | "public" | "hidden";
|
|
192
|
+
type RuntimeDeckMap = Record<string, string[]>;
|
|
193
|
+
type RuntimeHandMap = Record<string, PerPlayer<string[]>>;
|
|
194
|
+
type RuntimeZoneMap = {
|
|
195
|
+
shared: Record<string, string[]>;
|
|
196
|
+
perPlayer: Record<string, PerPlayer<string[]>>;
|
|
197
|
+
visibility: Record<string, RuntimeHandVisibilityMode>;
|
|
198
|
+
cardSetIdsByZoneId?: Record<string, readonly string[]>;
|
|
199
|
+
};
|
|
200
|
+
type RuntimeOwnerMap = Record<string, string | null>;
|
|
201
|
+
type RuntimeResourceMap = PerPlayer<RuntimeRecord>;
|
|
202
|
+
type RuntimeBoardSpaceState = {
|
|
203
|
+
id: string;
|
|
204
|
+
name?: string | null;
|
|
205
|
+
typeId?: string | null;
|
|
206
|
+
fields: RuntimeRecord;
|
|
207
|
+
zoneId?: string | null;
|
|
208
|
+
};
|
|
209
|
+
type RuntimeBoardRelationState = {
|
|
210
|
+
id?: string | null;
|
|
211
|
+
typeId: string;
|
|
212
|
+
fromSpaceId: string;
|
|
213
|
+
toSpaceId: string;
|
|
214
|
+
directed: boolean;
|
|
215
|
+
fields: RuntimeRecord;
|
|
216
|
+
};
|
|
217
|
+
type RuntimeBoardContainerState = {
|
|
218
|
+
id: string;
|
|
219
|
+
name: string;
|
|
220
|
+
host: {
|
|
221
|
+
type: "board";
|
|
222
|
+
} | {
|
|
223
|
+
type: "space";
|
|
224
|
+
spaceId: string;
|
|
225
|
+
};
|
|
226
|
+
allowedCardSetIds?: readonly string[];
|
|
227
|
+
zoneId: string;
|
|
228
|
+
fields: RuntimeRecord;
|
|
229
|
+
};
|
|
230
|
+
type RuntimeBoardCompatibilityState = {
|
|
231
|
+
spaces: Record<string, RuntimeBoardSpaceState>;
|
|
232
|
+
relations: RuntimeBoardRelationState[];
|
|
233
|
+
containers: Record<string, RuntimeBoardContainerState>;
|
|
234
|
+
};
|
|
235
|
+
type RuntimeBoardBaseState = {
|
|
236
|
+
id: string;
|
|
237
|
+
baseId?: string;
|
|
238
|
+
layout: "generic" | "hex" | "square";
|
|
239
|
+
typeId?: string | null;
|
|
240
|
+
scope: "shared" | "perPlayer";
|
|
241
|
+
playerId?: string | null;
|
|
242
|
+
templateId?: string | null;
|
|
243
|
+
fields: RuntimeRecord;
|
|
244
|
+
};
|
|
245
|
+
type RuntimeGenericBoardState = RuntimeBoardBaseState & {
|
|
246
|
+
layout: "generic";
|
|
247
|
+
} & RuntimeBoardCompatibilityState;
|
|
248
|
+
type RuntimeHexSpaceState = RuntimeBoardSpaceState & {
|
|
249
|
+
q: number;
|
|
250
|
+
r: number;
|
|
251
|
+
};
|
|
252
|
+
type RuntimeSquareSpaceState = RuntimeBoardSpaceState & {
|
|
253
|
+
row: number;
|
|
254
|
+
col: number;
|
|
255
|
+
};
|
|
256
|
+
type RuntimeTiledEdgeState = {
|
|
257
|
+
id: string;
|
|
258
|
+
spaceIds: readonly string[];
|
|
259
|
+
typeId?: string | null;
|
|
260
|
+
label?: string | null;
|
|
261
|
+
ownerId?: string | null;
|
|
262
|
+
fields: RuntimeRecord;
|
|
263
|
+
};
|
|
264
|
+
type RuntimeTiledVertexState = {
|
|
265
|
+
id: string;
|
|
266
|
+
spaceIds: readonly string[];
|
|
267
|
+
typeId?: string | null;
|
|
268
|
+
label?: string | null;
|
|
269
|
+
ownerId?: string | null;
|
|
270
|
+
fields: RuntimeRecord;
|
|
271
|
+
};
|
|
272
|
+
type RuntimeHexEdgeState = RuntimeTiledEdgeState;
|
|
273
|
+
type RuntimeHexVertexState = RuntimeTiledVertexState;
|
|
274
|
+
type RuntimeSquareEdgeState = RuntimeTiledEdgeState;
|
|
275
|
+
type RuntimeSquareVertexState = RuntimeTiledVertexState;
|
|
276
|
+
type RuntimeHexOrientation = "pointy-top" | "flat-top";
|
|
277
|
+
type RuntimeTiledBoardBaseState = RuntimeBoardBaseState & {
|
|
278
|
+
layout: "hex" | "square";
|
|
279
|
+
relations: RuntimeBoardRelationState[];
|
|
280
|
+
containers: Record<string, RuntimeBoardContainerState>;
|
|
281
|
+
edges: RuntimeTiledEdgeState[];
|
|
282
|
+
vertices: RuntimeTiledVertexState[];
|
|
283
|
+
};
|
|
284
|
+
type RuntimeHexBoardState = RuntimeTiledBoardBaseState & {
|
|
285
|
+
layout: "hex";
|
|
286
|
+
spaces: Record<string, RuntimeHexSpaceState>;
|
|
287
|
+
orientation: RuntimeHexOrientation;
|
|
288
|
+
edges: RuntimeHexEdgeState[];
|
|
289
|
+
vertices: RuntimeHexVertexState[];
|
|
290
|
+
};
|
|
291
|
+
type RuntimeSquareBoardState = RuntimeTiledBoardBaseState & {
|
|
292
|
+
layout: "square";
|
|
293
|
+
spaces: Record<string, RuntimeSquareSpaceState>;
|
|
294
|
+
edges: RuntimeSquareEdgeState[];
|
|
295
|
+
vertices: RuntimeSquareVertexState[];
|
|
296
|
+
};
|
|
297
|
+
type RuntimeTiledBoardState = RuntimeHexBoardState | RuntimeSquareBoardState;
|
|
298
|
+
type RuntimeBoardState = RuntimeGenericBoardState | RuntimeTiledBoardState;
|
|
299
|
+
type RuntimeBoardCollections = {
|
|
300
|
+
byId: Record<string, RuntimeBoardState>;
|
|
301
|
+
hex: Record<string, RuntimeHexBoardState>;
|
|
302
|
+
square: Record<string, RuntimeSquareBoardState>;
|
|
303
|
+
/** Structured board buckets used by manifest table schemas (empty when unused). */
|
|
304
|
+
network: Record<string, RuntimeRecord>;
|
|
305
|
+
track: Record<string, RuntimeRecord>;
|
|
306
|
+
};
|
|
307
|
+
type RuntimeCardVisibility = {
|
|
308
|
+
faceUp: boolean;
|
|
309
|
+
visibleTo?: string[] | null;
|
|
310
|
+
};
|
|
311
|
+
type RuntimeCardData = {
|
|
312
|
+
componentType?: string;
|
|
313
|
+
id: string;
|
|
314
|
+
cardSetId: string;
|
|
315
|
+
cardType: string;
|
|
316
|
+
name?: string;
|
|
317
|
+
text?: string;
|
|
318
|
+
properties: RuntimeRecord;
|
|
319
|
+
};
|
|
320
|
+
type RuntimePieceData = {
|
|
321
|
+
componentType?: string;
|
|
322
|
+
id: string;
|
|
323
|
+
pieceTypeId: string;
|
|
324
|
+
pieceName?: string | null;
|
|
325
|
+
ownerId?: string | null;
|
|
326
|
+
properties: RuntimeRecord;
|
|
327
|
+
};
|
|
328
|
+
type RuntimeDieData = {
|
|
329
|
+
componentType?: string;
|
|
330
|
+
id: string;
|
|
331
|
+
dieTypeId: string;
|
|
332
|
+
dieName?: string | null;
|
|
333
|
+
ownerId?: string | null;
|
|
334
|
+
sides: number;
|
|
335
|
+
value?: number | null;
|
|
336
|
+
properties: RuntimeRecord;
|
|
337
|
+
};
|
|
338
|
+
type RuntimeSlotHostRef = {
|
|
339
|
+
kind: "piece";
|
|
340
|
+
id: string;
|
|
341
|
+
} | {
|
|
342
|
+
kind: "die";
|
|
343
|
+
id: string;
|
|
344
|
+
};
|
|
345
|
+
type RuntimeComponentLocation = {
|
|
346
|
+
type: "Detached";
|
|
347
|
+
} | {
|
|
348
|
+
type: "InDeck";
|
|
349
|
+
deckId: string;
|
|
350
|
+
playedBy: string | null;
|
|
351
|
+
position?: number | null;
|
|
352
|
+
} | {
|
|
353
|
+
type: "InHand";
|
|
354
|
+
handId: string;
|
|
355
|
+
playerId: string;
|
|
356
|
+
position?: number | null;
|
|
357
|
+
} | {
|
|
358
|
+
type: "InZone";
|
|
359
|
+
zoneId: string;
|
|
360
|
+
playedBy?: string | null;
|
|
361
|
+
position?: number | null;
|
|
362
|
+
} | {
|
|
363
|
+
type: "OnSpace";
|
|
364
|
+
boardId: string;
|
|
365
|
+
spaceId: string;
|
|
366
|
+
position?: number | null;
|
|
367
|
+
} | {
|
|
368
|
+
type: "InContainer";
|
|
369
|
+
boardId: string;
|
|
370
|
+
containerId: string;
|
|
371
|
+
position?: number | null;
|
|
372
|
+
} | {
|
|
373
|
+
type: "OnEdge";
|
|
374
|
+
boardId: string;
|
|
375
|
+
edgeId: string;
|
|
376
|
+
position?: number | null;
|
|
377
|
+
} | {
|
|
378
|
+
type: "OnVertex";
|
|
379
|
+
boardId: string;
|
|
380
|
+
vertexId: string;
|
|
381
|
+
position?: number | null;
|
|
382
|
+
} | {
|
|
383
|
+
type: "InSlot";
|
|
384
|
+
host: RuntimeSlotHostRef;
|
|
385
|
+
slotId: string;
|
|
386
|
+
position?: number | null;
|
|
387
|
+
};
|
|
388
|
+
type RuntimeComponentLocationMap = Record<string, RuntimeComponentLocation>;
|
|
389
|
+
type RuntimeVisibilityMap = Record<string, RuntimeCardVisibility>;
|
|
390
|
+
type RuntimeTableRecord = {
|
|
391
|
+
playerOrder: string[];
|
|
392
|
+
zones: RuntimeZoneMap;
|
|
393
|
+
decks: RuntimeDeckMap;
|
|
394
|
+
hands: RuntimeHandMap;
|
|
395
|
+
handVisibility: Record<string, RuntimeHandVisibilityMode>;
|
|
396
|
+
cards: Record<string, RuntimeCardData>;
|
|
397
|
+
pieces: Record<string, RuntimePieceData>;
|
|
398
|
+
componentLocations: RuntimeComponentLocationMap;
|
|
399
|
+
ownerOfCard: RuntimeOwnerMap;
|
|
400
|
+
visibility: RuntimeVisibilityMap;
|
|
401
|
+
resources: RuntimeResourceMap;
|
|
402
|
+
boards: RuntimeBoardCollections;
|
|
403
|
+
dice: Record<string, RuntimeDieData>;
|
|
404
|
+
};
|
|
405
|
+
|
|
406
|
+
type TableOfState<State> = State extends {
|
|
407
|
+
table: infer Table;
|
|
408
|
+
} ? Table : never;
|
|
409
|
+
type TableOfManifest<Manifest> = Manifest extends GeneratedManifestContractLike<infer Table> ? Table : never;
|
|
410
|
+
type PhaseNameOfState<State> = State extends {
|
|
411
|
+
flow: {
|
|
412
|
+
currentPhase: infer PhaseName;
|
|
413
|
+
};
|
|
414
|
+
} ? Extract<PhaseName, string> : never;
|
|
415
|
+
type PhaseNameOfManifest<Manifest> = Manifest extends {
|
|
416
|
+
literals: {
|
|
417
|
+
phaseNames: readonly (infer PhaseName)[];
|
|
418
|
+
};
|
|
419
|
+
} ? Extract<PhaseName, string> : never;
|
|
420
|
+
type PlayerIdOfTable<Table> = Table extends {
|
|
421
|
+
playerOrder: readonly (infer PlayerId)[];
|
|
422
|
+
} ? Extract<PlayerId, string> : never;
|
|
423
|
+
type PlayerIdOfManifest<Manifest> = Manifest extends {
|
|
424
|
+
literals: {
|
|
425
|
+
playerIds: readonly (infer PlayerId)[];
|
|
426
|
+
};
|
|
427
|
+
} ? Extract<PlayerId, string> : string;
|
|
428
|
+
type PlayerIdOfState<State> = PlayerIdOfTable<TableOfState<State>>;
|
|
429
|
+
/**
|
|
430
|
+
* Manifest-declared resource id union for a runtime table.
|
|
431
|
+
*
|
|
432
|
+
* Derived from the shape of `table.resources`, which the generated
|
|
433
|
+
* manifest contract seeds as `PerPlayer<Record<ResourceId, number>>`.
|
|
434
|
+
* The helper peeks inside the `PerPlayer` wrapper to surface the
|
|
435
|
+
* resource-id keys without forcing callers to remember the wrapper.
|
|
436
|
+
*/
|
|
437
|
+
type ResourceIdOfTable<Table> = Table extends {
|
|
438
|
+
resources: infer Resources;
|
|
439
|
+
} ? ValueOfPerPlayer<Resources> extends infer PerPlayerValue ? PerPlayerValue extends Record<string, unknown> ? StringKeyOf<PerPlayerValue> : never : never : never;
|
|
440
|
+
/**
|
|
441
|
+
* Per-player balance shape for a runtime table. Strips the `PerPlayer`
|
|
442
|
+
* wrapper around `table.resources` so callers receive the manifest-typed
|
|
443
|
+
* record directly (e.g. `Record<ResourceId, number>`).
|
|
444
|
+
*/
|
|
445
|
+
type ResourceBalancesOfTable<Table> = Table extends {
|
|
446
|
+
resources: infer Resources;
|
|
447
|
+
} ? ValueOfPerPlayer<Resources> extends infer PerPlayerValue ? PerPlayerValue extends Record<string, unknown> ? PerPlayerValue : never : never : never;
|
|
448
|
+
/**
|
|
449
|
+
* Per-player resource counts: a partial `Record<ResourceId, number>`.
|
|
450
|
+
*
|
|
451
|
+
* Used as the input shape for {@link ReducerOps.addResources},
|
|
452
|
+
* {@link ReducerOps.spendResources}, and {@link ReducerOps.transferResources}.
|
|
453
|
+
*/
|
|
454
|
+
type ResourceAmountsOfTable<Table> = Partial<Record<ResourceIdOfTable<Table>, number>>;
|
|
455
|
+
type PhaseStateOfState<State> = State extends {
|
|
456
|
+
phase: infer PhaseState;
|
|
457
|
+
} ? PhaseState : never;
|
|
458
|
+
type PublicStateOfState<State> = State extends {
|
|
459
|
+
publicState: infer PublicState;
|
|
460
|
+
} ? PublicState : never;
|
|
461
|
+
type HiddenStateOfState<State> = State extends {
|
|
462
|
+
hiddenState: infer HiddenState;
|
|
463
|
+
} ? HiddenState : never;
|
|
464
|
+
type PrivateStateOfState<State> = State extends {
|
|
465
|
+
privateState: Record<string, infer PrivateState>;
|
|
466
|
+
} ? PrivateState : never;
|
|
467
|
+
type DeckIdOfTable<Table> = Table extends {
|
|
468
|
+
decks: infer Decks;
|
|
469
|
+
} ? StringKeyOf<Decks> : never;
|
|
470
|
+
type HandIdOfTable<Table> = Table extends {
|
|
471
|
+
hands: infer Hands;
|
|
472
|
+
} ? StringKeyOf<Hands> : never;
|
|
473
|
+
type CardIdOfTable<Table> = Table extends {
|
|
474
|
+
cards: infer Cards;
|
|
475
|
+
} ? StringKeyOf<Cards> : never;
|
|
476
|
+
type CardTypeOfTable<Table> = Table extends {
|
|
477
|
+
cards: Record<string, {
|
|
478
|
+
cardType: infer CardType;
|
|
479
|
+
}>;
|
|
480
|
+
} ? Extract<CardType, string> : string;
|
|
481
|
+
type DeckIdOfState<State> = DeckIdOfTable<TableOfState<State>>;
|
|
482
|
+
type HandIdOfState<State> = HandIdOfTable<TableOfState<State>>;
|
|
483
|
+
type CardIdOfState<State> = CardIdOfTable<TableOfState<State>>;
|
|
484
|
+
type CardTypeOfState<State> = CardTypeOfTable<TableOfState<State>>;
|
|
485
|
+
type CardIdOfManifest<Manifest> = Manifest extends {
|
|
486
|
+
literals: {
|
|
487
|
+
cardIds: readonly (infer CardId)[];
|
|
488
|
+
};
|
|
489
|
+
} ? Extract<CardId, string> : string;
|
|
490
|
+
type SharedZoneIdOfTable<Table> = DeckIdOfTable<Table>;
|
|
491
|
+
type PlayerZoneIdOfTable<Table> = HandIdOfTable<Table>;
|
|
492
|
+
type BoardMapOfTable<Table> = Table extends {
|
|
493
|
+
boards: {
|
|
494
|
+
byId: infer Boards;
|
|
495
|
+
};
|
|
496
|
+
} ? Boards : never;
|
|
497
|
+
type BoardIdOfTable<Table> = StringKeyOf<BoardMapOfTable<Table>>;
|
|
498
|
+
type BoardStateOfTable<Table, BoardId extends BoardIdOfTable<Table>> = BoardMapOfTable<Table>[BoardId];
|
|
499
|
+
type BoardTypeIdOfTable<Table> = BoardStateOfTable<Table, BoardIdOfTable<Table>> extends {
|
|
500
|
+
typeId?: infer BoardTypeId | null;
|
|
501
|
+
} ? Extract<BoardTypeId, string> : never;
|
|
502
|
+
type TiledBoardIdOfTable<Table> = {
|
|
503
|
+
[BoardId in BoardIdOfTable<Table>]: BoardStateOfTable<Table, BoardId> extends {
|
|
504
|
+
layout: "hex" | "square";
|
|
505
|
+
} ? BoardId : never;
|
|
506
|
+
}[BoardIdOfTable<Table>];
|
|
507
|
+
type TiledBoardStateOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends infer BoardState ? BoardState extends {
|
|
508
|
+
layout: "hex" | "square";
|
|
509
|
+
spaces: Record<string, unknown>;
|
|
510
|
+
edges: readonly {
|
|
511
|
+
id: string;
|
|
512
|
+
}[];
|
|
513
|
+
vertices: readonly {
|
|
514
|
+
id: string;
|
|
515
|
+
}[];
|
|
516
|
+
} ? BoardState : never : never;
|
|
517
|
+
type HexBoardIdOfTable<Table> = {
|
|
518
|
+
[BoardId in BoardIdOfTable<Table>]: BoardStateOfTable<Table, BoardId> extends {
|
|
519
|
+
layout: "hex";
|
|
520
|
+
} ? BoardId : never;
|
|
521
|
+
}[BoardIdOfTable<Table>];
|
|
522
|
+
type HexBoardStateOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends infer BoardState ? BoardState extends {
|
|
523
|
+
layout: "hex";
|
|
524
|
+
spaces: Record<string, unknown>;
|
|
525
|
+
edges: readonly {
|
|
526
|
+
id: string;
|
|
527
|
+
}[];
|
|
528
|
+
vertices: readonly {
|
|
529
|
+
id: string;
|
|
530
|
+
}[];
|
|
531
|
+
} ? BoardState : never : never;
|
|
532
|
+
type SquareBoardIdOfTable<Table> = {
|
|
533
|
+
[BoardId in BoardIdOfTable<Table>]: BoardStateOfTable<Table, BoardId> extends {
|
|
534
|
+
layout: "square";
|
|
535
|
+
} ? BoardId : never;
|
|
536
|
+
}[BoardIdOfTable<Table>];
|
|
537
|
+
type SquareBoardStateOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends infer BoardState ? BoardState extends {
|
|
538
|
+
layout: "square";
|
|
539
|
+
spaces: Record<string, unknown>;
|
|
540
|
+
edges: readonly {
|
|
541
|
+
id: string;
|
|
542
|
+
}[];
|
|
543
|
+
vertices: readonly {
|
|
544
|
+
id: string;
|
|
545
|
+
}[];
|
|
546
|
+
} ? BoardState : never : never;
|
|
547
|
+
type SpaceIdOfTable<Table, BoardId extends BoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends {
|
|
548
|
+
spaces: infer Spaces;
|
|
549
|
+
} ? StringKeyOf<Spaces> : never;
|
|
550
|
+
type SpaceTypeIdOfTable<Table, BoardId extends BoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends {
|
|
551
|
+
spaces: infer Spaces extends Record<string, unknown>;
|
|
552
|
+
} ? Spaces[StringKeyOf<Spaces>] extends {
|
|
553
|
+
typeId?: infer SpaceTypeId | null;
|
|
554
|
+
} ? Extract<SpaceTypeId, string> : never : never;
|
|
555
|
+
type BoardContainerIdOfTable<Table, BoardId extends BoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends {
|
|
556
|
+
containers: infer Containers;
|
|
557
|
+
} ? StringKeyOf<Containers> : never;
|
|
558
|
+
type RelationTypeIdOfTable<Table, BoardId extends BoardIdOfTable<Table>> = BoardStateOfTable<Table, BoardId> extends {
|
|
559
|
+
relations: readonly (infer Relation)[];
|
|
560
|
+
} ? Relation extends {
|
|
561
|
+
typeId: infer RelationTypeId;
|
|
562
|
+
} ? Extract<RelationTypeId, string> : never : never;
|
|
563
|
+
type TiledSpaceIdOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
564
|
+
spaces: infer Spaces;
|
|
565
|
+
} ? StringKeyOf<Spaces> : never;
|
|
566
|
+
type HexSpaceIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
567
|
+
spaces: infer Spaces;
|
|
568
|
+
} ? StringKeyOf<Spaces> : never;
|
|
569
|
+
type SquareSpaceIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
570
|
+
spaces: infer Spaces;
|
|
571
|
+
} ? StringKeyOf<Spaces> : never;
|
|
572
|
+
type HexSpaceTypeIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
573
|
+
spaces: infer Spaces extends Record<string, unknown>;
|
|
574
|
+
} ? Spaces[StringKeyOf<Spaces>] extends {
|
|
575
|
+
typeId?: infer SpaceTypeId | null;
|
|
576
|
+
} ? Extract<SpaceTypeId, string> : never : never;
|
|
577
|
+
type SquareSpaceTypeIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
578
|
+
spaces: infer Spaces extends Record<string, unknown>;
|
|
579
|
+
} ? Spaces[StringKeyOf<Spaces>] extends {
|
|
580
|
+
typeId?: infer SpaceTypeId | null;
|
|
581
|
+
} ? Extract<SpaceTypeId, string> : never : never;
|
|
582
|
+
type TiledEdgeIdOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
583
|
+
edges: readonly (infer Edge)[];
|
|
584
|
+
} ? Edge extends {
|
|
585
|
+
id: infer EdgeId;
|
|
586
|
+
} ? Extract<EdgeId, string> : never : never;
|
|
587
|
+
type HexEdgeIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
588
|
+
edges: readonly (infer Edge)[];
|
|
589
|
+
} ? Edge extends {
|
|
590
|
+
id: infer EdgeId;
|
|
591
|
+
} ? Extract<EdgeId, string> : never : never;
|
|
592
|
+
type SquareEdgeIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
593
|
+
edges: readonly (infer Edge)[];
|
|
594
|
+
} ? Edge extends {
|
|
595
|
+
id: infer EdgeId;
|
|
596
|
+
} ? Extract<EdgeId, string> : never : never;
|
|
597
|
+
/**
|
|
598
|
+
* Edge record on a tiled board narrowed to a specific `EdgeId` literal.
|
|
599
|
+
*
|
|
600
|
+
* The generated board state stores edges as a single array element type
|
|
601
|
+
* `{ id: <union-of-edge-ids>, spaceIds, typeId, fields, ... }`. Looking up an
|
|
602
|
+
* edge by id should return a record whose `id` is narrowed to the literal
|
|
603
|
+
* that was requested, not the entire edge-id union.
|
|
604
|
+
*/
|
|
605
|
+
type TiledEdgeStateOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>, EdgeId extends TiledEdgeIdOfTable<Table, BoardId>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
606
|
+
edges: readonly (infer Edge)[];
|
|
607
|
+
} ? Edge extends {
|
|
608
|
+
id: string;
|
|
609
|
+
} ? Omit<Edge, "id"> & {
|
|
610
|
+
id: EdgeId;
|
|
611
|
+
} : never : never;
|
|
612
|
+
type TiledEdgeTypeIdOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
613
|
+
edges: readonly (infer Edge)[];
|
|
614
|
+
} ? Edge extends {
|
|
615
|
+
typeId?: infer EdgeTypeId | null;
|
|
616
|
+
} ? Extract<EdgeTypeId, string> : never : never;
|
|
617
|
+
type HexEdgeTypeIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
618
|
+
edges: readonly (infer Edge)[];
|
|
619
|
+
} ? Edge extends {
|
|
620
|
+
typeId?: infer EdgeTypeId | null;
|
|
621
|
+
} ? Extract<EdgeTypeId, string> : never : never;
|
|
622
|
+
type SquareEdgeTypeIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
623
|
+
edges: readonly (infer Edge)[];
|
|
624
|
+
} ? Edge extends {
|
|
625
|
+
typeId?: infer EdgeTypeId | null;
|
|
626
|
+
} ? Extract<EdgeTypeId, string> : never : never;
|
|
627
|
+
type TiledVertexIdOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
628
|
+
vertices: readonly (infer Vertex)[];
|
|
629
|
+
} ? Vertex extends {
|
|
630
|
+
id: infer VertexId;
|
|
631
|
+
} ? Extract<VertexId, string> : never : never;
|
|
632
|
+
type HexVertexIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
633
|
+
vertices: readonly (infer Vertex)[];
|
|
634
|
+
} ? Vertex extends {
|
|
635
|
+
id: infer VertexId;
|
|
636
|
+
} ? Extract<VertexId, string> : never : never;
|
|
637
|
+
type SquareVertexIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
638
|
+
vertices: readonly (infer Vertex)[];
|
|
639
|
+
} ? Vertex extends {
|
|
640
|
+
id: infer VertexId;
|
|
641
|
+
} ? Extract<VertexId, string> : never : never;
|
|
642
|
+
/**
|
|
643
|
+
* Vertex record on a tiled board narrowed to a specific `VertexId` literal.
|
|
644
|
+
* See {@link TiledEdgeStateOfTable} for rationale.
|
|
645
|
+
*/
|
|
646
|
+
type TiledVertexStateOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>, VertexId extends TiledVertexIdOfTable<Table, BoardId>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
647
|
+
vertices: readonly (infer Vertex)[];
|
|
648
|
+
} ? Vertex extends {
|
|
649
|
+
id: string;
|
|
650
|
+
} ? Omit<Vertex, "id"> & {
|
|
651
|
+
id: VertexId;
|
|
652
|
+
} : never : never;
|
|
653
|
+
type TiledVertexTypeIdOfTable<Table, BoardId extends TiledBoardIdOfTable<Table>> = TiledBoardStateOfTable<Table, BoardId> extends {
|
|
654
|
+
vertices: readonly (infer Vertex)[];
|
|
655
|
+
} ? Vertex extends {
|
|
656
|
+
typeId?: infer VertexTypeId | null;
|
|
657
|
+
} ? Extract<VertexTypeId, string> : never : never;
|
|
658
|
+
type HexVertexTypeIdOfTable<Table, BoardId extends HexBoardIdOfTable<Table>> = HexBoardStateOfTable<Table, BoardId> extends {
|
|
659
|
+
vertices: readonly (infer Vertex)[];
|
|
660
|
+
} ? Vertex extends {
|
|
661
|
+
typeId?: infer VertexTypeId | null;
|
|
662
|
+
} ? Extract<VertexTypeId, string> : never : never;
|
|
663
|
+
type SquareVertexTypeIdOfTable<Table, BoardId extends SquareBoardIdOfTable<Table>> = SquareBoardStateOfTable<Table, BoardId> extends {
|
|
664
|
+
vertices: readonly (infer Vertex)[];
|
|
665
|
+
} ? Vertex extends {
|
|
666
|
+
typeId?: infer VertexTypeId | null;
|
|
667
|
+
} ? Extract<VertexTypeId, string> : never : never;
|
|
668
|
+
type TiledSpaceMap<Table, BoardId extends TiledBoardIdOfTable<Table>, Value> = Partial<Record<TiledSpaceIdOfTable<Table, BoardId>, Value>>;
|
|
669
|
+
type TiledEdgeMap<Table, BoardId extends TiledBoardIdOfTable<Table>, Value> = Partial<Record<TiledEdgeIdOfTable<Table, BoardId>, Value>>;
|
|
670
|
+
type TiledVertexMap<Table, BoardId extends TiledBoardIdOfTable<Table>, Value> = Partial<Record<TiledVertexIdOfTable<Table, BoardId>, Value>>;
|
|
671
|
+
type ComponentIdOfTable<Table> = Table extends {
|
|
672
|
+
componentLocations: infer ComponentLocations;
|
|
673
|
+
} ? StringKeyOf<ComponentLocations> : never;
|
|
674
|
+
type SharedZoneIdOfManifest<Manifest> = Manifest extends {
|
|
675
|
+
literals: {
|
|
676
|
+
sharedZoneIds: readonly (infer ZoneId)[];
|
|
677
|
+
};
|
|
678
|
+
} ? Extract<ZoneId, string> : string;
|
|
679
|
+
type PlayerZoneIdOfManifest<Manifest> = Manifest extends {
|
|
680
|
+
literals: {
|
|
681
|
+
playerZoneIds: readonly (infer ZoneId)[];
|
|
682
|
+
};
|
|
683
|
+
} ? Extract<ZoneId, string> : string;
|
|
684
|
+
type SharedZoneIdOfState<State> = DeckIdOfState<State>;
|
|
685
|
+
type PlayerZoneIdOfState<State> = HandIdOfState<State>;
|
|
686
|
+
type BoardIdOfManifest<Manifest> = Manifest extends {
|
|
687
|
+
literals: {
|
|
688
|
+
boardIds: readonly (infer BoardId)[];
|
|
689
|
+
};
|
|
690
|
+
} ? Extract<BoardId, string> : string;
|
|
691
|
+
type BoardLayoutOfManifest<Manifest> = Manifest extends {
|
|
692
|
+
literals: {
|
|
693
|
+
boardLayouts: readonly (infer BoardLayout)[];
|
|
694
|
+
};
|
|
695
|
+
} ? Extract<BoardLayout, string> : "generic" | "hex" | "square";
|
|
696
|
+
type BoardTypeIdOfManifest<Manifest> = Manifest extends {
|
|
697
|
+
literals: {
|
|
698
|
+
boardTypeIds: readonly (infer BoardTypeId)[];
|
|
699
|
+
};
|
|
700
|
+
} ? Extract<BoardTypeId, string> : string;
|
|
701
|
+
type BoardBaseIdOfManifest<Manifest> = Manifest extends {
|
|
702
|
+
literals: {
|
|
703
|
+
boardBaseIds: readonly (infer BoardBaseId)[];
|
|
704
|
+
};
|
|
705
|
+
} ? Extract<BoardBaseId, string> : string;
|
|
706
|
+
type RelationTypeIdOfManifest<Manifest> = Manifest extends {
|
|
707
|
+
literals: {
|
|
708
|
+
relationTypeIds: readonly (infer RelationTypeId)[];
|
|
709
|
+
};
|
|
710
|
+
} ? Extract<RelationTypeId, string> : string;
|
|
711
|
+
type BoardContainerIdOfManifest<Manifest> = Manifest extends {
|
|
712
|
+
literals: {
|
|
713
|
+
boardContainerIds: readonly (infer ContainerId)[];
|
|
714
|
+
};
|
|
715
|
+
} ? Extract<ContainerId, string> : string;
|
|
716
|
+
type EdgeTypeIdOfManifest<Manifest> = Manifest extends {
|
|
717
|
+
literals: {
|
|
718
|
+
edgeTypeIds: readonly (infer EdgeTypeId)[];
|
|
719
|
+
};
|
|
720
|
+
} ? Extract<EdgeTypeId, string> : string;
|
|
721
|
+
type VertexTypeIdOfManifest<Manifest> = Manifest extends {
|
|
722
|
+
literals: {
|
|
723
|
+
vertexTypeIds: readonly (infer VertexTypeId)[];
|
|
724
|
+
};
|
|
725
|
+
} ? Extract<VertexTypeId, string> : string;
|
|
726
|
+
type SpaceIdOfManifest<Manifest> = Manifest extends {
|
|
727
|
+
literals: {
|
|
728
|
+
spaceIds: readonly (infer SpaceId)[];
|
|
729
|
+
};
|
|
730
|
+
} ? Extract<SpaceId, string> : string;
|
|
731
|
+
type SpaceTypeIdOfManifest<Manifest> = Manifest extends {
|
|
732
|
+
literals: {
|
|
733
|
+
spaceTypeIds: readonly (infer SpaceTypeId)[];
|
|
734
|
+
};
|
|
735
|
+
} ? Extract<SpaceTypeId, string> : string;
|
|
736
|
+
type PieceIdOfManifest<Manifest> = Manifest extends {
|
|
737
|
+
literals: {
|
|
738
|
+
pieceIds: readonly (infer PieceId)[];
|
|
739
|
+
};
|
|
740
|
+
} ? Extract<PieceId, string> : string;
|
|
741
|
+
type DieIdOfManifest<Manifest> = Manifest extends {
|
|
742
|
+
literals: {
|
|
743
|
+
dieIds: readonly (infer DieId)[];
|
|
744
|
+
};
|
|
745
|
+
} ? Extract<DieId, string> : string;
|
|
746
|
+
type ManifestOf<Source> = Source extends {
|
|
747
|
+
contract: infer Contract;
|
|
748
|
+
} ? ManifestOf<Contract> : Source extends {
|
|
749
|
+
manifest: infer Manifest;
|
|
750
|
+
} ? Manifest : never;
|
|
751
|
+
type SetupOptionIdOfManifest<Manifest> = Manifest extends {
|
|
752
|
+
literals: {
|
|
753
|
+
setupOptionIds: readonly (infer SetupOptionId)[];
|
|
754
|
+
};
|
|
755
|
+
} ? Extract<SetupOptionId, string> : string;
|
|
756
|
+
type SetupProfileIdOfManifest<Manifest> = Manifest extends {
|
|
757
|
+
literals: {
|
|
758
|
+
setupProfileIds: readonly (infer SetupProfileId)[];
|
|
759
|
+
};
|
|
760
|
+
} ? Extract<SetupProfileId, string> : string;
|
|
761
|
+
type SetupSelectionInputOfManifest<Manifest> = {
|
|
762
|
+
profileId: SetupProfileIdOfManifest<Manifest>;
|
|
763
|
+
optionValues?: Partial<Record<SetupOptionIdOfManifest<Manifest>, string>>;
|
|
764
|
+
};
|
|
765
|
+
type SetupSelectionOfManifest<Manifest> = {
|
|
766
|
+
profileId: SetupProfileIdOfManifest<Manifest>;
|
|
767
|
+
optionValues: Record<SetupOptionIdOfManifest<Manifest>, string | null>;
|
|
768
|
+
};
|
|
769
|
+
type RuntimeSetupSelectionInput<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = SetupSelectionInputOfManifest<Manifest>;
|
|
770
|
+
type RuntimeSetupSelection<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = SetupSelectionOfManifest<Manifest>;
|
|
771
|
+
type StateDefinitionOfContract<Contract> = Contract extends {
|
|
772
|
+
state: infer StateDefinitionValue;
|
|
773
|
+
} ? StateDefinitionValue : never;
|
|
774
|
+
type PhaseSchemasOfContract<Contract> = Contract extends {
|
|
775
|
+
phases: infer Phases extends Record<string, SchemaLike<object>>;
|
|
776
|
+
} ? Phases : Record<PhaseNameOfManifest<ManifestOf<Contract>>, SchemaLike<object>>;
|
|
777
|
+
type PhaseStateMapOfContract<Contract> = {
|
|
778
|
+
[Name in keyof PhaseSchemasOfContract<Contract> & string]: z.infer<PhaseSchemasOfContract<Contract>[Name]>;
|
|
779
|
+
};
|
|
780
|
+
type PublicSchemaOfContract<Contract> = StateDefinitionOfContract<Contract> extends StateDefinition<infer PublicSchema, infer _PrivateSchema, infer _HiddenSchema> ? PublicSchema : never;
|
|
781
|
+
type PrivateSchemaOfContract<Contract> = StateDefinitionOfContract<Contract> extends StateDefinition<infer _PublicSchema, infer PrivateSchema, infer _HiddenSchema> ? PrivateSchema : never;
|
|
782
|
+
type HiddenSchemaOfContract<Contract> = StateDefinitionOfContract<Contract> extends StateDefinition<infer _PublicSchema, infer _PrivateSchema, infer HiddenSchema> ? HiddenSchema : never;
|
|
783
|
+
type PhaseNameOfContract<Contract> = keyof PhaseSchemasOfContract<Contract> extends string ? keyof PhaseSchemasOfContract<Contract> & string : PhaseNameOfManifest<ManifestOf<Contract>>;
|
|
784
|
+
type ManifestContractOf<Contract> = ManifestContract<TableOfManifest<ManifestOf<Contract>>>;
|
|
785
|
+
type ExactManifestContractOf<Contract> = ManifestOf<Contract> & GeneratedManifestContractLike<TableOfManifest<ManifestOf<Contract>>>;
|
|
786
|
+
type PhaseNameOf<Source> = Source extends {
|
|
787
|
+
flow: {
|
|
788
|
+
currentPhase: infer PhaseName;
|
|
789
|
+
};
|
|
790
|
+
} ? Extract<PhaseName, string> : PhaseNameOfContract<Source>;
|
|
791
|
+
type DeckCardsOfTable<Table, DeckId extends DeckIdOfTable<Table>> = Table extends {
|
|
792
|
+
decks: infer Decks extends Record<string, readonly unknown[]>;
|
|
793
|
+
} ? Decks[DeckId] : never;
|
|
794
|
+
type ValueOfPerPlayer<T> = T extends {
|
|
795
|
+
readonly entries: ReadonlyArray<readonly [unknown, infer Value]>;
|
|
796
|
+
} ? Value : never;
|
|
797
|
+
type HandCardsOfTable<Table, HandId extends HandIdOfTable<Table>> = Table extends {
|
|
798
|
+
hands: infer Hands extends Record<string, unknown>;
|
|
799
|
+
} ? HandId extends keyof Hands ? ValueOfPerPlayer<Hands[HandId]> extends infer Value ? Value extends readonly unknown[] ? Value : never : never : never : never;
|
|
800
|
+
type CardIdOfDeck<Table, DeckId extends DeckIdOfTable<Table>> = DeckCardsOfTable<Table, DeckId>[number];
|
|
801
|
+
type CardIdOfHand<Table, HandId extends HandIdOfTable<Table>> = HandCardsOfTable<Table, HandId>[number];
|
|
802
|
+
type CompatibleHandIdForDeck<Table, DeckId extends DeckIdOfTable<Table>> = {
|
|
803
|
+
[CandidateHandId in HandIdOfTable<Table>]: Extract<CardIdOfDeck<Table, DeckId>, CardIdOfHand<Table, CandidateHandId>> extends never ? never : CandidateHandId;
|
|
804
|
+
}[HandIdOfTable<Table>];
|
|
805
|
+
type CompatibleCardIdForHandAndDeck<Table, HandId extends HandIdOfTable<Table>, DeckId extends DeckIdOfTable<Table>> = Extract<CardIdOfHand<Table, HandId>, CardIdOfDeck<Table, DeckId>>;
|
|
806
|
+
type CompatibleCardIdForTwoPlayerZones<Table, FromZoneId extends HandIdOfTable<Table>, ToZoneId extends HandIdOfTable<Table>> = Extract<CardIdOfHand<Table, FromZoneId>, CardIdOfHand<Table, ToZoneId>>;
|
|
807
|
+
|
|
808
|
+
type BoardRecord<Table extends RuntimeTableRecord, BoardId extends BoardIdOfTable<Table>> = Table["boards"]["byId"][BoardId];
|
|
809
|
+
type TiledBoardRecord<Table extends RuntimeTableRecord, BoardId extends TiledBoardIdOfTable<Table>> = Extract<BoardRecord<Table, BoardId>, {
|
|
810
|
+
layout: "hex" | "square";
|
|
811
|
+
}>;
|
|
812
|
+
type ViewCardOfTable<Table extends RuntimeTableRecord, CardId extends CardIdOfTable<Table>> = CardId extends CardIdOfTable<Table> ? ViewCard<CardId & string, Table["cards"][CardId]["cardType"] & string, Extract<Table["cards"][CardId]["properties"], Record<string, unknown>>> : never;
|
|
813
|
+
type CardsByIdOfTable<Table extends RuntimeTableRecord, CardIds extends readonly CardIdOfTable<Table>[]> = Readonly<{
|
|
814
|
+
[Id in CardIds[number]]: ViewCardOfTable<Table, Id> | undefined;
|
|
815
|
+
}>;
|
|
816
|
+
type DeckCardsForZone<Table extends RuntimeTableRecord, ZoneId extends DeckIdOfTable<Table>> = ZoneId extends infer Each extends DeckIdOfTable<Table> ? DeckCardsOfTable<Table, Each> : never;
|
|
817
|
+
type HandCardsForZone<Table extends RuntimeTableRecord, ZoneId extends HandIdOfTable<Table>> = ZoneId extends infer Each extends HandIdOfTable<Table> ? HandCardsOfTable<Table, Each> : never;
|
|
818
|
+
type CardCollectionOfTable<Table extends RuntimeTableRecord> = CardCollection<CardIdOfTable<Table> & string, ViewCardOfTable<Table, CardIdOfTable<Table>>>;
|
|
819
|
+
type SlotOccupantOfTable<Table extends RuntimeTableRecord> = ViewSlotOccupant<ComponentIdOfTable<Table> & string, PlayerIdOfTable<Table> & string, string, Record<string, unknown>>;
|
|
820
|
+
type SlotOccupantsOfTable<Table extends RuntimeTableRecord> = ReadonlyArray<SlotOccupantOfTable<Table>>;
|
|
821
|
+
type SlotOccupantsBySlotIdOfTable<Table extends RuntimeTableRecord> = Readonly<Record<string, SlotOccupantsOfTable<Table>>>;
|
|
822
|
+
type ComponentLocationOfTable<Table, ComponentId extends ComponentIdOfTable<Table>> = Table extends {
|
|
823
|
+
componentLocations: infer ComponentLocations extends Record<string, unknown>;
|
|
824
|
+
} ? ComponentLocations[ComponentId] : never;
|
|
825
|
+
type ComponentDataOfTable<Table, ComponentId extends ComponentIdOfTable<Table>> = Table extends {
|
|
826
|
+
cards: infer Cards extends Record<string, unknown>;
|
|
827
|
+
pieces: infer Pieces extends Record<string, unknown>;
|
|
828
|
+
dice: infer Dice extends Record<string, unknown>;
|
|
829
|
+
} ? ComponentId extends keyof Cards ? Cards[ComponentId] : ComponentId extends keyof Pieces ? Pieces[ComponentId] : ComponentId extends keyof Dice ? Dice[ComponentId] : never : never;
|
|
830
|
+
type ComponentLocationByTypeOfTable<Table, ComponentId extends ComponentIdOfTable<Table>, Type extends RuntimeComponentLocation["type"]> = Extract<ComponentLocationOfTable<Table, ComponentId>, {
|
|
831
|
+
type: Type;
|
|
832
|
+
}>;
|
|
833
|
+
type ResolvedDeckLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
834
|
+
[DeckId in DeckIdOfTable<Table>]: {
|
|
835
|
+
componentId: ComponentId;
|
|
836
|
+
deckId: DeckId;
|
|
837
|
+
cards: DeckCardsOfTable<Table, DeckId>;
|
|
838
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "InDeck"> & {
|
|
839
|
+
deckId: DeckId;
|
|
840
|
+
};
|
|
841
|
+
};
|
|
842
|
+
}[DeckIdOfTable<Table>];
|
|
843
|
+
type ResolvedHandLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
844
|
+
[HandId in HandIdOfTable<Table>]: {
|
|
845
|
+
[PlayerId in PlayerIdOfTable<Table>]: {
|
|
846
|
+
componentId: ComponentId;
|
|
847
|
+
handId: HandId;
|
|
848
|
+
playerId: PlayerId;
|
|
849
|
+
cards: HandCardsOfTable<Table, HandId>;
|
|
850
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "InHand"> & {
|
|
851
|
+
handId: HandId;
|
|
852
|
+
playerId: PlayerId;
|
|
853
|
+
};
|
|
854
|
+
};
|
|
855
|
+
}[PlayerIdOfTable<Table>];
|
|
856
|
+
}[HandIdOfTable<Table>];
|
|
857
|
+
type ResolvedZoneLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = ComponentLocationByTypeOfTable<Table, ComponentId, "InZone"> extends infer Location ? Location extends {
|
|
858
|
+
type: "InZone";
|
|
859
|
+
zoneId: infer ZoneId extends string;
|
|
860
|
+
} ? {
|
|
861
|
+
componentId: ComponentId;
|
|
862
|
+
zoneId: ZoneId;
|
|
863
|
+
location: Location;
|
|
864
|
+
} : never : never;
|
|
865
|
+
type ResolvedSpaceLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
866
|
+
[BoardId in BoardIdOfTable<Table>]: {
|
|
867
|
+
[SpaceId in SpaceIdOfTable<Table, BoardId>]: {
|
|
868
|
+
componentId: ComponentId;
|
|
869
|
+
boardId: BoardId;
|
|
870
|
+
board: BoardRecord<Table, BoardId>;
|
|
871
|
+
spaceId: SpaceId;
|
|
872
|
+
space: Table["boards"]["byId"][BoardId]["spaces"][SpaceId];
|
|
873
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "OnSpace"> & {
|
|
874
|
+
boardId: BoardId;
|
|
875
|
+
spaceId: SpaceId;
|
|
876
|
+
};
|
|
877
|
+
};
|
|
878
|
+
}[SpaceIdOfTable<Table, BoardId>];
|
|
879
|
+
}[BoardIdOfTable<Table>];
|
|
880
|
+
type ResolvedContainerLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
881
|
+
[BoardId in BoardIdOfTable<Table>]: {
|
|
882
|
+
[ContainerId in BoardContainerIdOfTable<Table, BoardId>]: {
|
|
883
|
+
componentId: ComponentId;
|
|
884
|
+
boardId: BoardId;
|
|
885
|
+
board: BoardRecord<Table, BoardId>;
|
|
886
|
+
containerId: ContainerId;
|
|
887
|
+
container: Table["boards"]["byId"][BoardId]["containers"][ContainerId];
|
|
888
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "InContainer"> & {
|
|
889
|
+
boardId: BoardId;
|
|
890
|
+
containerId: ContainerId;
|
|
891
|
+
};
|
|
892
|
+
};
|
|
893
|
+
}[BoardContainerIdOfTable<Table, BoardId>];
|
|
894
|
+
}[BoardIdOfTable<Table>];
|
|
895
|
+
type ResolvedEdgeLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
896
|
+
[BoardId in TiledBoardIdOfTable<Table>]: {
|
|
897
|
+
[EdgeId in TiledEdgeIdOfTable<Table, BoardId>]: {
|
|
898
|
+
componentId: ComponentId;
|
|
899
|
+
boardId: BoardId;
|
|
900
|
+
board: TiledBoardRecord<Table, BoardId>;
|
|
901
|
+
edgeId: EdgeId;
|
|
902
|
+
edge: Extract<Table["boards"]["byId"][BoardId], {
|
|
903
|
+
layout: "hex" | "square";
|
|
904
|
+
}>["edges"][number];
|
|
905
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "OnEdge"> & {
|
|
906
|
+
boardId: BoardId;
|
|
907
|
+
edgeId: EdgeId;
|
|
908
|
+
};
|
|
909
|
+
};
|
|
910
|
+
}[TiledEdgeIdOfTable<Table, BoardId>];
|
|
911
|
+
}[TiledBoardIdOfTable<Table>];
|
|
912
|
+
type ResolvedVertexLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = {
|
|
913
|
+
[BoardId in TiledBoardIdOfTable<Table>]: {
|
|
914
|
+
[VertexId in TiledVertexIdOfTable<Table, BoardId>]: {
|
|
915
|
+
componentId: ComponentId;
|
|
916
|
+
boardId: BoardId;
|
|
917
|
+
board: TiledBoardRecord<Table, BoardId>;
|
|
918
|
+
vertexId: VertexId;
|
|
919
|
+
vertex: Extract<Table["boards"]["byId"][BoardId], {
|
|
920
|
+
layout: "hex" | "square";
|
|
921
|
+
}>["vertices"][number];
|
|
922
|
+
location: ComponentLocationByTypeOfTable<Table, ComponentId, "OnVertex"> & {
|
|
923
|
+
boardId: BoardId;
|
|
924
|
+
vertexId: VertexId;
|
|
925
|
+
};
|
|
926
|
+
};
|
|
927
|
+
}[TiledVertexIdOfTable<Table, BoardId>];
|
|
928
|
+
}[TiledBoardIdOfTable<Table>];
|
|
929
|
+
type ResolvedSlotLocation<Table extends RuntimeTableRecord, ComponentId extends ComponentIdOfTable<Table>> = ComponentLocationByTypeOfTable<Table, ComponentId, "InSlot"> extends infer Location ? Location extends {
|
|
930
|
+
type: "InSlot";
|
|
931
|
+
host: infer Host extends RuntimeSlotHostRef;
|
|
932
|
+
slotId: infer SlotId extends string;
|
|
933
|
+
} ? {
|
|
934
|
+
componentId: ComponentId;
|
|
935
|
+
host: Host;
|
|
936
|
+
slotId: SlotId;
|
|
937
|
+
location: Location;
|
|
938
|
+
} : never : never;
|
|
939
|
+
type TableQueries<Table extends RuntimeTableRecord> = {
|
|
940
|
+
board: {
|
|
941
|
+
get: <BoardId extends BoardIdOfTable<Table>>(boardId: BoardId) => BoardRecord<Table, BoardId>;
|
|
942
|
+
hex: <BoardId extends HexBoardIdOfTable<Table>>(boardId: BoardId) => Extract<BoardRecord<Table, BoardId>, {
|
|
943
|
+
layout: "hex";
|
|
944
|
+
}>;
|
|
945
|
+
square: <BoardId extends SquareBoardIdOfTable<Table>>(boardId: BoardId) => Extract<BoardRecord<Table, BoardId>, {
|
|
946
|
+
layout: "square";
|
|
947
|
+
}>;
|
|
948
|
+
tiled: <BoardId extends TiledBoardIdOfTable<Table>>(boardId: BoardId) => TiledBoardRecord<Table, BoardId>;
|
|
949
|
+
space: <BoardId extends BoardIdOfTable<Table>, SpaceId extends SpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId) => Table["boards"]["byId"][BoardId]["spaces"][SpaceId];
|
|
950
|
+
hexSpace: <BoardId extends HexBoardIdOfTable<Table>, SpaceId extends HexSpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId) => Extract<Table["boards"]["byId"][BoardId], {
|
|
951
|
+
layout: "hex";
|
|
952
|
+
}>["spaces"][SpaceId];
|
|
953
|
+
squareSpace: <BoardId extends SquareBoardIdOfTable<Table>, SpaceId extends SquareSpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId) => Extract<Table["boards"]["byId"][BoardId], {
|
|
954
|
+
layout: "square";
|
|
955
|
+
}>["spaces"][SpaceId];
|
|
956
|
+
container: <BoardId extends BoardIdOfTable<Table>, ContainerId extends BoardContainerIdOfTable<Table, BoardId>>(boardId: BoardId, containerId: ContainerId) => Table["boards"]["byId"][BoardId]["containers"][ContainerId];
|
|
957
|
+
edge: <BoardId extends TiledBoardIdOfTable<Table>, EdgeId extends TiledEdgeIdOfTable<Table, BoardId>>(boardId: BoardId, edgeId: EdgeId) => TiledEdgeStateOfTable<Table, BoardId, EdgeId>;
|
|
958
|
+
vertex: <BoardId extends TiledBoardIdOfTable<Table>, VertexId extends TiledVertexIdOfTable<Table, BoardId>>(boardId: BoardId, vertexId: VertexId) => TiledVertexStateOfTable<Table, BoardId, VertexId>;
|
|
959
|
+
byType: <TypeId extends BoardTypeIdOfTable<Table>>(typeId: TypeId) => BoardIdOfTable<Table>[];
|
|
960
|
+
spacesByType: <BoardId extends BoardIdOfTable<Table>, TypeId extends SpaceTypeIdOfTable<Table, BoardId>>(boardId: BoardId, typeId: TypeId) => SpaceIdOfTable<Table, BoardId>[];
|
|
961
|
+
edgesByType: <BoardId extends TiledBoardIdOfTable<Table>, TypeId extends TiledEdgeTypeIdOfTable<Table, BoardId>>(boardId: BoardId, typeId: TypeId) => TiledEdgeIdOfTable<Table, BoardId>[];
|
|
962
|
+
verticesByType: <BoardId extends TiledBoardIdOfTable<Table>, TypeId extends TiledVertexTypeIdOfTable<Table, BoardId>>(boardId: BoardId, typeId: TypeId) => TiledVertexIdOfTable<Table, BoardId>[];
|
|
963
|
+
adjacentSpaces: <BoardId extends BoardIdOfTable<Table>, SpaceId extends SpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId) => SpaceIdOfTable<Table, BoardId>[];
|
|
964
|
+
relatedSpaces: <BoardId extends BoardIdOfTable<Table>, SpaceId extends SpaceIdOfTable<Table, BoardId>, TypeId extends RelationTypeIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId, relationTypeId: TypeId) => SpaceIdOfTable<Table, BoardId>[];
|
|
965
|
+
incidentEdges: <BoardId extends TiledBoardIdOfTable<Table>, VertexId extends TiledVertexIdOfTable<Table, BoardId>>(boardId: BoardId, vertexId: VertexId) => TiledEdgeIdOfTable<Table, BoardId>[];
|
|
966
|
+
incidentVertices: <BoardId extends TiledBoardIdOfTable<Table>, EdgeId extends TiledEdgeIdOfTable<Table, BoardId>>(boardId: BoardId, edgeId: EdgeId) => TiledVertexIdOfTable<Table, BoardId>[];
|
|
967
|
+
spaceEdges: <BoardId extends TiledBoardIdOfTable<Table>>(boardId: BoardId, spaceId: SpaceIdOfTable<Table, BoardId>) => TiledEdgeIdOfTable<Table, BoardId>[];
|
|
968
|
+
spaceVertices: <BoardId extends TiledBoardIdOfTable<Table>>(boardId: BoardId, spaceId: SpaceIdOfTable<Table, BoardId>) => TiledVertexIdOfTable<Table, BoardId>[];
|
|
969
|
+
spaceDistance: <BoardId extends BoardIdOfTable<Table>, SpaceId extends SpaceIdOfTable<Table, BoardId>>(boardId: BoardId, fromSpaceId: SpaceId, toSpaceId: SpaceId) => number;
|
|
970
|
+
hexSpaceAt: <BoardId extends HexBoardIdOfTable<Table>>(boardId: BoardId, q: number, r: number) => Extract<Table["boards"]["byId"][BoardId], {
|
|
971
|
+
layout: "hex";
|
|
972
|
+
}>["spaces"][HexSpaceIdOfTable<Table, BoardId>] | undefined;
|
|
973
|
+
squareSpaceAt: <BoardId extends SquareBoardIdOfTable<Table>>(boardId: BoardId, row: number, col: number) => Extract<Table["boards"]["byId"][BoardId], {
|
|
974
|
+
layout: "square";
|
|
975
|
+
}>["spaces"][SquareSpaceIdOfTable<Table, BoardId>] | undefined;
|
|
976
|
+
squareNeighbors: <BoardId extends SquareBoardIdOfTable<Table>, SpaceId extends SquareSpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId, options?: {
|
|
977
|
+
mode?: "orthogonal" | "diagonal" | "all";
|
|
978
|
+
}) => SquareSpaceIdOfTable<Table, BoardId>[];
|
|
979
|
+
squareDistance: <BoardId extends SquareBoardIdOfTable<Table>, SpaceId extends SquareSpaceIdOfTable<Table, BoardId>>(boardId: BoardId, fromSpaceId: SpaceId, toSpaceId: SpaceId, options?: {
|
|
980
|
+
metric?: "manhattan" | "chebyshev";
|
|
981
|
+
}) => number;
|
|
982
|
+
spaceOccupants: <BoardId extends BoardIdOfTable<Table>, SpaceId extends SpaceIdOfTable<Table, BoardId>>(boardId: BoardId, spaceId: SpaceId) => ComponentIdOfTable<Table>[];
|
|
983
|
+
containerOccupants: <BoardId extends BoardIdOfTable<Table>, ContainerId extends BoardContainerIdOfTable<Table, BoardId>>(boardId: BoardId, containerId: ContainerId) => ComponentIdOfTable<Table>[];
|
|
984
|
+
edgeOccupants: <BoardId extends TiledBoardIdOfTable<Table>, EdgeId extends TiledEdgeIdOfTable<Table, BoardId>>(boardId: BoardId, edgeId: EdgeId) => ComponentIdOfTable<Table>[];
|
|
985
|
+
vertexOccupants: <BoardId extends TiledBoardIdOfTable<Table>, VertexId extends TiledVertexIdOfTable<Table, BoardId>>(boardId: BoardId, vertexId: VertexId) => ComponentIdOfTable<Table>[];
|
|
986
|
+
};
|
|
987
|
+
zone: {
|
|
988
|
+
sharedCards: <ZoneId extends DeckIdOfTable<Table>>(zoneId: ZoneId) => DeckCardsForZone<Table, ZoneId>;
|
|
989
|
+
sharedCardCollection: <ZoneId extends DeckIdOfTable<Table>>(zoneId: ZoneId) => CardCollectionOfTable<Table>;
|
|
990
|
+
allSharedCards: () => {
|
|
991
|
+
readonly [Z in DeckIdOfTable<Table>]: DeckCardsOfTable<Table, Z>;
|
|
992
|
+
};
|
|
993
|
+
playerCards: <PlayerId extends PlayerIdOfTable<Table>, ZoneId extends HandIdOfTable<Table>>(playerId: PlayerId, zoneId: ZoneId) => HandCardsForZone<Table, ZoneId>;
|
|
994
|
+
playerCardCollection: <PlayerId extends PlayerIdOfTable<Table>, ZoneId extends HandIdOfTable<Table>>(playerId: PlayerId, zoneId: ZoneId) => CardCollectionOfTable<Table>;
|
|
995
|
+
allPlayerCards: <ZoneId extends HandIdOfTable<Table>>(zoneId: ZoneId) => {
|
|
996
|
+
readonly [P in PlayerIdOfTable<Table>]: HandCardsOfTable<Table, ZoneId>;
|
|
997
|
+
};
|
|
998
|
+
};
|
|
999
|
+
card: {
|
|
1000
|
+
get: <CardId extends CardIdOfTable<Table>>(cardId: CardId) => ViewCardOfTable<Table, CardId>;
|
|
1001
|
+
byIds: <CardIds extends readonly CardIdOfTable<Table>[]>(cardIds: CardIds) => CardsByIdOfTable<Table, CardIds>;
|
|
1002
|
+
owner: <CardId extends CardIdOfTable<Table>>(cardId: CardId) => Table["ownerOfCard"][CardId];
|
|
1003
|
+
visibility: <CardId extends CardIdOfTable<Table>>(cardId: CardId) => Table["visibility"][CardId];
|
|
1004
|
+
};
|
|
1005
|
+
slot: {
|
|
1006
|
+
occupants: (host: RuntimeSlotHostRef, slotId: string) => SlotOccupantsOfTable<Table>;
|
|
1007
|
+
occupantsByHost: (host: RuntimeSlotHostRef) => SlotOccupantsBySlotIdOfTable<Table>;
|
|
1008
|
+
pieceOccupants: (hostId: string, slotId: string) => SlotOccupantsOfTable<Table>;
|
|
1009
|
+
pieceOccupantsByHost: (hostId: string) => SlotOccupantsBySlotIdOfTable<Table>;
|
|
1010
|
+
dieOccupants: (hostId: string, slotId: string) => SlotOccupantsOfTable<Table>;
|
|
1011
|
+
dieOccupantsByHost: (hostId: string) => SlotOccupantsBySlotIdOfTable<Table>;
|
|
1012
|
+
};
|
|
1013
|
+
player: {
|
|
1014
|
+
/** Seating order from the manifest / setup profile. */
|
|
1015
|
+
order: () => Table["playerOrder"];
|
|
1016
|
+
/**
|
|
1017
|
+
* Next player id in seating order after `playerId`, wrapping around to
|
|
1018
|
+
* the first seat. Returns `null` when `playerId` is unknown or the
|
|
1019
|
+
* order is empty. Convenient for "whose turn is next" logic.
|
|
1020
|
+
*/
|
|
1021
|
+
nextInOrder: (playerId: PlayerIdOfTable<Table>) => PlayerIdOfTable<Table> | null;
|
|
1022
|
+
/** All resource balances for a player, as the manifest-typed record. */
|
|
1023
|
+
resources: <PlayerId extends PlayerIdOfTable<Table>>(playerId: PlayerId) => ResourceBalancesOfTable<Table>;
|
|
1024
|
+
/** Balance of a single resource; returns `0` when unset. */
|
|
1025
|
+
resource: (playerId: PlayerIdOfTable<Table>, resourceId: ResourceIdOfTable<Table>) => number;
|
|
1026
|
+
/**
|
|
1027
|
+
* Sum of every resource amount held by a player (e.g. "total cards in
|
|
1028
|
+
* hand" checks). Returns `0` for unknown players or empty balances.
|
|
1029
|
+
*/
|
|
1030
|
+
resourceTotal: (playerId: PlayerIdOfTable<Table>) => number;
|
|
1031
|
+
/** `true` when the player can pay every non-zero amount in `amounts`. */
|
|
1032
|
+
canAfford: (playerId: PlayerIdOfTable<Table>, amounts: ResourceAmountsOfTable<Table>) => boolean;
|
|
1033
|
+
/** Shortfall per resource when the player cannot afford `amounts`. */
|
|
1034
|
+
missingResources: (playerId: PlayerIdOfTable<Table>, amounts: ResourceAmountsOfTable<Table>) => Partial<Record<ResourceIdOfTable<Table>, number>>;
|
|
1035
|
+
};
|
|
1036
|
+
component: {
|
|
1037
|
+
data: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ComponentDataOfTable<Table, ComponentId> | undefined;
|
|
1038
|
+
location: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ComponentLocationOfTable<Table, ComponentId> | undefined;
|
|
1039
|
+
deck: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedDeckLocation<Table, ComponentId> | null;
|
|
1040
|
+
hand: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedHandLocation<Table, ComponentId> | null;
|
|
1041
|
+
zone: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedZoneLocation<Table, ComponentId> | null;
|
|
1042
|
+
space: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedSpaceLocation<Table, ComponentId> | null;
|
|
1043
|
+
container: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedContainerLocation<Table, ComponentId> | null;
|
|
1044
|
+
edge: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedEdgeLocation<Table, ComponentId> | null;
|
|
1045
|
+
vertex: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedVertexLocation<Table, ComponentId> | null;
|
|
1046
|
+
slot: <ComponentId extends ComponentIdOfTable<Table>>(componentId: ComponentId) => ResolvedSlotLocation<Table, ComponentId> | null;
|
|
1047
|
+
};
|
|
1048
|
+
};
|
|
1049
|
+
type TableQueriesOfState<State extends {
|
|
1050
|
+
table: RuntimeTableRecord;
|
|
1051
|
+
}> = TableQueries<TableOfState<State>>;
|
|
1052
|
+
|
|
1053
|
+
declare const manifestIdSchemaBrand: unique symbol;
|
|
1054
|
+
type ManifestIdSchema<Output = unknown> = z.ZodType<Output> & {
|
|
1055
|
+
readonly [manifestIdSchemaBrand]: true;
|
|
1056
|
+
};
|
|
1057
|
+
type ManifestLiterals<PlayerId extends string, DeckId extends string, HandId extends string, CardId extends string, PhaseName extends string = string> = {
|
|
1058
|
+
playerIds: readonly PlayerId[];
|
|
1059
|
+
phaseNames: readonly PhaseName[];
|
|
1060
|
+
boardLayouts: readonly ("generic" | "hex" | "square")[];
|
|
1061
|
+
setupOptionIds: readonly string[];
|
|
1062
|
+
setupProfileIds: readonly string[];
|
|
1063
|
+
cardSetIds: readonly string[];
|
|
1064
|
+
cardTypes: readonly string[];
|
|
1065
|
+
deckIds: readonly DeckId[];
|
|
1066
|
+
handIds: readonly HandId[];
|
|
1067
|
+
sharedZoneIds: readonly DeckId[];
|
|
1068
|
+
playerZoneIds: readonly HandId[];
|
|
1069
|
+
zoneIds: readonly (DeckId | HandId)[];
|
|
1070
|
+
cardIds: readonly CardId[];
|
|
1071
|
+
resourceIds: readonly string[];
|
|
1072
|
+
resourcePresentationById?: Record<string, {
|
|
1073
|
+
label: string;
|
|
1074
|
+
icon?: string | null;
|
|
1075
|
+
}>;
|
|
1076
|
+
pieceTypeIds: readonly string[];
|
|
1077
|
+
pieceIds: readonly string[];
|
|
1078
|
+
dieTypeIds: readonly string[];
|
|
1079
|
+
dieIds: readonly string[];
|
|
1080
|
+
boardTemplateIds: readonly string[];
|
|
1081
|
+
boardTypeIds: readonly string[];
|
|
1082
|
+
boardBaseIds: readonly string[];
|
|
1083
|
+
boardIds: readonly string[];
|
|
1084
|
+
boardContainerIds: readonly string[];
|
|
1085
|
+
relationTypeIds: readonly string[];
|
|
1086
|
+
edgeIds: readonly string[];
|
|
1087
|
+
edgeTypeIds: readonly string[];
|
|
1088
|
+
vertexIds: readonly string[];
|
|
1089
|
+
vertexTypeIds: readonly string[];
|
|
1090
|
+
spaceIds: readonly string[];
|
|
1091
|
+
spaceTypeIds: readonly string[];
|
|
1092
|
+
handVisibilityById: Record<HandId, RuntimeHandVisibilityMode>;
|
|
1093
|
+
zoneVisibilityById: Record<DeckId | HandId, RuntimeHandVisibilityMode>;
|
|
1094
|
+
setupChoiceIdsByOptionId: Record<string, readonly string[]>;
|
|
1095
|
+
cardSetIdByCardId: Record<CardId, string>;
|
|
1096
|
+
cardTypeByCardId: Record<CardId, string>;
|
|
1097
|
+
cardSetIdsBySharedZoneId: Record<DeckId, readonly string[]>;
|
|
1098
|
+
cardSetIdsByPlayerZoneId: Record<HandId, readonly string[]>;
|
|
1099
|
+
};
|
|
1100
|
+
type ManifestIds<PlayerId extends string, DeckId extends string, HandId extends string, CardId extends string, PhaseName extends string = string> = {
|
|
1101
|
+
playerId: z.ZodType<PlayerId>;
|
|
1102
|
+
phaseName: z.ZodType<PhaseName>;
|
|
1103
|
+
boardLayout: AnySchema;
|
|
1104
|
+
setupOptionId: AnySchema;
|
|
1105
|
+
setupProfileId: AnySchema;
|
|
1106
|
+
cardSetId: AnySchema;
|
|
1107
|
+
cardType: AnySchema;
|
|
1108
|
+
cardId: z.ZodType<CardId>;
|
|
1109
|
+
deckId: z.ZodType<DeckId>;
|
|
1110
|
+
handId: z.ZodType<HandId>;
|
|
1111
|
+
sharedZoneId: AnySchema;
|
|
1112
|
+
playerZoneId: AnySchema;
|
|
1113
|
+
zoneId: AnySchema;
|
|
1114
|
+
resourceId: AnySchema;
|
|
1115
|
+
pieceTypeId: AnySchema;
|
|
1116
|
+
pieceId: AnySchema;
|
|
1117
|
+
dieId: AnySchema;
|
|
1118
|
+
dieTypeId: AnySchema;
|
|
1119
|
+
boardTypeId: AnySchema;
|
|
1120
|
+
boardId: AnySchema;
|
|
1121
|
+
boardBaseId: AnySchema;
|
|
1122
|
+
boardContainerId: AnySchema;
|
|
1123
|
+
relationTypeId: AnySchema;
|
|
1124
|
+
edgeId: AnySchema;
|
|
1125
|
+
edgeTypeId: AnySchema;
|
|
1126
|
+
vertexId: AnySchema;
|
|
1127
|
+
vertexTypeId: AnySchema;
|
|
1128
|
+
spaceId: AnySchema;
|
|
1129
|
+
spaceTypeId: AnySchema;
|
|
1130
|
+
};
|
|
1131
|
+
type ManifestDefaults<Table extends RuntimeTableRecord> = {
|
|
1132
|
+
zones: (playerIds?: readonly string[]) => Table["zones"];
|
|
1133
|
+
decks: (playerIds?: readonly string[]) => Table["decks"];
|
|
1134
|
+
hands: (playerIds?: readonly string[]) => Table["hands"];
|
|
1135
|
+
handVisibility: (playerIds?: readonly string[]) => Table["handVisibility"];
|
|
1136
|
+
ownerOfCard: (playerIds?: readonly string[]) => Table["ownerOfCard"];
|
|
1137
|
+
visibility: (playerIds?: readonly string[]) => Table["visibility"];
|
|
1138
|
+
resources: (playerIds?: readonly string[]) => Table["resources"];
|
|
1139
|
+
};
|
|
1140
|
+
type StaticBoards<Table extends RuntimeTableRecord> = Pick<Table["boards"], "byId" | "hex" | "square">;
|
|
1141
|
+
type SetupOptionChoiceMetadata = {
|
|
1142
|
+
id: string;
|
|
1143
|
+
label: string;
|
|
1144
|
+
description?: string | null;
|
|
1145
|
+
};
|
|
1146
|
+
type SetupOptionMetadata = {
|
|
1147
|
+
id: string;
|
|
1148
|
+
name: string;
|
|
1149
|
+
description?: string | null;
|
|
1150
|
+
choices: readonly SetupOptionChoiceMetadata[];
|
|
1151
|
+
};
|
|
1152
|
+
type SetupProfileMetadata = {
|
|
1153
|
+
id: string;
|
|
1154
|
+
name: string;
|
|
1155
|
+
description?: string | null;
|
|
1156
|
+
optionValues?: Record<string, string> | null;
|
|
1157
|
+
};
|
|
1158
|
+
type ReducerManifestContract<Table extends RuntimeTableRecord, PhaseName extends string, PlayerId extends string, DeckId extends string, HandId extends string, CardId extends string> = {
|
|
1159
|
+
literals: ManifestLiterals<PlayerId, DeckId, HandId, CardId, PhaseName>;
|
|
1160
|
+
ids: ManifestIds<PlayerId, DeckId, HandId, CardId, PhaseName>;
|
|
1161
|
+
defaults: ManifestDefaults<Table>;
|
|
1162
|
+
staticBoards?: StaticBoards<Table>;
|
|
1163
|
+
setupOptionsById: Record<string, SetupOptionMetadata>;
|
|
1164
|
+
setupChoiceIdsByOptionId: Record<string, readonly string[]>;
|
|
1165
|
+
setupProfilesById: Record<string, SetupProfileMetadata>;
|
|
1166
|
+
tableSchema: z.ZodType<Table>;
|
|
1167
|
+
runtimeSchema: AnySchema;
|
|
1168
|
+
createGameStateSchema: (config: {
|
|
1169
|
+
phaseNameSchema: AnySchema;
|
|
1170
|
+
publicSchema: AnySchema;
|
|
1171
|
+
privateSchema: AnySchema;
|
|
1172
|
+
hiddenSchema: AnySchema;
|
|
1173
|
+
phasesSchema: AnySchema;
|
|
1174
|
+
}) => AnySchema;
|
|
1175
|
+
};
|
|
1176
|
+
type GeneratedManifestContractLike<Table extends RuntimeTableRecord = RuntimeTableRecord, PhaseName extends string = string, PlayerId extends string = string, DeckId extends string = string, HandId extends string = string, CardId extends string = string> = ReducerManifestContract<Table, PhaseName, PlayerId, DeckId, HandId, CardId>;
|
|
1177
|
+
type ManifestContract<Table extends RuntimeTableRecord> = ReducerManifestContract<Table, string, PlayerIdOfTable<Table>, DeckIdOfTable<Table>, HandIdOfTable<Table>, CardIdOfTable<Table>>;
|
|
1178
|
+
declare function markManifestScopedSchema<Schema extends z.ZodTypeAny>(schema: Schema): Schema & ManifestIdSchema<z.infer<Schema>>;
|
|
1179
|
+
declare function createManifestStringLiteralSchema<Values extends readonly string[]>(values: Values): ManifestIdSchema<Values[number] extends never ? string : Values[number]>;
|
|
1180
|
+
declare function assumeManifestSchema<Output>(schema: z.ZodTypeAny): z.ZodType<Output>;
|
|
1181
|
+
declare function cloneManifestDefault<Value>(value: Value): Value;
|
|
1182
|
+
declare function resolveManifestPlayerIds<PlayerId extends string>(manifestPlayerIds: readonly PlayerId[], playerIds: readonly string[] | undefined): readonly PlayerId[];
|
|
1183
|
+
declare function createManifestRuntimeSchema<PhaseNameSchema extends z.ZodTypeAny, PlayerId extends string, SetupProfileId extends string>({ phaseNameSchema, playerIdSchema, setupProfileIdSchema, }: {
|
|
1184
|
+
phaseNameSchema: PhaseNameSchema;
|
|
1185
|
+
playerIdSchema: z.ZodType<PlayerId>;
|
|
1186
|
+
setupProfileIdSchema: z.ZodType<SetupProfileId>;
|
|
1187
|
+
}): z.ZodObject<{
|
|
1188
|
+
prompts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1189
|
+
id: z.ZodString;
|
|
1190
|
+
promptId: z.ZodString;
|
|
1191
|
+
to: z.ZodType<PlayerId, unknown, z.core.$ZodTypeInternals<PlayerId, unknown>>;
|
|
1192
|
+
title: z.ZodOptional<z.ZodString>;
|
|
1193
|
+
payload: z.ZodOptional<z.ZodUnknown>;
|
|
1194
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1195
|
+
id: z.ZodString;
|
|
1196
|
+
label: z.ZodString;
|
|
1197
|
+
}, z.core.$strip>>>;
|
|
1198
|
+
resume: z.ZodObject<{
|
|
1199
|
+
id: z.ZodString;
|
|
1200
|
+
data: z.ZodUnknown;
|
|
1201
|
+
}, z.core.$strip>;
|
|
1202
|
+
}, z.core.$strip>>>;
|
|
1203
|
+
rng: z.ZodDefault<z.ZodObject<{
|
|
1204
|
+
seed: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1205
|
+
cursor: z.ZodDefault<z.ZodNumber>;
|
|
1206
|
+
trace: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1207
|
+
}, z.core.$strip>>;
|
|
1208
|
+
setup: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1209
|
+
profileId: z.ZodType<SetupProfileId, unknown, z.core.$ZodTypeInternals<SetupProfileId, unknown>>;
|
|
1210
|
+
optionValues: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodString>>>;
|
|
1211
|
+
}, z.core.$strip>>>;
|
|
1212
|
+
simultaneous: z.ZodDefault<z.ZodObject<{
|
|
1213
|
+
current: z.ZodNullable<z.ZodObject<{
|
|
1214
|
+
phaseName: PhaseNameSchema;
|
|
1215
|
+
actors: z.ZodArray<z.ZodType<PlayerId, unknown, z.core.$ZodTypeInternals<PlayerId, unknown>>>;
|
|
1216
|
+
submissions: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1217
|
+
interactionId: z.ZodString;
|
|
1218
|
+
params: z.ZodUnknown;
|
|
1219
|
+
}, z.core.$strip>>;
|
|
1220
|
+
}, z.core.$strip>>;
|
|
1221
|
+
}, z.core.$strip>>;
|
|
1222
|
+
lastTransition: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1223
|
+
from: PhaseNameSchema;
|
|
1224
|
+
to: PhaseNameSchema;
|
|
1225
|
+
}, z.core.$strip>>>;
|
|
1226
|
+
nextInstanceId: z.ZodDefault<z.ZodNumber>;
|
|
1227
|
+
}, z.core.$strip>;
|
|
1228
|
+
declare function createManifestGameStateSchema<Table extends RuntimeTableRecord, PhaseNameSchema extends z.ZodTypeAny, PublicSchema extends z.ZodTypeAny, PrivateSchema extends z.ZodTypeAny, HiddenSchema extends z.ZodTypeAny, PhasesSchema extends z.ZodTypeAny, PlayerId extends string, SetupProfileId extends string>({ tableSchema, playerIdSchema, setupProfileIdSchema, phaseNameSchema, publicSchema, privateSchema, hiddenSchema, phasesSchema, }: {
|
|
1229
|
+
tableSchema: z.ZodType<Table>;
|
|
1230
|
+
playerIdSchema: z.ZodType<PlayerId>;
|
|
1231
|
+
setupProfileIdSchema: z.ZodType<SetupProfileId>;
|
|
1232
|
+
phaseNameSchema: PhaseNameSchema;
|
|
1233
|
+
publicSchema: PublicSchema;
|
|
1234
|
+
privateSchema: PrivateSchema;
|
|
1235
|
+
hiddenSchema: HiddenSchema;
|
|
1236
|
+
phasesSchema: PhasesSchema;
|
|
1237
|
+
}): z.ZodObject<{
|
|
1238
|
+
table: z.ZodType<Table, unknown, z.core.$ZodTypeInternals<Table, unknown>>;
|
|
1239
|
+
public: PublicSchema;
|
|
1240
|
+
private: z.ZodRecord<z.ZodString, PrivateSchema>;
|
|
1241
|
+
hidden: HiddenSchema;
|
|
1242
|
+
flow: z.ZodObject<{
|
|
1243
|
+
currentPhase: PhaseNameSchema;
|
|
1244
|
+
turn: z.ZodNumber;
|
|
1245
|
+
round: z.ZodNumber;
|
|
1246
|
+
activePlayers: z.ZodArray<z.ZodType<PlayerId, unknown, z.core.$ZodTypeInternals<PlayerId, unknown>>>;
|
|
1247
|
+
}, z.core.$strip>;
|
|
1248
|
+
phase: PhasesSchema;
|
|
1249
|
+
runtime: z.ZodObject<{
|
|
1250
|
+
prompts: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1251
|
+
id: z.ZodString;
|
|
1252
|
+
promptId: z.ZodString;
|
|
1253
|
+
to: z.ZodType<PlayerId, unknown, z.core.$ZodTypeInternals<PlayerId, unknown>>;
|
|
1254
|
+
title: z.ZodOptional<z.ZodString>;
|
|
1255
|
+
payload: z.ZodOptional<z.ZodUnknown>;
|
|
1256
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1257
|
+
id: z.ZodString;
|
|
1258
|
+
label: z.ZodString;
|
|
1259
|
+
}, z.core.$strip>>>;
|
|
1260
|
+
resume: z.ZodObject<{
|
|
1261
|
+
id: z.ZodString;
|
|
1262
|
+
data: z.ZodUnknown;
|
|
1263
|
+
}, z.core.$strip>;
|
|
1264
|
+
}, z.core.$strip>>>;
|
|
1265
|
+
rng: z.ZodDefault<z.ZodObject<{
|
|
1266
|
+
seed: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1267
|
+
cursor: z.ZodDefault<z.ZodNumber>;
|
|
1268
|
+
trace: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1269
|
+
}, z.core.$strip>>;
|
|
1270
|
+
setup: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1271
|
+
profileId: z.ZodType<SetupProfileId, unknown, z.core.$ZodTypeInternals<SetupProfileId, unknown>>;
|
|
1272
|
+
optionValues: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNullable<z.ZodString>>>;
|
|
1273
|
+
}, z.core.$strip>>>;
|
|
1274
|
+
simultaneous: z.ZodDefault<z.ZodObject<{
|
|
1275
|
+
current: z.ZodNullable<z.ZodObject<{
|
|
1276
|
+
phaseName: PhaseNameSchema;
|
|
1277
|
+
actors: z.ZodArray<z.ZodType<PlayerId, unknown, z.core.$ZodTypeInternals<PlayerId, unknown>>>;
|
|
1278
|
+
submissions: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1279
|
+
interactionId: z.ZodString;
|
|
1280
|
+
params: z.ZodUnknown;
|
|
1281
|
+
}, z.core.$strip>>;
|
|
1282
|
+
}, z.core.$strip>>;
|
|
1283
|
+
}, z.core.$strip>>;
|
|
1284
|
+
lastTransition: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
1285
|
+
from: PhaseNameSchema;
|
|
1286
|
+
to: PhaseNameSchema;
|
|
1287
|
+
}, z.core.$strip>>>;
|
|
1288
|
+
nextInstanceId: z.ZodDefault<z.ZodNumber>;
|
|
1289
|
+
}, z.core.$strip>;
|
|
1290
|
+
}, z.core.$strip>;
|
|
1291
|
+
type StateDefinition<PublicSchema extends SchemaLike<object>, PrivateSchema extends SchemaLike<object>, HiddenSchema extends SchemaLike<object>> = {
|
|
1292
|
+
public: PublicSchema;
|
|
1293
|
+
private: PrivateSchema;
|
|
1294
|
+
hidden: HiddenSchema;
|
|
1295
|
+
};
|
|
1296
|
+
type InitContext<Table extends RuntimeTableRecord, Manifest extends ReducerManifestContract<Table, string, string, string, string, string> = ManifestContract<Table>> = {
|
|
1297
|
+
manifest: Manifest;
|
|
1298
|
+
table: Table;
|
|
1299
|
+
playerIds: PlayerIdOfTable<Table>[];
|
|
1300
|
+
rngSeed?: number | null;
|
|
1301
|
+
setup: SetupSelectionOfManifest<Manifest> | null;
|
|
1302
|
+
q: TableQueriesOfState<{
|
|
1303
|
+
table: Table;
|
|
1304
|
+
}>;
|
|
1305
|
+
};
|
|
1306
|
+
type SetupBootstrapSharedZoneRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1307
|
+
type: "sharedZone";
|
|
1308
|
+
zoneId: SharedZoneIdOfManifest<Manifest>;
|
|
1309
|
+
};
|
|
1310
|
+
type SetupBootstrapPerPlayerZoneRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1311
|
+
type: "playerZone";
|
|
1312
|
+
zoneId: PlayerZoneIdOfManifest<Manifest>;
|
|
1313
|
+
playerId: PlayerIdOfManifest<Manifest>;
|
|
1314
|
+
};
|
|
1315
|
+
type SetupBootstrapSharedBoardContainerRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1316
|
+
type: "sharedBoardContainer";
|
|
1317
|
+
boardId: BoardBaseIdOfManifest<Manifest>;
|
|
1318
|
+
containerId: BoardContainerIdOfManifest<Manifest>;
|
|
1319
|
+
};
|
|
1320
|
+
type SetupBootstrapPerPlayerBoardContainerRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1321
|
+
type: "playerBoardContainer";
|
|
1322
|
+
boardId: BoardBaseIdOfManifest<Manifest>;
|
|
1323
|
+
playerId: PlayerIdOfManifest<Manifest>;
|
|
1324
|
+
containerId: BoardContainerIdOfManifest<Manifest>;
|
|
1325
|
+
};
|
|
1326
|
+
type SetupBootstrapSharedBoardSpaceRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1327
|
+
type: "sharedBoardSpace";
|
|
1328
|
+
boardId: BoardBaseIdOfManifest<Manifest>;
|
|
1329
|
+
spaceId: SpaceIdOfManifest<Manifest>;
|
|
1330
|
+
};
|
|
1331
|
+
type SetupBootstrapPerPlayerBoardSpaceRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1332
|
+
type: "playerBoardSpace";
|
|
1333
|
+
boardId: BoardBaseIdOfManifest<Manifest>;
|
|
1334
|
+
playerId: PlayerIdOfManifest<Manifest>;
|
|
1335
|
+
spaceId: SpaceIdOfManifest<Manifest>;
|
|
1336
|
+
};
|
|
1337
|
+
type SetupBootstrapContainerRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = SetupBootstrapSharedZoneRef<Manifest> | SetupBootstrapPerPlayerZoneRef<Manifest> | SetupBootstrapSharedBoardContainerRef<Manifest> | SetupBootstrapPerPlayerBoardContainerRef<Manifest>;
|
|
1338
|
+
type SetupBootstrapDestinationRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = SetupBootstrapContainerRef<Manifest> | SetupBootstrapSharedBoardSpaceRef<Manifest> | SetupBootstrapPerPlayerBoardSpaceRef<Manifest>;
|
|
1339
|
+
type SetupBootstrapPerPlayerContainerTemplateRef<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1340
|
+
type: "playerZone";
|
|
1341
|
+
zoneId: PlayerZoneIdOfManifest<Manifest>;
|
|
1342
|
+
} | {
|
|
1343
|
+
type: "playerBoardContainer";
|
|
1344
|
+
boardId: BoardBaseIdOfManifest<Manifest>;
|
|
1345
|
+
containerId: BoardContainerIdOfManifest<Manifest>;
|
|
1346
|
+
};
|
|
1347
|
+
type SetupBootstrapStep<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1348
|
+
type: "shuffle";
|
|
1349
|
+
container: SetupBootstrapContainerRef<Manifest>;
|
|
1350
|
+
} | {
|
|
1351
|
+
type: "move";
|
|
1352
|
+
from: SetupBootstrapContainerRef<Manifest>;
|
|
1353
|
+
to: SetupBootstrapDestinationRef<Manifest>;
|
|
1354
|
+
count?: number;
|
|
1355
|
+
componentIds?: readonly (CardIdOfManifest<Manifest> | PieceIdOfManifest<Manifest> | DieIdOfManifest<Manifest>)[];
|
|
1356
|
+
} | {
|
|
1357
|
+
type: "deal";
|
|
1358
|
+
from: SetupBootstrapSharedZoneRef<Manifest> | SetupBootstrapSharedBoardContainerRef<Manifest>;
|
|
1359
|
+
to: SetupBootstrapPerPlayerContainerTemplateRef<Manifest>;
|
|
1360
|
+
count: number;
|
|
1361
|
+
playerIds?: readonly PlayerIdOfManifest<Manifest>[];
|
|
1362
|
+
};
|
|
1363
|
+
type SetupProfileDefinition<PhaseName extends string = string, Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike> = {
|
|
1364
|
+
initialPhase?: PhaseName;
|
|
1365
|
+
bootstrap?: readonly SetupBootstrapStep<Manifest>[];
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
type FlowInstruction<PhaseName extends string> = {
|
|
1369
|
+
kind: "flow.transition";
|
|
1370
|
+
to: PhaseName;
|
|
1371
|
+
};
|
|
1372
|
+
type EngineRollDieInstruction = {
|
|
1373
|
+
kind: "engine.rollDie";
|
|
1374
|
+
dieId: string;
|
|
1375
|
+
continuation?: AnyContinuationToken;
|
|
1376
|
+
};
|
|
1377
|
+
type EngineShuffleSharedZoneInstruction<DeckId extends string> = {
|
|
1378
|
+
kind: "engine.shuffleSharedZone";
|
|
1379
|
+
zoneId: DeckId;
|
|
1380
|
+
continuation?: AnyContinuationToken;
|
|
1381
|
+
};
|
|
1382
|
+
type EngineShufflePlayerZoneInstruction<PlayerZoneId extends string, PlayerId extends string> = {
|
|
1383
|
+
kind: "engine.shufflePlayerZone";
|
|
1384
|
+
zoneId: PlayerZoneId;
|
|
1385
|
+
playerId: PlayerId;
|
|
1386
|
+
continuation?: AnyContinuationToken;
|
|
1387
|
+
};
|
|
1388
|
+
type EngineInstruction<DeckId extends string, PlayerZoneId extends string = string, PlayerId extends string = string> = EngineRollDieInstruction | EngineShuffleSharedZoneInstruction<DeckId> | EngineShufflePlayerZoneInstruction<PlayerZoneId, PlayerId>;
|
|
1389
|
+
type RuntimeInstruction<PhaseName extends string, DeckId extends string, PlayerZoneId extends string = string, PlayerId extends string = string> = FlowInstruction<PhaseName> | EngineInstruction<DeckId, PlayerZoneId, PlayerId>;
|
|
1390
|
+
type RuntimeInstructionForState<State> = RuntimeInstruction<PhaseNameOfState<State>, DeckIdOfState<State>, PlayerZoneIdOfState<State>, PlayerIdOfState<State>>;
|
|
1391
|
+
|
|
1392
|
+
type ContinuationToken<Data = RuntimePayload, ContinuationId extends string = string, Response = RuntimePayload> = {
|
|
1393
|
+
id: ContinuationId;
|
|
1394
|
+
data: Data;
|
|
1395
|
+
readonly __responseType?: Response;
|
|
1396
|
+
};
|
|
1397
|
+
type ContinuationResponseOf<Token> = Token extends ContinuationToken<any, string, infer Response> ? Response : never;
|
|
1398
|
+
type AnyContinuationToken = ContinuationToken<RuntimePayload, string, RuntimePayload>;
|
|
1399
|
+
/**
|
|
1400
|
+
* Declarative choice option. Retained as the shape used by prompt-kind
|
|
1401
|
+
* interactions' `options` field (see `InteractionSpec.options` in
|
|
1402
|
+
* `model/spec.ts`). Independent of any specific prompt authoring API.
|
|
1403
|
+
*/
|
|
1404
|
+
type ChoiceOption<OptionId extends string = string> = {
|
|
1405
|
+
id: OptionId;
|
|
1406
|
+
label: string;
|
|
1407
|
+
};
|
|
1408
|
+
type RuntimePhaseState = object;
|
|
1409
|
+
type PhaseAccessor<PhaseStates extends Record<string, object>, CurrentPhase extends keyof PhaseStates & string = keyof PhaseStates & string> = {
|
|
1410
|
+
get<PhaseName extends keyof PhaseStates & string>(phaseName: PhaseName): CurrentPhase extends PhaseName ? PhaseStates[PhaseName] : PhaseStates[PhaseName] | null;
|
|
1411
|
+
};
|
|
1412
|
+
type FlowState<PhaseName extends string, PlayerId extends string> = {
|
|
1413
|
+
currentPhase: PhaseName;
|
|
1414
|
+
turn: number;
|
|
1415
|
+
round: number;
|
|
1416
|
+
activePlayers: PlayerId[];
|
|
1417
|
+
};
|
|
1418
|
+
type RuntimeRngState = {
|
|
1419
|
+
seed?: number | null;
|
|
1420
|
+
cursor: number;
|
|
1421
|
+
trace: string[];
|
|
1422
|
+
};
|
|
1423
|
+
type RuntimeSimultaneousSubmission = {
|
|
1424
|
+
interactionId: string;
|
|
1425
|
+
params: RuntimePayload;
|
|
1426
|
+
};
|
|
1427
|
+
type RuntimeSimultaneousState<PhaseName extends string, PlayerId extends string> = {
|
|
1428
|
+
current: {
|
|
1429
|
+
phaseName: PhaseName;
|
|
1430
|
+
actors: PlayerId[];
|
|
1431
|
+
submissions: Partial<Record<PlayerId, RuntimeSimultaneousSubmission>>;
|
|
1432
|
+
} | null;
|
|
1433
|
+
};
|
|
1434
|
+
/**
|
|
1435
|
+
* Marker tag attached by `defineEffect` to every effect spec. `fx.effect`
|
|
1436
|
+
* uses `type` to dispatch to the right wire-effect builder.
|
|
1437
|
+
*/
|
|
1438
|
+
type EffectTypeTag = "rollDie" | "shuffleSharedZone" | "shufflePlayerZone";
|
|
1439
|
+
/**
|
|
1440
|
+
* Structural shape of the objects produced by `defineEffect`, as seen by
|
|
1441
|
+
* the `fx.effect` dispatcher. The public, per-type effect definitions live
|
|
1442
|
+
* in `model/spec.ts`.
|
|
1443
|
+
*/
|
|
1444
|
+
type EffectSpecLike<ContextSchema extends AnySchema = AnySchema> = {
|
|
1445
|
+
type: EffectTypeTag;
|
|
1446
|
+
id: string;
|
|
1447
|
+
contextSchema?: ContextSchema;
|
|
1448
|
+
/**
|
|
1449
|
+
* Opaque authoring-time continuation callable. The runtime only needs its
|
|
1450
|
+
* `id`; the heterogeneously-typed `(data) => ...` signature is erased
|
|
1451
|
+
* here. The `data` parameter is typed as `never` so that this structural
|
|
1452
|
+
* upper bound is assignable-from every concrete per-effect continuation
|
|
1453
|
+
* (function parameters are contravariant — a specific `(data: T) => R`
|
|
1454
|
+
* is assignable to `(data: X) => R` only when `X <: T`, and `never <: T`
|
|
1455
|
+
* holds for every `T`).
|
|
1456
|
+
*/
|
|
1457
|
+
__continuation?: ((data: never) => unknown) & {
|
|
1458
|
+
id: string;
|
|
1459
|
+
};
|
|
1460
|
+
};
|
|
1461
|
+
/**
|
|
1462
|
+
* Options accepted by `fx.effect(effect, options)`, specialized by
|
|
1463
|
+
* `effect.type`.
|
|
1464
|
+
*/
|
|
1465
|
+
type EffectContextValue<Effect extends EffectSpecLike> = NonNullable<Effect["contextSchema"]> extends AnySchema ? z.infer<NonNullable<Effect["contextSchema"]>> : undefined;
|
|
1466
|
+
type EffectInvokeOptions<Effect extends EffectSpecLike, State extends {
|
|
1467
|
+
table: RuntimeTableRecord;
|
|
1468
|
+
flow: {
|
|
1469
|
+
currentPhase: string;
|
|
1470
|
+
};
|
|
1471
|
+
}> = Effect["type"] extends "rollDie" ? {
|
|
1472
|
+
dieId: StringKeyOf<TableOfState<State>["dice"]>;
|
|
1473
|
+
context?: EffectContextValue<Effect>;
|
|
1474
|
+
} : Effect["type"] extends "shuffleSharedZone" ? {
|
|
1475
|
+
zoneId: DeckIdOfState<State>;
|
|
1476
|
+
context?: EffectContextValue<Effect>;
|
|
1477
|
+
} : Effect["type"] extends "shufflePlayerZone" ? {
|
|
1478
|
+
zoneId: PlayerZoneIdOfState<State>;
|
|
1479
|
+
playerId: PlayerIdOfState<State>;
|
|
1480
|
+
context?: EffectContextValue<Effect>;
|
|
1481
|
+
} : never;
|
|
1482
|
+
type EffectInstructionForState<Effect extends EffectSpecLike, State extends {
|
|
1483
|
+
table: RuntimeTableRecord;
|
|
1484
|
+
flow: {
|
|
1485
|
+
currentPhase: string;
|
|
1486
|
+
};
|
|
1487
|
+
}> = Effect["type"] extends "rollDie" ? EngineRollDieInstruction : Effect["type"] extends "shuffleSharedZone" ? EngineShuffleSharedZoneInstruction<DeckIdOfState<State>> : Effect["type"] extends "shufflePlayerZone" ? EngineShufflePlayerZoneInstruction<PlayerZoneIdOfState<State>, PlayerIdOfState<State>> : never;
|
|
1488
|
+
type ReducerFx<State extends {
|
|
1489
|
+
table: RuntimeTableRecord;
|
|
1490
|
+
flow: {
|
|
1491
|
+
currentPhase: string;
|
|
1492
|
+
};
|
|
1493
|
+
}> = {
|
|
1494
|
+
transition: <To extends PhaseNameOfState<State>>(to: To) => FlowInstruction<To>;
|
|
1495
|
+
/**
|
|
1496
|
+
* Invoke an engine-side resumable effect authored via `defineEffect`.
|
|
1497
|
+
* The returned runtime instruction is consumed by the engine; if the effect
|
|
1498
|
+
* has a `reduce`, its continuation is delivered back as a typed input.
|
|
1499
|
+
*/
|
|
1500
|
+
effect: <Effect extends EffectSpecLike>(effect: Effect, options: EffectInvokeOptions<Effect, State>) => EffectInstructionForState<Effect, State>;
|
|
1501
|
+
};
|
|
1502
|
+
type RuntimeState<PhaseName extends string, PlayerId extends string, Setup extends RuntimeSetupSelection = RuntimeSetupSelection> = {
|
|
1503
|
+
rng: RuntimeRngState;
|
|
1504
|
+
setup: Setup | null;
|
|
1505
|
+
simultaneous: RuntimeSimultaneousState<PhaseName, PlayerId>;
|
|
1506
|
+
lastTransition: {
|
|
1507
|
+
from: PhaseName;
|
|
1508
|
+
to: PhaseName;
|
|
1509
|
+
} | null;
|
|
1510
|
+
};
|
|
1511
|
+
type ReducerRuntimeStateForState<State extends {
|
|
1512
|
+
table: RuntimeTableRecord;
|
|
1513
|
+
flow: {
|
|
1514
|
+
currentPhase: string;
|
|
1515
|
+
};
|
|
1516
|
+
}, Setup extends RuntimeSetupSelection = RuntimeSetupSelection> = RuntimeState<PhaseNameOfState<State>, PlayerIdOfState<State>, Setup>;
|
|
1517
|
+
type ReducerGameState<Table extends RuntimeTableRecord, PublicState extends object, PrivateState extends object, HiddenState extends object, PhaseState extends RuntimePhaseState, PhaseName extends string, PhaseStates extends Record<PhaseName, object> = Record<PhaseName, PhaseState>> = {
|
|
1518
|
+
table: Table;
|
|
1519
|
+
publicState: PublicState;
|
|
1520
|
+
privateState: Record<PlayerIdOfTable<Table>, PrivateState>;
|
|
1521
|
+
hiddenState: HiddenState;
|
|
1522
|
+
flow: FlowState<PhaseName, PlayerIdOfTable<Table>>;
|
|
1523
|
+
phase: PhaseState & PhaseAccessor<PhaseStates>;
|
|
1524
|
+
};
|
|
1525
|
+
type ReducerValidationResult = {
|
|
1526
|
+
valid: true;
|
|
1527
|
+
} | {
|
|
1528
|
+
valid: false;
|
|
1529
|
+
errorCode: string;
|
|
1530
|
+
message?: string;
|
|
1531
|
+
};
|
|
1532
|
+
type ReducerReject = {
|
|
1533
|
+
type: "reject";
|
|
1534
|
+
errorCode: string;
|
|
1535
|
+
message?: string;
|
|
1536
|
+
};
|
|
1537
|
+
type ReducerAccept<State> = {
|
|
1538
|
+
type: "accept";
|
|
1539
|
+
state: State;
|
|
1540
|
+
instructions?: RuntimeInstructionForState<State>[];
|
|
1541
|
+
};
|
|
1542
|
+
type ReducerResult<State> = ReducerAccept<State> | ReducerReject;
|
|
1543
|
+
|
|
1544
|
+
/**
|
|
1545
|
+
* State composition primitives.
|
|
1546
|
+
*
|
|
1547
|
+
* `pipe` threads a seed state through a sequence of `State -> State`
|
|
1548
|
+
* transformations, left to right. It is the preferred way to compose curried
|
|
1549
|
+
* writers (the `ops.*` namespace) in reducers:
|
|
1550
|
+
*
|
|
1551
|
+
* return accept(
|
|
1552
|
+
* pipe(state,
|
|
1553
|
+
* ops.spendPlayerResources({ playerId, resources: cost }),
|
|
1554
|
+
* ops.placePieceOnVertex({ boardId, vertexId, pieceId, ownerId: playerId }),
|
|
1555
|
+
* ),
|
|
1556
|
+
* );
|
|
1557
|
+
*/
|
|
1558
|
+
/**
|
|
1559
|
+
* A state-preserving transformation.
|
|
1560
|
+
*
|
|
1561
|
+
* `Op<State>` is polymorphic in the exact input subtype — given a state `S`
|
|
1562
|
+
* that extends `State`, it returns the same `S`. This lets curried writers
|
|
1563
|
+
* from `ops.*` and author-written helpers thread through phase-scoped `pipe`
|
|
1564
|
+
* calls without losing the narrowed phase state type.
|
|
1565
|
+
*/
|
|
1566
|
+
type Op<State> = <S extends State>(state: S) => S;
|
|
1567
|
+
declare function pipe<State>(state: State, ...ops: ReadonlyArray<Op<NoInfer<State>>>): State;
|
|
1568
|
+
|
|
1569
|
+
/**
|
|
1570
|
+
* Curried state writers for use with `pipe`.
|
|
1571
|
+
*
|
|
1572
|
+
* Each entry in the returned `ops` namespace is a curried transformation
|
|
1573
|
+
* `(args) => (state) => state` that can be composed with `pipe`:
|
|
1574
|
+
*
|
|
1575
|
+
* const ops = createReducerOps<GameState>();
|
|
1576
|
+
*
|
|
1577
|
+
* return accept(
|
|
1578
|
+
* pipe(state,
|
|
1579
|
+
* ops.setActivePlayers([playerId]),
|
|
1580
|
+
* ops.moveCardFromPlayerZoneToSharedZone({
|
|
1581
|
+
* playerId,
|
|
1582
|
+
* fromZoneId: "things-hand",
|
|
1583
|
+
* toZoneId: "ring-1",
|
|
1584
|
+
* cardId: "a-dog",
|
|
1585
|
+
* }),
|
|
1586
|
+
* ),
|
|
1587
|
+
* );
|
|
1588
|
+
*
|
|
1589
|
+
* The factory binds all ops to a specific `State` type so that ID arguments
|
|
1590
|
+
* (deck ids, card ids, etc.) are checked against the manifest-derived table
|
|
1591
|
+
* shape of the game.
|
|
1592
|
+
*/
|
|
1593
|
+
|
|
1594
|
+
/**
|
|
1595
|
+
* Minimum shape required for any state targeted by reducer ops.
|
|
1596
|
+
*
|
|
1597
|
+
* All curried writers operate on a game state with a `table` field.
|
|
1598
|
+
*/
|
|
1599
|
+
type ReducerStateBase = {
|
|
1600
|
+
table: RuntimeTableRecord;
|
|
1601
|
+
};
|
|
1602
|
+
type PipeTable<State extends ReducerStateBase> = TableOfState<State>;
|
|
1603
|
+
/**
|
|
1604
|
+
* A shallow patch for a slice of state. Either a partial object to merge
|
|
1605
|
+
* over the previous value, or a functional updater `(prev) => next`.
|
|
1606
|
+
*/
|
|
1607
|
+
type StatePatch<T> = Partial<T> | ((prev: T) => T);
|
|
1608
|
+
/**
|
|
1609
|
+
* Curried writer namespace for a specific game state type.
|
|
1610
|
+
*
|
|
1611
|
+
* Created via {@link createReducerOps}.
|
|
1612
|
+
*/
|
|
1613
|
+
interface ReducerOps<State extends ReducerStateBase> {
|
|
1614
|
+
/** Set the list of players whose turn is currently active. */
|
|
1615
|
+
setActivePlayers(activePlayers: ReadonlyArray<PlayerIdOfState<State>>): Op<State>;
|
|
1616
|
+
/**
|
|
1617
|
+
* Advance `flow.activePlayers` to the single next seat in `playerOrder`.
|
|
1618
|
+
*
|
|
1619
|
+
* Uses `state.flow.activePlayers[0]` as the current seat (or the first
|
|
1620
|
+
* seat in `playerOrder` when `activePlayers` is empty) and sets
|
|
1621
|
+
* `activePlayers` to `[q.player.nextInOrder(current)]`. No-op when the
|
|
1622
|
+
* player order is empty.
|
|
1623
|
+
*/
|
|
1624
|
+
advanceActivePlayer(): Op<State>;
|
|
1625
|
+
/**
|
|
1626
|
+
* Update the current phase's local state.
|
|
1627
|
+
*
|
|
1628
|
+
* Accepts either a `Partial<PhaseState>` which is shallow-merged into the
|
|
1629
|
+
* previous value, or a functional updater `(prev) => next` which must
|
|
1630
|
+
* return a complete `PhaseState`.
|
|
1631
|
+
*/
|
|
1632
|
+
patchPhaseState(patch: StatePatch<PhaseStateOfState<State>>): Op<State>;
|
|
1633
|
+
/**
|
|
1634
|
+
* Update `state.publicState`.
|
|
1635
|
+
*
|
|
1636
|
+
* Accepts either a `Partial<PublicState>` which is shallow-merged into the
|
|
1637
|
+
* previous value, or a functional updater `(prev) => next` which must
|
|
1638
|
+
* return a complete `PublicState`.
|
|
1639
|
+
*/
|
|
1640
|
+
patchPublicState(patch: StatePatch<PublicStateOfState<State>>): Op<State>;
|
|
1641
|
+
/**
|
|
1642
|
+
* Update `state.hiddenState`.
|
|
1643
|
+
*
|
|
1644
|
+
* Accepts either a `Partial<HiddenState>` or a functional updater.
|
|
1645
|
+
*/
|
|
1646
|
+
patchHiddenState(patch: StatePatch<HiddenStateOfState<State>>): Op<State>;
|
|
1647
|
+
/**
|
|
1648
|
+
* Update a single player's entry in `state.privateState`.
|
|
1649
|
+
*
|
|
1650
|
+
* Accepts either a `Partial<PrivateState>` or a functional updater.
|
|
1651
|
+
*/
|
|
1652
|
+
patchPlayerPrivateState(args: {
|
|
1653
|
+
playerId: PlayerIdOfState<State>;
|
|
1654
|
+
patch: StatePatch<PrivateStateOfState<State>>;
|
|
1655
|
+
}): Op<State>;
|
|
1656
|
+
/**
|
|
1657
|
+
* Append a card to a shared zone (deck). Defaults to placing the card at the
|
|
1658
|
+
* bottom; pass `position: "top"` for top-of-deck placement (e.g. Bureaucrat-style).
|
|
1659
|
+
*/
|
|
1660
|
+
addCardToSharedZone<DeckId extends SharedZoneIdOfTable<PipeTable<State>>>(args: {
|
|
1661
|
+
deckId: DeckId;
|
|
1662
|
+
cardId: DeckCardsOfTable<PipeTable<State>, DeckId>[number];
|
|
1663
|
+
playedBy?: PlayerIdOfTable<PipeTable<State>> | null;
|
|
1664
|
+
position?: "top" | "bottom";
|
|
1665
|
+
}): Op<State>;
|
|
1666
|
+
/** Remove a card from a shared zone (deck). */
|
|
1667
|
+
removeCardFromSharedZone<DeckId extends DeckIdOfTable<PipeTable<State>>>(args: {
|
|
1668
|
+
deckId: DeckId;
|
|
1669
|
+
cardId: DeckCardsOfTable<PipeTable<State>, DeckId>[number];
|
|
1670
|
+
}): Op<State>;
|
|
1671
|
+
/**
|
|
1672
|
+
* Move a card between two shared zones (decks). Defaults to placing the card
|
|
1673
|
+
* at the bottom of the destination; pass `position: "top"` for top placement.
|
|
1674
|
+
*/
|
|
1675
|
+
moveCardBetweenSharedZones<FromZoneId extends SharedZoneIdOfTable<PipeTable<State>>, ToZoneId extends SharedZoneIdOfTable<PipeTable<State>>>(args: {
|
|
1676
|
+
fromZoneId: FromZoneId;
|
|
1677
|
+
toZoneId: ToZoneId;
|
|
1678
|
+
cardId: DeckCardsOfTable<PipeTable<State>, FromZoneId>[number];
|
|
1679
|
+
playedBy?: PlayerIdOfTable<PipeTable<State>> | null;
|
|
1680
|
+
position?: "top" | "bottom";
|
|
1681
|
+
}): Op<State>;
|
|
1682
|
+
/**
|
|
1683
|
+
* Draw the top `count` cards from one perPlayer zone into another for the
|
|
1684
|
+
* same player (e.g. deck → hand at the start of a turn). Companion to
|
|
1685
|
+
* {@link dealCardsToPlayerZone} for the perPlayer → perPlayer case. Stops
|
|
1686
|
+
* silently if the source runs out before `count` is reached.
|
|
1687
|
+
*/
|
|
1688
|
+
dealCardsBetweenPlayerZones<FromZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, ToZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>>(args: {
|
|
1689
|
+
playerId: PlayerId;
|
|
1690
|
+
fromZoneId: FromZoneId;
|
|
1691
|
+
toZoneId: ToZoneId;
|
|
1692
|
+
count: number;
|
|
1693
|
+
}): Op<State>;
|
|
1694
|
+
/**
|
|
1695
|
+
* Move a card between two perPlayer zones owned by the same player (e.g.
|
|
1696
|
+
* hand → in-play → discard). Owner is preserved; visibility is recomputed
|
|
1697
|
+
* from the destination zone.
|
|
1698
|
+
*/
|
|
1699
|
+
moveCardBetweenPlayerZones<FromZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, ToZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>>(args: {
|
|
1700
|
+
playerId: PlayerId;
|
|
1701
|
+
fromZoneId: FromZoneId;
|
|
1702
|
+
toZoneId: ToZoneId;
|
|
1703
|
+
cardId: CompatibleCardIdForTwoPlayerZones<PipeTable<State>, FromZoneId, ToZoneId>;
|
|
1704
|
+
position?: "top" | "bottom";
|
|
1705
|
+
}): Op<State>;
|
|
1706
|
+
/**
|
|
1707
|
+
* Move a card from a player zone (hand) to a shared zone (deck). Defaults to
|
|
1708
|
+
* placing the card at the bottom; pass `position: "top"` to topdeck.
|
|
1709
|
+
*/
|
|
1710
|
+
moveCardFromPlayerZoneToSharedZone<FromZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, ToZoneId extends SharedZoneIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>>(args: {
|
|
1711
|
+
playerId: PlayerId;
|
|
1712
|
+
fromZoneId: FromZoneId;
|
|
1713
|
+
toZoneId: ToZoneId;
|
|
1714
|
+
cardId: CompatibleCardIdForHandAndDeck<PipeTable<State>, FromZoneId, ToZoneId>;
|
|
1715
|
+
playedBy?: PlayerIdOfTable<PipeTable<State>> | null;
|
|
1716
|
+
position?: "top" | "bottom";
|
|
1717
|
+
}): Op<State>;
|
|
1718
|
+
/**
|
|
1719
|
+
* Move a named card from a shared zone (supply pile, deck) to a perPlayer
|
|
1720
|
+
* zone (e.g. discard). The "gain" verb in deck-builders. Distinct from
|
|
1721
|
+
* {@link dealCardsToPlayerZone}, which draws unspecified top-N cards from a
|
|
1722
|
+
* deck. Owner flips to the receiving player; visibility is recomputed.
|
|
1723
|
+
*/
|
|
1724
|
+
moveCardFromSharedZoneToPlayerZone<FromZoneId extends SharedZoneIdOfTable<PipeTable<State>>, ToZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>>(args: {
|
|
1725
|
+
playerId: PlayerId;
|
|
1726
|
+
fromZoneId: FromZoneId;
|
|
1727
|
+
toZoneId: ToZoneId;
|
|
1728
|
+
cardId: CompatibleCardIdForHandAndDeck<PipeTable<State>, ToZoneId, FromZoneId>;
|
|
1729
|
+
position?: "top" | "bottom";
|
|
1730
|
+
}): Op<State>;
|
|
1731
|
+
/**
|
|
1732
|
+
* Deal the top `count` cards from a shared deck into a player's hand zone.
|
|
1733
|
+
*
|
|
1734
|
+
* This op does not consume RNG. If the deck needs to be random, shuffle it
|
|
1735
|
+
* first with `fx.shuffleSharedZone(...)`, then deal from the shuffled deck
|
|
1736
|
+
* inside the same reducer via this op.
|
|
1737
|
+
*/
|
|
1738
|
+
dealCardsToPlayerZone<FromZoneId extends DeckIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>, ToZoneId extends CompatibleHandIdForDeck<PipeTable<State>, FromZoneId> & HandIdOfTable<PipeTable<State>>>(args: {
|
|
1739
|
+
fromZoneId: FromZoneId;
|
|
1740
|
+
playerId: PlayerId;
|
|
1741
|
+
toZoneId: ToZoneId;
|
|
1742
|
+
count: number;
|
|
1743
|
+
}): Op<State>;
|
|
1744
|
+
/**
|
|
1745
|
+
* Atomically rotate cards in a per-player zone around the table.
|
|
1746
|
+
*
|
|
1747
|
+
* Defaults to rotating every card currently in `zoneId` for every player in
|
|
1748
|
+
* turn order. Pass `players` to use a smaller explicit order, or
|
|
1749
|
+
* `cardIdsByPlayer` to rotate only selected cards such as Hearts passes.
|
|
1750
|
+
*/
|
|
1751
|
+
rotatePlayerZone<ZoneId extends PlayerZoneIdOfTable<PipeTable<State>>, PlayerId extends PlayerIdOfTable<PipeTable<State>>>(args: {
|
|
1752
|
+
zoneId: ZoneId;
|
|
1753
|
+
direction: "left" | "right";
|
|
1754
|
+
players?: readonly PlayerId[];
|
|
1755
|
+
cardIdsByPlayer?: Partial<Record<PlayerId, readonly CardIdOfTable<PipeTable<State>>[]>>;
|
|
1756
|
+
position?: "top" | "bottom";
|
|
1757
|
+
}): Op<State>;
|
|
1758
|
+
/** Move a component onto a board space. */
|
|
1759
|
+
moveComponentToSpace<BoardId extends BoardIdOfTable<PipeTable<State>>, SpaceId extends SpaceIdOfTable<PipeTable<State>, BoardId>, ComponentId extends ComponentIdOfTable<PipeTable<State>>>(args: {
|
|
1760
|
+
componentId: ComponentId;
|
|
1761
|
+
boardId: BoardId;
|
|
1762
|
+
spaceId: SpaceId;
|
|
1763
|
+
}): Op<State>;
|
|
1764
|
+
/** Move a component into a board container. */
|
|
1765
|
+
moveComponentToContainer<BoardId extends BoardIdOfTable<PipeTable<State>>, ContainerId extends BoardContainerIdOfTable<PipeTable<State>, BoardId>, ComponentId extends ComponentIdOfTable<PipeTable<State>>>(args: {
|
|
1766
|
+
componentId: ComponentId;
|
|
1767
|
+
boardId: BoardId;
|
|
1768
|
+
containerId: ContainerId;
|
|
1769
|
+
}): Op<State>;
|
|
1770
|
+
/** Move a component onto a tiled board edge. */
|
|
1771
|
+
moveComponentToEdge<BoardId extends TiledBoardIdOfTable<PipeTable<State>>, EdgeId extends TiledEdgeIdOfTable<PipeTable<State>, BoardId>, ComponentId extends ComponentIdOfTable<PipeTable<State>>>(args: {
|
|
1772
|
+
componentId: ComponentId;
|
|
1773
|
+
boardId: BoardId;
|
|
1774
|
+
edgeId: EdgeId;
|
|
1775
|
+
}): Op<State>;
|
|
1776
|
+
/** Move a component onto a tiled board vertex. */
|
|
1777
|
+
moveComponentToVertex<BoardId extends TiledBoardIdOfTable<PipeTable<State>>, VertexId extends TiledVertexIdOfTable<PipeTable<State>, BoardId>, ComponentId extends ComponentIdOfTable<PipeTable<State>>>(args: {
|
|
1778
|
+
componentId: ComponentId;
|
|
1779
|
+
boardId: BoardId;
|
|
1780
|
+
vertexId: VertexId;
|
|
1781
|
+
}): Op<State>;
|
|
1782
|
+
/** Move a component back to the detached pool. */
|
|
1783
|
+
moveComponentToDetached<ComponentId extends ComponentIdOfTable<PipeTable<State>>>(args: {
|
|
1784
|
+
componentId: ComponentId;
|
|
1785
|
+
}): Op<State>;
|
|
1786
|
+
/**
|
|
1787
|
+
* Credit the specified resources to a player.
|
|
1788
|
+
*
|
|
1789
|
+
* Amounts must be non-negative; use {@link spendResources} for deductions
|
|
1790
|
+
* so that affordability is checked explicitly.
|
|
1791
|
+
*
|
|
1792
|
+
* pipe(
|
|
1793
|
+
* state,
|
|
1794
|
+
* ops.addResources({ playerId, amounts: { wood: 1, brick: 1 } }),
|
|
1795
|
+
* )
|
|
1796
|
+
*/
|
|
1797
|
+
addResources(args: {
|
|
1798
|
+
playerId: PlayerIdOfTable<PipeTable<State>>;
|
|
1799
|
+
amounts: ResourceAmountsOfTable<PipeTable<State>>;
|
|
1800
|
+
}): Op<State>;
|
|
1801
|
+
/**
|
|
1802
|
+
* Debit the specified resources from a player.
|
|
1803
|
+
*
|
|
1804
|
+
* Throws when the player cannot afford the full cost — gate with
|
|
1805
|
+
* `q.player.canAfford(...)` in your `validate` step before invoking.
|
|
1806
|
+
*
|
|
1807
|
+
* pipe(
|
|
1808
|
+
* state,
|
|
1809
|
+
* ops.spendResources({ playerId, amounts: COST_DEV_CARD }),
|
|
1810
|
+
* ops.dealCardsToPlayerZone({ ... }),
|
|
1811
|
+
* )
|
|
1812
|
+
*/
|
|
1813
|
+
spendResources(args: {
|
|
1814
|
+
playerId: PlayerIdOfTable<PipeTable<State>>;
|
|
1815
|
+
amounts: ResourceAmountsOfTable<PipeTable<State>>;
|
|
1816
|
+
}): Op<State>;
|
|
1817
|
+
/**
|
|
1818
|
+
* Transfer the specified resources from one player to another.
|
|
1819
|
+
*
|
|
1820
|
+
* Throws when the source cannot afford the full amount. On success the
|
|
1821
|
+
* destination gains exactly what the source loses.
|
|
1822
|
+
*/
|
|
1823
|
+
transferResources(args: {
|
|
1824
|
+
fromPlayerId: PlayerIdOfTable<PipeTable<State>>;
|
|
1825
|
+
toPlayerId: PlayerIdOfTable<PipeTable<State>>;
|
|
1826
|
+
amounts: ResourceAmountsOfTable<PipeTable<State>>;
|
|
1827
|
+
}): Op<State>;
|
|
1828
|
+
/**
|
|
1829
|
+
* Overwrite a single resource balance for a player. Prefer
|
|
1830
|
+
* {@link addResources} / {@link spendResources} — use this only when the
|
|
1831
|
+
* new balance is an absolute (e.g. scripted setup).
|
|
1832
|
+
*/
|
|
1833
|
+
setResource(args: {
|
|
1834
|
+
playerId: PlayerIdOfTable<PipeTable<State>>;
|
|
1835
|
+
resourceId: ResourceIdOfTable<PipeTable<State>>;
|
|
1836
|
+
amount: number;
|
|
1837
|
+
}): Op<State>;
|
|
1838
|
+
}
|
|
1839
|
+
/**
|
|
1840
|
+
* Create the `ops.*` namespace specialised to a game state.
|
|
1841
|
+
*
|
|
1842
|
+
* Call this once (typically in a shared reducer-support module) and reuse the
|
|
1843
|
+
* resulting object across phases:
|
|
1844
|
+
*
|
|
1845
|
+
* export const ops = createReducerOps<GameState>();
|
|
1846
|
+
*/
|
|
1847
|
+
declare function createReducerOps<State extends ReducerStateBase>(): ReducerOps<State>;
|
|
1848
|
+
|
|
1849
|
+
type RotatePlayerZoneArgs<State extends {
|
|
1850
|
+
table: RuntimeTableRecord;
|
|
1851
|
+
}, ZoneId extends PlayerZoneIdOfTable<TableOfState<State>> = PlayerZoneIdOfTable<TableOfState<State>>, PlayerId extends PlayerIdOfTable<TableOfState<State>> = PlayerIdOfTable<TableOfState<State>>> = {
|
|
1852
|
+
zoneId: ZoneId;
|
|
1853
|
+
direction: "left" | "right";
|
|
1854
|
+
players?: readonly PlayerId[];
|
|
1855
|
+
cardIdsByPlayer?: Partial<Record<PlayerId, readonly CardIdOfTable<TableOfState<State>>[]>>;
|
|
1856
|
+
position?: "top" | "bottom";
|
|
1857
|
+
};
|
|
1858
|
+
type TransactionMethods<State extends {
|
|
1859
|
+
table: RuntimeTableRecord;
|
|
1860
|
+
}> = {
|
|
1861
|
+
[Key in Exclude<keyof ReducerOps<State>, "moveComponentToSpace">]: ReducerOps<State>[Key] extends (...args: infer Args) => Op<State> ? (...args: Args) => State : never;
|
|
1862
|
+
} & {
|
|
1863
|
+
moveComponentToSpace<BoardId extends BoardIdOfTable<TableOfState<State>>, SpaceId extends SpaceIdOfTable<TableOfState<State>, BoardId>, ComponentId extends ComponentIdOfTable<TableOfState<State>>>(args: {
|
|
1864
|
+
componentId: ComponentId;
|
|
1865
|
+
boardId: BoardId;
|
|
1866
|
+
spaceId: SpaceId;
|
|
1867
|
+
}): State;
|
|
1868
|
+
};
|
|
1869
|
+
type ReducerTransaction<State extends {
|
|
1870
|
+
table: RuntimeTableRecord;
|
|
1871
|
+
}> = TransactionMethods<State> & {
|
|
1872
|
+
readonly state: State;
|
|
1873
|
+
readonly q: TableQueriesOfState<State>;
|
|
1874
|
+
apply(op: Op<State>): State;
|
|
1875
|
+
rotatePlayerZone<ZoneId extends PlayerZoneIdOfTable<TableOfState<State>>, PlayerId extends PlayerIdOfTable<TableOfState<State>>>(args: RotatePlayerZoneArgs<State, ZoneId, PlayerId>): State;
|
|
1876
|
+
};
|
|
1877
|
+
type ReducerEdit<State extends {
|
|
1878
|
+
table: RuntimeTableRecord;
|
|
1879
|
+
}> = <DraftState extends State>(state: DraftState) => ReducerTransaction<DraftState>;
|
|
1880
|
+
declare function createReducerTransaction<State extends {
|
|
1881
|
+
table: RuntimeTableRecord;
|
|
1882
|
+
}>(initialState: State, ops?: ReducerOps<State>): ReducerTransaction<State>;
|
|
1883
|
+
declare function createReducerEdit<State extends {
|
|
1884
|
+
table: RuntimeTableRecord;
|
|
1885
|
+
}>(ops?: ReducerOps<State>): ReducerEdit<State>;
|
|
1886
|
+
|
|
1887
|
+
type ReducerGameContract<Table extends RuntimeTableRecord, Manifest extends ReducerManifestContract<Table, string, string, string, string, string>, PublicSchema extends SchemaLike<object>, PrivateSchema extends SchemaLike<object>, HiddenSchema extends SchemaLike<object>, Phases extends Record<string, SchemaLike<object>>> = {
|
|
1888
|
+
manifest: Manifest;
|
|
1889
|
+
state: StateDefinition<PublicSchema, PrivateSchema, HiddenSchema>;
|
|
1890
|
+
phases: Phases;
|
|
1891
|
+
/** Derived from `phases`; retained as an internal runtime convenience. */
|
|
1892
|
+
phaseNames: readonly string[];
|
|
1893
|
+
};
|
|
1894
|
+
type BaseGameStateOfContract<Contract> = ReducerGameState<TableOfManifest<ManifestContractOf<Contract>>, z.infer<PublicSchemaOfContract<Contract>>, z.infer<PrivateSchemaOfContract<Contract>>, z.infer<HiddenSchemaOfContract<Contract>>, PhaseStateMapOfContract<Contract>[PhaseNameOfContract<Contract>], PhaseNameOfContract<Contract>, PhaseStateMapOfContract<Contract>>;
|
|
1895
|
+
/**
|
|
1896
|
+
* Heterogeneous phase map for a contract. Each phase carries its own local
|
|
1897
|
+
* `PhaseStateSchema` plus authoring-time Actions/Flows/Interactions/
|
|
1898
|
+
* Stages/Zones maps. The registries are bound to the contract's base state +
|
|
1899
|
+
* manifest so the runtime can iterate them through a single index type
|
|
1900
|
+
* without reaching for `any`.
|
|
1901
|
+
*/
|
|
1902
|
+
type PhaseMapOf<Contract> = {
|
|
1903
|
+
[Name in PhaseNameOfContract<Contract>]: PhaseDefinition<SchemaLike<object>, BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>, Record<string, InputCollector>, EffectMap<BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>>, InteractionMap<BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>>, StageMap<BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>>, PhaseZoneList<ManifestContractOf<Contract>>, CardActionMap<BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>>>;
|
|
1904
|
+
};
|
|
1905
|
+
type PhaseStateOfDefinitions<Definitions extends Record<string, PhaseDefinition<SchemaLike<object>, any, any, Record<string, InputCollector>, EffectMap<any, any>, InteractionMap<any, any>, StageMap<any, any>, PhaseZoneList<any>, CardActionMap<any, any>>>> = {
|
|
1906
|
+
[Name in keyof Definitions & string]: Definitions[Name] extends PhaseDefinition<infer PhaseStateSchema, infer _State, infer _Manifest> ? z.infer<PhaseStateSchema> : never;
|
|
1907
|
+
}[keyof Definitions & string];
|
|
1908
|
+
type ResolvedGameStateOf<Contract, Definitions extends PhaseMapOf<Contract>> = {
|
|
1909
|
+
[Name in keyof Definitions & string]: ReducerGameState<TableOfManifest<ManifestContractOf<Contract>>, z.infer<PublicSchemaOfContract<Contract>>, z.infer<PrivateSchemaOfContract<Contract>>, z.infer<HiddenSchemaOfContract<Contract>>, Definitions[Name] extends PhaseDefinition<infer PhaseStateSchema, infer _State, infer _Manifest> ? z.infer<PhaseStateSchema> : never, PhaseNameOfContract<Contract>> & {
|
|
1910
|
+
flow: ReducerGameState<TableOfManifest<ManifestContractOf<Contract>>, z.infer<PublicSchemaOfContract<Contract>>, z.infer<PrivateSchemaOfContract<Contract>>, z.infer<HiddenSchemaOfContract<Contract>>, PhaseStateOfDefinitions<Definitions>, PhaseNameOfContract<Contract>>["flow"] & {
|
|
1911
|
+
currentPhase: Name;
|
|
1912
|
+
};
|
|
1913
|
+
};
|
|
1914
|
+
}[keyof Definitions & string];
|
|
1915
|
+
type ViewMapOf<Contract> = Record<string, ViewDefinition<BaseGameStateOfContract<Contract>, ManifestContractOf<Contract>, unknown>>;
|
|
1916
|
+
type PhasesOfDefinition<Definition> = Definition extends {
|
|
1917
|
+
phases: infer Definitions extends Record<string, unknown>;
|
|
1918
|
+
} ? Definitions : never;
|
|
1919
|
+
type ViewsOfDefinition<Definition> = Definition extends {
|
|
1920
|
+
views?: infer Views;
|
|
1921
|
+
} ? NonNullable<Views> : never;
|
|
1922
|
+
type NonNeverKeys<Registry> = {
|
|
1923
|
+
[Key in keyof Registry]-?: [Registry[Key]] extends [never] ? never : Key;
|
|
1924
|
+
}[keyof Registry];
|
|
1925
|
+
type ViewNamesOfDefinition<Definition> = NonNeverKeys<ViewsOfDefinition<Definition>> & string;
|
|
1926
|
+
type ViewDefinitionByName<Definition, ViewName extends ViewNamesOfDefinition<Definition>> = ViewsOfDefinition<Definition>[ViewName];
|
|
1927
|
+
type ViewOfDefinition<Definition, ViewName extends ViewNamesOfDefinition<Definition>> = ViewDefinitionByName<Definition, ViewName> extends ViewDefinition<infer _State, infer _Manifest, infer Projection> ? Projection : never;
|
|
1928
|
+
type PhaseNamesOfDefinition<Definition> = keyof PhasesOfDefinition<Definition> & string;
|
|
1929
|
+
type PhaseDefinitionByName<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseName extends keyof PhasesOfDefinition<Definition> & string ? PhasesOfDefinition<Definition>[PhaseName] : never;
|
|
1930
|
+
type EffectsOfDefinition<Definition> = PhasesOfDefinition<Definition>[keyof PhasesOfDefinition<Definition> & string] extends {
|
|
1931
|
+
effects?: infer Effects;
|
|
1932
|
+
} ? Effects extends Record<string, unknown> ? Effects[keyof Effects & string] : never : never;
|
|
1933
|
+
type EffectIdsOfDefinition<Definition> = EffectsOfDefinition<Definition> extends infer Effect ? Effect extends {
|
|
1934
|
+
id: infer Id;
|
|
1935
|
+
} ? Extract<Id, string> : never : never;
|
|
1936
|
+
type GameStateOf<Source> = Source extends ReducerGameDefinition<infer Contract, infer Definitions, infer _Views> ? ResolvedGameStateOf<Contract, Definitions> : Source extends ReducerGameContract<any, any, any, any, any, any> ? BaseGameStateOfContract<Source> : never;
|
|
1937
|
+
/**
|
|
1938
|
+
* Public structural upper bound for a reducer game contract.
|
|
1939
|
+
*
|
|
1940
|
+
* The `manifest` slot is intentionally erased with `any` because concrete
|
|
1941
|
+
* manifests bind per-contract branded literals (e.g. `PlayerId` unions with
|
|
1942
|
+
* specific string literals). Using a ground `ManifestContract<...>` type
|
|
1943
|
+
* here would prevent assignability from contract-bound manifests in a
|
|
1944
|
+
* contravariant position.
|
|
1945
|
+
*/
|
|
1946
|
+
type ReducerGameContractLike = {
|
|
1947
|
+
manifest: any;
|
|
1948
|
+
state: StateDefinition<SchemaLike<object>, SchemaLike<object>, SchemaLike<object>>;
|
|
1949
|
+
};
|
|
1950
|
+
type InitialStateContextOf<Contract extends ReducerGameContractLike> = InitContext<TableOfManifest<ManifestOf<Contract>>, ExactManifestContractOf<Contract>>;
|
|
1951
|
+
type InitialStateCallbacks<Contract extends ReducerGameContractLike> = {
|
|
1952
|
+
public?: (ctx: InitialStateContextOf<Contract>) => z.infer<PublicSchemaOfContract<Contract>>;
|
|
1953
|
+
private?: (ctx: InitialStateContextOf<Contract> & {
|
|
1954
|
+
playerId: PlayerIdOfTable<TableOfManifest<ManifestOf<Contract>>>;
|
|
1955
|
+
}) => z.infer<PrivateSchemaOfContract<Contract>>;
|
|
1956
|
+
hidden?: (ctx: InitialStateContextOf<Contract>) => z.infer<HiddenSchemaOfContract<Contract>>;
|
|
1957
|
+
};
|
|
1958
|
+
type ReducerGameDefinition<Contract extends ReducerGameContractLike, Definitions extends PhaseMapOf<Contract>, Views extends ViewMapOf<Contract> = Record<string, never>> = {
|
|
1959
|
+
contract: Contract;
|
|
1960
|
+
initial?: InitialStateCallbacks<NoInfer<Contract>>;
|
|
1961
|
+
initialPhase?: keyof Definitions & string;
|
|
1962
|
+
setupProfiles?: Record<string, SetupProfileDefinition<keyof Definitions & string, ExactManifestContractOf<Contract>>>;
|
|
1963
|
+
phases: Definitions;
|
|
1964
|
+
views?: Views;
|
|
1965
|
+
/**
|
|
1966
|
+
* Optional session-scoped static projection. Authored via
|
|
1967
|
+
* {@link StaticViewDefinition}; computed once per reducer session from the
|
|
1968
|
+
* manifest + setup profile and cached by the host. The client merges the
|
|
1969
|
+
* cached payload into every seat view, so the per-tick `projectSeatsDynamic`
|
|
1970
|
+
* call no longer needs to re-serialize static board topology.
|
|
1971
|
+
*/
|
|
1972
|
+
staticView?: StaticViewDefinition<ExactManifestContractOf<NoInfer<Contract>>, unknown>;
|
|
1973
|
+
};
|
|
1974
|
+
type InteractionRegistriesOfDefinition<Definition> = PhasesOfDefinition<Definition>[keyof PhasesOfDefinition<Definition> & string] extends {
|
|
1975
|
+
interactions?: infer Interactions;
|
|
1976
|
+
} ? NonNullable<Interactions> : never;
|
|
1977
|
+
type SimultaneousSubmitRegistriesOfDefinition<Definition> = PhasesOfDefinition<Definition>[keyof PhasesOfDefinition<Definition> & string] extends {
|
|
1978
|
+
submit?: infer Submit;
|
|
1979
|
+
} ? {
|
|
1980
|
+
submit: NonNullable<Submit>;
|
|
1981
|
+
} : never;
|
|
1982
|
+
type CardActionRegistriesOfDefinition<Definition> = PhasesOfDefinition<Definition>[keyof PhasesOfDefinition<Definition> & string] extends {
|
|
1983
|
+
cardActions?: infer CardActions;
|
|
1984
|
+
} ? NonNullable<CardActions> : never;
|
|
1985
|
+
type InteractionIdOfDefinition<Definition> = InteractionRegistriesOfDefinition<Definition> extends infer Interactions ? SimultaneousSubmitRegistriesOfDefinition<Definition> extends infer Submit ? CardActionRegistriesOfDefinition<Definition> extends infer CardActions ? Interactions extends Record<string, unknown> ? CardActions extends Record<string, unknown> ? Submit extends Record<string, unknown> ? (NonNeverKeys<Interactions> & string) | (NonNeverKeys<CardActions> & string) | (NonNeverKeys<Submit> & string) : (NonNeverKeys<Interactions> & string) | (NonNeverKeys<CardActions> & string) : Submit extends Record<string, unknown> ? (NonNeverKeys<Interactions> & string) | (NonNeverKeys<Submit> & string) : NonNeverKeys<Interactions> & string : CardActions extends Record<string, unknown> ? Submit extends Record<string, unknown> ? (NonNeverKeys<CardActions> & string) | (NonNeverKeys<Submit> & string) : NonNeverKeys<CardActions> & string : Submit extends Record<string, unknown> ? NonNeverKeys<Submit> & string : never : never : never : never;
|
|
1986
|
+
type InteractionRegistryOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseDefinitionByName<Definition, PhaseName> extends {
|
|
1987
|
+
interactions?: infer Interactions;
|
|
1988
|
+
} ? NonNullable<Interactions> : Record<string, never>;
|
|
1989
|
+
type SimultaneousSubmitRegistryOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseDefinitionByName<Definition, PhaseName> extends {
|
|
1990
|
+
submit?: infer Submit;
|
|
1991
|
+
} ? {
|
|
1992
|
+
submit: NonNullable<Submit>;
|
|
1993
|
+
} : Record<string, never>;
|
|
1994
|
+
type CardActionRegistryOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseDefinitionByName<Definition, PhaseName> extends {
|
|
1995
|
+
cardActions?: infer CardActions;
|
|
1996
|
+
} ? NonNullable<CardActions> : Record<string, never>;
|
|
1997
|
+
type NonNeverRegistryValue<Registry, Key extends string> = Registry extends Record<string, unknown> ? Key extends keyof Registry ? [Registry[Key]] extends [never] ? never : Registry[Key] : never : never;
|
|
1998
|
+
type InteractionIdOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = InteractionRegistryOfDefinitionPhase<Definition, PhaseName> extends infer Interactions ? SimultaneousSubmitRegistryOfDefinitionPhase<Definition, PhaseName> extends infer Submit ? CardActionRegistryOfDefinitionPhase<Definition, PhaseName> extends infer CardActions ? Interactions extends Record<string, unknown> ? CardActions extends Record<string, unknown> ? Submit extends Record<string, unknown> ? (NonNeverKeys<Interactions> & string) | (NonNeverKeys<CardActions> & string) | (NonNeverKeys<Submit> & string) : (NonNeverKeys<Interactions> & string) | (NonNeverKeys<CardActions> & string) : Submit extends Record<string, unknown> ? (NonNeverKeys<Interactions> & string) | (NonNeverKeys<Submit> & string) : NonNeverKeys<Interactions> & string : CardActions extends Record<string, unknown> ? Submit extends Record<string, unknown> ? (NonNeverKeys<CardActions> & string) | (NonNeverKeys<Submit> & string) : NonNeverKeys<CardActions> & string : Submit extends Record<string, unknown> ? NonNeverKeys<Submit> & string : never : never : never : never;
|
|
1999
|
+
type InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>> = InteractionRegistryOfDefinitionPhase<Definition, PhaseName> extends infer Interactions ? Interactions extends Record<string, unknown> ? NonNeverRegistryValue<Interactions, InteractionId> extends infer InteractionSpec ? [InteractionSpec] extends [never] ? CardActionRegistryOfDefinitionPhase<Definition, PhaseName> extends infer CardActions ? NonNeverRegistryValue<CardActions, InteractionId> extends infer CardActionSpec ? [CardActionSpec] extends [never] ? SimultaneousSubmitRegistryOfDefinitionPhase<Definition, PhaseName> extends infer Submit ? NonNeverRegistryValue<Submit, InteractionId> : never : CardActionSpec : never : never : InteractionSpec : never : never : never;
|
|
2000
|
+
type CollectorKindsOf<Collectors> = Collectors extends Record<string, InputCollector> ? Collectors[keyof Collectors] extends infer Collector ? Collector extends {
|
|
2001
|
+
kind: infer Kind extends string;
|
|
2002
|
+
} ? Kind : never : never : never;
|
|
2003
|
+
type CollectorKeysWithKind<Collectors, Kind extends string> = Collectors extends Record<string, InputCollector> ? {
|
|
2004
|
+
[K in keyof Collectors]: Collectors[K] extends {
|
|
2005
|
+
kind: infer CollectorKind;
|
|
2006
|
+
} ? Extract<CollectorKind, Kind> extends never ? never : K : never;
|
|
2007
|
+
}[keyof Collectors] : never;
|
|
2008
|
+
type CardCollectorZoneIds<Collector> = Collector extends {
|
|
2009
|
+
kind: "card";
|
|
2010
|
+
meta: infer Meta;
|
|
2011
|
+
} ? Meta extends {
|
|
2012
|
+
readonly zoneIds: infer ZoneIds extends readonly string[];
|
|
2013
|
+
} ? ZoneIds[number] : Meta extends {
|
|
2014
|
+
readonly zoneId: infer ZoneId extends string;
|
|
2015
|
+
} ? ZoneId : never : never;
|
|
2016
|
+
type CollectorCardZoneIds<Collectors, Input extends string> = Collectors extends Record<string, InputCollector> ? Input extends keyof Collectors ? CardCollectorZoneIds<Collectors[Input]> : never : never;
|
|
2017
|
+
type InteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, Kind extends string> = {
|
|
2018
|
+
[InteractionId in InteractionIdOfDefinitionPhase<Definition, PhaseName>]: InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? Extract<CollectorKindsOf<Collectors>, Kind> extends never ? never : InteractionId : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? Extract<"card" | CollectorKindsOf<Collectors>, Kind> extends never ? never : InteractionId : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? Extract<CollectorKindsOf<Collectors>, Kind> extends never ? never : InteractionId : never;
|
|
2019
|
+
}[InteractionIdOfDefinitionPhase<Definition, PhaseName>];
|
|
2020
|
+
type QualifiedInteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, Kind extends string> = InteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName, Kind> extends infer InteractionId extends string ? `${PhaseName}.${InteractionId}` : never;
|
|
2021
|
+
type PromptInteractionKeyOfDefinition<Definition> = {
|
|
2022
|
+
[PhaseName in PhaseNamesOfDefinition<Definition>]: QualifiedInteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName, "prompt">;
|
|
2023
|
+
}[PhaseNamesOfDefinition<Definition>];
|
|
2024
|
+
type BoardInteractionKeyOfDefinition<Definition> = {
|
|
2025
|
+
[PhaseName in PhaseNamesOfDefinition<Definition>]: QualifiedInteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName, "board-edge" | "board-space" | "board-tile" | "board-vertex">;
|
|
2026
|
+
}[PhaseNamesOfDefinition<Definition>];
|
|
2027
|
+
type CardInteractionKeyOfDefinition<Definition> = {
|
|
2028
|
+
[PhaseName in PhaseNamesOfDefinition<Definition>]: QualifiedInteractionIdsWithCollectorKindOfDefinitionPhase<Definition, PhaseName, "card">;
|
|
2029
|
+
}[PhaseNamesOfDefinition<Definition>];
|
|
2030
|
+
type InputKeysWithCollectorKindOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>, Kind extends string> = InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? CollectorKeysWithKind<Collectors, Kind> & string : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? (Extract<"card", Kind> extends never ? never : "cardId") | (CollectorKeysWithKind<Collectors, Kind> & string) : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? CollectorKeysWithKind<Collectors, Kind> & string : never;
|
|
2031
|
+
type CardInputZoneIdsOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>, Input extends string> = InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? CollectorCardZoneIds<Collectors, Input> : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? Input extends "cardId" ? InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends {
|
|
2032
|
+
readonly playFrom: infer PlayFrom extends string;
|
|
2033
|
+
} ? PlayFrom : never : CollectorCardZoneIds<Collectors, Input> : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? CollectorCardZoneIds<Collectors, Input> : never;
|
|
2034
|
+
type ParamsOfInteractionOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>> = InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2035
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2036
|
+
} : never : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2037
|
+
cardId: string;
|
|
2038
|
+
} & {
|
|
2039
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2040
|
+
} : {
|
|
2041
|
+
cardId: string;
|
|
2042
|
+
} : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2043
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2044
|
+
} : never : never;
|
|
2045
|
+
/**
|
|
2046
|
+
* Client-facing params shape for an interaction. Omits engine-sampled
|
|
2047
|
+
* collectors (`rngInput.*`) — clients never supply those fields; the
|
|
2048
|
+
* trusted reducer bundle fills them during `submitInteraction`.
|
|
2049
|
+
*
|
|
2050
|
+
* This is the type that drives `submit(playerId, id, params)`,
|
|
2051
|
+
* `handle.submit(params)`, and the generated `InteractionParams` surface
|
|
2052
|
+
* in `shared/generated/ui-contract.ts`. The `reduce`-input counterpart is
|
|
2053
|
+
* {@link ParamsOfInteractionOfDefinition}, which includes every field
|
|
2054
|
+
* because the engine has already filled the sampled ones by then.
|
|
2055
|
+
*/
|
|
2056
|
+
type ClientParamsOfInteractionOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>> = InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2057
|
+
[K in keyof Collectors as Collectors[K] extends InputCollector<infer _S, infer _S2> & {
|
|
2058
|
+
kind: "rng";
|
|
2059
|
+
} ? never : K]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2060
|
+
} : never : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2061
|
+
cardId: string;
|
|
2062
|
+
} & {
|
|
2063
|
+
[K in keyof Collectors as Collectors[K] extends InputCollector<infer _S, infer _S2> & {
|
|
2064
|
+
kind: "rng";
|
|
2065
|
+
} ? never : K]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2066
|
+
} : {
|
|
2067
|
+
cardId: string;
|
|
2068
|
+
} : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? {
|
|
2069
|
+
[K in keyof Collectors as Collectors[K] extends InputCollector<infer _S, infer _S2> & {
|
|
2070
|
+
kind: "rng";
|
|
2071
|
+
} ? never : K]: Collectors[K] extends InputCollector<infer S, infer _S2> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2072
|
+
} : never : never;
|
|
2073
|
+
type DefaultedClientCollectorKeys<Collectors extends Record<string, InputCollector>> = {
|
|
2074
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector<infer _S, infer _S2> & {
|
|
2075
|
+
kind: "rng";
|
|
2076
|
+
} ? never : Collectors[K] extends {
|
|
2077
|
+
readonly defaultValue: unknown;
|
|
2078
|
+
} ? K : never;
|
|
2079
|
+
}[keyof Collectors];
|
|
2080
|
+
type DefaultedClientParamKeysOfInteractionOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, InteractionId extends InteractionIdOfDefinitionPhase<Definition, PhaseName>> = InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends InteractionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? DefaultedClientCollectorKeys<Collectors> & string : never : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends CardActionSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? DefaultedClientCollectorKeys<Collectors> & string : never : InteractionSpecByNameOfDefinitionPhase<Definition, PhaseName, InteractionId> extends SimultaneousSubmitSpec<infer Collectors, infer _State, infer _Manifest> ? Collectors extends Record<string, InputCollector> ? DefaultedClientCollectorKeys<Collectors> & string : never : never;
|
|
2081
|
+
type StageRegistryOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseDefinitionByName<Definition, PhaseName> extends {
|
|
2082
|
+
stages?: infer Stages;
|
|
2083
|
+
} ? NonNullable<Stages> : Record<string, never>;
|
|
2084
|
+
type StageNamesOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = StageRegistryOfDefinitionPhase<Definition, PhaseName> extends infer Stages ? Stages extends Record<string, unknown> ? NonNeverKeys<Stages> & string : never : never;
|
|
2085
|
+
type ZoneRegistriesOfDefinition<Definition> = PhasesOfDefinition<Definition>[keyof PhasesOfDefinition<Definition> & string] extends {
|
|
2086
|
+
zones?: infer Zones;
|
|
2087
|
+
} ? NonNullable<Zones> : never;
|
|
2088
|
+
type ZoneIdsOfDefinition<Definition> = ZoneRegistriesOfDefinition<Definition> extends infer Zones ? Zones extends readonly (infer ZoneId)[] ? Extract<ZoneId, string> : never : never;
|
|
2089
|
+
type ZoneListOfDefinitionPhase<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>> = PhaseDefinitionByName<Definition, PhaseName> extends {
|
|
2090
|
+
zones?: infer Zones;
|
|
2091
|
+
} ? NonNullable<Zones> : readonly [];
|
|
2092
|
+
type PlayableInteractionsOfZoneOfDefinition<Definition, PhaseName extends PhaseNamesOfDefinition<Definition>, ZoneId extends string> = ZoneListOfDefinitionPhase<Definition, PhaseName> extends readonly (infer From)[] ? Extract<From, ZoneId> extends never ? never : CardActionRegistryOfDefinitionPhase<Definition, PhaseName> extends infer CardActions ? CardActions extends Record<string, unknown> ? {
|
|
2093
|
+
[ActionId in keyof CardActions & string]: CardActions[ActionId] extends {
|
|
2094
|
+
playFrom: infer PlayFrom extends string;
|
|
2095
|
+
} ? Extract<PlayFrom, ZoneId> extends never ? never : ActionId : never;
|
|
2096
|
+
}[keyof CardActions & string] : never : never : never;
|
|
2097
|
+
|
|
2098
|
+
/**
|
|
2099
|
+
* A freestanding, memoized projection of immutable game state.
|
|
2100
|
+
*
|
|
2101
|
+
* Use `defineDerived` for values that are pure functions of component
|
|
2102
|
+
* locations, zone contents, resources, or other state fields - and are
|
|
2103
|
+
* consumed from multiple reducer or view call sites, or whose compute cost
|
|
2104
|
+
* is non-trivial (graph walks, aggregate reductions).
|
|
2105
|
+
*
|
|
2106
|
+
* Do NOT cache derived values in `publicState`. State fields should be
|
|
2107
|
+
* inputs to derivations, not mirrors of them.
|
|
2108
|
+
*/
|
|
2109
|
+
type DerivedDefinition<Contract, Value> = {
|
|
2110
|
+
/** Optional label for debugging. Does not affect caching. */
|
|
2111
|
+
readonly name?: string;
|
|
2112
|
+
readonly compute: (ctx: {
|
|
2113
|
+
readonly state: BaseGameStateOfContract<Contract>;
|
|
2114
|
+
readonly q: TableQueriesOfState<BaseGameStateOfContract<Contract>>;
|
|
2115
|
+
readonly derived: DerivedResolver;
|
|
2116
|
+
}) => Value;
|
|
2117
|
+
};
|
|
2118
|
+
/**
|
|
2119
|
+
* Resolves a `DerivedDefinition` to its value. Callers do not need to know
|
|
2120
|
+
* about memoization - the resolver handles caching internally.
|
|
2121
|
+
*/
|
|
2122
|
+
type DerivedResolver = <Value>(def: DerivedDefinition<never, Value>) => Value;
|
|
2123
|
+
/**
|
|
2124
|
+
* Author-facing factory for creating a derived value tied to a game
|
|
2125
|
+
* contract. Usage:
|
|
2126
|
+
*
|
|
2127
|
+
* ```ts
|
|
2128
|
+
* export const longestRoad = defineDerived<GameContract>()({
|
|
2129
|
+
* name: "longestRoad",
|
|
2130
|
+
* compute: ({ q, derived }) => computeLongestRoad(q),
|
|
2131
|
+
* });
|
|
2132
|
+
* ```
|
|
2133
|
+
*/
|
|
2134
|
+
declare function defineDerived<Contract>(): <Value>(def: {
|
|
2135
|
+
name?: string;
|
|
2136
|
+
compute: (ctx: {
|
|
2137
|
+
state: BaseGameStateOfContract<Contract>;
|
|
2138
|
+
q: TableQueriesOfState<BaseGameStateOfContract<Contract>>;
|
|
2139
|
+
derived: DerivedResolver;
|
|
2140
|
+
}) => Value;
|
|
2141
|
+
}) => DerivedDefinition<Contract, Value>;
|
|
2142
|
+
/**
|
|
2143
|
+
* Creates a resolver scoped to a single state snapshot. Each engine tick
|
|
2144
|
+
* and each view projection call creates its own resolver; cache lifetime
|
|
2145
|
+
* ends with the call. Cache key is the `DerivedDefinition` identity (the
|
|
2146
|
+
* object reference).
|
|
2147
|
+
*
|
|
2148
|
+
* Re-entry on an in-flight definition throws a readable error.
|
|
2149
|
+
*/
|
|
2150
|
+
declare function createDerivedResolver<State extends {
|
|
2151
|
+
table: RuntimeTableRecord;
|
|
2152
|
+
}>(state: State, options?: {
|
|
2153
|
+
q?: TableQueriesOfState<State>;
|
|
2154
|
+
}): DerivedResolver;
|
|
2155
|
+
|
|
2156
|
+
type StaticBoardsOfManifest<Manifest> = Manifest extends {
|
|
2157
|
+
staticBoards?: infer StaticBoards;
|
|
2158
|
+
} ? NonNullable<StaticBoards> : {
|
|
2159
|
+
byId: Record<string, never>;
|
|
2160
|
+
hex: Record<string, never>;
|
|
2161
|
+
square: Record<string, never>;
|
|
2162
|
+
};
|
|
2163
|
+
type StaticBoardMapOfManifest<Manifest> = StaticBoardsOfManifest<Manifest> extends {
|
|
2164
|
+
byId: infer Boards;
|
|
2165
|
+
} ? Boards : Record<string, never>;
|
|
2166
|
+
type StaticHexBoardMapOfManifest<Manifest> = StaticBoardsOfManifest<Manifest> extends {
|
|
2167
|
+
hex: infer Boards;
|
|
2168
|
+
} ? Boards : Record<string, never>;
|
|
2169
|
+
type StaticSquareBoardMapOfManifest<Manifest> = StaticBoardsOfManifest<Manifest> extends {
|
|
2170
|
+
square: infer Boards;
|
|
2171
|
+
} ? Boards : Record<string, never>;
|
|
2172
|
+
type StaticViewQueries<Manifest extends ManifestContract<RuntimeTableRecord>> = {
|
|
2173
|
+
board: {
|
|
2174
|
+
get: <BoardId extends StringKeyOf<StaticBoardMapOfManifest<Manifest>>>(boardId: BoardId) => StaticBoardMapOfManifest<Manifest>[BoardId];
|
|
2175
|
+
hex: <BoardId extends StringKeyOf<StaticHexBoardMapOfManifest<Manifest>>>(boardId: BoardId) => StaticHexBoardMapOfManifest<Manifest>[BoardId];
|
|
2176
|
+
square: <BoardId extends StringKeyOf<StaticSquareBoardMapOfManifest<Manifest>>>(boardId: BoardId) => StaticSquareBoardMapOfManifest<Manifest>[BoardId];
|
|
2177
|
+
};
|
|
2178
|
+
};
|
|
2179
|
+
type ContinuationSourceKind = "effect";
|
|
2180
|
+
type ResumableEffectKind = "rollDie" | "shuffleSharedZone" | "shufflePlayerZone";
|
|
2181
|
+
type RollDieContinuationResponse = {
|
|
2182
|
+
dieId: string;
|
|
2183
|
+
value: number;
|
|
2184
|
+
};
|
|
2185
|
+
type ShuffleSharedZoneContinuationResponse = {
|
|
2186
|
+
zoneId: string;
|
|
2187
|
+
orderedCardIds: readonly string[];
|
|
2188
|
+
};
|
|
2189
|
+
type ShufflePlayerZoneContinuationResponse = {
|
|
2190
|
+
zoneId: string;
|
|
2191
|
+
playerId: string;
|
|
2192
|
+
orderedCardIds: readonly string[];
|
|
2193
|
+
};
|
|
2194
|
+
type EffectContinuationResponse<Kind extends ResumableEffectKind> = Kind extends "rollDie" ? RollDieContinuationResponse : Kind extends "shuffleSharedZone" ? ShuffleSharedZoneContinuationResponse : Kind extends "shufflePlayerZone" ? ShufflePlayerZoneContinuationResponse : never;
|
|
2195
|
+
type EffectContinuationInput<DataSchema extends AnySchema, Kind extends ResumableEffectKind = ResumableEffectKind> = {
|
|
2196
|
+
source: "effect";
|
|
2197
|
+
effectKind: Kind;
|
|
2198
|
+
data: z.infer<DataSchema>;
|
|
2199
|
+
response: EffectContinuationResponse<Kind>;
|
|
2200
|
+
};
|
|
2201
|
+
type ContinuationInput<DataSchema extends AnySchema> = EffectContinuationInput<DataSchema, ResumableEffectKind>;
|
|
2202
|
+
type ContinuationInputForSource<DataSchema extends AnySchema, EffectType extends ResumableEffectKind = ResumableEffectKind> = EffectContinuationInput<DataSchema, EffectType>;
|
|
2203
|
+
type PhaseEnterContext = {
|
|
2204
|
+
event: "initialize" | "transition";
|
|
2205
|
+
};
|
|
2206
|
+
type BivariantCallback<Args, Result> = {
|
|
2207
|
+
bivarianceHack(args: Args): Result;
|
|
2208
|
+
}["bivarianceHack"];
|
|
2209
|
+
type ActionContext<State extends {
|
|
2210
|
+
table: RuntimeTableRecord;
|
|
2211
|
+
flow: {
|
|
2212
|
+
currentPhase: string;
|
|
2213
|
+
};
|
|
2214
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
2215
|
+
currentPhase: PhaseNameOfState<State>;
|
|
2216
|
+
manifest: Manifest;
|
|
2217
|
+
playerOrder: PlayerIdOfState<State>[];
|
|
2218
|
+
activePlayers: PlayerIdOfState<State>[];
|
|
2219
|
+
runtime: Omit<ReducerRuntimeStateForState<State>, "rng">;
|
|
2220
|
+
setup: SetupSelectionOfManifest<Manifest> | null;
|
|
2221
|
+
};
|
|
2222
|
+
type ValidationIssue = {
|
|
2223
|
+
errorCode: string;
|
|
2224
|
+
message?: string;
|
|
2225
|
+
};
|
|
2226
|
+
type RuntimeHelpers<State extends {
|
|
2227
|
+
table: RuntimeTableRecord;
|
|
2228
|
+
flow: {
|
|
2229
|
+
currentPhase: string;
|
|
2230
|
+
};
|
|
2231
|
+
}> = {
|
|
2232
|
+
accept(state: State, instructions?: RuntimeInstructionForState<State>[]): ReducerAccept<State>;
|
|
2233
|
+
reject: (errorCode: string, message?: string) => ReducerReject;
|
|
2234
|
+
fx: ReducerFx<State>;
|
|
2235
|
+
ops: ReducerOps<State>;
|
|
2236
|
+
edit<DraftState extends State>(state: DraftState): ReducerTransaction<DraftState>;
|
|
2237
|
+
q: TableQueriesOfState<State>;
|
|
2238
|
+
derived: DerivedResolver;
|
|
2239
|
+
};
|
|
2240
|
+
type RandomHelpers = {
|
|
2241
|
+
subset<const Values extends readonly unknown[]>(options: {
|
|
2242
|
+
from: Values;
|
|
2243
|
+
count: number;
|
|
2244
|
+
}): readonly Values[number][];
|
|
2245
|
+
};
|
|
2246
|
+
type MutationRuntimeHelpers = {
|
|
2247
|
+
random: RandomHelpers;
|
|
2248
|
+
};
|
|
2249
|
+
type PhaseEnterArgs<State extends {
|
|
2250
|
+
table: RuntimeTableRecord;
|
|
2251
|
+
flow: {
|
|
2252
|
+
currentPhase: string;
|
|
2253
|
+
};
|
|
2254
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & RuntimeHelpers<State> & MutationRuntimeHelpers & PhaseEnterContext & {
|
|
2255
|
+
state: State;
|
|
2256
|
+
};
|
|
2257
|
+
type ActorSelectorArgs<State extends {
|
|
2258
|
+
table: RuntimeTableRecord;
|
|
2259
|
+
flow: {
|
|
2260
|
+
currentPhase: string;
|
|
2261
|
+
};
|
|
2262
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & RuntimeHelpers<State> & {
|
|
2263
|
+
state: State;
|
|
2264
|
+
};
|
|
2265
|
+
type ActorSelection<State extends {
|
|
2266
|
+
table: RuntimeTableRecord;
|
|
2267
|
+
flow: {
|
|
2268
|
+
currentPhase: string;
|
|
2269
|
+
};
|
|
2270
|
+
}> = PlayerIdOfState<State> | readonly PlayerIdOfState<State>[] | null | undefined;
|
|
2271
|
+
type ActorSelector<State extends {
|
|
2272
|
+
table: RuntimeTableRecord;
|
|
2273
|
+
flow: {
|
|
2274
|
+
currentPhase: string;
|
|
2275
|
+
};
|
|
2276
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = BivariantCallback<ActorSelectorArgs<State, Manifest>, ActorSelection<State>>;
|
|
2277
|
+
type ContinuationReduceArgs<DataSchema extends AnySchema, State extends {
|
|
2278
|
+
table: RuntimeTableRecord;
|
|
2279
|
+
flow: {
|
|
2280
|
+
currentPhase: string;
|
|
2281
|
+
};
|
|
2282
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, EffectType extends ResumableEffectKind = ResumableEffectKind> = ActionContext<State, Manifest> & RuntimeHelpers<State> & MutationRuntimeHelpers & {
|
|
2283
|
+
state: State;
|
|
2284
|
+
input: ContinuationInputForSource<DataSchema, EffectType>;
|
|
2285
|
+
};
|
|
2286
|
+
type ScopedPhaseState<State extends {
|
|
2287
|
+
table: RuntimeTableRecord;
|
|
2288
|
+
flow: {
|
|
2289
|
+
currentPhase: string;
|
|
2290
|
+
};
|
|
2291
|
+
phase: object;
|
|
2292
|
+
}, PhaseState extends object> = State & {
|
|
2293
|
+
phase: PhaseState;
|
|
2294
|
+
};
|
|
2295
|
+
type ContinuationCallable<DataSchema extends AnySchema, State extends {
|
|
2296
|
+
table: RuntimeTableRecord;
|
|
2297
|
+
flow: {
|
|
2298
|
+
currentPhase: string;
|
|
2299
|
+
};
|
|
2300
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, ContinuationId extends string = string, EffectType extends ResumableEffectKind = ResumableEffectKind> = ((data: z.infer<DataSchema>) => ContinuationToken<z.infer<DataSchema>, ContinuationId, EffectContinuationResponse<EffectType>>) & {
|
|
2301
|
+
id: ContinuationId;
|
|
2302
|
+
source: "effect";
|
|
2303
|
+
dataSchema: DataSchema;
|
|
2304
|
+
responseSchema: AnySchema;
|
|
2305
|
+
effectKind?: EffectType;
|
|
2306
|
+
reduce: BivariantCallback<ContinuationReduceArgs<DataSchema, State, Manifest, EffectType>, ReducerResult<State>>;
|
|
2307
|
+
};
|
|
2308
|
+
type EffectContinuationCallable<DataSchema extends AnySchema, State extends {
|
|
2309
|
+
table: RuntimeTableRecord;
|
|
2310
|
+
flow: {
|
|
2311
|
+
currentPhase: string;
|
|
2312
|
+
};
|
|
2313
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, ContinuationId extends string = string, Kind extends ResumableEffectKind = ResumableEffectKind> = ContinuationCallable<DataSchema, State, Manifest, ContinuationId, Kind>;
|
|
2314
|
+
/**
|
|
2315
|
+
* `rollDie` effect. Resolves a `rollDie` wire effect. `reduce` / `context`
|
|
2316
|
+
* are both optional so authors can fire-and-forget a die roll without
|
|
2317
|
+
* observing the result.
|
|
2318
|
+
*/
|
|
2319
|
+
type EffectRollDieDefinition<Id extends string, ContextSchema extends AnySchema, State extends {
|
|
2320
|
+
table: RuntimeTableRecord;
|
|
2321
|
+
flow: {
|
|
2322
|
+
currentPhase: string;
|
|
2323
|
+
};
|
|
2324
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
2325
|
+
readonly type: "rollDie";
|
|
2326
|
+
readonly id: Id;
|
|
2327
|
+
readonly contextSchema?: ContextSchema;
|
|
2328
|
+
readonly __continuation?: EffectContinuationCallable<ContextSchema, State, Manifest, Id, "rollDie">;
|
|
2329
|
+
};
|
|
2330
|
+
/**
|
|
2331
|
+
* `shuffleSharedZone` effect. Resolves a `shuffleSharedZone` wire effect.
|
|
2332
|
+
* `reduce` / `context` are both optional.
|
|
2333
|
+
*/
|
|
2334
|
+
type EffectShuffleDefinition<Id extends string, ContextSchema extends AnySchema, State extends {
|
|
2335
|
+
table: RuntimeTableRecord;
|
|
2336
|
+
flow: {
|
|
2337
|
+
currentPhase: string;
|
|
2338
|
+
};
|
|
2339
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
2340
|
+
readonly type: "shuffleSharedZone";
|
|
2341
|
+
readonly id: Id;
|
|
2342
|
+
readonly contextSchema?: ContextSchema;
|
|
2343
|
+
readonly __continuation?: EffectContinuationCallable<ContextSchema, State, Manifest, Id, "shuffleSharedZone">;
|
|
2344
|
+
};
|
|
2345
|
+
/**
|
|
2346
|
+
* `shufflePlayerZone` effect. Resolves a `shufflePlayerZone` wire effect for
|
|
2347
|
+
* a single player's perPlayer zone (e.g. deck-builder reshuffle of discard
|
|
2348
|
+
* into deck). `reduce` / `context` are both optional.
|
|
2349
|
+
*/
|
|
2350
|
+
type EffectShufflePlayerZoneDefinition<Id extends string, ContextSchema extends AnySchema, State extends {
|
|
2351
|
+
table: RuntimeTableRecord;
|
|
2352
|
+
flow: {
|
|
2353
|
+
currentPhase: string;
|
|
2354
|
+
};
|
|
2355
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
2356
|
+
readonly type: "shufflePlayerZone";
|
|
2357
|
+
readonly id: Id;
|
|
2358
|
+
readonly contextSchema?: ContextSchema;
|
|
2359
|
+
readonly __continuation?: EffectContinuationCallable<ContextSchema, State, Manifest, Id, "shufflePlayerZone">;
|
|
2360
|
+
};
|
|
2361
|
+
/**
|
|
2362
|
+
* Discriminated union of every `defineEffect` output.
|
|
2363
|
+
*/
|
|
2364
|
+
type EffectDefinition<State extends {
|
|
2365
|
+
table: RuntimeTableRecord;
|
|
2366
|
+
flow: {
|
|
2367
|
+
currentPhase: string;
|
|
2368
|
+
};
|
|
2369
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = EffectRollDieDefinition<string, AnySchema, State, Manifest> | EffectShuffleDefinition<string, AnySchema, State, Manifest> | EffectShufflePlayerZoneDefinition<string, AnySchema, State, Manifest>;
|
|
2370
|
+
type EffectMap<State extends {
|
|
2371
|
+
table: RuntimeTableRecord;
|
|
2372
|
+
flow: {
|
|
2373
|
+
currentPhase: string;
|
|
2374
|
+
};
|
|
2375
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, EffectDefinition<State, Manifest>>;
|
|
2376
|
+
type SimultaneousSubmission<Collectors extends Record<string, InputCollector>, State extends {
|
|
2377
|
+
table: RuntimeTableRecord;
|
|
2378
|
+
flow: {
|
|
2379
|
+
currentPhase: string;
|
|
2380
|
+
};
|
|
2381
|
+
}> = {
|
|
2382
|
+
playerId: PlayerIdOfState<State>;
|
|
2383
|
+
params: ParamsOf<Collectors>;
|
|
2384
|
+
};
|
|
2385
|
+
type SimultaneousResolveArgs<Collectors extends Record<string, InputCollector>, State extends {
|
|
2386
|
+
table: RuntimeTableRecord;
|
|
2387
|
+
flow: {
|
|
2388
|
+
currentPhase: string;
|
|
2389
|
+
};
|
|
2390
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & RuntimeHelpers<State> & MutationRuntimeHelpers & {
|
|
2391
|
+
state: State;
|
|
2392
|
+
submissions: Record<PlayerIdOfState<State>, SimultaneousSubmission<Collectors, State>>;
|
|
2393
|
+
submittedPlayerIds: PlayerIdOfState<State>[];
|
|
2394
|
+
waitingPlayerIds: PlayerIdOfState<State>[];
|
|
2395
|
+
};
|
|
2396
|
+
type SimultaneousSubmitSpec<Collectors extends Record<string, InputCollector> = Record<string, InputCollector>, State extends {
|
|
2397
|
+
table: RuntimeTableRecord;
|
|
2398
|
+
flow: {
|
|
2399
|
+
currentPhase: string;
|
|
2400
|
+
};
|
|
2401
|
+
} = {
|
|
2402
|
+
table: RuntimeTableRecord;
|
|
2403
|
+
flow: {
|
|
2404
|
+
currentPhase: string;
|
|
2405
|
+
};
|
|
2406
|
+
}, Manifest extends ManifestContract<TableOfState<State>> = ManifestContract<TableOfState<State>>> = Omit<InteractionSpec<Collectors, State, Manifest>, "reduce"> & {
|
|
2407
|
+
/**
|
|
2408
|
+
* Optional compatibility slot for callers that reuse `defineInteraction`.
|
|
2409
|
+
* The simultaneous phase barrier stores submissions and invokes the
|
|
2410
|
+
* phase-level `resolve`; this per-submission reducer is intentionally
|
|
2411
|
+
* ignored when present.
|
|
2412
|
+
*/
|
|
2413
|
+
reduce?: InteractionSpec<Collectors, State, Manifest>["reduce"];
|
|
2414
|
+
};
|
|
2415
|
+
type PhaseDefinitionCommon<PhaseStateSchema extends SchemaLike<object>, State extends {
|
|
2416
|
+
table: RuntimeTableRecord;
|
|
2417
|
+
flow: {
|
|
2418
|
+
currentPhase: string;
|
|
2419
|
+
};
|
|
2420
|
+
phase: object;
|
|
2421
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
2422
|
+
name?: string;
|
|
2423
|
+
state: PhaseStateSchema;
|
|
2424
|
+
initialState?: (ctx: {
|
|
2425
|
+
manifest: Manifest;
|
|
2426
|
+
state: State;
|
|
2427
|
+
playerIds: PlayerIdOfState<State>[];
|
|
2428
|
+
setup: SetupSelectionOfManifest<Manifest> | null;
|
|
2429
|
+
}) => z.infer<PhaseStateSchema>;
|
|
2430
|
+
enter?: BivariantCallback<PhaseEnterArgs<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest>, ReducerResult<ScopedPhaseState<State, z.infer<PhaseStateSchema>>> | void>;
|
|
2431
|
+
};
|
|
2432
|
+
type AutoPhaseDefinition<PhaseStateSchema extends SchemaLike<object>, State extends {
|
|
2433
|
+
table: RuntimeTableRecord;
|
|
2434
|
+
flow: {
|
|
2435
|
+
currentPhase: string;
|
|
2436
|
+
};
|
|
2437
|
+
phase: object;
|
|
2438
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = PhaseDefinitionCommon<PhaseStateSchema, State, Manifest> & {
|
|
2439
|
+
kind: "auto";
|
|
2440
|
+
actor?: never;
|
|
2441
|
+
actors?: never;
|
|
2442
|
+
submit?: never;
|
|
2443
|
+
canResubmit?: never;
|
|
2444
|
+
resolve?: never;
|
|
2445
|
+
effects?: never;
|
|
2446
|
+
interactions?: never;
|
|
2447
|
+
stages?: never;
|
|
2448
|
+
zones?: never;
|
|
2449
|
+
cardActions?: never;
|
|
2450
|
+
};
|
|
2451
|
+
type PlayerPhaseDefinition<PhaseStateSchema extends SchemaLike<object>, State extends {
|
|
2452
|
+
table: RuntimeTableRecord;
|
|
2453
|
+
flow: {
|
|
2454
|
+
currentPhase: string;
|
|
2455
|
+
};
|
|
2456
|
+
phase: object;
|
|
2457
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, Effects extends EffectMap<State, Manifest> = Record<string, never>, Interactions extends InteractionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Stages extends StageMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Zones extends PhaseZoneList<Manifest> = readonly [], CardActions extends CardActionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>> = PhaseDefinitionCommon<PhaseStateSchema, State, Manifest> & {
|
|
2458
|
+
kind: "player";
|
|
2459
|
+
/**
|
|
2460
|
+
* Default actor selector for interactions in this phase. When omitted the
|
|
2461
|
+
* runtime falls back to `flow.activePlayers`, preserving the existing turn
|
|
2462
|
+
* ownership model. Returning multiple players models simultaneous actors.
|
|
2463
|
+
*/
|
|
2464
|
+
actor?: ActorSelector<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest>;
|
|
2465
|
+
actors?: never;
|
|
2466
|
+
submit?: never;
|
|
2467
|
+
canResubmit?: never;
|
|
2468
|
+
resolve?: never;
|
|
2469
|
+
effects?: Effects;
|
|
2470
|
+
interactions?: Interactions;
|
|
2471
|
+
stages?: Stages;
|
|
2472
|
+
zones?: Zones;
|
|
2473
|
+
cardActions?: CardActions;
|
|
2474
|
+
};
|
|
2475
|
+
type SimultaneousPlayerPhaseDefinition<PhaseStateSchema extends SchemaLike<object>, State extends {
|
|
2476
|
+
table: RuntimeTableRecord;
|
|
2477
|
+
flow: {
|
|
2478
|
+
currentPhase: string;
|
|
2479
|
+
};
|
|
2480
|
+
phase: object;
|
|
2481
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, SubmitCollectors extends Record<string, InputCollector> = Record<string, InputCollector>, Effects extends EffectMap<State, Manifest> = Record<string, never>, Interactions extends InteractionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Stages extends StageMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Zones extends PhaseZoneList<Manifest> = readonly [], CardActions extends CardActionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>> = PhaseDefinitionCommon<PhaseStateSchema, State, Manifest> & {
|
|
2482
|
+
kind: "simultaneousPlayer";
|
|
2483
|
+
actor?: never;
|
|
2484
|
+
/**
|
|
2485
|
+
* Actor selector for `kind: "simultaneousPlayer"` phases. This is an alias
|
|
2486
|
+
* of `actor` with wording that matches simultaneous submission semantics.
|
|
2487
|
+
*/
|
|
2488
|
+
actors: ActorSelector<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest>;
|
|
2489
|
+
/**
|
|
2490
|
+
* Canonical sealed submission interaction for simultaneous phases. It is
|
|
2491
|
+
* projected like a normal interaction, but the trusted runtime stores the
|
|
2492
|
+
* parsed params until every actor has submitted, then calls `resolve`.
|
|
2493
|
+
*/
|
|
2494
|
+
submit: SimultaneousSubmitSpec<SubmitCollectors, ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest>;
|
|
2495
|
+
/**
|
|
2496
|
+
* When false or omitted, each actor can submit once per simultaneous
|
|
2497
|
+
* barrier. Set true to allow replacing the sealed submission before every
|
|
2498
|
+
* required actor has submitted.
|
|
2499
|
+
*/
|
|
2500
|
+
canResubmit?: boolean;
|
|
2501
|
+
/**
|
|
2502
|
+
* Batch resolver invoked once all simultaneous actors have submitted. The
|
|
2503
|
+
* submitted params are passed together so game state mutates from one
|
|
2504
|
+
* deterministic base state instead of one player at a time.
|
|
2505
|
+
*/
|
|
2506
|
+
resolve: BivariantCallback<SimultaneousResolveArgs<SubmitCollectors, ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest>, ReducerResult<ScopedPhaseState<State, z.infer<PhaseStateSchema>>>>;
|
|
2507
|
+
effects?: Effects;
|
|
2508
|
+
interactions?: Interactions;
|
|
2509
|
+
stages?: Stages;
|
|
2510
|
+
zones?: Zones;
|
|
2511
|
+
cardActions?: CardActions;
|
|
2512
|
+
};
|
|
2513
|
+
type PhaseDefinition<PhaseStateSchema extends SchemaLike<object>, State extends {
|
|
2514
|
+
table: RuntimeTableRecord;
|
|
2515
|
+
flow: {
|
|
2516
|
+
currentPhase: string;
|
|
2517
|
+
};
|
|
2518
|
+
phase: object;
|
|
2519
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, SubmitCollectors extends Record<string, InputCollector> = Record<string, InputCollector>, Effects extends EffectMap<State, Manifest> = Record<string, never>, Interactions extends InteractionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Stages extends StageMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>, Zones extends PhaseZoneList<Manifest> = readonly [], CardActions extends CardActionMap<ScopedPhaseState<State, z.infer<PhaseStateSchema>>, Manifest> = Record<string, never>> = AutoPhaseDefinition<PhaseStateSchema, State, Manifest> | PlayerPhaseDefinition<PhaseStateSchema, State, Manifest, Effects, Interactions, Stages, Zones, CardActions> | SimultaneousPlayerPhaseDefinition<PhaseStateSchema, State, Manifest, SubmitCollectors, Effects, Interactions, Stages, Zones, CardActions>;
|
|
2520
|
+
type ViewDefinition<State extends {
|
|
2521
|
+
table: RuntimeTableRecord;
|
|
2522
|
+
flow: {
|
|
2523
|
+
currentPhase: string;
|
|
2524
|
+
};
|
|
2525
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, Projection = unknown> = {
|
|
2526
|
+
project: (args: ActionContext<State, Manifest> & RuntimeHelpers<State> & {
|
|
2527
|
+
state: State;
|
|
2528
|
+
playerId: PlayerIdOfState<State>;
|
|
2529
|
+
runtime: State extends {
|
|
2530
|
+
runtime: infer RuntimeStateValue;
|
|
2531
|
+
} ? RuntimeStateValue : never;
|
|
2532
|
+
}) => Projection;
|
|
2533
|
+
};
|
|
2534
|
+
/**
|
|
2535
|
+
* Session-scoped, once-per-init view. The `project` callback receives only
|
|
2536
|
+
* the authored manifest — the mutable-state helpers (`state`, `playerId`,
|
|
2537
|
+
* `runtime`, `fx`, `ops`, `accept`, `reject`, `q`) that `ViewDefinition.project`
|
|
2538
|
+
* exposes are structurally absent, so an author cannot accidentally project
|
|
2539
|
+
* per-tick state into the payload. The host calls this once per reducer
|
|
2540
|
+
* session, caches the result, and merges it back into every seat view on
|
|
2541
|
+
* the client. Moving static board topology here is what lets the adapter
|
|
2542
|
+
* skip the ~87% of `projectSeatsDynamic` wall time that used to re-serialize
|
|
2543
|
+
* manifest-sourced fields on every input.
|
|
2544
|
+
*/
|
|
2545
|
+
type StaticViewDefinition<Manifest extends ManifestContract<RuntimeTableRecord>, Projection = unknown> = {
|
|
2546
|
+
project: (args: {
|
|
2547
|
+
manifest: Manifest;
|
|
2548
|
+
q: StaticViewQueries<Manifest>;
|
|
2549
|
+
}) => Projection;
|
|
2550
|
+
};
|
|
2551
|
+
type InputCollectorKind = "form" | "board-vertex" | "board-edge" | "board-tile" | "board-space" | "card" | "prompt" | "rng";
|
|
2552
|
+
type TargetKind = "edge" | "vertex" | "space" | "tile" | "card";
|
|
2553
|
+
type BoardInputCollectorKind = Exclude<InputCollectorKind, "form" | "card" | "prompt" | "rng">;
|
|
2554
|
+
type CardInputCollectorMeta = {
|
|
2555
|
+
readonly zoneId: string;
|
|
2556
|
+
readonly zoneIds?: readonly string[];
|
|
2557
|
+
readonly targetKind: "card";
|
|
2558
|
+
};
|
|
2559
|
+
type BoardInputCollectorMeta = {
|
|
2560
|
+
readonly targetKind: TargetKind;
|
|
2561
|
+
readonly boardId: string;
|
|
2562
|
+
readonly valueKind?: "board-id" | "player-board-space";
|
|
2563
|
+
};
|
|
2564
|
+
type PromptInputCollectorMeta = {
|
|
2565
|
+
readonly options: (state: unknown, playerId: unknown, q: unknown) => ReadonlyArray<{
|
|
2566
|
+
id: unknown;
|
|
2567
|
+
label?: string;
|
|
2568
|
+
}>;
|
|
2569
|
+
readonly eligibleOptions: (state: unknown, playerId: unknown, q: unknown) => ReadonlyArray<{
|
|
2570
|
+
id: unknown;
|
|
2571
|
+
label?: string;
|
|
2572
|
+
}>;
|
|
2573
|
+
};
|
|
2574
|
+
type RngInputCollectorMeta = {
|
|
2575
|
+
readonly rng: "d6";
|
|
2576
|
+
readonly count: number;
|
|
2577
|
+
} | {
|
|
2578
|
+
readonly rng: "coin";
|
|
2579
|
+
};
|
|
2580
|
+
type InputCollectorMetaForKind<Kind extends InputCollectorKind> = Kind extends "card" ? CardInputCollectorMeta : Kind extends BoardInputCollectorKind ? BoardInputCollectorMeta : Kind extends "prompt" ? PromptInputCollectorMeta | undefined : Kind extends "rng" ? RngInputCollectorMeta : never;
|
|
2581
|
+
type InputSelectionDescriptor = {
|
|
2582
|
+
readonly mode: "single";
|
|
2583
|
+
} | {
|
|
2584
|
+
readonly mode: "many";
|
|
2585
|
+
readonly min: number;
|
|
2586
|
+
readonly max?: number;
|
|
2587
|
+
readonly distinct?: boolean;
|
|
2588
|
+
};
|
|
2589
|
+
type InputDomainResolverDescriptor = {
|
|
2590
|
+
readonly interactionKey?: string;
|
|
2591
|
+
readonly inputKey: string;
|
|
2592
|
+
};
|
|
2593
|
+
type InputDomainDependencyCase<Domain extends InputDomainDescriptor = InputDomainDescriptor> = {
|
|
2594
|
+
when: Record<string, string>;
|
|
2595
|
+
domain: Domain;
|
|
2596
|
+
};
|
|
2597
|
+
type EagerInputDomainDependencies<Domain extends InputDomainDescriptor = InputDomainDescriptor> = {
|
|
2598
|
+
readonly mode: "eager";
|
|
2599
|
+
readonly dependentCases: readonly InputDomainDependencyCase<Domain>[];
|
|
2600
|
+
};
|
|
2601
|
+
type LazyInputDomainDependencies = {
|
|
2602
|
+
readonly mode: "lazy";
|
|
2603
|
+
readonly dependsOn: readonly string[];
|
|
2604
|
+
readonly resolver: InputDomainResolverDescriptor;
|
|
2605
|
+
};
|
|
2606
|
+
type CardTargetDomainDescriptor = ResolvedCardTargetDomainDescriptor | LazyCardTargetDomainDescriptor;
|
|
2607
|
+
type ResolvedCardTargetDomainDescriptor = {
|
|
2608
|
+
readonly type: "cardTarget";
|
|
2609
|
+
readonly projection: "resolved";
|
|
2610
|
+
readonly targetKind: "card";
|
|
2611
|
+
readonly zoneIds: readonly string[];
|
|
2612
|
+
readonly eligibleTargets: readonly string[];
|
|
2613
|
+
readonly selection?: InputSelectionDescriptor;
|
|
2614
|
+
readonly dependencies?: EagerInputDomainDependencies<ResolvedCardTargetDomainDescriptor>;
|
|
2615
|
+
};
|
|
2616
|
+
type LazyCardTargetDomainDescriptor = {
|
|
2617
|
+
readonly type: "cardTarget";
|
|
2618
|
+
readonly projection: "lazy";
|
|
2619
|
+
readonly targetKind: "card";
|
|
2620
|
+
readonly zoneIds: readonly string[];
|
|
2621
|
+
readonly eligibleTargets?: never;
|
|
2622
|
+
readonly selection?: InputSelectionDescriptor;
|
|
2623
|
+
readonly dependencies: LazyInputDomainDependencies;
|
|
2624
|
+
};
|
|
2625
|
+
type BoardTargetDomainDescriptor = ResolvedBoardTargetDomainDescriptor | LazyBoardTargetDomainDescriptor;
|
|
2626
|
+
type ResolvedBoardTargetDomainDescriptor = {
|
|
2627
|
+
readonly type: "boardTarget";
|
|
2628
|
+
readonly projection: "resolved";
|
|
2629
|
+
readonly targetKind: Exclude<TargetKind, "card">;
|
|
2630
|
+
readonly boardId: string;
|
|
2631
|
+
readonly valueKind?: "board-id" | "player-board-space";
|
|
2632
|
+
readonly eligibleTargets: readonly string[];
|
|
2633
|
+
readonly selection?: InputSelectionDescriptor;
|
|
2634
|
+
readonly dependencies?: EagerInputDomainDependencies<ResolvedBoardTargetDomainDescriptor>;
|
|
2635
|
+
};
|
|
2636
|
+
type LazyBoardTargetDomainDescriptor = {
|
|
2637
|
+
readonly type: "boardTarget";
|
|
2638
|
+
readonly projection: "lazy";
|
|
2639
|
+
readonly targetKind: Exclude<TargetKind, "card">;
|
|
2640
|
+
readonly boardId: string;
|
|
2641
|
+
readonly valueKind?: "board-id" | "player-board-space";
|
|
2642
|
+
readonly eligibleTargets?: never;
|
|
2643
|
+
readonly selection?: InputSelectionDescriptor;
|
|
2644
|
+
readonly dependencies: LazyInputDomainDependencies;
|
|
2645
|
+
};
|
|
2646
|
+
type ResourceMapDomainDescriptor = {
|
|
2647
|
+
type: "resourceMap";
|
|
2648
|
+
resources: Array<{
|
|
2649
|
+
resourceId: string;
|
|
2650
|
+
label?: string;
|
|
2651
|
+
icon?: string;
|
|
2652
|
+
min: number;
|
|
2653
|
+
max: number;
|
|
2654
|
+
}>;
|
|
2655
|
+
selection?: InputSelectionDescriptor;
|
|
2656
|
+
};
|
|
2657
|
+
type BoundedNumberDomainDescriptor = {
|
|
2658
|
+
type: "boundedNumber";
|
|
2659
|
+
min: number;
|
|
2660
|
+
max: number;
|
|
2661
|
+
step?: number;
|
|
2662
|
+
selection?: InputSelectionDescriptor;
|
|
2663
|
+
};
|
|
2664
|
+
type ChoiceDomainDescriptor = {
|
|
2665
|
+
type: "choice";
|
|
2666
|
+
choices: Array<{
|
|
2667
|
+
value: string | null;
|
|
2668
|
+
label: string;
|
|
2669
|
+
icon?: string;
|
|
2670
|
+
badge?: string;
|
|
2671
|
+
description?: string;
|
|
2672
|
+
disabled?: boolean;
|
|
2673
|
+
disabledReason?: string;
|
|
2674
|
+
}>;
|
|
2675
|
+
selection?: InputSelectionDescriptor;
|
|
2676
|
+
dependencies?: EagerInputDomainDependencies<ChoiceDomainDescriptor>;
|
|
2677
|
+
};
|
|
2678
|
+
type ChoiceListDomainDescriptor = {
|
|
2679
|
+
type: "choiceList";
|
|
2680
|
+
choices: Array<{
|
|
2681
|
+
value: string;
|
|
2682
|
+
label: string;
|
|
2683
|
+
icon?: string;
|
|
2684
|
+
badge?: string;
|
|
2685
|
+
description?: string;
|
|
2686
|
+
disabled?: boolean;
|
|
2687
|
+
disabledReason?: string;
|
|
2688
|
+
}>;
|
|
2689
|
+
min?: number;
|
|
2690
|
+
max?: number;
|
|
2691
|
+
selection?: InputSelectionDescriptor;
|
|
2692
|
+
dependencies?: EagerInputDomainDependencies<ChoiceListDomainDescriptor>;
|
|
2693
|
+
};
|
|
2694
|
+
type InputDomainDescriptor = CardTargetDomainDescriptor | BoardTargetDomainDescriptor | ResourceMapDomainDescriptor | BoundedNumberDomainDescriptor | ChoiceDomainDescriptor | ChoiceListDomainDescriptor;
|
|
2695
|
+
type DomainProjector<Domain extends InputDomainDescriptor> = (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, values?: Readonly<Record<string, unknown>>) => Domain;
|
|
2696
|
+
type InputDomainForCollectorKind<Kind extends InputCollectorKind> = Kind extends "card" ? CardTargetDomainDescriptor : Kind extends BoardInputCollectorKind ? BoardTargetDomainDescriptor : Exclude<InputDomainDescriptor, CardTargetDomainDescriptor | BoardTargetDomainDescriptor>;
|
|
2697
|
+
/**
|
|
2698
|
+
* Base state shape every collector is generic over. Collectors that need
|
|
2699
|
+
* narrowed ids (card / player) use `PlayerIdOfState<State>` etc. to thread
|
|
2700
|
+
* the manifest's branded types.
|
|
2701
|
+
*/
|
|
2702
|
+
type CollectorState = {
|
|
2703
|
+
table: RuntimeTableRecord;
|
|
2704
|
+
flow: {
|
|
2705
|
+
currentPhase: string;
|
|
2706
|
+
};
|
|
2707
|
+
};
|
|
2708
|
+
/**
|
|
2709
|
+
* An input collector declares:
|
|
2710
|
+
* - a Zod schema for the parameter value the interaction expects. The
|
|
2711
|
+
* schema's `z.infer` feeds `ParamsOf<Collectors>`, so downstream
|
|
2712
|
+
* `reduce({ input: { params } })` sees branded ids from `cardInput` /
|
|
2713
|
+
* `boardInput` without a second declaration.
|
|
2714
|
+
* - an optional `eligibleTargets(state, playerId, q)` hook that the runtime
|
|
2715
|
+
* calls to enumerate server-authoritative valid values. The hook receives
|
|
2716
|
+
* the same `q` table-queries helper that `validate` / `reduce` see, so
|
|
2717
|
+
* board/card/prompt collectors can reuse whatever board-graph or zone
|
|
2718
|
+
* lookups they already use for validation without rebuilding them from
|
|
2719
|
+
* raw state. Each collector helper narrows the return type to its own
|
|
2720
|
+
* branded id (`CardIdOfState<State>` for `cardInput`, the caller-supplied
|
|
2721
|
+
* `Id extends string` for `boardInput.*`, etc.). At the generic interface
|
|
2722
|
+
* level we keep inputs weak (`CollectorState`, `string`, `unknown`) and
|
|
2723
|
+
* the return `ReadonlyArray<unknown>` so the runtime can treat all
|
|
2724
|
+
* collectors uniformly; per-helper signatures provide the author-facing
|
|
2725
|
+
* strong typing.
|
|
2726
|
+
* - optional `meta` for collector-kind-specific routing (e.g. `cardInput`
|
|
2727
|
+
* stores the `zoneId` the card must come from).
|
|
2728
|
+
*
|
|
2729
|
+
* Collectors without meaningful eligibility (`form`, `rng`) leave
|
|
2730
|
+
* `eligibleTargets` undefined.
|
|
2731
|
+
*/
|
|
2732
|
+
type InputCollectorMetaSlot<Kind extends InputCollectorKind> = [
|
|
2733
|
+
InputCollectorMetaForKind<Kind>
|
|
2734
|
+
] extends [never] ? {
|
|
2735
|
+
readonly meta?: never;
|
|
2736
|
+
} : undefined extends InputCollectorMetaForKind<Kind> ? {
|
|
2737
|
+
readonly meta?: Exclude<InputCollectorMetaForKind<Kind>, undefined>;
|
|
2738
|
+
} : {
|
|
2739
|
+
readonly meta: InputCollectorMetaForKind<Kind>;
|
|
2740
|
+
};
|
|
2741
|
+
type InputCollectorBase<Schema extends SchemaLike<unknown> = SchemaLike<unknown>, State extends CollectorState = CollectorState, Kind extends InputCollectorKind = InputCollectorKind> = {
|
|
2742
|
+
readonly kind: Kind;
|
|
2743
|
+
readonly schema: Schema;
|
|
2744
|
+
readonly defaultValue?: z.infer<Schema>;
|
|
2745
|
+
readonly selection?: InputSelectionDescriptor;
|
|
2746
|
+
readonly eligibleTargets?: (state: CollectorState, playerId: string, q: unknown, values?: Readonly<Record<string, unknown>>) => ReadonlyArray<unknown>;
|
|
2747
|
+
readonly validateTarget?: (state: CollectorState, playerId: string, q: unknown, targetId: unknown, values?: Readonly<Record<string, unknown>>) => ValidationIssue | null | undefined;
|
|
2748
|
+
readonly dependsOn?: readonly string[];
|
|
2749
|
+
readonly resolveDefaultValue?: (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, domain: InputDomainDescriptor) => z.infer<Schema> | undefined;
|
|
2750
|
+
} & (Kind extends "rng" ? {
|
|
2751
|
+
readonly domain?: never;
|
|
2752
|
+
} : Kind extends "card" | BoardInputCollectorKind ? {
|
|
2753
|
+
readonly domain: DomainProjector<InputDomainForCollectorKind<Kind>>;
|
|
2754
|
+
} : {
|
|
2755
|
+
readonly domain?: DomainProjector<InputDomainForCollectorKind<Kind>>;
|
|
2756
|
+
}) & InputCollectorMetaSlot<Kind>;
|
|
2757
|
+
type InputCollector<Schema extends SchemaLike<unknown> = SchemaLike<unknown>, State extends CollectorState = CollectorState, Kind extends InputCollectorKind = InputCollectorKind> = Kind extends InputCollectorKind ? InputCollectorBase<Schema, State, Kind> : never;
|
|
2758
|
+
type ParamsOf<Collectors extends Record<string, InputCollector>> = {
|
|
2759
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector<infer S> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2760
|
+
};
|
|
2761
|
+
type EngineSampledCollectorKeys<Collectors extends Record<string, InputCollector>> = {
|
|
2762
|
+
[K in keyof Collectors]: Collectors[K] extends InputCollector & {
|
|
2763
|
+
kind: "rng";
|
|
2764
|
+
} ? K : never;
|
|
2765
|
+
}[keyof Collectors];
|
|
2766
|
+
type ClientParamsOf<Collectors extends Record<string, InputCollector>> = {
|
|
2767
|
+
[K in keyof Collectors as K extends EngineSampledCollectorKeys<Collectors> ? never : K]: Collectors[K] extends InputCollector<infer S> ? S extends SchemaLike<infer V> ? V : never : never;
|
|
2768
|
+
};
|
|
2769
|
+
type InteractionReduceInput<Collectors extends Record<string, InputCollector>, State extends {
|
|
2770
|
+
table: RuntimeTableRecord;
|
|
2771
|
+
flow: {
|
|
2772
|
+
currentPhase: string;
|
|
2773
|
+
};
|
|
2774
|
+
}> = {
|
|
2775
|
+
playerId: PlayerIdOfState<State>;
|
|
2776
|
+
params: ParamsOf<Collectors>;
|
|
2777
|
+
};
|
|
2778
|
+
type InteractionValidateArgs<Collectors extends Record<string, InputCollector>, State extends {
|
|
2779
|
+
table: RuntimeTableRecord;
|
|
2780
|
+
flow: {
|
|
2781
|
+
currentPhase: string;
|
|
2782
|
+
};
|
|
2783
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & RuntimeHelpers<State> & {
|
|
2784
|
+
state: State;
|
|
2785
|
+
input: InteractionReduceInput<Collectors, State>;
|
|
2786
|
+
};
|
|
2787
|
+
type InteractionReduceArgs<Collectors extends Record<string, InputCollector>, State extends {
|
|
2788
|
+
table: RuntimeTableRecord;
|
|
2789
|
+
flow: {
|
|
2790
|
+
currentPhase: string;
|
|
2791
|
+
};
|
|
2792
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = InteractionValidateArgs<Collectors, State, Manifest> & MutationRuntimeHelpers;
|
|
2793
|
+
type InteractionAvailabilityArgs<State extends {
|
|
2794
|
+
table: RuntimeTableRecord;
|
|
2795
|
+
flow: {
|
|
2796
|
+
currentPhase: string;
|
|
2797
|
+
};
|
|
2798
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & RuntimeHelpers<State> & {
|
|
2799
|
+
state: State;
|
|
2800
|
+
input: {
|
|
2801
|
+
playerId: PlayerIdOfState<State>;
|
|
2802
|
+
};
|
|
2803
|
+
};
|
|
2804
|
+
type InteractionRuleValidationResult = boolean | ValidationIssue | null | undefined;
|
|
2805
|
+
type InteractionRule<Collectors extends Record<string, InputCollector> = Record<string, InputCollector>, State extends {
|
|
2806
|
+
table: RuntimeTableRecord;
|
|
2807
|
+
flow: {
|
|
2808
|
+
currentPhase: string;
|
|
2809
|
+
};
|
|
2810
|
+
} = {
|
|
2811
|
+
table: RuntimeTableRecord;
|
|
2812
|
+
flow: {
|
|
2813
|
+
currentPhase: string;
|
|
2814
|
+
};
|
|
2815
|
+
}, Manifest extends ManifestContract<TableOfState<State>> = ManifestContract<TableOfState<State>>> = {
|
|
2816
|
+
/**
|
|
2817
|
+
* Stable rule id for diagnostics and tests. Rule ids are author-owned and
|
|
2818
|
+
* should be unique within one interaction.
|
|
2819
|
+
*/
|
|
2820
|
+
id: string;
|
|
2821
|
+
/**
|
|
2822
|
+
* Error code used when the rule fails. The same code is used for descriptor
|
|
2823
|
+
* availability and submit-time validation unless `validate` returns a
|
|
2824
|
+
* specific ValidationIssue.
|
|
2825
|
+
*/
|
|
2826
|
+
errorCode: string;
|
|
2827
|
+
message?: string;
|
|
2828
|
+
/**
|
|
2829
|
+
* Projection-time rule. Runs without submitted params, so UI descriptors can
|
|
2830
|
+
* reflect action availability before the user clicks.
|
|
2831
|
+
*/
|
|
2832
|
+
available?: BivariantCallback<InteractionAvailabilityArgs<State, Manifest>, boolean>;
|
|
2833
|
+
/**
|
|
2834
|
+
* Submit-time rule. Runs with parsed params and may return false, a concrete
|
|
2835
|
+
* ValidationIssue, null, or undefined.
|
|
2836
|
+
*/
|
|
2837
|
+
validate?: BivariantCallback<InteractionValidateArgs<Collectors, State, Manifest>, InteractionRuleValidationResult>;
|
|
2838
|
+
};
|
|
2839
|
+
type InteractionCommitPolicy = {
|
|
2840
|
+
mode: "manual";
|
|
2841
|
+
} | {
|
|
2842
|
+
mode: "autoWhenReady";
|
|
2843
|
+
};
|
|
2844
|
+
type HasManyInputCollector<Collectors extends Record<string, InputCollector>> = Extract<Collectors[keyof Collectors], {
|
|
2845
|
+
readonly selection: {
|
|
2846
|
+
readonly mode: "many";
|
|
2847
|
+
};
|
|
2848
|
+
}> extends never ? false : true;
|
|
2849
|
+
type InteractionCommitPolicyFor<Collectors extends Record<string, InputCollector>> = HasManyInputCollector<Collectors> extends true ? {
|
|
2850
|
+
mode: "manual";
|
|
2851
|
+
} : InteractionCommitPolicy;
|
|
2852
|
+
/**
|
|
2853
|
+
* Projection-level interaction kind, derived by the trusted bundle from
|
|
2854
|
+
* collector shape:
|
|
2855
|
+
*
|
|
2856
|
+
* - `"action"`: any interaction whose inputs are ordinary collectors
|
|
2857
|
+
* (`formInput`, `cardInput`).
|
|
2858
|
+
* - `"prompt"`: any interaction whose inputs include a `promptInput`
|
|
2859
|
+
* collector. Prompt descriptors carry addressed-player context and options
|
|
2860
|
+
* so UI primitives can render response controls without reducer-owned
|
|
2861
|
+
* placement metadata.
|
|
2862
|
+
*
|
|
2863
|
+
* Authors never set this directly — the `promptInput(...)` collector is
|
|
2864
|
+
* the single source of truth for prompt semantics. See {@link promptInput}
|
|
2865
|
+
* and {@link InteractionDescriptor.kind}.
|
|
2866
|
+
*/
|
|
2867
|
+
type InteractionKind = "action" | "prompt";
|
|
2868
|
+
type InteractionToArgs<State extends {
|
|
2869
|
+
table: RuntimeTableRecord;
|
|
2870
|
+
flow: {
|
|
2871
|
+
currentPhase: string;
|
|
2872
|
+
};
|
|
2873
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = ActionContext<State, Manifest> & {
|
|
2874
|
+
state: State;
|
|
2875
|
+
};
|
|
2876
|
+
type InteractionSpec<Collectors extends Record<string, InputCollector> = Record<string, InputCollector>, State extends {
|
|
2877
|
+
table: RuntimeTableRecord;
|
|
2878
|
+
flow: {
|
|
2879
|
+
currentPhase: string;
|
|
2880
|
+
};
|
|
2881
|
+
} = {
|
|
2882
|
+
table: RuntimeTableRecord;
|
|
2883
|
+
flow: {
|
|
2884
|
+
currentPhase: string;
|
|
2885
|
+
};
|
|
2886
|
+
}, Manifest extends ManifestContract<TableOfState<State>> = ManifestContract<TableOfState<State>>> = {
|
|
2887
|
+
inputs: Collectors;
|
|
2888
|
+
paramsSchema?: SchemaLike<ClientParamsOf<Collectors>>;
|
|
2889
|
+
/** @internal Phase-local step gates are attached by `defineStepPhase`. */
|
|
2890
|
+
__steps?: readonly string[];
|
|
2891
|
+
/**
|
|
2892
|
+
* Draft commit policy. The input collectors still own value shape and
|
|
2893
|
+
* validation; this only controls whether a ready draft may be submitted
|
|
2894
|
+
* automatically by SDK controls.
|
|
2895
|
+
*
|
|
2896
|
+
* Multi-value collectors created with `many(...)` are always manual draft
|
|
2897
|
+
* interactions. They represent a selection set that should be committed by
|
|
2898
|
+
* explicit player intent, so `autoWhenReady` is intentionally not accepted.
|
|
2899
|
+
*/
|
|
2900
|
+
commit?: InteractionCommitPolicyFor<Collectors>;
|
|
2901
|
+
/**
|
|
2902
|
+
* Addressed-player selector, used by prompt-kind interactions. When
|
|
2903
|
+
* present, the trusted bundle only emits this descriptor for players in
|
|
2904
|
+
* the returned set (or the single player, if a scalar is returned). Use
|
|
2905
|
+
* to thread e.g. `state.publicState.knowerPlayerId` through without
|
|
2906
|
+
* having to manage `activePlayers`. `undefined` / empty returns fall back
|
|
2907
|
+
* to the standard `activePlayers` gating used by action-kind interactions.
|
|
2908
|
+
*/
|
|
2909
|
+
to?: BivariantCallback<InteractionToArgs<State, Manifest>, PlayerIdOfState<State> | ReadonlyArray<PlayerIdOfState<State>> | null | undefined>;
|
|
2910
|
+
/**
|
|
2911
|
+
* Explicit actor selector. Overrides the phase-level actor for this
|
|
2912
|
+
* interaction. Prefer this over `to` for new non-prompt interactions; `to`
|
|
2913
|
+
* remains the prompt/addressee shorthand.
|
|
2914
|
+
*/
|
|
2915
|
+
actor?: ActorSelector<State, Manifest>;
|
|
2916
|
+
/**
|
|
2917
|
+
* Descriptor visibility policy. `all` keeps non-actors visible but disabled;
|
|
2918
|
+
* `actorsOnly` suppresses descriptors for seats that cannot act.
|
|
2919
|
+
*/
|
|
2920
|
+
visibility?: "all" | "actorsOnly";
|
|
2921
|
+
errorCodes?: readonly string[];
|
|
2922
|
+
cost?: BivariantCallback<InteractionValidateArgs<Collectors, State, Manifest>, Readonly<Record<string, number>>>;
|
|
2923
|
+
rules?: readonly InteractionRule<NoInfer<Collectors>, State, Manifest>[];
|
|
2924
|
+
reduce: BivariantCallback<InteractionReduceArgs<Collectors, State, Manifest>, ReducerResult<State>>;
|
|
2925
|
+
};
|
|
2926
|
+
type CardActionSpec<Collectors extends Record<string, InputCollector> = Record<string, InputCollector>, State extends {
|
|
2927
|
+
table: RuntimeTableRecord;
|
|
2928
|
+
flow: {
|
|
2929
|
+
currentPhase: string;
|
|
2930
|
+
};
|
|
2931
|
+
} = {
|
|
2932
|
+
table: RuntimeTableRecord;
|
|
2933
|
+
flow: {
|
|
2934
|
+
currentPhase: string;
|
|
2935
|
+
};
|
|
2936
|
+
}, Manifest extends ManifestContract<TableOfState<State>> = ManifestContract<TableOfState<State>>, PlayFrom extends PlayerZoneIdOfManifest<Manifest> = PlayerZoneIdOfManifest<Manifest>> = {
|
|
2937
|
+
cardType: CardTypeOfState<State>;
|
|
2938
|
+
playFrom: PlayFrom;
|
|
2939
|
+
inputs?: Collectors;
|
|
2940
|
+
paramsSchema?: SchemaLike<Record<string, unknown>>;
|
|
2941
|
+
/** @internal Phase-local step gates are attached by `defineStepPhase`. */
|
|
2942
|
+
__steps?: readonly string[];
|
|
2943
|
+
/**
|
|
2944
|
+
* Draft commit policy. Card clicks still mutate the draft first;
|
|
2945
|
+
* `autoWhenReady` submits only once the full interaction draft validates.
|
|
2946
|
+
* Multi-value collectors created with `many(...)` are always manual draft
|
|
2947
|
+
* interactions and cannot opt into `autoWhenReady`.
|
|
2948
|
+
*/
|
|
2949
|
+
commit?: InteractionCommitPolicyFor<Collectors>;
|
|
2950
|
+
actor?: ActorSelector<State, Manifest>;
|
|
2951
|
+
visibility?: "all" | "actorsOnly";
|
|
2952
|
+
errorCodes?: readonly string[];
|
|
2953
|
+
cost?: BivariantCallback<InteractionValidateArgs<Collectors & {
|
|
2954
|
+
cardId: InputCollector<SchemaLike<CardIdOfState<State>>>;
|
|
2955
|
+
}, State, Manifest>, Readonly<Record<string, number>>>;
|
|
2956
|
+
rules?: readonly InteractionRule<NoInfer<Collectors & {
|
|
2957
|
+
cardId: InputCollector<SchemaLike<CardIdOfState<State>>>;
|
|
2958
|
+
}>, State, Manifest>[];
|
|
2959
|
+
reduce: BivariantCallback<InteractionReduceArgs<Collectors & {
|
|
2960
|
+
cardId: InputCollector<SchemaLike<CardIdOfState<State>>>;
|
|
2961
|
+
}, State, Manifest>, ReducerResult<State>>;
|
|
2962
|
+
};
|
|
2963
|
+
type AnyCardActionSpec<State extends {
|
|
2964
|
+
table: RuntimeTableRecord;
|
|
2965
|
+
flow: {
|
|
2966
|
+
currentPhase: string;
|
|
2967
|
+
};
|
|
2968
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = CardActionSpec<Record<string, InputCollector>, State, Manifest>;
|
|
2969
|
+
type CardActionMap<State extends {
|
|
2970
|
+
table: RuntimeTableRecord;
|
|
2971
|
+
flow: {
|
|
2972
|
+
currentPhase: string;
|
|
2973
|
+
};
|
|
2974
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, AnyCardActionSpec<State, Manifest>>;
|
|
2975
|
+
/**
|
|
2976
|
+
* Type-safe erasure of {@link InteractionSpec} used by the runtime when it
|
|
2977
|
+
* stores heterogeneous interactions in a single map. The collectors generic
|
|
2978
|
+
* is erased to the structural upper bound (`Record<string, InputCollector>`)
|
|
2979
|
+
* so that lookups and metadata helpers can iterate collectors without
|
|
2980
|
+
* committing to a specific authoring-time shape.
|
|
2981
|
+
*/
|
|
2982
|
+
type AnyInteractionSpec<State extends {
|
|
2983
|
+
table: RuntimeTableRecord;
|
|
2984
|
+
flow: {
|
|
2985
|
+
currentPhase: string;
|
|
2986
|
+
};
|
|
2987
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = InteractionSpec<Record<string, InputCollector>, State, Manifest>;
|
|
2988
|
+
type InteractionMap<State extends {
|
|
2989
|
+
table: RuntimeTableRecord;
|
|
2990
|
+
flow: {
|
|
2991
|
+
currentPhase: string;
|
|
2992
|
+
};
|
|
2993
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, AnyInteractionSpec<State, Manifest>>;
|
|
2994
|
+
type StageSpec<State extends {
|
|
2995
|
+
table: RuntimeTableRecord;
|
|
2996
|
+
flow: {
|
|
2997
|
+
currentPhase: string;
|
|
2998
|
+
};
|
|
2999
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = {
|
|
3000
|
+
when?: BivariantCallback<ActionContext<State, Manifest> & {
|
|
3001
|
+
state: State;
|
|
3002
|
+
}, boolean>;
|
|
3003
|
+
onEnter?: BivariantCallback<PhaseEnterArgs<State, Manifest>, ReducerResult<State> | void>;
|
|
3004
|
+
onExit?: BivariantCallback<PhaseEnterArgs<State, Manifest>, ReducerResult<State> | void>;
|
|
3005
|
+
allow: readonly string[];
|
|
3006
|
+
};
|
|
3007
|
+
type StageMap<State extends {
|
|
3008
|
+
table: RuntimeTableRecord;
|
|
3009
|
+
flow: {
|
|
3010
|
+
currentPhase: string;
|
|
3011
|
+
};
|
|
3012
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, StageSpec<State, Manifest>>;
|
|
3013
|
+
type PhaseZoneList<Manifest extends ManifestContract<RuntimeTableRecord>> = readonly PlayerZoneIdOfManifest<Manifest>[];
|
|
3014
|
+
|
|
3015
|
+
/**
|
|
3016
|
+
* Structural upper bound for reducer game contracts accepted by the
|
|
3017
|
+
* authoring-level `define*` factories. The `manifest` slot admits any
|
|
3018
|
+
* contract-generated manifest shape (tables, players, decks, etc. vary per
|
|
3019
|
+
* contract); `state` is pinned to the base {@link StateDefinition} so the
|
|
3020
|
+
* authoring helpers can infer public/private/hidden schemas from it.
|
|
3021
|
+
*/
|
|
3022
|
+
type AnyReducerGameContract = {
|
|
3023
|
+
manifest: ManifestContract<RuntimeTableRecord>;
|
|
3024
|
+
state: StateDefinition<SchemaLike<object>, SchemaLike<object>, SchemaLike<object>>;
|
|
3025
|
+
};
|
|
3026
|
+
type PhaseStateInput = SchemaLike<object> | object;
|
|
3027
|
+
type InferPhaseState<Input extends PhaseStateInput> = Input extends SchemaLike<infer Output> ? Output extends object ? Output : object : Input extends object ? Input : object;
|
|
3028
|
+
type ContractState<Contract extends AnyReducerGameContract> = BaseGameStateOfContract<Contract>;
|
|
3029
|
+
type ContractManifest<Contract extends AnyReducerGameContract> = ManifestContractOf<Contract>;
|
|
3030
|
+
type ReducerPhaseDefinition<Contract extends AnyReducerGameContract, PhaseStateSchema extends SchemaLike<object>> = PhaseDefinition<PhaseStateSchema, ContractState<Contract>, ContractManifest<Contract>>;
|
|
3031
|
+
type ReducerViewDefinition<Contract extends AnyReducerGameContract, Projection = unknown> = ViewDefinition<ContractState<Contract>, ContractManifest<Contract>, Projection>;
|
|
3032
|
+
|
|
3033
|
+
type ManifestIdSchemasOf<Ids extends Record<string, SchemaLike<unknown>>> = {
|
|
3034
|
+
readonly [Key in keyof Ids]: Ids[Key] extends SchemaLike<infer Output> ? Ids[Key] & ManifestIdSchema<Output> : Ids[Key];
|
|
3035
|
+
};
|
|
3036
|
+
|
|
3037
|
+
/**
|
|
3038
|
+
* Narrows a manifest's `literals.phaseNames` and `ids.phaseName` to the
|
|
3039
|
+
* author-supplied phase-name tuple. Lets `defineGameContract` override the
|
|
3040
|
+
* codegen-emitted `phaseNames: readonly string[]` / `phaseName: z.string()`
|
|
3041
|
+
* placeholders so `PhaseNameOfContract<Contract>` resolves to a literal
|
|
3042
|
+
* union and flows through `fx.transition`, `PhaseMapOf`, and the flow
|
|
3043
|
+
* state's `currentPhase`.
|
|
3044
|
+
*/
|
|
3045
|
+
type NarrowManifestPhaseNames<Manifest, PhaseNames extends readonly string[]> = Omit<Manifest, "literals" | "ids"> & {
|
|
3046
|
+
literals: Manifest extends {
|
|
3047
|
+
literals: infer L;
|
|
3048
|
+
} ? Omit<L, "phaseNames"> & {
|
|
3049
|
+
phaseNames: PhaseNames;
|
|
3050
|
+
} : {
|
|
3051
|
+
phaseNames: PhaseNames;
|
|
3052
|
+
};
|
|
3053
|
+
ids: Manifest extends {
|
|
3054
|
+
ids: infer I;
|
|
3055
|
+
} ? Omit<I, "phaseName"> & {
|
|
3056
|
+
phaseName: z.ZodType<PhaseNames[number]>;
|
|
3057
|
+
} : {
|
|
3058
|
+
phaseName: z.ZodType<PhaseNames[number]>;
|
|
3059
|
+
};
|
|
3060
|
+
};
|
|
3061
|
+
type ReducerGameContractInput<Table extends RuntimeTableRecord, Manifest extends ReducerManifestContract<Table, string, string, string, string, string>, PublicSchema extends SchemaLike<object>, PrivateSchema extends SchemaLike<object>, HiddenSchema extends SchemaLike<object>, Phases extends Record<string, SchemaLike<object>>> = {
|
|
3062
|
+
manifest: Manifest;
|
|
3063
|
+
state: StateDefinition<PublicSchema, PrivateSchema, HiddenSchema>;
|
|
3064
|
+
phases: Phases;
|
|
3065
|
+
};
|
|
3066
|
+
declare function defineGameContract<Table extends RuntimeTableRecord, const Manifest extends ReducerManifestContract<Table, string, string, string, string, string>, PublicSchema extends SchemaLike<object>, PrivateSchema extends SchemaLike<object>, HiddenSchema extends SchemaLike<object>, const Phases extends Record<string, SchemaLike<object>>>(definition: ReducerGameContractInput<Table, Manifest, PublicSchema, PrivateSchema, HiddenSchema, Phases>): ReducerGameContract<Table, NarrowManifestPhaseNames<Manifest, readonly (keyof Phases & string)[]>, PublicSchema, PrivateSchema, HiddenSchema, Phases> & {
|
|
3067
|
+
readonly phases: Phases;
|
|
3068
|
+
readonly phaseNames: readonly (keyof Phases & string)[];
|
|
3069
|
+
/**
|
|
3070
|
+
* Ergonomic shortcut to the manifest-backed Zod id schemas. Equivalent to
|
|
3071
|
+
* `definition.manifest.ids`. Prefer `gameContract.schemas.playerId` etc.
|
|
3072
|
+
* over re-importing the generated `ids` namespace so that every authored
|
|
3073
|
+
* schema is anchored to the same SDK-guided source.
|
|
3074
|
+
*/
|
|
3075
|
+
readonly schemas: ManifestIdSchemasOf<NarrowManifestPhaseNames<Manifest, readonly (keyof Phases & string)[]>["ids"]>;
|
|
3076
|
+
};
|
|
3077
|
+
|
|
3078
|
+
type EffectRollDieInput<Contract extends AnyReducerGameContract, Id extends string, ContextSchema extends AnySchema> = {
|
|
3079
|
+
type: "rollDie";
|
|
3080
|
+
id: Id;
|
|
3081
|
+
context?: ContextSchema;
|
|
3082
|
+
reduce?: ContinuationCallable<ContextSchema, ContractState<Contract>, ContractManifest<Contract>, Id, "rollDie">["reduce"];
|
|
3083
|
+
};
|
|
3084
|
+
type EffectShuffleInput<Contract extends AnyReducerGameContract, Id extends string, ContextSchema extends AnySchema> = {
|
|
3085
|
+
type: "shuffleSharedZone";
|
|
3086
|
+
id: Id;
|
|
3087
|
+
context?: ContextSchema;
|
|
3088
|
+
reduce?: ContinuationCallable<ContextSchema, ContractState<Contract>, ContractManifest<Contract>, Id, "shuffleSharedZone">["reduce"];
|
|
3089
|
+
};
|
|
3090
|
+
type EffectShufflePlayerZoneInput<Contract extends AnyReducerGameContract, Id extends string, ContextSchema extends AnySchema> = {
|
|
3091
|
+
type: "shufflePlayerZone";
|
|
3092
|
+
id: Id;
|
|
3093
|
+
context?: ContextSchema;
|
|
3094
|
+
reduce?: ContinuationCallable<ContextSchema, ContractState<Contract>, ContractManifest<Contract>, Id, "shufflePlayerZone">["reduce"];
|
|
3095
|
+
};
|
|
3096
|
+
declare function defineEffect<Contract extends AnyReducerGameContract>(): {
|
|
3097
|
+
<Id extends string, ContextSchema extends AnySchema = z.ZodObject<Record<string, never>, z.core.$strip>>(definition: EffectRollDieInput<Contract, Id, ContextSchema>): EffectRollDieDefinition<Id, ContextSchema, ContractState<Contract>, ContractManifest<Contract>>;
|
|
3098
|
+
<Id extends string, ContextSchema extends AnySchema = z.ZodObject<Record<string, never>, z.core.$strip>>(definition: EffectShuffleInput<Contract, Id, ContextSchema>): EffectShuffleDefinition<Id, ContextSchema, ContractState<Contract>, ContractManifest<Contract>>;
|
|
3099
|
+
<Id extends string, ContextSchema extends AnySchema = z.ZodObject<Record<string, never>, z.core.$strip>>(definition: EffectShufflePlayerZoneInput<Contract, Id, ContextSchema>): EffectShufflePlayerZoneDefinition<Id, ContextSchema, ContractState<Contract>, ContractManifest<Contract>>;
|
|
3100
|
+
};
|
|
3101
|
+
|
|
3102
|
+
declare function defineGame<const Contract extends AnyReducerGameContract, Definitions extends PhaseMapOf<Contract>, Views extends ViewMapOf<Contract> = Record<string, never>>(definition: {
|
|
3103
|
+
contract: Contract;
|
|
3104
|
+
} & Omit<ReducerGameDefinition<NoInfer<Contract>, Definitions, Views>, "contract">): ReducerGameDefinition<Contract, Definitions, Views>;
|
|
3105
|
+
|
|
3106
|
+
declare function defineInteraction<Contract extends AnyReducerGameContract, PhaseState extends PhaseStateInput = SchemaLike<object>>(): <Collectors extends Record<string, InputCollector>>(definition: InteractionSpec<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>>) => InteractionSpec<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>>;
|
|
3107
|
+
declare function defineInteractionRule<Contract extends AnyReducerGameContract, PhaseState extends PhaseStateInput = SchemaLike<object>>(): <Collectors extends Record<string, InputCollector> = Record<string, InputCollector>>(definition: InteractionRule<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>>) => InteractionRule<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>>;
|
|
3108
|
+
declare function defineCardAction<Contract extends AnyReducerGameContract, PhaseState extends PhaseStateInput>(): <Collectors extends Record<string, InputCollector> = Record<string, never>, const PlayFrom extends PlayerZoneIdOfManifest<ContractManifest<Contract>> = PlayerZoneIdOfManifest<ContractManifest<Contract>>>(definition: CardActionSpec<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>, PlayFrom>) => CardActionSpec<Collectors, ScopedPhaseState<ContractState<Contract>, InferPhaseState<PhaseState>>, ContractManifest<Contract>, PlayFrom>;
|
|
3109
|
+
|
|
3110
|
+
type StepPhaseState<PhaseStateSchema extends SchemaLike<object>, Steps extends readonly string[]> = z.infer<PhaseStateSchema> & {
|
|
3111
|
+
step: Steps[number];
|
|
3112
|
+
};
|
|
3113
|
+
type StepPhaseInteractionEntry<Step extends string, Interaction> = {
|
|
3114
|
+
steps: readonly Step[];
|
|
3115
|
+
interaction: Interaction;
|
|
3116
|
+
};
|
|
3117
|
+
type StepPhaseCardActionEntry<Step extends string, Action> = {
|
|
3118
|
+
steps: readonly Step[];
|
|
3119
|
+
action: Action;
|
|
3120
|
+
};
|
|
3121
|
+
type StepPhaseInteractionMap<Step extends string, State extends {
|
|
3122
|
+
table: RuntimeTableRecord;
|
|
3123
|
+
flow: {
|
|
3124
|
+
currentPhase: string;
|
|
3125
|
+
};
|
|
3126
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, StepPhaseInteractionEntry<Step, AnyInteractionSpec<State, Manifest>>>;
|
|
3127
|
+
type StepPhaseCardActionMap<Step extends string, State extends {
|
|
3128
|
+
table: RuntimeTableRecord;
|
|
3129
|
+
flow: {
|
|
3130
|
+
currentPhase: string;
|
|
3131
|
+
};
|
|
3132
|
+
}, Manifest extends ManifestContract<TableOfState<State>>> = Record<string, StepPhaseCardActionEntry<Step, AnyCardActionSpec<State, Manifest>>>;
|
|
3133
|
+
type UnwrappedStepInteractions<State extends {
|
|
3134
|
+
table: RuntimeTableRecord;
|
|
3135
|
+
flow: {
|
|
3136
|
+
currentPhase: string;
|
|
3137
|
+
};
|
|
3138
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, Interactions extends Record<string, StepPhaseInteractionEntry<string, AnyInteractionSpec<State, Manifest>>>> = {
|
|
3139
|
+
[Key in keyof Interactions]: Interactions[Key]["interaction"];
|
|
3140
|
+
};
|
|
3141
|
+
type UnwrappedStepCardActions<State extends {
|
|
3142
|
+
table: RuntimeTableRecord;
|
|
3143
|
+
flow: {
|
|
3144
|
+
currentPhase: string;
|
|
3145
|
+
};
|
|
3146
|
+
}, Manifest extends ManifestContract<TableOfState<State>>, CardActions extends Record<string, StepPhaseCardActionEntry<string, AnyCardActionSpec<State, Manifest>>>> = {
|
|
3147
|
+
[Key in keyof CardActions]: CardActions[Key]["action"];
|
|
3148
|
+
};
|
|
3149
|
+
declare function definePhase<Contract extends AnyReducerGameContract>(): <PhaseStateSchema extends SchemaLike<object>, SubmitCollectors extends Record<string, InputCollector> = Record<string, InputCollector>, Effects extends EffectMap<ContractState<Contract>, ContractManifest<Contract>> = Record<string, never>, Interactions extends Record<string, AnyInteractionSpec<ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>, ContractManifest<Contract>>> = Record<string, never>, Stages extends StageMap<ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>, ContractManifest<Contract>> = Record<string, never>, const Zones extends PhaseZoneList<ContractManifest<Contract>> = readonly [], CardActions extends CardActionMap<ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>, ContractManifest<Contract>> = Record<string, never>>(definition: PhaseDefinition<PhaseStateSchema, ContractState<Contract>, ContractManifest<Contract>, SubmitCollectors, Effects, Interactions, Stages, Zones, CardActions>) => PhaseDefinition<PhaseStateSchema, ContractState<Contract>, ContractManifest<Contract>, SubmitCollectors, Effects, Interactions, Stages, Zones, CardActions>;
|
|
3150
|
+
declare function defineStepPhase<Contract extends AnyReducerGameContract>(): <const Steps extends readonly [string, ...string[]], PhaseStateSchema extends SchemaLike<object>, SubmitCollectors extends Record<string, InputCollector> = Record<string, InputCollector>, Effects extends EffectMap<ContractState<Contract>, ContractManifest<Contract>> = Record<string, never>, Interactions extends StepPhaseInteractionMap<Steps[number], ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>> = Record<string, never>, Stages extends StageMap<ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>> = Record<string, never>, const Zones extends PhaseZoneList<ContractManifest<Contract>> = readonly [], CardActions extends StepPhaseCardActionMap<Steps[number], ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>> = Record<string, never>>(definition: Omit<PhaseDefinition<PhaseStateSchema, ContractState<Contract>, ContractManifest<Contract>, SubmitCollectors, Effects, UnwrappedStepInteractions<ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>, Interactions>, Stages, Zones, UnwrappedStepCardActions<ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>, CardActions>>, "state" | "initialState" | "interactions" | "cardActions"> & {
|
|
3151
|
+
steps: Steps;
|
|
3152
|
+
state: PhaseStateSchema;
|
|
3153
|
+
initialState?: (ctx: {
|
|
3154
|
+
manifest: ContractManifest<Contract>;
|
|
3155
|
+
state: ContractState<Contract>;
|
|
3156
|
+
playerIds: PlayerIdOfState<ContractState<Contract>>[];
|
|
3157
|
+
setup: SetupSelectionOfManifest<ContractManifest<Contract>> | null;
|
|
3158
|
+
}) => z.infer<PhaseStateSchema>;
|
|
3159
|
+
interactions?: Interactions;
|
|
3160
|
+
cardActions?: CardActions;
|
|
3161
|
+
}) => PhaseDefinition<SchemaLike<StepPhaseState<PhaseStateSchema, Steps>>, ContractState<Contract>, ContractManifest<Contract>, SubmitCollectors, Effects, UnwrappedStepInteractions<ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>, Interactions>, Stages, Zones, UnwrappedStepCardActions<ScopedPhaseState<ContractState<Contract>, StepPhaseState<PhaseStateSchema, Steps>>, ContractManifest<Contract>, CardActions>>;
|
|
3162
|
+
|
|
3163
|
+
declare function defineView<Contract extends AnyReducerGameContract>(): <Projection>(definition: ViewDefinition<ContractState<Contract>, ContractManifest<Contract>, Projection>) => ViewDefinition<ContractState<Contract>, ContractManifest<Contract>, Projection>;
|
|
3164
|
+
/**
|
|
3165
|
+
* Factory for the session-scoped static view (see {@link StaticViewDefinition}).
|
|
3166
|
+
* Kept separate from {@link defineView} because the argument shape is
|
|
3167
|
+
* structurally different: it exposes only the manifest and generated static
|
|
3168
|
+
* queries, with no `state`, `playerId`, `runtime`, `fx`, `ops`, or
|
|
3169
|
+
* `accept/reject`. That shape is what prevents authors from accidentally
|
|
3170
|
+
* projecting per-tick state into the once-per-session payload.
|
|
3171
|
+
*/
|
|
3172
|
+
declare function defineStaticView<Contract extends AnyReducerGameContract>(): <Projection>(definition: StaticViewDefinition<ExactManifestContractOf<Contract>, Projection>) => StaticViewDefinition<ExactManifestContractOf<Contract>, Projection>;
|
|
3173
|
+
declare function defineStage<Contract extends AnyReducerGameContract>(): (definition: StageSpec<ContractState<Contract>, ContractManifest<Contract>>) => StageSpec<ContractState<Contract>, ContractManifest<Contract>>;
|
|
3174
|
+
declare function definePhaseStage<Contract extends AnyReducerGameContract, PhaseStateSchema extends SchemaLike<object>>(): (definition: StageSpec<ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>, ContractManifest<Contract>>) => StageSpec<ScopedPhaseState<ContractState<Contract>, z.infer<PhaseStateSchema>>, ContractManifest<Contract>>;
|
|
3175
|
+
|
|
3176
|
+
type InputFieldRef<Key extends string = string, Value = unknown, Collector extends InputCollector = InputCollector> = {
|
|
3177
|
+
readonly key: Key;
|
|
3178
|
+
readonly collector: Collector;
|
|
3179
|
+
readonly __value?: Value;
|
|
3180
|
+
};
|
|
3181
|
+
type RefValue<Ref> = Ref extends InputFieldRef<string, infer Value, InputCollector> ? Value : never;
|
|
3182
|
+
type CollectorOfRef<Ref> = Ref extends InputFieldRef<string, unknown, infer Collector> ? Collector : never;
|
|
3183
|
+
type CollectorValue<Collector> = Collector extends InputCollector<infer Schema> ? z.infer<Schema> : never;
|
|
3184
|
+
type DependencyValues<Dependencies extends readonly InputFieldRef<string, unknown, InputCollector>[]> = {
|
|
3185
|
+
readonly [Ref in Dependencies[number] as Ref["key"]]: RefValue<Ref>;
|
|
3186
|
+
};
|
|
3187
|
+
type DefinedInputRefs = Record<string, InputFieldRef<string, unknown, InputCollector>>;
|
|
3188
|
+
type DefinedInputs<Refs extends DefinedInputRefs> = {
|
|
3189
|
+
readonly [Key in keyof Refs]: CollectorOfRef<Refs[Key]>;
|
|
3190
|
+
};
|
|
3191
|
+
declare class InputBuilder {
|
|
3192
|
+
add<const Key extends string, Collector extends InputCollector<SchemaLike<unknown>>>(key: Key, collector: Collector): InputFieldRef<Key, CollectorValue<Collector>, Collector>;
|
|
3193
|
+
}
|
|
3194
|
+
/**
|
|
3195
|
+
* Define an interaction's inputs with typed field references. Field refs can be
|
|
3196
|
+
* passed to dependent input domains, and the returned collector map preserves
|
|
3197
|
+
* the original key/value types for interaction params.
|
|
3198
|
+
*/
|
|
3199
|
+
declare function defineInputs<const Refs extends DefinedInputRefs>(define: (input: InputBuilder) => Refs): DefinedInputs<Refs>;
|
|
3200
|
+
|
|
3201
|
+
type DomainContext<State extends CollectorState, Values extends Readonly<Record<string, unknown>> = Record<string, never>> = {
|
|
3202
|
+
state: State;
|
|
3203
|
+
playerId: PlayerIdOfState<State>;
|
|
3204
|
+
q: TableQueriesOfState<State>;
|
|
3205
|
+
derived: DerivedResolver;
|
|
3206
|
+
values: Values;
|
|
3207
|
+
};
|
|
3208
|
+
type ManifestFormInputSchema = ManifestIdSchema<unknown> | z.ZodOptional<ManifestIdSchema<unknown>> | z.ZodNullable<ManifestIdSchema<unknown>>;
|
|
3209
|
+
type DomainNumber<State extends CollectorState> = number | ((context: DomainContext<State>) => number);
|
|
3210
|
+
type ChoiceValue = string | null;
|
|
3211
|
+
type DomainChoice<Value extends ChoiceValue, State extends CollectorState> = {
|
|
3212
|
+
value: Value;
|
|
3213
|
+
label: string;
|
|
3214
|
+
icon?: string;
|
|
3215
|
+
badge?: string;
|
|
3216
|
+
description?: string;
|
|
3217
|
+
disabled?: boolean;
|
|
3218
|
+
disabledReason?: string;
|
|
3219
|
+
};
|
|
3220
|
+
type DomainChoicePresentation = {
|
|
3221
|
+
badge?: string;
|
|
3222
|
+
description?: string;
|
|
3223
|
+
disabled?: boolean;
|
|
3224
|
+
disabledReason?: string;
|
|
3225
|
+
};
|
|
3226
|
+
type ResourceMapChoiceDecorator<State extends CollectorState> = (context: DomainContext<State> & {
|
|
3227
|
+
resourceId: string;
|
|
3228
|
+
label: string;
|
|
3229
|
+
icon?: string;
|
|
3230
|
+
}) => DomainChoicePresentation | null | undefined;
|
|
3231
|
+
type ResourceMapChoiceSource<State extends CollectorState> = "resourceMap" | {
|
|
3232
|
+
source: "resourceMap";
|
|
3233
|
+
decorate?: ResourceMapChoiceDecorator<State>;
|
|
3234
|
+
};
|
|
3235
|
+
type DomainChoices<Value extends ChoiceValue, State extends CollectorState> = ReadonlyArray<DomainChoice<Value, State>> | ResourceMapChoiceSource<State> | ((context: DomainContext<State>) => ReadonlyArray<DomainChoice<Value, State>>);
|
|
3236
|
+
type DependentDomainChoices<Value extends ChoiceValue, State extends CollectorState, Dependencies extends readonly InputFieldRef<string, unknown>[]> = ReadonlyArray<DomainChoice<Value, State>> | ((context: DomainContext<State, DependencyValues<Dependencies>>) => ReadonlyArray<DomainChoice<Value, State>>);
|
|
3237
|
+
type ChoiceListDefaultValue<Value extends string, State extends CollectorState> = Value[] | "all" | ((context: DomainContext<State> & {
|
|
3238
|
+
choices: ReadonlyArray<DomainChoice<Value, State>>;
|
|
3239
|
+
}) => Value[]);
|
|
3240
|
+
type ChoiceDefaultResolver<Value extends ChoiceValue, State extends CollectorState, Values extends Readonly<Record<string, unknown>> = Record<string, never>> = (context: DomainContext<State, Values> & {
|
|
3241
|
+
choices: ReadonlyArray<DomainChoice<Value, State>>;
|
|
3242
|
+
}) => Value | undefined;
|
|
3243
|
+
declare function baseFormInput<Schema extends ManifestFormInputSchema & SchemaLike<unknown>, State extends CollectorState = CollectorState>(schema: Schema): InputCollector<Schema, State, "form">;
|
|
3244
|
+
declare function baseFormInput<Schema extends ManifestFormInputSchema & SchemaLike<unknown>, State extends CollectorState = CollectorState>(schema: Schema, options: {
|
|
3245
|
+
defaultValue: z.infer<Schema>;
|
|
3246
|
+
}): InputCollector<Schema, State, "form"> & {
|
|
3247
|
+
readonly defaultValue: z.infer<Schema>;
|
|
3248
|
+
};
|
|
3249
|
+
declare function resourceMapInput<State extends CollectorState = CollectorState>(options: {
|
|
3250
|
+
resources: ReadonlyArray<{
|
|
3251
|
+
resourceId: string;
|
|
3252
|
+
label?: string;
|
|
3253
|
+
icon?: string;
|
|
3254
|
+
min?: DomainNumber<State>;
|
|
3255
|
+
max: DomainNumber<State>;
|
|
3256
|
+
}>;
|
|
3257
|
+
}): InputCollector<z.ZodRecord<z.ZodString, z.ZodNumber>, State, "form">;
|
|
3258
|
+
declare function resourceMapInput<State extends CollectorState = CollectorState>(options: {
|
|
3259
|
+
resources: ReadonlyArray<{
|
|
3260
|
+
resourceId: string;
|
|
3261
|
+
label?: string;
|
|
3262
|
+
icon?: string;
|
|
3263
|
+
min?: DomainNumber<State>;
|
|
3264
|
+
max: DomainNumber<State>;
|
|
3265
|
+
}>;
|
|
3266
|
+
defaultValue: Record<string, number>;
|
|
3267
|
+
}): InputCollector<z.ZodRecord<z.ZodString, z.ZodNumber>, State, "form"> & {
|
|
3268
|
+
readonly defaultValue: Record<string, number>;
|
|
3269
|
+
};
|
|
3270
|
+
declare function numberInput<State extends CollectorState = CollectorState>(options: {
|
|
3271
|
+
min: DomainNumber<State>;
|
|
3272
|
+
max: DomainNumber<State>;
|
|
3273
|
+
step?: DomainNumber<State>;
|
|
3274
|
+
}): InputCollector<z.ZodNumber, State, "form">;
|
|
3275
|
+
declare function numberInput<State extends CollectorState = CollectorState>(options: {
|
|
3276
|
+
min: DomainNumber<State>;
|
|
3277
|
+
max: DomainNumber<State>;
|
|
3278
|
+
step?: DomainNumber<State>;
|
|
3279
|
+
defaultValue: number;
|
|
3280
|
+
}): InputCollector<z.ZodNumber, State, "form"> & {
|
|
3281
|
+
readonly defaultValue: number;
|
|
3282
|
+
};
|
|
3283
|
+
declare function choiceInput<const Dependencies extends readonly InputFieldRef<string, unknown>[], Value extends ChoiceValue = string, State extends CollectorState = CollectorState>(options: {
|
|
3284
|
+
dependsOn: Dependencies;
|
|
3285
|
+
choices: DependentDomainChoices<Value, State, Dependencies>;
|
|
3286
|
+
defaultValue: Value;
|
|
3287
|
+
}): InputCollector<SchemaLike<Value>, State, "form"> & {
|
|
3288
|
+
readonly defaultValue: Value;
|
|
3289
|
+
};
|
|
3290
|
+
declare function choiceInput<const Dependencies extends readonly InputFieldRef<string, unknown>[], Value extends ChoiceValue = string, State extends CollectorState = CollectorState>(options: {
|
|
3291
|
+
dependsOn: Dependencies;
|
|
3292
|
+
choices: DependentDomainChoices<Value, State, Dependencies>;
|
|
3293
|
+
defaultValue: ChoiceDefaultResolver<Value, State, DependencyValues<Dependencies>>;
|
|
3294
|
+
}): InputCollector<SchemaLike<Value>, State, "form">;
|
|
3295
|
+
declare function choiceInput<Value extends ChoiceValue, State extends CollectorState = CollectorState>(options: {
|
|
3296
|
+
choices: DomainChoices<Value, State>;
|
|
3297
|
+
defaultValue: Value;
|
|
3298
|
+
}): InputCollector<SchemaLike<Value>, State, "form"> & {
|
|
3299
|
+
readonly defaultValue: Value;
|
|
3300
|
+
};
|
|
3301
|
+
declare function choiceInput<Value extends ChoiceValue, State extends CollectorState = CollectorState>(options: {
|
|
3302
|
+
choices: DomainChoices<Value, State>;
|
|
3303
|
+
defaultValue: ChoiceDefaultResolver<Value, State>;
|
|
3304
|
+
}): InputCollector<SchemaLike<Value>, State, "form">;
|
|
3305
|
+
declare function choiceInput<Value extends ChoiceValue, State extends CollectorState = CollectorState, const Dependencies extends readonly InputFieldRef<string, unknown>[] = readonly InputFieldRef<string, unknown>[]>(options: {
|
|
3306
|
+
dependsOn: Dependencies;
|
|
3307
|
+
choices: DependentDomainChoices<Value, State, Dependencies>;
|
|
3308
|
+
defaultValue: Value;
|
|
3309
|
+
}): InputCollector<SchemaLike<Value>, State, "form"> & {
|
|
3310
|
+
readonly defaultValue: Value;
|
|
3311
|
+
};
|
|
3312
|
+
declare function choiceInput<Value extends ChoiceValue, State extends CollectorState = CollectorState, const Dependencies extends readonly InputFieldRef<string, unknown>[] = readonly InputFieldRef<string, unknown>[]>(options: {
|
|
3313
|
+
dependsOn: Dependencies;
|
|
3314
|
+
choices: DependentDomainChoices<Value, State, Dependencies>;
|
|
3315
|
+
defaultValue: ChoiceDefaultResolver<Value, State, DependencyValues<Dependencies>>;
|
|
3316
|
+
}): InputCollector<SchemaLike<Value>, State, "form">;
|
|
3317
|
+
declare function choiceListInput<Value extends string, State extends CollectorState = CollectorState>(options: {
|
|
3318
|
+
choices: DomainChoices<Value, State>;
|
|
3319
|
+
min?: DomainNumber<State>;
|
|
3320
|
+
max?: DomainNumber<State>;
|
|
3321
|
+
defaultValue: Value[];
|
|
3322
|
+
}): InputCollector<SchemaLike<Value[]>, State, "form"> & {
|
|
3323
|
+
readonly defaultValue: Value[];
|
|
3324
|
+
};
|
|
3325
|
+
declare function choiceListInput<Value extends string, State extends CollectorState = CollectorState>(options: {
|
|
3326
|
+
choices: DomainChoices<Value, State>;
|
|
3327
|
+
min?: DomainNumber<State>;
|
|
3328
|
+
max?: DomainNumber<State>;
|
|
3329
|
+
defaultValue?: ChoiceListDefaultValue<Value, State>;
|
|
3330
|
+
}): InputCollector<SchemaLike<Value[]>, State, "form">;
|
|
3331
|
+
type FormInputForState<State extends CollectorState> = {
|
|
3332
|
+
<Schema extends ManifestFormInputSchema & SchemaLike<unknown>>(schema: Schema): InputCollector<Schema, State, "form">;
|
|
3333
|
+
<Schema extends ManifestFormInputSchema & SchemaLike<unknown>>(schema: Schema, options: {
|
|
3334
|
+
defaultValue: z.infer<Schema>;
|
|
3335
|
+
}): InputCollector<Schema, State, "form"> & {
|
|
3336
|
+
readonly defaultValue: z.infer<Schema>;
|
|
3337
|
+
};
|
|
3338
|
+
resourceMap(options: Parameters<typeof resourceMapInput<State>>[0]): ReturnType<typeof resourceMapInput<State>>;
|
|
3339
|
+
resourceChoices(options?: {
|
|
3340
|
+
decorate?: ResourceMapChoiceDecorator<State>;
|
|
3341
|
+
}): ResourceMapChoiceSource<State>;
|
|
3342
|
+
number(options: Parameters<typeof numberInput<State>>[0]): ReturnType<typeof numberInput<State>>;
|
|
3343
|
+
choice<Value extends ChoiceValue>(options: {
|
|
3344
|
+
choices: DomainChoices<Value, State>;
|
|
3345
|
+
defaultValue: Value;
|
|
3346
|
+
}): InputCollector<SchemaLike<Value>, State, "form"> & {
|
|
3347
|
+
readonly defaultValue: Value;
|
|
3348
|
+
};
|
|
3349
|
+
choice<Value extends ChoiceValue>(options: {
|
|
3350
|
+
choices: DomainChoices<Value, State>;
|
|
3351
|
+
defaultValue: ChoiceDefaultResolver<Value, State>;
|
|
3352
|
+
}): InputCollector<SchemaLike<Value>, State, "form">;
|
|
3353
|
+
choiceList<Value extends string>(options: {
|
|
3354
|
+
choices: DomainChoices<Value, State>;
|
|
3355
|
+
min?: DomainNumber<State>;
|
|
3356
|
+
max?: DomainNumber<State>;
|
|
3357
|
+
defaultValue: Value[];
|
|
3358
|
+
}): InputCollector<SchemaLike<Value[]>, State, "form"> & {
|
|
3359
|
+
readonly defaultValue: Value[];
|
|
3360
|
+
};
|
|
3361
|
+
choiceList<Value extends string>(options: {
|
|
3362
|
+
choices: DomainChoices<Value, State>;
|
|
3363
|
+
min?: DomainNumber<State>;
|
|
3364
|
+
max?: DomainNumber<State>;
|
|
3365
|
+
defaultValue?: ChoiceListDefaultValue<Value, State>;
|
|
3366
|
+
}): InputCollector<SchemaLike<Value[]>, State, "form">;
|
|
3367
|
+
};
|
|
3368
|
+
declare function formInputForState<State extends CollectorState>(): FormInputForState<State>;
|
|
3369
|
+
/**
|
|
3370
|
+
* Manifest-backed id input. Free-form Zod schemas are intentionally explicit:
|
|
3371
|
+
* if the runtime cannot disclose valid values or numeric bounds through a
|
|
3372
|
+
* manifest id or domain helper, use a custom interaction surface with an
|
|
3373
|
+
* explicit `paramsSchema` instead of the default form renderer.
|
|
3374
|
+
*/
|
|
3375
|
+
declare const formInput: typeof baseFormInput & {
|
|
3376
|
+
resourceMap: typeof resourceMapInput;
|
|
3377
|
+
resourceChoices: <State extends CollectorState = CollectorState>(options?: {
|
|
3378
|
+
decorate?: ResourceMapChoiceDecorator<State>;
|
|
3379
|
+
}) => ResourceMapChoiceSource<State>;
|
|
3380
|
+
number: typeof numberInput;
|
|
3381
|
+
choice: typeof choiceInput;
|
|
3382
|
+
choiceList: typeof choiceListInput;
|
|
3383
|
+
forState: typeof formInputForState;
|
|
3384
|
+
};
|
|
3385
|
+
|
|
3386
|
+
type TargetContext<State extends CollectorState> = {
|
|
3387
|
+
state: State;
|
|
3388
|
+
playerId: PlayerIdOfState<State>;
|
|
3389
|
+
q: TableQueriesOfState<State>;
|
|
3390
|
+
values?: Readonly<Record<string, unknown>>;
|
|
3391
|
+
};
|
|
3392
|
+
type TargetPredicateArgs<State extends CollectorState, Target> = TargetContext<State> & {
|
|
3393
|
+
targetId: Target;
|
|
3394
|
+
target: Target;
|
|
3395
|
+
};
|
|
3396
|
+
type TargetPredicate<State extends CollectorState, Target> = {
|
|
3397
|
+
id: string;
|
|
3398
|
+
errorCode: string;
|
|
3399
|
+
message?: string;
|
|
3400
|
+
test: (args: TargetPredicateArgs<State, Target>) => boolean;
|
|
3401
|
+
};
|
|
3402
|
+
type BoundTargetRule<Target> = {
|
|
3403
|
+
readonly eligible: () => readonly Target[];
|
|
3404
|
+
readonly validate: (target: Target) => ValidationIssue | null;
|
|
3405
|
+
readonly isEligible: (target: Target) => boolean;
|
|
3406
|
+
};
|
|
3407
|
+
type TargetRule<State extends CollectorState, Target> = {
|
|
3408
|
+
readonly eligible: (ctx: TargetContext<State>) => readonly Target[];
|
|
3409
|
+
readonly validate: (ctx: TargetContext<State>, target: Target) => ValidationIssue | null;
|
|
3410
|
+
readonly isEligible: (ctx: TargetContext<State>, target: Target) => boolean;
|
|
3411
|
+
readonly bind: (ctx: TargetContext<State>) => BoundTargetRule<Target>;
|
|
3412
|
+
};
|
|
3413
|
+
type TargetRuleBuilder<State extends CollectorState, Target, Rule extends TargetRule<State, Target>> = {
|
|
3414
|
+
readonly where: (predicate: TargetPredicate<State, Target>) => TargetRuleBuilder<State, Target, Rule>;
|
|
3415
|
+
readonly build: () => Rule;
|
|
3416
|
+
};
|
|
3417
|
+
|
|
3418
|
+
type BoardTargetPredicate<State extends CollectorState, Target> = TargetPredicate<State, Target>;
|
|
3419
|
+
type BoardTargetRule<State extends CollectorState, Target> = TargetRule<State, Target> & {
|
|
3420
|
+
readonly boardId: string;
|
|
3421
|
+
readonly targetKind: TargetKind;
|
|
3422
|
+
readonly valueKind: "board-id" | "player-board-space";
|
|
3423
|
+
};
|
|
3424
|
+
type BoardTargetBuilder<State extends CollectorState, Target> = TargetRuleBuilder<State, Target, BoardTargetRule<State, Target>>;
|
|
3425
|
+
type PlayerBoardSpaceTarget<BoardId extends string, SpaceId extends string, PlayerId extends string> = {
|
|
3426
|
+
readonly boardId: BoardId;
|
|
3427
|
+
readonly playerId: PlayerId;
|
|
3428
|
+
readonly spaceId: SpaceId;
|
|
3429
|
+
};
|
|
3430
|
+
declare const boardTarget: {
|
|
3431
|
+
edge: <State extends CollectorState, Id extends string>(boardId: string) => BoardTargetBuilder<State, Id>;
|
|
3432
|
+
vertex: <State extends CollectorState, Id extends string>(boardId: string) => BoardTargetBuilder<State, Id>;
|
|
3433
|
+
space: <State extends CollectorState, Id extends string>(boardId: string) => BoardTargetBuilder<State, Id>;
|
|
3434
|
+
tile: <State extends CollectorState, Id extends string>(boardId: string) => BoardTargetBuilder<State, Id>;
|
|
3435
|
+
playerSpace<State extends CollectorState, BoardId extends string, SpaceId extends string>(boardId: BoardId): BoardTargetBuilder<State, PlayerBoardSpaceTarget<BoardId, SpaceId, PlayerIdOfState<State>>>;
|
|
3436
|
+
};
|
|
3437
|
+
|
|
3438
|
+
declare function playerSpaceInput<State extends CollectorState = CollectorState, BoardId extends string = string, SpaceId extends string = string, PlayerId extends string = string>(options: {
|
|
3439
|
+
target: BoardTargetRule<State, PlayerBoardSpaceTarget<BoardId, SpaceId, PlayerId>>;
|
|
3440
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3441
|
+
}): InputCollector<z.ZodType<PlayerBoardSpaceTarget<BoardId, SpaceId, PlayerId>>, State, "board-space">;
|
|
3442
|
+
declare const boardInput: {
|
|
3443
|
+
vertex: <State extends CollectorState = CollectorState, Id extends string = string>(options: {
|
|
3444
|
+
target: BoardTargetRule<State, Id>;
|
|
3445
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3446
|
+
}) => {
|
|
3447
|
+
readonly kind: "board-vertex";
|
|
3448
|
+
readonly schema: z.ZodType<Id, unknown, z.core.$ZodTypeInternals<Id, unknown>>;
|
|
3449
|
+
readonly defaultValue?: Id | undefined;
|
|
3450
|
+
readonly selection?: InputSelectionDescriptor;
|
|
3451
|
+
readonly eligibleTargets?: (state: CollectorState, playerId: string, q: unknown, values?: Readonly<Record<string, unknown>>) => ReadonlyArray<unknown>;
|
|
3452
|
+
readonly validateTarget?: (state: CollectorState, playerId: string, q: unknown, targetId: unknown, values?: Readonly<Record<string, unknown>>) => ValidationIssue | null | undefined;
|
|
3453
|
+
readonly dependsOn?: readonly string[];
|
|
3454
|
+
readonly resolveDefaultValue?: ((state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, domain: InputDomainDescriptor) => Id | undefined) | undefined;
|
|
3455
|
+
} & {
|
|
3456
|
+
readonly domain: (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, values?: Readonly<Record<string, unknown>>) => BoardTargetDomainDescriptor;
|
|
3457
|
+
} & {
|
|
3458
|
+
readonly meta: BoardInputCollectorMeta;
|
|
3459
|
+
};
|
|
3460
|
+
edge: <State extends CollectorState = CollectorState, Id extends string = string>(options: {
|
|
3461
|
+
target: BoardTargetRule<State, Id>;
|
|
3462
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3463
|
+
}) => {
|
|
3464
|
+
readonly kind: "board-edge";
|
|
3465
|
+
readonly schema: z.ZodType<Id, unknown, z.core.$ZodTypeInternals<Id, unknown>>;
|
|
3466
|
+
readonly defaultValue?: Id | undefined;
|
|
3467
|
+
readonly selection?: InputSelectionDescriptor;
|
|
3468
|
+
readonly eligibleTargets?: (state: CollectorState, playerId: string, q: unknown, values?: Readonly<Record<string, unknown>>) => ReadonlyArray<unknown>;
|
|
3469
|
+
readonly validateTarget?: (state: CollectorState, playerId: string, q: unknown, targetId: unknown, values?: Readonly<Record<string, unknown>>) => ValidationIssue | null | undefined;
|
|
3470
|
+
readonly dependsOn?: readonly string[];
|
|
3471
|
+
readonly resolveDefaultValue?: ((state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, domain: InputDomainDescriptor) => Id | undefined) | undefined;
|
|
3472
|
+
} & {
|
|
3473
|
+
readonly domain: (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, values?: Readonly<Record<string, unknown>>) => BoardTargetDomainDescriptor;
|
|
3474
|
+
} & {
|
|
3475
|
+
readonly meta: BoardInputCollectorMeta;
|
|
3476
|
+
};
|
|
3477
|
+
tile: <State extends CollectorState = CollectorState, Id extends string = string>(options: {
|
|
3478
|
+
target: BoardTargetRule<State, Id>;
|
|
3479
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3480
|
+
}) => {
|
|
3481
|
+
readonly kind: "board-tile";
|
|
3482
|
+
readonly schema: z.ZodType<Id, unknown, z.core.$ZodTypeInternals<Id, unknown>>;
|
|
3483
|
+
readonly defaultValue?: Id | undefined;
|
|
3484
|
+
readonly selection?: InputSelectionDescriptor;
|
|
3485
|
+
readonly eligibleTargets?: (state: CollectorState, playerId: string, q: unknown, values?: Readonly<Record<string, unknown>>) => ReadonlyArray<unknown>;
|
|
3486
|
+
readonly validateTarget?: (state: CollectorState, playerId: string, q: unknown, targetId: unknown, values?: Readonly<Record<string, unknown>>) => ValidationIssue | null | undefined;
|
|
3487
|
+
readonly dependsOn?: readonly string[];
|
|
3488
|
+
readonly resolveDefaultValue?: ((state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, domain: InputDomainDescriptor) => Id | undefined) | undefined;
|
|
3489
|
+
} & {
|
|
3490
|
+
readonly domain: (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, values?: Readonly<Record<string, unknown>>) => BoardTargetDomainDescriptor;
|
|
3491
|
+
} & {
|
|
3492
|
+
readonly meta: BoardInputCollectorMeta;
|
|
3493
|
+
};
|
|
3494
|
+
space: <State extends CollectorState = CollectorState, Id extends string = string>(options: {
|
|
3495
|
+
target: BoardTargetRule<State, Id>;
|
|
3496
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3497
|
+
}) => {
|
|
3498
|
+
readonly kind: "board-space";
|
|
3499
|
+
readonly schema: z.ZodType<Id, unknown, z.core.$ZodTypeInternals<Id, unknown>>;
|
|
3500
|
+
readonly defaultValue?: Id | undefined;
|
|
3501
|
+
readonly selection?: InputSelectionDescriptor;
|
|
3502
|
+
readonly eligibleTargets?: (state: CollectorState, playerId: string, q: unknown, values?: Readonly<Record<string, unknown>>) => ReadonlyArray<unknown>;
|
|
3503
|
+
readonly validateTarget?: (state: CollectorState, playerId: string, q: unknown, targetId: unknown, values?: Readonly<Record<string, unknown>>) => ValidationIssue | null | undefined;
|
|
3504
|
+
readonly dependsOn?: readonly string[];
|
|
3505
|
+
readonly resolveDefaultValue?: ((state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, domain: InputDomainDescriptor) => Id | undefined) | undefined;
|
|
3506
|
+
} & {
|
|
3507
|
+
readonly domain: (state: CollectorState, playerId: string, q: unknown, derived: DerivedResolver, values?: Readonly<Record<string, unknown>>) => BoardTargetDomainDescriptor;
|
|
3508
|
+
} & {
|
|
3509
|
+
readonly meta: BoardInputCollectorMeta;
|
|
3510
|
+
};
|
|
3511
|
+
playerSpace: typeof playerSpaceInput;
|
|
3512
|
+
};
|
|
3513
|
+
|
|
3514
|
+
type CardTargetPredicate<State extends CollectorState, Id extends string> = TargetPredicate<State, Id>;
|
|
3515
|
+
type CardTargetRule<State extends CollectorState, Id extends string, ZoneIds extends readonly string[] = readonly string[]> = TargetRule<State, Id> & {
|
|
3516
|
+
readonly zoneIds: ZoneIds;
|
|
3517
|
+
readonly zoneId: ZoneIds[number];
|
|
3518
|
+
readonly targetKind: "card";
|
|
3519
|
+
};
|
|
3520
|
+
type CardTargetBuilder<State extends CollectorState, Id extends string, ZoneIds extends readonly string[] = readonly string[]> = TargetRuleBuilder<State, Id, CardTargetRule<State, Id, ZoneIds>>;
|
|
3521
|
+
declare const cardTarget: {
|
|
3522
|
+
zones<State extends CollectorState, Id extends string = CardIdOfState<State>, const ZoneIds extends readonly string[] = readonly string[]>(zoneIds: ZoneIds): CardTargetBuilder<State, Id, ZoneIds>;
|
|
3523
|
+
};
|
|
3524
|
+
|
|
3525
|
+
type ChoiceTargetOption<Id extends string> = {
|
|
3526
|
+
id: Id;
|
|
3527
|
+
label?: string;
|
|
3528
|
+
};
|
|
3529
|
+
type ChoiceOptionsFactory<State extends CollectorState, Id extends string> = (state: State, playerId: PlayerIdOfState<State>, q: TableQueriesOfState<State>) => ReadonlyArray<ChoiceTargetOption<Id>>;
|
|
3530
|
+
type ChoiceTargetPredicate<State extends CollectorState, Id extends string> = TargetPredicate<State, Id>;
|
|
3531
|
+
type ChoiceTargetRule<State extends CollectorState, Id extends string> = TargetRule<State, Id> & {
|
|
3532
|
+
readonly targetKind: "choice";
|
|
3533
|
+
readonly options: (ctx: TargetContext<State>) => ReadonlyArray<ChoiceTargetOption<Id>>;
|
|
3534
|
+
readonly eligibleOptions: (ctx: TargetContext<State>) => ReadonlyArray<ChoiceTargetOption<Id>>;
|
|
3535
|
+
};
|
|
3536
|
+
type ChoiceTargetBuilder<State extends CollectorState, Id extends string> = TargetRuleBuilder<State, Id, ChoiceTargetRule<State, Id>>;
|
|
3537
|
+
declare const choiceTarget: {
|
|
3538
|
+
options<State extends CollectorState, Id extends string>(options: ReadonlyArray<ChoiceTargetOption<Id>> | ChoiceOptionsFactory<State, Id>): ChoiceTargetBuilder<State, Id>;
|
|
3539
|
+
};
|
|
3540
|
+
|
|
3541
|
+
/**
|
|
3542
|
+
* `cardInput` produces a collector backed by one built `cardTarget` rule.
|
|
3543
|
+
* The submitted value is a manifest-branded card id.
|
|
3544
|
+
*
|
|
3545
|
+
* The target rule feeds server-authoritative eligible-card projection, submit
|
|
3546
|
+
* validation, and tests through its `bind({ state, playerId, q })` helper.
|
|
3547
|
+
*/
|
|
3548
|
+
declare function cardInput<State extends CollectorState = CollectorState, Id extends string = CardIdOfState<State>, const ZoneIds extends readonly string[] = readonly string[]>(options: {
|
|
3549
|
+
target: CardTargetRule<State, Id, ZoneIds>;
|
|
3550
|
+
dependsOn?: readonly InputFieldRef<string, unknown>[];
|
|
3551
|
+
}): InputCollector<z.ZodType<Id>, State, "card"> & {
|
|
3552
|
+
readonly meta: {
|
|
3553
|
+
readonly zoneId: ZoneIds[number];
|
|
3554
|
+
readonly zoneIds: ZoneIds;
|
|
3555
|
+
readonly targetKind: "card";
|
|
3556
|
+
};
|
|
3557
|
+
};
|
|
3558
|
+
|
|
3559
|
+
type SchemaStringValue<Schema extends SchemaLike<unknown>> = Extract<Schema extends z.ZodType<infer V> ? V : never, string>;
|
|
3560
|
+
/**
|
|
3561
|
+
* `promptInput` marks an interaction as a prompt delivered to a player's
|
|
3562
|
+
* inbox. The submitted value is validated by the supplied Zod schema.
|
|
3563
|
+
*
|
|
3564
|
+
* Static or free-form prompts need only `schema`. Finite dynamic choices use
|
|
3565
|
+
* a built `choiceTarget.options(...).build()` rule so projected options and
|
|
3566
|
+
* submit validation share one source of truth.
|
|
3567
|
+
*/
|
|
3568
|
+
declare function promptInput<Schema extends SchemaLike<unknown>, State extends CollectorState = CollectorState>(options: {
|
|
3569
|
+
schema: Schema;
|
|
3570
|
+
target?: ChoiceTargetRule<State, SchemaStringValue<Schema>>;
|
|
3571
|
+
}): InputCollector<Schema, State, "prompt">;
|
|
3572
|
+
|
|
3573
|
+
/**
|
|
3574
|
+
* `rngInput.*` helpers produce collectors whose value is *sampled by the
|
|
3575
|
+
* engine on submit* rather than supplied by the client. The schema pins
|
|
3576
|
+
* the exact output shape so `ParamsOf<Collectors>` sees precisely typed
|
|
3577
|
+
* results.
|
|
3578
|
+
*
|
|
3579
|
+
* Determinism:
|
|
3580
|
+
* Sampling happens inside `submitInteraction` only, never inside
|
|
3581
|
+
* `validateInteraction`. This lets clients dry-run a submission without
|
|
3582
|
+
* burning RNG state.
|
|
3583
|
+
*/
|
|
3584
|
+
type DieRoll = z.ZodObject<{
|
|
3585
|
+
values: z.ZodArray<z.ZodNumber>;
|
|
3586
|
+
}>;
|
|
3587
|
+
type CoinFlip = z.ZodObject<{
|
|
3588
|
+
value: z.ZodEnum<{
|
|
3589
|
+
heads: "heads";
|
|
3590
|
+
tails: "tails";
|
|
3591
|
+
}>;
|
|
3592
|
+
}>;
|
|
3593
|
+
type RngCollector<Schema extends DieRoll | CoinFlip, State extends CollectorState> = InputCollector<Schema, State, "rng">;
|
|
3594
|
+
/**
|
|
3595
|
+
* Roll `count` d6s. The submitted value is `{ values: number[] }` with
|
|
3596
|
+
* `values.length === count` and each face `1..6`.
|
|
3597
|
+
*/
|
|
3598
|
+
declare function d6<State extends CollectorState = CollectorState>(count?: number): RngCollector<DieRoll, State>;
|
|
3599
|
+
/** Flip a coin. The submitted value is `{ value: "heads" | "tails" }`. */
|
|
3600
|
+
declare function coin<State extends CollectorState = CollectorState>(): RngCollector<CoinFlip, State>;
|
|
3601
|
+
declare const rngInput: {
|
|
3602
|
+
d6: typeof d6;
|
|
3603
|
+
coin: typeof coin;
|
|
3604
|
+
};
|
|
3605
|
+
|
|
3606
|
+
type ManyOptions = {
|
|
3607
|
+
count: number;
|
|
3608
|
+
distinct?: boolean;
|
|
3609
|
+
} | {
|
|
3610
|
+
min?: number;
|
|
3611
|
+
max?: number;
|
|
3612
|
+
distinct?: boolean;
|
|
3613
|
+
};
|
|
3614
|
+
type NonRngCollector = InputCollector<SchemaLike<unknown>, CollectorState> & {
|
|
3615
|
+
readonly kind: Exclude<InputCollector["kind"], "rng">;
|
|
3616
|
+
};
|
|
3617
|
+
type CollectorSchema<Collector extends NonRngCollector> = [Collector] extends [
|
|
3618
|
+
InputCollector<infer Schema, CollectorState>
|
|
3619
|
+
] ? Schema : never;
|
|
3620
|
+
type CollectorStateOf<Collector extends NonRngCollector> = [Collector] extends [
|
|
3621
|
+
InputCollector<SchemaLike<unknown>, infer State>
|
|
3622
|
+
] ? State : never;
|
|
3623
|
+
type CollectorKindOf<Collector extends NonRngCollector> = [Collector] extends [
|
|
3624
|
+
{
|
|
3625
|
+
readonly kind: infer Kind extends Exclude<InputCollector["kind"], "rng">;
|
|
3626
|
+
}
|
|
3627
|
+
] ? Kind : never;
|
|
3628
|
+
type ManyInputCollector<Schema extends SchemaLike<unknown> = SchemaLike<unknown>, State extends CollectorState = CollectorState, Kind extends Exclude<InputCollector["kind"], "rng"> = Exclude<InputCollector["kind"], "rng">> = InputCollector<z.ZodType<ReadonlyArray<z.infer<Schema>>>, State, Kind> & {
|
|
3629
|
+
readonly selection: Extract<InputSelectionDescriptor, {
|
|
3630
|
+
mode: "many";
|
|
3631
|
+
}>;
|
|
3632
|
+
};
|
|
3633
|
+
declare function many<Collector extends NonRngCollector>(collector: Collector, options: ManyOptions): ManyInputCollector<CollectorSchema<Collector>, CollectorStateOf<Collector>, CollectorKindOf<Collector>> & Pick<Collector, "meta">;
|
|
3634
|
+
|
|
3635
|
+
type SparseMap<Key extends string, Value> = Partial<Record<Key, Value>>;
|
|
3636
|
+
type SparseCounts<Key extends string> = SparseMap<Key, number>;
|
|
3637
|
+
declare function sparseMap<KeySchema extends z.ZodType<string>, ValueSchema extends z.ZodTypeAny>(keySchema: KeySchema, valueSchema: ValueSchema): z.ZodType<SparseMap<z.infer<KeySchema>, z.infer<ValueSchema>>>;
|
|
3638
|
+
declare function sparseCounts<KeySchema extends z.ZodType<string>>(keySchema: KeySchema): z.ZodType<SparseCounts<z.infer<KeySchema>>>;
|
|
3639
|
+
declare function normalizeCommandParams<Output>(schema: SchemaLike<Output>, input: unknown): Output;
|
|
3640
|
+
|
|
3641
|
+
type ReducerBundle = ReducerBundleContract & {
|
|
3642
|
+
createInProcessRuntime(): {
|
|
3643
|
+
initialize(input: {
|
|
3644
|
+
table: unknown;
|
|
3645
|
+
playerIds: string[];
|
|
3646
|
+
rngSeed?: number | null;
|
|
3647
|
+
setup?: unknown;
|
|
3648
|
+
}): Promise<void>;
|
|
3649
|
+
hydrate(input: {
|
|
3650
|
+
state: unknown;
|
|
3651
|
+
}): void;
|
|
3652
|
+
dispatch(input: {
|
|
3653
|
+
input: unknown;
|
|
3654
|
+
}): Promise<{
|
|
3655
|
+
kind: "accept";
|
|
3656
|
+
} | {
|
|
3657
|
+
kind: "accept";
|
|
3658
|
+
state: unknown;
|
|
3659
|
+
trace: unknown[];
|
|
3660
|
+
} | {
|
|
3661
|
+
kind: "reject";
|
|
3662
|
+
errorCode: string;
|
|
3663
|
+
message?: string;
|
|
3664
|
+
}>;
|
|
3665
|
+
projectSeatViewDynamic(input: {
|
|
3666
|
+
playerId: unknown;
|
|
3667
|
+
viewId?: string;
|
|
3668
|
+
}): unknown;
|
|
3669
|
+
projectSeatsDynamic(input: {
|
|
3670
|
+
playerIds: unknown[];
|
|
3671
|
+
viewId?: string;
|
|
3672
|
+
projectionMode?: "full" | "actionsOnly";
|
|
3673
|
+
}): {
|
|
3674
|
+
currentStage: string | null;
|
|
3675
|
+
stageSeats: string[];
|
|
3676
|
+
simultaneousPhase: {
|
|
3677
|
+
phaseName: string;
|
|
3678
|
+
interactionId: string;
|
|
3679
|
+
actorIds: string[];
|
|
3680
|
+
sealedPlayerIds: string[];
|
|
3681
|
+
pendingPlayerIds: string[];
|
|
3682
|
+
} | null;
|
|
3683
|
+
seats: Record<string, {
|
|
3684
|
+
view?: unknown;
|
|
3685
|
+
availableInteractionRefs: unknown;
|
|
3686
|
+
zones?: unknown;
|
|
3687
|
+
}>;
|
|
3688
|
+
interactionsByRef: Record<string, unknown>;
|
|
3689
|
+
};
|
|
3690
|
+
snapshot(): unknown;
|
|
3691
|
+
unsafeState(): unknown;
|
|
3692
|
+
};
|
|
3693
|
+
projectSeatViewDynamic(input: {
|
|
3694
|
+
state: unknown;
|
|
3695
|
+
playerId: unknown;
|
|
3696
|
+
viewId?: string;
|
|
3697
|
+
}): unknown;
|
|
3698
|
+
};
|
|
3699
|
+
|
|
3700
|
+
declare function createReducerBundle<Contract extends ReducerGameContractLike, Definitions extends PhaseMapOf<Contract>, Views extends ViewMapOf<Contract>>(definition: ReducerGameDefinition<Contract, Definitions, Views>): ReducerBundle;
|
|
3701
|
+
|
|
3702
|
+
type ClientParamSchema = {
|
|
3703
|
+
safeParse: (value: unknown) => {
|
|
3704
|
+
success: true;
|
|
3705
|
+
data: Record<string, unknown>;
|
|
3706
|
+
} | {
|
|
3707
|
+
success: false;
|
|
3708
|
+
error: {
|
|
3709
|
+
issues: Array<{
|
|
3710
|
+
path: PropertyKey[];
|
|
3711
|
+
message: string;
|
|
3712
|
+
}>;
|
|
3713
|
+
};
|
|
3714
|
+
};
|
|
3715
|
+
};
|
|
3716
|
+
type ClientParamSchemasByPhase = Readonly<Record<string, Readonly<Record<string, ClientParamSchema>>>>;
|
|
3717
|
+
declare function createClientParamSchemasByPhase<Contract extends ReducerGameContractLike, Definitions extends PhaseMapOf<Contract>, Views extends ViewMapOf<Contract>>(definition: ReducerGameDefinition<Contract, Definitions, Views>): ClientParamSchemasByPhase;
|
|
3718
|
+
|
|
3719
|
+
type StatefulBootstrapContext = {
|
|
3720
|
+
table: RuntimeTableRecord;
|
|
3721
|
+
runtime: {
|
|
3722
|
+
rng: RuntimeRngState;
|
|
3723
|
+
};
|
|
3724
|
+
};
|
|
3725
|
+
declare function applySetupBootstrap<State extends StatefulBootstrapContext>(state: State, steps: readonly SetupBootstrapStep[]): State;
|
|
3726
|
+
|
|
3727
|
+
declare function shuffle<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike>(container: SetupBootstrapContainerRef<Manifest>): SetupBootstrapStep<Manifest>;
|
|
3728
|
+
declare function dealToPlayerZone<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike>({ from, zoneId, count, playerIds, }: {
|
|
3729
|
+
from: Extract<SetupBootstrapContainerRef<Manifest>, {
|
|
3730
|
+
type: "sharedZone" | "sharedBoardContainer";
|
|
3731
|
+
}>;
|
|
3732
|
+
zoneId: Extract<SetupBootstrapPerPlayerContainerTemplateRef<Manifest>, {
|
|
3733
|
+
type: "playerZone";
|
|
3734
|
+
}>["zoneId"];
|
|
3735
|
+
count: number;
|
|
3736
|
+
playerIds?: readonly PlayerIdOfManifest<Manifest>[];
|
|
3737
|
+
}): SetupBootstrapStep<Manifest>;
|
|
3738
|
+
declare function dealToPlayerBoardContainer<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike>({ from, boardId, containerId, count, playerIds, }: {
|
|
3739
|
+
from: Extract<SetupBootstrapContainerRef<Manifest>, {
|
|
3740
|
+
type: "sharedZone" | "sharedBoardContainer";
|
|
3741
|
+
}>;
|
|
3742
|
+
boardId: Extract<SetupBootstrapPerPlayerContainerTemplateRef<Manifest>, {
|
|
3743
|
+
type: "playerBoardContainer";
|
|
3744
|
+
}>["boardId"];
|
|
3745
|
+
containerId: Extract<SetupBootstrapPerPlayerContainerTemplateRef<Manifest>, {
|
|
3746
|
+
type: "playerBoardContainer";
|
|
3747
|
+
}>["containerId"];
|
|
3748
|
+
count: number;
|
|
3749
|
+
playerIds?: readonly PlayerIdOfManifest<Manifest>[];
|
|
3750
|
+
}): SetupBootstrapStep<Manifest>;
|
|
3751
|
+
declare function seedSharedBoardContainer<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike>({ from, boardId, containerId, count, componentIds, }: {
|
|
3752
|
+
from: SetupBootstrapContainerRef<Manifest>;
|
|
3753
|
+
boardId: Extract<SetupBootstrapDestinationRef<Manifest>, {
|
|
3754
|
+
type: "sharedBoardContainer";
|
|
3755
|
+
}>["boardId"];
|
|
3756
|
+
containerId: Extract<SetupBootstrapDestinationRef<Manifest>, {
|
|
3757
|
+
type: "sharedBoardContainer";
|
|
3758
|
+
}>["containerId"];
|
|
3759
|
+
count?: number;
|
|
3760
|
+
componentIds?: readonly (CardIdOfManifest<Manifest> | PieceIdOfManifest<Manifest> | DieIdOfManifest<Manifest>)[];
|
|
3761
|
+
}): SetupBootstrapStep<Manifest>;
|
|
3762
|
+
declare function seedSharedBoardSpace<Manifest extends GeneratedManifestContractLike = GeneratedManifestContractLike>({ from, boardId, spaceId, count, componentIds, }: {
|
|
3763
|
+
from: SetupBootstrapContainerRef<Manifest>;
|
|
3764
|
+
boardId: Extract<SetupBootstrapDestinationRef<Manifest>, {
|
|
3765
|
+
type: "sharedBoardSpace";
|
|
3766
|
+
}>["boardId"];
|
|
3767
|
+
spaceId: Extract<SetupBootstrapDestinationRef<Manifest>, {
|
|
3768
|
+
type: "sharedBoardSpace";
|
|
3769
|
+
}>["spaceId"];
|
|
3770
|
+
count?: number;
|
|
3771
|
+
componentIds?: readonly (CardIdOfManifest<Manifest> | PieceIdOfManifest<Manifest> | DieIdOfManifest<Manifest>)[];
|
|
3772
|
+
}): SetupBootstrapStep<Manifest>;
|
|
3773
|
+
|
|
3774
|
+
declare function setActivePlayers<State extends {
|
|
3775
|
+
flow: {
|
|
3776
|
+
activePlayers: PlayerIdOfState<State>[];
|
|
3777
|
+
};
|
|
3778
|
+
}>(state: State, activePlayers: PlayerIdOfState<State>[]): State;
|
|
3779
|
+
declare function assertCardAllowedInContainer<Table extends RuntimeTableRecord, BoardId extends BoardIdOfTable<NoInfer<Table>>, ContainerId extends BoardContainerIdOfTable<NoInfer<Table>, BoardId>>(table: Table, boardId: BoardId, containerId: ContainerId, componentId: string): void;
|
|
3780
|
+
|
|
3781
|
+
declare function createTableQueries<Table extends RuntimeTableRecord>(table: Table): TableQueries<Table>;
|
|
3782
|
+
declare function createStateQueries<State extends {
|
|
3783
|
+
table: RuntimeTableRecord;
|
|
3784
|
+
}>(state: State): TableQueriesOfState<State>;
|
|
3785
|
+
|
|
3786
|
+
export { type ActionContext, type BoardBaseIdOfManifest, type BoardContainerIdOfManifest, type BoardContainerIdOfTable, type BoardIdOfManifest, type BoardIdOfTable, type BoardInteractionKeyOfDefinition, type BoardLayoutOfManifest, type BoardMapOfTable, type BoardRef, type BoardStateOfTable, type BoardTargetBuilder, type BoardTargetPredicate, type BoardTargetRule, type BoardTypeIdOfManifest, type BoardTypeIdOfTable, type BoundTargetRule, type CardIdOfDeck, type CardIdOfHand, type CardIdOfManifest, type CardIdOfState, type CardIdOfTable, type CardInputZoneIdsOfDefinition, type CardInteractionKeyOfDefinition, type CardTargetBuilder, type CardTargetPredicate, type CardTargetRule, type ChoiceOption, type ChoiceOptionsFactory, type ChoiceTargetBuilder, type ChoiceTargetOption, type ChoiceTargetPredicate, type ChoiceTargetRule, type ClientParamSchema, type ClientParamSchemasByPhase, type ClientParamsOf, type ClientParamsOfInteractionOfDefinition, type CompatibleCardIdForHandAndDeck, type CompatibleHandIdForDeck, type ComponentDataOfTable, type ComponentIdOfTable, type ComponentLocationByTypeOfTable, type ComponentLocationOfTable, type ContinuationCallable, type ContinuationInput, type ContinuationResponseOf, type ContinuationSourceKind, type ContinuationToken, type DeckCardsOfTable, type DeckIdOfState, type DeckIdOfTable, type DefaultedClientParamKeysOfInteractionOfDefinition, type DefinedInputs, type DependencyValues, type DerivedDefinition, type DerivedResolver, type DieIdOfManifest, type EdgeTypeIdOfManifest, type EffectContinuationCallable, type EffectContinuationInput, type EffectContinuationResponse, type EffectDefinition, type EffectIdsOfDefinition, type EffectMap, type EffectRollDieDefinition, type EffectShuffleDefinition, type GameStateOf, type HandCardsOfTable, type HandIdOfState, type HandIdOfTable, type HexBoardIdOfTable, type HexEdgeIdOfTable, type HexEdgeTypeIdOfTable, type HexSpaceIdOfTable, type HexSpaceTypeIdOfTable, type HexVertexIdOfTable, type HexVertexTypeIdOfTable, type InitContext, type InitialStateCallbacks, type InputCollector, type InputCollectorKind, type InputFieldRef, type InputKeysWithCollectorKindOfDefinition, type InteractionAvailabilityArgs, type InteractionIdOfDefinition, type InteractionIdOfDefinitionPhase, type InteractionKind, type InteractionMap, type InteractionRule, type InteractionSpec, type InteractionToArgs, type InteractionValidateArgs, type ManifestIdSchema, type ManifestOf, type ManyOptions, type Op, type ParamsOf, type ParamsOfInteractionOfDefinition, type PerPlayer, type PerPlayerBoardRef, type PerPlayerSchemaOptions, type PhaseDefinitionByName, type PhaseMapOf, type PhaseNameOf, type PhaseNamesOfDefinition, type PhaseZoneList, type PieceIdOfManifest, type PlayableInteractionsOfZoneOfDefinition, type PlayerBoardSpaceTarget, type PlayerId, type PlayerIdOfManifest, type PlayerIdOfState, type PlayerIdOfTable, type PlayerZoneIdOfManifest, type PlayerZoneIdOfState, type PlayerZoneIdOfTable, type PromptInteractionKeyOfDefinition, type ReducerAccept, type ReducerBundle, type ReducerEdit, type ReducerGameContract, type ReducerGameDefinition, type ReducerManifestContract, type ReducerOps, type ReducerPhaseDefinition, type ReducerReject, type ReducerResult, type ReducerStateBase, type ReducerTransaction, type ReducerValidationResult, type ReducerViewDefinition, type RelationTypeIdOfManifest, type RelationTypeIdOfTable, type ResolvedContainerLocation, type ResolvedDeckLocation, type ResolvedEdgeLocation, type ResolvedHandLocation, type ResolvedSlotLocation, type ResolvedSpaceLocation, type ResolvedVertexLocation, type ResolvedZoneLocation, type ResumableEffectKind, type RollDieContinuationResponse, type RotatePlayerZoneArgs, type RuntimeCardData, type RuntimeCardVisibility, type RuntimeComponentLocation, type RuntimeDieData, type RuntimeHandVisibilityMode, type RuntimePayload, type RuntimePieceData, type RuntimeRecord, type RuntimeSetupSelection, type RuntimeSetupSelectionInput, type RuntimeTableRecord, type RuntimeZoneMap, type SetupBootstrapContainerRef, type SetupBootstrapDestinationRef, type SetupBootstrapPerPlayerContainerTemplateRef, type SetupBootstrapStep, type SetupOptionChoiceMetadata, type SetupOptionIdOfManifest, type SetupOptionMetadata, type SetupProfileDefinition, type SetupProfileIdOfManifest, type SetupProfileMetadata, type SetupSelectionInputOfManifest, type SetupSelectionOfManifest, type SharedBoardRef, type SharedZoneIdOfManifest, type SharedZoneIdOfState, type SharedZoneIdOfTable, type ShuffleSharedZoneContinuationResponse, type SpaceIdOfManifest, type SpaceIdOfTable, type SpaceTypeIdOfManifest, type SpaceTypeIdOfTable, type SparseCounts, type SparseMap, type SquareBoardIdOfTable, type SquareEdgeIdOfTable, type SquareEdgeTypeIdOfTable, type SquareSpaceIdOfTable, type SquareSpaceTypeIdOfTable, type SquareVertexIdOfTable, type SquareVertexTypeIdOfTable, type StageMap, type StageNamesOfDefinitionPhase, type StageSpec, type StaticBoards, type StaticViewDefinition, type StaticViewQueries, type TableQueries, type TableQueriesOfState, type TargetContext, type TargetPredicate, type TargetPredicateArgs, type TargetRule, type TargetRuleBuilder, type TiledBoardIdOfTable, type TiledEdgeIdOfTable, type TiledEdgeMap, type TiledEdgeTypeIdOfTable, type TiledSpaceIdOfTable, type TiledSpaceMap, type TiledVertexIdOfTable, type TiledVertexMap, type TiledVertexTypeIdOfTable, type VertexTypeIdOfManifest, type ViewNamesOfDefinition, type ViewOfDefinition, type ZoneIdsOfDefinition, applySetupBootstrap, asPlayerId, assertCardAllowedInContainer, assumeManifestSchema, boardInput, boardRef, boardRefKey, boardRefSchema, boardTarget, cardInput, cardTarget, choiceTarget, cloneManifestDefault, createClientParamSchemasByPhase, createDerivedResolver, createManifestGameStateSchema, createManifestRuntimeSchema, createManifestStringLiteralSchema, createReducerBundle, createReducerEdit, createReducerOps, createReducerTransaction, createStateQueries, createTableQueries, dealToPlayerBoardContainer, dealToPlayerZone, defineCardAction, defineDerived, defineEffect, defineGame, defineGameContract, defineInputs, defineInteraction, defineInteractionRule, definePhase, definePhaseStage, defineStage, defineStaticView, defineStepPhase, defineView, formInput, isPerPlayer, isPerPlayerBoardRef, isPlayerId, isSharedBoardRef, many, markManifestScopedSchema, normalizeCommandParams, parseBoardRefKey, perPlayer, perPlayerBoardRef, perPlayerEntries, perPlayerGet, perPlayerHas, perPlayerKeys, perPlayerMap, perPlayerRequire, perPlayerSchema, perPlayerSet, perPlayerSize, perPlayerValues, pipe, promptInput, resolveManifestPlayerIds, rngInput, seedSharedBoardContainer, seedSharedBoardSpace, setActivePlayers, sharedBoardRef, shuffle, sparseCounts, sparseMap };
|