dreamboard 0.1.14 → 0.1.16
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.
|
@@ -5509,7 +5509,7 @@ function renderCardPropertiesSchemaByCardSetId(cardSets) {
|
|
|
5509
5509
|
` ${quote(cardSet.id)}: ${toPascalCase(cardSet.id)}CardPropertiesSchema,`
|
|
5510
5510
|
];
|
|
5511
5511
|
});
|
|
5512
|
-
return `const cardPropertiesSchemaByCardSetId: Record<string, z.
|
|
5512
|
+
return `const cardPropertiesSchemaByCardSetId: Record<string, z.ZodType<unknown>> = {
|
|
5513
5513
|
${entries.join("\n")}
|
|
5514
5514
|
};`;
|
|
5515
5515
|
}
|
|
@@ -5715,7 +5715,7 @@ function renderCardStateSchemaById(analysis) {
|
|
|
5715
5715
|
return `z.object(
|
|
5716
5716
|
Object.fromEntries(
|
|
5717
5717
|
literals.cardIds.map((cardId) => [cardId, createCardStateSchema(cardId)]),
|
|
5718
|
-
) as Record<CardId, z.
|
|
5718
|
+
) as Record<CardId, z.ZodType<unknown>>,
|
|
5719
5719
|
)`;
|
|
5720
5720
|
}
|
|
5721
5721
|
function renderCardStateSchemaFactory(analysis) {
|
|
@@ -5793,8 +5793,17 @@ function renderGenericBoardStateSchema(board, runtimeBoardId) {
|
|
|
5793
5793
|
playerId: ${playerId ? `z.literal(${quote(playerId)})` : "ids.playerId.nullable().optional()"},
|
|
5794
5794
|
templateId: z.string().nullable().optional(),
|
|
5795
5795
|
fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
|
|
5796
|
+
// T220: per-board state.spaces is loose-keyed by string. The
|
|
5797
|
+
// canonical narrow id (\`ids.spaceId\`) is a Zod enum of EVERY
|
|
5798
|
+
// space id across every board, which makes a strict
|
|
5799
|
+
// \`z.record(enum, \u2026)\` reject any board whose spaces are a
|
|
5800
|
+
// proper subset of that enum. Loose keying matches the JSON wire
|
|
5801
|
+
// shape (\`additionalProperties\`); the inner \`id: ids.spaceId\`
|
|
5802
|
+
// narrows the value's spaceId at parse time. A future per-board
|
|
5803
|
+
// branded-id refactor (option B) can re-tighten this without a
|
|
5804
|
+
// wire change.
|
|
5796
5805
|
spaces: z.record(
|
|
5797
|
-
|
|
5806
|
+
z.string(),
|
|
5798
5807
|
z.object({
|
|
5799
5808
|
id: ids.spaceId,
|
|
5800
5809
|
name: z.string().nullable().optional(),
|
|
@@ -5840,8 +5849,9 @@ function renderHexBoardStateSchema(board, runtimeBoardId) {
|
|
|
5840
5849
|
playerId: ${playerId ? `z.literal(${quote(playerId)})` : "ids.playerId.nullable().optional()"},
|
|
5841
5850
|
templateId: z.string().nullable().optional(),
|
|
5842
5851
|
fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
|
|
5852
|
+
// T220: see generic-board comment on the loose-keying choice.
|
|
5843
5853
|
spaces: z.record(
|
|
5844
|
-
|
|
5854
|
+
z.string(),
|
|
5845
5855
|
z.object({
|
|
5846
5856
|
id: ids.spaceId,
|
|
5847
5857
|
name: z.string().nullable().optional(),
|
|
@@ -5897,8 +5907,9 @@ function renderSquareBoardStateSchema(board, runtimeBoardId) {
|
|
|
5897
5907
|
playerId: ${playerId ? `z.literal(${quote(playerId)})` : "ids.playerId.nullable().optional()"},
|
|
5898
5908
|
templateId: z.string().nullable().optional(),
|
|
5899
5909
|
fields: ${`${boardFieldsTypeName(board.board.id)}Schema`},
|
|
5910
|
+
// T220: see generic-board comment on the loose-keying choice.
|
|
5900
5911
|
spaces: z.record(
|
|
5901
|
-
|
|
5912
|
+
z.string(),
|
|
5902
5913
|
z.object({
|
|
5903
5914
|
id: ids.spaceId,
|
|
5904
5915
|
name: z.string().nullable().optional(),
|
|
@@ -7611,7 +7622,11 @@ const runtimeGenericBoardStateSchema = z.object({
|
|
|
7611
7622
|
playerId: ids.playerId.nullable().optional(),
|
|
7612
7623
|
templateId: z.string().nullable().optional(),
|
|
7613
7624
|
fields: unknownRecordSchema,
|
|
7614
|
-
|
|
7625
|
+
// T220: per-board state.spaces is loose-keyed by string. See the
|
|
7626
|
+
// codegen-template comment in renderGenericBoardStateSchema for
|
|
7627
|
+
// the rationale; the wire shape is unchanged (additionalProperties
|
|
7628
|
+
// JSON), and the inner id field narrows at parse time.
|
|
7629
|
+
spaces: z.record(z.string(), boardSpaceStateSchema),
|
|
7615
7630
|
relations: z.array(boardRelationStateSchema),
|
|
7616
7631
|
containers: z.record(ids.boardContainerId, boardContainerStateSchema),
|
|
7617
7632
|
});
|
|
@@ -7641,7 +7656,8 @@ const squareVertexStateSchema = z.object({
|
|
|
7641
7656
|
});
|
|
7642
7657
|
const runtimeHexBoardStateSchema = runtimeGenericBoardStateSchema.extend({
|
|
7643
7658
|
layout: z.literal("hex"),
|
|
7644
|
-
|
|
7659
|
+
// T220: loose-keyed by string \u2014 see comment above.
|
|
7660
|
+
spaces: z.record(z.string(), hexSpaceStateSchema),
|
|
7645
7661
|
relations: z.array(boardRelationStateSchema),
|
|
7646
7662
|
containers: z.object({}),
|
|
7647
7663
|
orientation: z.enum(["pointy-top", "flat-top"]),
|
|
@@ -7650,7 +7666,8 @@ const runtimeHexBoardStateSchema = runtimeGenericBoardStateSchema.extend({
|
|
|
7650
7666
|
});
|
|
7651
7667
|
const runtimeSquareBoardStateSchema = runtimeGenericBoardStateSchema.extend({
|
|
7652
7668
|
layout: z.literal("square"),
|
|
7653
|
-
|
|
7669
|
+
// T220: loose-keyed by string \u2014 see comment above.
|
|
7670
|
+
spaces: z.record(z.string(), squareSpaceStateSchema),
|
|
7654
7671
|
relations: z.array(boardRelationStateSchema),
|
|
7655
7672
|
containers: z.record(ids.boardContainerId, boardContainerStateSchema),
|
|
7656
7673
|
edges: z.array(hexEdgeStateSchema),
|
|
@@ -7862,11 +7879,11 @@ export const schemas = {
|
|
|
7862
7879
|
} as const;
|
|
7863
7880
|
|
|
7864
7881
|
export function createGameStateSchema<
|
|
7865
|
-
PhaseNameSchema extends z.
|
|
7866
|
-
PublicSchema extends z.
|
|
7867
|
-
PrivateSchema extends z.
|
|
7868
|
-
HiddenSchema extends z.
|
|
7869
|
-
PhasesSchema extends z.
|
|
7882
|
+
PhaseNameSchema extends z.ZodType<unknown>,
|
|
7883
|
+
PublicSchema extends z.ZodType<unknown>,
|
|
7884
|
+
PrivateSchema extends z.ZodType<unknown>,
|
|
7885
|
+
HiddenSchema extends z.ZodType<unknown>,
|
|
7886
|
+
PhasesSchema extends z.ZodType<unknown>,
|
|
7870
7887
|
>({
|
|
7871
7888
|
phaseNameSchema,
|
|
7872
7889
|
publicSchema,
|
|
@@ -8050,6 +8067,27 @@ import { literals } from "./manifest-literals";
|
|
|
8050
8067
|
import type { PlayerId as PublicPlayerId, TableState as PublicTableState } from "./manifest-types";
|
|
8051
8068
|
|
|
8052
8069
|
const unknownRecordSchema`
|
|
8070
|
+
).replaceAll(
|
|
8071
|
+
"literals.playerIds as unknown as readonly PlayerId[]",
|
|
8072
|
+
"literals.playerIds"
|
|
8073
|
+
).replaceAll(
|
|
8074
|
+
"cardId: cardIdSchema as unknown as z.ZodType<CardId>,",
|
|
8075
|
+
"cardId: assumeManifestSchema<CardId>(cardIdSchema),"
|
|
8076
|
+
).replaceAll(
|
|
8077
|
+
"deckId: deckIdSchema as unknown as z.ZodType<DeckId>,",
|
|
8078
|
+
"deckId: assumeManifestSchema<DeckId>(deckIdSchema),"
|
|
8079
|
+
).replaceAll(
|
|
8080
|
+
"handId: handIdSchema as unknown as z.ZodType<HandId>,",
|
|
8081
|
+
"handId: assumeManifestSchema<HandId>(handIdSchema),"
|
|
8082
|
+
).replace(
|
|
8083
|
+
/export const staticBoards = ([\s\S]*?) as const;\n\nconst baseInitialTable = /,
|
|
8084
|
+
"export const staticBoards = $1 as const satisfies StaticBoards<PublicTableState>;\n\nconst baseInitialTable = "
|
|
8085
|
+
).replace(
|
|
8086
|
+
/const baseInitialTable = ([\s\S]*?) as const as unknown as TableState;\nconst baseDeckCardsByZoneId:/,
|
|
8087
|
+
"const baseInitialTable = cloneManifestDefault<PublicTableState>($1);\nconst baseDeckCardsByZoneId:"
|
|
8088
|
+
).replace(
|
|
8089
|
+
"staticBoards: staticBoards as unknown as StaticBoards<TableState>,",
|
|
8090
|
+
"staticBoards,"
|
|
8053
8091
|
).replace(
|
|
8054
8092
|
`export const manifestContract: ReducerManifestContract<
|
|
8055
8093
|
RuntimeTableRecord,`,
|
|
@@ -8071,12 +8109,14 @@ const unknownRecordSchema`
|
|
|
8071
8109
|
.min(1)
|
|
8072
8110
|
.transform((value) => asPlayerId(value)),
|
|
8073
8111
|
);`,
|
|
8074
|
-
`const playerIdSchema =
|
|
8075
|
-
|
|
8076
|
-
|
|
8077
|
-
|
|
8078
|
-
|
|
8079
|
-
)
|
|
8112
|
+
`const playerIdSchema = assumeManifestSchema<PublicPlayerId>(
|
|
8113
|
+
markManifestScopedSchema(
|
|
8114
|
+
z
|
|
8115
|
+
.string()
|
|
8116
|
+
.min(1)
|
|
8117
|
+
.transform((value) => asPlayerId(value)),
|
|
8118
|
+
),
|
|
8119
|
+
);`
|
|
8080
8120
|
);
|
|
8081
8121
|
}
|
|
8082
8122
|
function renderCardSetTypeSections(analysis) {
|
|
@@ -9157,9 +9197,9 @@ import {
|
|
|
9157
9197
|
createClientParamSchemasByPhase,
|
|
9158
9198
|
} from "@dreamboard/app-sdk/reducer";
|
|
9159
9199
|
import type {
|
|
9160
|
-
|
|
9161
|
-
|
|
9162
|
-
|
|
9200
|
+
ClientParamsOfInteractionOfDefinition,
|
|
9201
|
+
DefaultedClientParamKeysOfInteractionOfDefinition,
|
|
9202
|
+
InteractionIdOfDefinition,
|
|
9163
9203
|
InteractionIdOfDefinitionPhase,
|
|
9164
9204
|
PhaseNamesOfDefinition,
|
|
9165
9205
|
StageNamesOfDefinitionPhase,
|
|
@@ -9167,35 +9207,38 @@ import type {
|
|
|
9167
9207
|
ViewOfDefinition,
|
|
9168
9208
|
} from "@dreamboard/app-sdk/reducer";
|
|
9169
9209
|
import {
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
|
|
9182
|
-
|
|
9183
|
-
|
|
9184
|
-
|
|
9185
|
-
|
|
9186
|
-
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9190
|
-
|
|
9191
|
-
} from "@dreamboard/ui-sdk";
|
|
9192
|
-
import { createElement,
|
|
9193
|
-
import {
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9210
|
+
createDreamboardUI,
|
|
9211
|
+
createResourceCounter,
|
|
9212
|
+
type BoardHexGridProps as BoardHexGridPropsGeneric,
|
|
9213
|
+
type BoardHexViewProps as BoardHexViewPropsGeneric,
|
|
9214
|
+
type BoardSpaceIdOf,
|
|
9215
|
+
type ClientParamSchemaMap,
|
|
9216
|
+
type InteractionDescriptor,
|
|
9217
|
+
type InteractionHandle,
|
|
9218
|
+
type InteractionRouteMap as InteractionRouteMapGeneric,
|
|
9219
|
+
type InteractionSwitchProps as InteractionSwitchPropsGeneric,
|
|
9220
|
+
type InteractionSwitchRenderState,
|
|
9221
|
+
type DreamboardUI,
|
|
9222
|
+
type ResourceCounterComponents,
|
|
9223
|
+
type ResourceDisplayConfig,
|
|
9224
|
+
type TypedGame,
|
|
9225
|
+
type UIContract,
|
|
9226
|
+
type UIRootProps,
|
|
9227
|
+
type ZoneCardAtProps,
|
|
9228
|
+
type ZoneCardRenderItem,
|
|
9229
|
+
type ZoneListProps,
|
|
9230
|
+
type ZonePileCardsProps,
|
|
9231
|
+
} from "@dreamboard/ui-sdk";
|
|
9232
|
+
import { createElement, type ReactElement, type ReactNode } from "react";
|
|
9233
|
+
import {
|
|
9234
|
+
literals,
|
|
9235
|
+
staticBoards,
|
|
9236
|
+
type CardId,
|
|
9237
|
+
type CardProperties,
|
|
9238
|
+
type CardType,
|
|
9239
|
+
type EdgeId,
|
|
9198
9240
|
type PlayerId,
|
|
9241
|
+
type ResourceId,
|
|
9199
9242
|
type SpaceId,
|
|
9200
9243
|
type VertexId,
|
|
9201
9244
|
type ZoneId as ManifestZoneId,
|
|
@@ -9294,8 +9337,7 @@ export type InteractionDescriptorFor<Key extends InteractionKey> =
|
|
|
9294
9337
|
|
|
9295
9338
|
/**
|
|
9296
9339
|
* Params shape for a phase-qualified interaction key. Drives strong typing
|
|
9297
|
-
* for
|
|
9298
|
-
* \`submit\`, and \`setInput\`.
|
|
9340
|
+
* for component-first interaction state, forms, and submits.
|
|
9299
9341
|
*/
|
|
9300
9342
|
export type InteractionParamsOf<Key extends InteractionKey> =
|
|
9301
9343
|
InteractionParams<PhaseOfInteractionKey<Key>, IdOfInteractionKey<Key>>;
|
|
@@ -9318,6 +9360,50 @@ type InteractionHandleDefaultedKeys<Key extends InteractionKey> = Extract<
|
|
|
9318
9360
|
keyof InteractionParamsShape<Key> & string
|
|
9319
9361
|
>;
|
|
9320
9362
|
|
|
9363
|
+
type RequiredInteractionInputKeysOf<Key extends InteractionKey> = Exclude<
|
|
9364
|
+
InteractionInputKeysOf<Key>,
|
|
9365
|
+
InteractionHandleDefaultedKeys<Key>
|
|
9366
|
+
>;
|
|
9367
|
+
|
|
9368
|
+
export type RequiredInteractionInputKey<Key extends InteractionKey> =
|
|
9369
|
+
RequiredInteractionInputKeysOf<Key>;
|
|
9370
|
+
|
|
9371
|
+
export type ZeroInputInteractionKey = {
|
|
9372
|
+
[K in InteractionKey]: InteractionInputKeysOf<K> extends never
|
|
9373
|
+
? K
|
|
9374
|
+
: never;
|
|
9375
|
+
}[InteractionKey];
|
|
9376
|
+
|
|
9377
|
+
export type InputInteractionKey = Exclude<
|
|
9378
|
+
InteractionKey,
|
|
9379
|
+
ZeroInputInteractionKey
|
|
9380
|
+
>;
|
|
9381
|
+
|
|
9382
|
+
export type InteractionRouteRenderState<Key extends InteractionKey> =
|
|
9383
|
+
Omit<InteractionSwitchRenderState<Key>, "descriptor"> & {
|
|
9384
|
+
descriptor: InteractionDescriptorFor<Key>;
|
|
9385
|
+
};
|
|
9386
|
+
|
|
9387
|
+
export type InteractionRouteMap = {
|
|
9388
|
+
[K in InteractionKey]: (state: InteractionRouteRenderState<K>) => ReactNode;
|
|
9389
|
+
};
|
|
9390
|
+
|
|
9391
|
+
type ExactInteractionRoutes<Routes extends InteractionRouteMap> = Routes &
|
|
9392
|
+
Record<Exclude<keyof Routes, keyof InteractionRouteMap>, never>;
|
|
9393
|
+
|
|
9394
|
+
export function defineInteractionRoutes<const Routes extends InteractionRouteMap>(
|
|
9395
|
+
routes: ExactInteractionRoutes<Routes>,
|
|
9396
|
+
): InteractionRouteMap {
|
|
9397
|
+
return routes;
|
|
9398
|
+
}
|
|
9399
|
+
|
|
9400
|
+
type InteractionSwitchProps = Omit<
|
|
9401
|
+
InteractionSwitchPropsGeneric<InteractionKey>,
|
|
9402
|
+
"routes"
|
|
9403
|
+
> & {
|
|
9404
|
+
routes: InteractionRouteMap;
|
|
9405
|
+
};
|
|
9406
|
+
|
|
9321
9407
|
type InteractionInputKeyOf<Key extends InteractionKey> =
|
|
9322
9408
|
Key extends InteractionKey ? InteractionInputKeysOf<Key> : never;
|
|
9323
9409
|
|
|
@@ -9349,6 +9435,10 @@ type UIPromptOptionRegistry = {
|
|
|
9349
9435
|
[K in PromptOptionValue]: { value: K };
|
|
9350
9436
|
};
|
|
9351
9437
|
|
|
9438
|
+
type UIPlayerRegistry = {
|
|
9439
|
+
[K in PlayerId & string]: { player: K };
|
|
9440
|
+
};
|
|
9441
|
+
|
|
9352
9442
|
type UIZoneRegistry = {
|
|
9353
9443
|
[K in ZoneId & string]: { zone: K };
|
|
9354
9444
|
};
|
|
@@ -9370,6 +9460,7 @@ export const uiContract = {
|
|
|
9370
9460
|
inputs: {} as UIInputRegistry,
|
|
9371
9461
|
prompts: {} as UIPromptRegistry,
|
|
9372
9462
|
promptOptions: {} as UIPromptOptionRegistry,
|
|
9463
|
+
players: {} as UIPlayerRegistry,
|
|
9373
9464
|
zones: {} as UIZoneRegistry,
|
|
9374
9465
|
cards: {} as UICardRegistry,
|
|
9375
9466
|
phases: {} as UIPhaseRegistry,
|
|
@@ -9383,142 +9474,6 @@ declare module "@dreamboard/ui-sdk" {
|
|
|
9383
9474
|
}
|
|
9384
9475
|
}
|
|
9385
9476
|
|
|
9386
|
-
type WorkspaceUI = DreamboardUI<typeof uiContract>;
|
|
9387
|
-
|
|
9388
|
-
export const UI: WorkspaceUI = createDreamboardUI(uiContract);
|
|
9389
|
-
export const Interaction = UI.Interaction;
|
|
9390
|
-
export const Prompt = UI.Prompt;
|
|
9391
|
-
export const PromptInbox = UI.PromptInbox;
|
|
9392
|
-
export const PromptDialogHost = UI.PromptDialogHost;
|
|
9393
|
-
export const PlayerRoster: WorkspaceUI["PlayerRoster"] = UI.PlayerRoster;
|
|
9394
|
-
export const Phase = UI.Phase;
|
|
9395
|
-
export const Zone = UI.Zone;
|
|
9396
|
-
export const Board = UI.Board;
|
|
9397
|
-
|
|
9398
|
-
export type InteractionFieldRenderers<Key extends InteractionKey> =
|
|
9399
|
-
InteractionFieldRenderMap<InteractionParamsShape<Key>>;
|
|
9400
|
-
|
|
9401
|
-
export type InteractionFormProps<Key extends InteractionKey> = Omit<
|
|
9402
|
-
InteractionFormPropsGeneric<
|
|
9403
|
-
InteractionParamsShape<Key>,
|
|
9404
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9405
|
-
>,
|
|
9406
|
-
"descriptor" | "handle"
|
|
9407
|
-
> & {
|
|
9408
|
-
descriptor: InteractionDescriptorFor<Key>;
|
|
9409
|
-
handle: InteractionHandle<
|
|
9410
|
-
InteractionParamsShape<Key>,
|
|
9411
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9412
|
-
>;
|
|
9413
|
-
renderFields?: InteractionFieldRenderers<Key>;
|
|
9414
|
-
};
|
|
9415
|
-
|
|
9416
|
-
export type InteractionFieldProps<
|
|
9417
|
-
Key extends InteractionKey,
|
|
9418
|
-
InputKey extends keyof InteractionParamsShape<Key> & string,
|
|
9419
|
-
> = Omit<
|
|
9420
|
-
InteractionFieldPropsGeneric<InteractionParamsShape<Key>, InputKey>,
|
|
9421
|
-
"descriptor" | "handle"
|
|
9422
|
-
> & {
|
|
9423
|
-
descriptor: InteractionDescriptorFor<Key>;
|
|
9424
|
-
handle: InteractionHandle<
|
|
9425
|
-
InteractionParamsShape<Key>,
|
|
9426
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9427
|
-
>;
|
|
9428
|
-
};
|
|
9429
|
-
|
|
9430
|
-
export const clientParamSchemasByPhase = createClientParamSchemasByPhase(
|
|
9431
|
-
game,
|
|
9432
|
-
) as ClientParamSchemaMap;
|
|
9433
|
-
|
|
9434
|
-
/**
|
|
9435
|
-
* Workspace-typed wrapper over \`@dreamboard/ui-sdk\`'s generic
|
|
9436
|
-
* \`useInteractionByKey\`. The \`key\` argument is constrained to the
|
|
9437
|
-
* generated {@link InteractionKey} union (typos are compile errors), and
|
|
9438
|
-
* the returned {@link InteractionHandle} is parameterised on
|
|
9439
|
-
* {@link InteractionParamsOf} so \`handle.draft\`, \`handle.submit\`, and
|
|
9440
|
-
* \`handle.setInput\` are statically typed against the interaction's
|
|
9441
|
-
* declared inputs.
|
|
9442
|
-
*
|
|
9443
|
-
* \`\`\`ts
|
|
9444
|
-
* const handle = useInteractionByKey("play.placeThingCard");
|
|
9445
|
-
* if (!handle) return null;
|
|
9446
|
-
* handle.setInput("cardId", card.id); // inferred as ThingsDeckCardId
|
|
9447
|
-
* await handle.submit(); // params typed from the reducer contract
|
|
9448
|
-
* \`\`\`
|
|
9449
|
-
*/
|
|
9450
|
-
export function useInteractionByKey<Key extends InteractionKey>(
|
|
9451
|
-
key: Key | null | undefined,
|
|
9452
|
-
): InteractionHandle<
|
|
9453
|
-
InteractionParamsShape<Key>,
|
|
9454
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9455
|
-
> | null {
|
|
9456
|
-
return useInteractionByKeyGeneric<
|
|
9457
|
-
Key,
|
|
9458
|
-
InteractionParamsShape<Key>,
|
|
9459
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9460
|
-
>(key);
|
|
9461
|
-
}
|
|
9462
|
-
|
|
9463
|
-
export function InteractionForm<Key extends InteractionKey>(
|
|
9464
|
-
props: InteractionFormProps<Key>,
|
|
9465
|
-
): ReactElement {
|
|
9466
|
-
return createElement(
|
|
9467
|
-
InteractionFormGeneric<
|
|
9468
|
-
InteractionParamsShape<Key>,
|
|
9469
|
-
InteractionHandleDefaultedKeys<Key>
|
|
9470
|
-
>,
|
|
9471
|
-
props,
|
|
9472
|
-
);
|
|
9473
|
-
}
|
|
9474
|
-
|
|
9475
|
-
export function InteractionField<
|
|
9476
|
-
Key extends InteractionKey,
|
|
9477
|
-
InputKey extends keyof InteractionParamsShape<Key> & string,
|
|
9478
|
-
>(props: InteractionFieldProps<Key, InputKey>): ReactElement | null {
|
|
9479
|
-
return createElement(
|
|
9480
|
-
InteractionFieldGeneric<InteractionParamsShape<Key>, InputKey>,
|
|
9481
|
-
props,
|
|
9482
|
-
);
|
|
9483
|
-
}
|
|
9484
|
-
|
|
9485
|
-
/**
|
|
9486
|
-
* Workspace-typed wrapper over \`@dreamboard/ui-sdk\`'s
|
|
9487
|
-
* \`useBoardInteractions\`. Returns a {@link BoardInteractionsContext}
|
|
9488
|
-
* narrowed to this workspace's board-interaction union for exhaustive
|
|
9489
|
-
* downstream logic.
|
|
9490
|
-
*
|
|
9491
|
-
* \`\`\`tsx
|
|
9492
|
-
* const board = useBoardInteractions();
|
|
9493
|
-
* <HexGrid interactiveVertices={board.targetLayers.vertex()} />
|
|
9494
|
-
* \`\`\`
|
|
9495
|
-
*
|
|
9496
|
-
* Reach for this whenever a screen keeps more than one board target
|
|
9497
|
-
* interaction live simultaneously and dispatch is target-driven instead of
|
|
9498
|
-
* armed-then-clicked. Ambiguous unarmed overlaps should be resolved in the UI
|
|
9499
|
-
* by arming an explicit interaction/input route.
|
|
9500
|
-
*/
|
|
9501
|
-
export function useBoardInteractions(
|
|
9502
|
-
options?: BoardInteractionsOptions,
|
|
9503
|
-
): BoardInteractionsContext<BoardInteractions> {
|
|
9504
|
-
return useBoardInteractionsGeneric<BoardInteractions>(options);
|
|
9505
|
-
}
|
|
9506
|
-
|
|
9507
|
-
/** Workspace-typed active-player hook. */
|
|
9508
|
-
export function useActivePlayers(): readonly PlayerId[] {
|
|
9509
|
-
return useActivePlayersGeneric() as readonly PlayerId[];
|
|
9510
|
-
}
|
|
9511
|
-
|
|
9512
|
-
/** Workspace-typed reducer-native player view hook. */
|
|
9513
|
-
export function useGameView(): GameView {
|
|
9514
|
-
return useGameViewGeneric() as GameView;
|
|
9515
|
-
}
|
|
9516
|
-
|
|
9517
|
-
/** Workspace-typed player turn order hook. */
|
|
9518
|
-
export function usePlayerTurnOrder(): readonly PlayerId[] {
|
|
9519
|
-
return usePlayerTurnOrderGeneric() as readonly PlayerId[];
|
|
9520
|
-
}
|
|
9521
|
-
|
|
9522
9477
|
// -------------------------------------------------------------------------
|
|
9523
9478
|
// Typed hex-board view adapter
|
|
9524
9479
|
// -------------------------------------------------------------------------
|
|
@@ -9537,49 +9492,176 @@ export type HexBoardSpaceId<Id extends HexBoardId> = BoardSpaceIdOf<
|
|
|
9537
9492
|
HexBoardTopology<Id>
|
|
9538
9493
|
>;
|
|
9539
9494
|
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
|
|
9564
|
-
|
|
9565
|
-
>
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9495
|
+
export type HexBoardViewProps<
|
|
9496
|
+
Id extends HexBoardId,
|
|
9497
|
+
TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9498
|
+
> = Omit<BoardHexViewPropsGeneric<HexBoardTopology<Id>, TSpaceView>, "board"> & {
|
|
9499
|
+
board: Id;
|
|
9500
|
+
};
|
|
9501
|
+
|
|
9502
|
+
export type HexBoardGridProps<
|
|
9503
|
+
Id extends HexBoardId,
|
|
9504
|
+
TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9505
|
+
> = Omit<
|
|
9506
|
+
BoardHexGridPropsGeneric<HexBoardTopology<Id>, TSpaceView>,
|
|
9507
|
+
"board" | "interactions"
|
|
9508
|
+
> & {
|
|
9509
|
+
board: Id;
|
|
9510
|
+
interactions?:
|
|
9511
|
+
| "auto"
|
|
9512
|
+
| false
|
|
9513
|
+
| {
|
|
9514
|
+
edge?: readonly InteractionKey[];
|
|
9515
|
+
vertex?: readonly InteractionKey[];
|
|
9516
|
+
space?: readonly InteractionKey[];
|
|
9517
|
+
};
|
|
9518
|
+
};
|
|
9519
|
+
|
|
9520
|
+
type WorkspaceBoard = Omit<DreamboardUI<typeof uiContract>["Board"], "HexView" | "HexGrid"> & {
|
|
9521
|
+
HexView<
|
|
9522
|
+
const Id extends HexBoardId,
|
|
9523
|
+
const TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9524
|
+
>(props: HexBoardViewProps<Id, TSpaceView>): ReactElement;
|
|
9525
|
+
HexGrid<
|
|
9526
|
+
const Id extends HexBoardId,
|
|
9527
|
+
const TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9528
|
+
>(props: HexBoardGridProps<Id, TSpaceView>): ReactElement;
|
|
9529
|
+
};
|
|
9530
|
+
|
|
9531
|
+
type WorkspaceCardProperties = CardProperties extends Record<string, unknown>
|
|
9532
|
+
? CardProperties
|
|
9533
|
+
: Record<string, unknown>;
|
|
9534
|
+
type WorkspaceZoneId = [ZoneId] extends [never] ? string : ZoneId;
|
|
9535
|
+
type WorkspaceCardId = [CardId] extends [never] ? string : CardId;
|
|
9536
|
+
type WorkspaceCardType = [CardType] extends [never] ? string : CardType;
|
|
9537
|
+
|
|
9538
|
+
// ZoneCardRenderItem is a discriminated union (hidden: true | false).
|
|
9539
|
+
// A bare Omit<..., "zone"> would collapse the union to its common keys and
|
|
9540
|
+
// strip cardType / properties from the hydrated branch, defeating the
|
|
9541
|
+
// discriminated-union narrowing the SDK contract promises. Distribute Omit
|
|
9542
|
+
// across the union so each branch keeps its own shape.
|
|
9543
|
+
type WorkspaceZoneCard = ZoneCardRenderItem<
|
|
9544
|
+
WorkspaceCardId & string,
|
|
9545
|
+
WorkspaceCardType & string,
|
|
9546
|
+
WorkspaceCardProperties
|
|
9547
|
+
> extends infer Item
|
|
9548
|
+
? Item extends { zone: string }
|
|
9549
|
+
? Omit<Item, "zone"> & { zone: WorkspaceZoneId }
|
|
9550
|
+
: never
|
|
9551
|
+
: never;
|
|
9552
|
+
|
|
9553
|
+
type WorkspaceZone = Omit<
|
|
9554
|
+
DreamboardUI<typeof uiContract>["Zone"],
|
|
9555
|
+
"CardAt" | "TopCard" | "List" | "PileCards"
|
|
9556
|
+
> & {
|
|
9557
|
+
CardAt(
|
|
9558
|
+
props: Omit<ZoneCardAtProps<WorkspaceZoneId>, "zone" | "children"> & {
|
|
9559
|
+
zone?: WorkspaceZoneId;
|
|
9560
|
+
children?: ReactNode | ((card: WorkspaceZoneCard) => ReactNode);
|
|
9561
|
+
},
|
|
9562
|
+
): ReactElement | null;
|
|
9563
|
+
TopCard(
|
|
9564
|
+
props: Omit<
|
|
9565
|
+
ZoneCardAtProps<WorkspaceZoneId>,
|
|
9566
|
+
"zone" | "index" | "children"
|
|
9567
|
+
> & {
|
|
9568
|
+
zone?: WorkspaceZoneId;
|
|
9569
|
+
children?: ReactNode | ((card: WorkspaceZoneCard) => ReactNode);
|
|
9570
|
+
},
|
|
9571
|
+
): ReactElement | null;
|
|
9572
|
+
List(
|
|
9573
|
+
props: Omit<ZoneListProps, "children"> & {
|
|
9574
|
+
children?: ReactNode | ((card: WorkspaceZoneCard) => ReactNode);
|
|
9575
|
+
},
|
|
9576
|
+
): ReactElement;
|
|
9577
|
+
PileCards(
|
|
9578
|
+
props: Omit<ZonePileCardsProps, "renderCard"> & {
|
|
9579
|
+
renderCard: (card: WorkspaceZoneCard) => ReactNode;
|
|
9580
|
+
},
|
|
9581
|
+
): ReactElement | null;
|
|
9582
|
+
};
|
|
9583
|
+
|
|
9584
|
+
type WorkspaceUI = Omit<
|
|
9585
|
+
DreamboardUI<typeof uiContract>,
|
|
9586
|
+
"Root" | "Game" | "Interaction" | "Board" | "Zone"
|
|
9587
|
+
> & {
|
|
9588
|
+
Root(props: UIRootProps): ReactElement;
|
|
9589
|
+
readonly Game: TypedGame<typeof uiContract, GameView, PlayerId, PhaseName>;
|
|
9590
|
+
readonly Interaction: Omit<
|
|
9591
|
+
DreamboardUI<typeof uiContract>["Interaction"],
|
|
9592
|
+
"Switch"
|
|
9593
|
+
> & {
|
|
9594
|
+
Switch(props: InteractionSwitchProps): ReactElement;
|
|
9595
|
+
};
|
|
9596
|
+
readonly Board: WorkspaceBoard;
|
|
9597
|
+
readonly Zone: WorkspaceZone;
|
|
9598
|
+
readonly ResourceCounter: ResourceCounterComponents<ResourceId>;
|
|
9599
|
+
};
|
|
9600
|
+
|
|
9601
|
+
const baseUI = createDreamboardUI(uiContract);
|
|
9602
|
+
|
|
9603
|
+
const resourcePresentationById = literals.resourcePresentationById as Partial<
|
|
9604
|
+
Record<string, { label?: string; icon?: string }>
|
|
9605
|
+
>;
|
|
9606
|
+
|
|
9607
|
+
const resourceDisplayConfig = literals.resourceIds.map((resource) => {
|
|
9608
|
+
const resourceId = resource as ResourceId;
|
|
9609
|
+
const presentation = resourcePresentationById[resource as string];
|
|
9610
|
+
return {
|
|
9611
|
+
type: resourceId,
|
|
9612
|
+
label: presentation?.label ?? resource,
|
|
9613
|
+
icon: presentation?.icon ?? resource,
|
|
9614
|
+
};
|
|
9615
|
+
}) satisfies readonly ResourceDisplayConfig<ResourceId>[];
|
|
9616
|
+
|
|
9617
|
+
const resourceCounter = createResourceCounter<ResourceId>(resourceDisplayConfig);
|
|
9618
|
+
|
|
9619
|
+
export const Board: WorkspaceUI["Board"] = {
|
|
9620
|
+
...baseUI.Board,
|
|
9621
|
+
HexView<
|
|
9622
|
+
const Id extends HexBoardId,
|
|
9623
|
+
const TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9624
|
+
>({ board: boardId, ...props }: HexBoardViewProps<Id, TSpaceView>) {
|
|
9625
|
+
return createElement(baseUI.Board.HexView<HexBoardTopology<Id>, TSpaceView>, {
|
|
9626
|
+
...props,
|
|
9627
|
+
board: hexStaticBoards[boardId],
|
|
9628
|
+
});
|
|
9629
|
+
},
|
|
9630
|
+
HexGrid<
|
|
9631
|
+
const Id extends HexBoardId,
|
|
9632
|
+
const TSpaceView extends { id: HexBoardSpaceId<Id> },
|
|
9633
|
+
>({ board: boardId, ...props }: HexBoardGridProps<Id, TSpaceView>) {
|
|
9634
|
+
return createElement(baseUI.Board.HexGrid<HexBoardTopology<Id>, TSpaceView>, {
|
|
9635
|
+
...props,
|
|
9636
|
+
board: hexStaticBoards[boardId],
|
|
9637
|
+
});
|
|
9638
|
+
},
|
|
9639
|
+
} as WorkspaceUI["Board"];
|
|
9640
|
+
|
|
9641
|
+
export const UI: WorkspaceUI = {
|
|
9642
|
+
...baseUI,
|
|
9643
|
+
Board,
|
|
9644
|
+
ResourceCounter: resourceCounter,
|
|
9645
|
+
};
|
|
9646
|
+
export const Game: WorkspaceUI["Game"] = UI.Game;
|
|
9647
|
+
export const Interaction = UI.Interaction;
|
|
9648
|
+
export const Prompt = UI.Prompt;
|
|
9649
|
+
export const PromptInbox = UI.PromptInbox;
|
|
9650
|
+
export const PlayerRoster: WorkspaceUI["PlayerRoster"] = UI.PlayerRoster;
|
|
9651
|
+
export const Dice: WorkspaceUI["Dice"] = UI.Dice;
|
|
9652
|
+
export const Phase = UI.Phase;
|
|
9653
|
+
export const Zone = UI.Zone;
|
|
9654
|
+
export const ResourceCounter: WorkspaceUI["ResourceCounter"] = UI.ResourceCounter;
|
|
9655
|
+
|
|
9656
|
+
export const clientParamSchemasByPhase = createClientParamSchemasByPhase(
|
|
9657
|
+
game,
|
|
9658
|
+
) as ClientParamSchemaMap;
|
|
9576
9659
|
`;
|
|
9577
9660
|
}
|
|
9578
9661
|
function generateReducerSupportSeed() {
|
|
9579
9662
|
return `import {
|
|
9580
|
-
|
|
9663
|
+
createReducerEdit,
|
|
9581
9664
|
createStateQueries,
|
|
9582
|
-
pipe,
|
|
9583
9665
|
} from "@dreamboard/app-sdk/reducer";
|
|
9584
9666
|
import type { GameState } from "./game-contract";
|
|
9585
9667
|
|
|
@@ -9598,16 +9680,12 @@ import type { GameState } from "./game-contract";
|
|
|
9598
9680
|
*
|
|
9599
9681
|
* Recommended authoring pattern inside a phase reducer:
|
|
9600
9682
|
*
|
|
9601
|
-
* const
|
|
9602
|
-
*
|
|
9603
|
-
*
|
|
9604
|
-
* );
|
|
9605
|
-
* return accept(next);
|
|
9683
|
+
* const tx = edit(state);
|
|
9684
|
+
* tx.setActivePlayers([q.players.order()[0]]);
|
|
9685
|
+
* return accept(tx.state);
|
|
9606
9686
|
*/
|
|
9607
9687
|
|
|
9608
|
-
export const
|
|
9609
|
-
|
|
9610
|
-
export { pipe };
|
|
9688
|
+
export const edit = createReducerEdit<GameState>();
|
|
9611
9689
|
|
|
9612
9690
|
export function stateQueries(state: GameState) {
|
|
9613
9691
|
return createStateQueries(state);
|
|
@@ -9688,7 +9766,7 @@ function generateReducerGameContractSeed() {
|
|
|
9688
9766
|
import { ids, manifestContract } from "../shared/manifest-contract";
|
|
9689
9767
|
import { defineGameContract, type GameStateOf } from "@dreamboard/app-sdk/reducer";
|
|
9690
9768
|
|
|
9691
|
-
// Contract files should stay focused on schemas,
|
|
9769
|
+
// Contract files should stay focused on schemas, phases, and exported
|
|
9692
9770
|
// state types. Put reducers in app/phases/* and pure computations in
|
|
9693
9771
|
// app/derived.ts or app/rules/*.
|
|
9694
9772
|
const publicStateSchema = z.object({
|
|
@@ -9700,15 +9778,14 @@ const hiddenStateSchema = z.object({});
|
|
|
9700
9778
|
|
|
9701
9779
|
export const gameContract = defineGameContract({
|
|
9702
9780
|
manifest: manifestContract,
|
|
9703
|
-
// Keep this list in sync with the keys of the \`phases\` record in ./phases.
|
|
9704
|
-
// Declaring phase names here narrows \`fx.transition(...)\`, \`phase.dispatch\`,
|
|
9705
|
-
// and the flow state's \`currentPhase\` to a literal union.
|
|
9706
|
-
phaseNames: ["setup"] as const,
|
|
9707
9781
|
state: {
|
|
9708
9782
|
public: publicStateSchema,
|
|
9709
9783
|
private: privateStateSchema,
|
|
9710
9784
|
hidden: hiddenStateSchema,
|
|
9711
9785
|
},
|
|
9786
|
+
phases: {
|
|
9787
|
+
setup: z.object({}),
|
|
9788
|
+
},
|
|
9712
9789
|
});
|
|
9713
9790
|
|
|
9714
9791
|
export type GameContract = typeof gameContract;
|
|
@@ -9809,8 +9886,10 @@ function generateAppFrameworkTsConfig() {
|
|
|
9809
9886
|
moduleResolution: "bundler",
|
|
9810
9887
|
strict: true,
|
|
9811
9888
|
esModuleInterop: true,
|
|
9812
|
-
skipLibCheck:
|
|
9889
|
+
skipLibCheck: false,
|
|
9890
|
+
types: [],
|
|
9813
9891
|
declaration: false,
|
|
9892
|
+
rootDir: "..",
|
|
9814
9893
|
outDir: "./dist",
|
|
9815
9894
|
paths: {
|
|
9816
9895
|
"@dreamboard/manifest-contract": ["../shared/manifest-contract.ts"],
|
|
@@ -9832,48 +9911,57 @@ function generateAppFrameworkTsConfig() {
|
|
|
9832
9911
|
`;
|
|
9833
9912
|
}
|
|
9834
9913
|
function generateUiFrameworkTsConfig() {
|
|
9835
|
-
return
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
|
|
9843
|
-
|
|
9844
|
-
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
]
|
|
9854
|
-
}
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
"./**/*.tsx",
|
|
9859
|
-
"../shared/**/*.ts"
|
|
9860
|
-
],
|
|
9861
|
-
"exclude": [
|
|
9862
|
-
"node_modules",
|
|
9863
|
-
"dist"
|
|
9864
|
-
]
|
|
9865
|
-
}
|
|
9914
|
+
return `${JSON.stringify(
|
|
9915
|
+
{
|
|
9916
|
+
compilerOptions: {
|
|
9917
|
+
target: "ES2020",
|
|
9918
|
+
module: "ESNext",
|
|
9919
|
+
moduleResolution: "bundler",
|
|
9920
|
+
jsx: "react-jsx",
|
|
9921
|
+
strict: true,
|
|
9922
|
+
esModuleInterop: true,
|
|
9923
|
+
skipLibCheck: false,
|
|
9924
|
+
types: [],
|
|
9925
|
+
paths: {
|
|
9926
|
+
"@dreamboard/manifest-contract": ["../shared/manifest-contract.ts"],
|
|
9927
|
+
"@dreamboard/ui-contract": ["../shared/generated/ui-contract.ts"],
|
|
9928
|
+
"@shared/*": ["../shared/*"]
|
|
9929
|
+
}
|
|
9930
|
+
},
|
|
9931
|
+
include: ["./**/*.ts", "./**/*.tsx", "../shared/**/*.ts"],
|
|
9932
|
+
exclude: ["node_modules", "dist"]
|
|
9933
|
+
},
|
|
9934
|
+
null,
|
|
9935
|
+
2
|
|
9936
|
+
)}
|
|
9866
9937
|
`;
|
|
9867
9938
|
}
|
|
9868
9939
|
function generateReducerUiAppContent() {
|
|
9869
|
-
return `import { Phase, PromptInbox } from "@dreamboard/ui-contract";
|
|
9940
|
+
return `import { Game, Phase, Prompt, PromptInbox } from "@dreamboard/ui-contract";
|
|
9870
9941
|
|
|
9871
9942
|
function SetupPhase() {
|
|
9872
9943
|
return (
|
|
9873
9944
|
<main>
|
|
9874
9945
|
<PromptInbox.Root>
|
|
9875
9946
|
<PromptInbox.Empty>No available prompts.</PromptInbox.Empty>
|
|
9876
|
-
<PromptInbox.Items
|
|
9947
|
+
<PromptInbox.Items>
|
|
9948
|
+
{(prompt) => (
|
|
9949
|
+
<Prompt.Root
|
|
9950
|
+
key={prompt.interactionKey}
|
|
9951
|
+
interaction={prompt.interactionKey}
|
|
9952
|
+
>
|
|
9953
|
+
<Prompt.Title />
|
|
9954
|
+
<Prompt.Message />
|
|
9955
|
+
<Prompt.Options>
|
|
9956
|
+
{(option) => (
|
|
9957
|
+
<Prompt.Option value={option.id}>
|
|
9958
|
+
{option.label ?? option.id}
|
|
9959
|
+
</Prompt.Option>
|
|
9960
|
+
)}
|
|
9961
|
+
</Prompt.Options>
|
|
9962
|
+
</Prompt.Root>
|
|
9963
|
+
)}
|
|
9964
|
+
</PromptInbox.Items>
|
|
9877
9965
|
</PromptInbox.Root>
|
|
9878
9966
|
</main>
|
|
9879
9967
|
);
|
|
@@ -9881,11 +9969,15 @@ function SetupPhase() {
|
|
|
9881
9969
|
|
|
9882
9970
|
export default function App() {
|
|
9883
9971
|
return (
|
|
9884
|
-
<
|
|
9885
|
-
|
|
9886
|
-
|
|
9887
|
-
|
|
9888
|
-
|
|
9972
|
+
<Game.Root>
|
|
9973
|
+
{() => (
|
|
9974
|
+
<Phase.Switch
|
|
9975
|
+
routes={{
|
|
9976
|
+
setup: () => <SetupPhase />,
|
|
9977
|
+
}}
|
|
9978
|
+
/>
|
|
9979
|
+
)}
|
|
9980
|
+
</Game.Root>
|
|
9889
9981
|
);
|
|
9890
9982
|
}
|
|
9891
9983
|
`;
|
|
@@ -21316,6 +21408,11 @@ var ShadowReducerRuntime = class {
|
|
|
21316
21408
|
this.version = version;
|
|
21317
21409
|
this.started = true;
|
|
21318
21410
|
}
|
|
21411
|
+
patchState(mutator) {
|
|
21412
|
+
const next = structuredClone(this.rawState());
|
|
21413
|
+
mutator(next);
|
|
21414
|
+
this.hydrate(next, this.version + 1);
|
|
21415
|
+
}
|
|
21319
21416
|
projectAllSeats() {
|
|
21320
21417
|
const projection = this.runtime.projectSeatsDynamic({
|
|
21321
21418
|
playerIds: this.playerIds
|
|
@@ -21616,6 +21713,15 @@ async function createScenarioContext(options) {
|
|
|
21616
21713
|
await assertLiveMatchesShadow("browser", options.shadow, live);
|
|
21617
21714
|
}
|
|
21618
21715
|
},
|
|
21716
|
+
patchState: async (mutator) => {
|
|
21717
|
+
await api.start();
|
|
21718
|
+
if (options.live || options.embedded || options.browser || options.actionPlan) {
|
|
21719
|
+
throw new Error(
|
|
21720
|
+
"game.patchState is only supported for reducer snapshot scenarios. Use it to materialize a state before --from-scenario or reducer tests, not inside live replay/browser runners."
|
|
21721
|
+
);
|
|
21722
|
+
}
|
|
21723
|
+
options.shadow.patchState(mutator);
|
|
21724
|
+
},
|
|
21619
21725
|
submit: async (playerId, interactionId, params) => {
|
|
21620
21726
|
await api.start();
|
|
21621
21727
|
const interactionParams = params ?? {};
|
|
@@ -26119,4 +26225,4 @@ export {
|
|
|
26119
26225
|
test_default,
|
|
26120
26226
|
runDreamboardCli
|
|
26121
26227
|
};
|
|
26122
|
-
//# sourceMappingURL=chunk-
|
|
26228
|
+
//# sourceMappingURL=chunk-WDTE6OFH.js.map
|