@dreamboard-games/ui-sdk 0.0.43 → 0.0.46
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/dist/components/ActionButton.d.ts.map +1 -1
- package/dist/components/ActionButton.js +2 -1
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/Card.d.ts.map +1 -1
- package/dist/components/DiceRoller.d.ts +3 -2
- package/dist/components/DiceRoller.d.ts.map +1 -1
- package/dist/components/DiceRoller.js +4 -13
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/ErrorBoundary.js +94 -2
- package/dist/components/InteractionForm.d.ts +1 -1
- package/dist/components/InteractionForm.d.ts.map +1 -1
- package/dist/components/InteractionForm.js +29 -15
- package/dist/components/PrimaryActionButton.d.ts.map +1 -1
- package/dist/components/PrimaryActionButton.js +7 -6
- package/dist/components/ResourceCounter.d.ts +59 -25
- package/dist/components/ResourceCounter.d.ts.map +1 -1
- package/dist/components/ResourceCounter.js +106 -115
- package/dist/components/Toast.d.ts +13 -6
- package/dist/components/Toast.d.ts.map +1 -1
- package/dist/components/Toast.js +10 -5
- package/dist/components/board/HexGrid.js +6 -6
- package/dist/components/board/target-layer.d.ts +18 -2
- package/dist/components/board/target-layer.d.ts.map +1 -1
- package/dist/components/board/target-layer.js +20 -3
- package/dist/components/index.d.ts +3 -4
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +3 -4
- package/dist/components/surfaces/InboxSurface.d.ts.map +1 -1
- package/dist/components/surfaces/InboxSurface.js +2 -6
- package/dist/components/surfaces/PlayerCardsSurface.js +2 -2
- package/dist/components/surfaces/internal/CardZoneRoutedForm.d.ts +7 -0
- package/dist/components/surfaces/internal/CardZoneRoutedForm.d.ts.map +1 -0
- package/dist/components/surfaces/internal/CardZoneRoutedForm.js +9 -0
- package/dist/components/surfaces/internal/DefaultInteractionButton.d.ts.map +1 -1
- package/dist/components/surfaces/internal/DefaultInteractionButton.js +5 -8
- package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts +2 -2
- package/dist/components/surfaces/internal/useCardZoneInteractions.d.ts.map +1 -1
- package/dist/components/surfaces/internal/useCardZoneInteractions.js +19 -43
- package/dist/context/InteractionDraftContext.d.ts +11 -2
- package/dist/context/InteractionDraftContext.d.ts.map +1 -1
- package/dist/context/InteractionDraftContext.js +41 -4
- package/dist/defaults/components.d.ts +0 -5
- package/dist/defaults/components.d.ts.map +1 -1
- package/dist/defaults/components.js +7 -11
- package/dist/hooks/useBoardInteractions.d.ts +35 -12
- package/dist/hooks/useBoardInteractions.d.ts.map +1 -1
- package/dist/hooks/useBoardInteractions.js +186 -82
- package/dist/hooks/useInteractionHandle.d.ts +1 -1
- package/dist/hooks/useInteractionHandle.d.ts.map +1 -1
- package/dist/hooks/useInteractionHandle.js +12 -27
- package/dist/index.d.ts +11 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -14
- package/dist/primitives/board.d.ts +53 -3
- package/dist/primitives/board.d.ts.map +1 -1
- package/dist/primitives/board.js +65 -41
- package/dist/primitives/dialog-lifecycle.d.ts +17 -0
- package/dist/primitives/dialog-lifecycle.d.ts.map +1 -0
- package/dist/primitives/dialog-lifecycle.js +24 -0
- package/dist/primitives/dice.d.ts +31 -0
- package/dist/primitives/dice.d.ts.map +1 -0
- package/dist/primitives/dice.js +33 -0
- package/dist/primitives/game.d.ts +55 -0
- package/dist/primitives/game.d.ts.map +1 -0
- package/dist/primitives/game.js +101 -0
- package/dist/primitives/index.d.ts +7 -4
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +7 -4
- package/dist/primitives/interaction-form-binding.d.ts +12 -0
- package/dist/primitives/interaction-form-binding.d.ts.map +1 -0
- package/dist/primitives/interaction-form-binding.js +14 -0
- package/dist/primitives/interaction-submit.d.ts +23 -0
- package/dist/primitives/interaction-submit.d.ts.map +1 -0
- package/dist/primitives/interaction-submit.js +41 -0
- package/dist/primitives/interaction.d.ts +76 -6
- package/dist/primitives/interaction.d.ts.map +1 -1
- package/dist/primitives/interaction.js +210 -26
- package/dist/primitives/player-roster.d.ts +2 -1
- package/dist/primitives/player-roster.d.ts.map +1 -1
- package/dist/primitives/prompt.d.ts +36 -11
- package/dist/primitives/prompt.d.ts.map +1 -1
- package/dist/primitives/prompt.js +29 -17
- package/dist/primitives/ui.d.ts +9 -0
- package/dist/primitives/ui.d.ts.map +1 -0
- package/dist/primitives/ui.js +7 -0
- package/dist/primitives/zone.d.ts +111 -5
- package/dist/primitives/zone.d.ts.map +1 -1
- package/dist/primitives/zone.js +349 -9
- package/dist/reducer.d.ts +2 -14
- package/dist/reducer.d.ts.map +1 -1
- package/dist/reducer.js +1 -14
- package/dist/runtime/createPluginRuntimeAPI.js +1 -1
- package/dist/types/hex-color.d.ts +7 -0
- package/dist/types/hex-color.d.ts.map +1 -0
- package/dist/types/hex-color.js +13 -0
- package/dist/types/player-state.d.ts +28 -14
- package/dist/types/player-state.d.ts.map +1 -1
- package/dist/types/plugin-state.d.ts +9 -3
- package/dist/types/plugin-state.d.ts.map +1 -1
- package/dist/ui-contract.d.ts +119 -14
- package/dist/ui-contract.d.ts.map +1 -1
- package/dist/ui-contract.js +4 -3
- package/dist/ui-sdk.d.ts +1637 -1245
- package/dist/utils/interaction-inputs.d.ts +8 -5
- package/dist/utils/interaction-inputs.d.ts.map +1 -1
- package/dist/utils/interaction-inputs.js +82 -14
- package/dist/utils/interaction-router.d.ts +31 -0
- package/dist/utils/interaction-router.d.ts.map +1 -0
- package/dist/utils/interaction-router.js +114 -0
- package/package.json +2 -1
- package/src/components/ActionButton.tsx +2 -1
- package/src/components/Card.tsx +1 -1
- package/src/components/DiceRoller.tsx +13 -22
- package/src/components/ErrorBoundary.test.tsx +19 -0
- package/src/components/ErrorBoundary.tsx +113 -24
- package/src/components/InteractionForm.test.tsx +24 -0
- package/src/components/InteractionForm.tsx +48 -23
- package/src/components/PrimaryActionButton.tsx +19 -5
- package/src/components/ResourceCounter.test.tsx +13 -13
- package/src/components/ResourceCounter.tsx +238 -244
- package/src/components/Toast.tsx +23 -10
- package/src/components/__fixtures__/ResourceCounter.fixture.tsx +70 -169
- package/src/components/board/HexGrid.tsx +6 -6
- package/src/components/board/target-layer.ts +44 -5
- package/src/components/index.ts +17 -10
- package/src/components/surfaces/InboxSurface.tsx +7 -5
- package/src/components/surfaces/PlayerCardsSurface.tsx +6 -6
- package/src/components/surfaces/internal/CardZoneRoutedForm.tsx +35 -0
- package/src/components/surfaces/internal/DefaultInteractionButton.tsx +17 -7
- package/src/components/surfaces/internal/useCardZoneInteractions.ts +25 -67
- package/src/context/InteractionDraftContext.tsx +51 -5
- package/src/defaults/components.tsx +12 -50
- package/src/defaults/defaults.test.tsx +1 -50
- package/src/hooks/useBoardInteractions.test.tsx +240 -17
- package/src/hooks/useBoardInteractions.ts +330 -105
- package/src/hooks/useInteractionHandle.ts +23 -28
- package/src/index.test.ts +60 -40
- package/src/index.ts +30 -36
- package/src/primitives/board.test.tsx +73 -0
- package/src/primitives/board.tsx +191 -40
- package/src/primitives/dialog-lifecycle.ts +58 -0
- package/src/primitives/dice.test.tsx +47 -0
- package/src/primitives/dice.tsx +79 -0
- package/src/primitives/game.test.tsx +98 -0
- package/src/primitives/game.tsx +213 -0
- package/src/primitives/index.ts +84 -0
- package/src/primitives/interaction-form-binding.tsx +56 -0
- package/src/primitives/interaction-submit.ts +90 -0
- package/src/primitives/interaction.test.tsx +396 -0
- package/src/primitives/interaction.tsx +451 -31
- package/src/primitives/player-roster.tsx +2 -1
- package/src/primitives/prompt.test.tsx +94 -3
- package/src/primitives/prompt.tsx +87 -48
- package/src/primitives/ui.test.tsx +131 -0
- package/src/primitives/ui.tsx +13 -0
- package/src/primitives/zone.test.tsx +305 -0
- package/src/primitives/zone.tsx +660 -12
- package/src/reducer.ts +7 -20
- package/src/runtime/createPluginRuntimeAPI.ts +1 -1
- package/src/types/hex-color.ts +20 -0
- package/src/types/player-state.ts +36 -18
- package/src/types/plugin-state.ts +10 -3
- package/src/ui-contract.ts +253 -21
- package/src/utils/interaction-inputs.test.ts +400 -0
- package/src/utils/interaction-inputs.ts +113 -11
- package/src/utils/interaction-router.ts +200 -0
- package/type-stubs/manifest-contract.d.ts +42 -0
- package/type-stubs/manifest-contract.d.ts.map +1 -0
- package/type-stubs/manifest-contract.js +72 -0
- package/type-stubs/ui-contract.d.ts +5 -0
- package/type-stubs/ui-contract.d.ts.map +1 -0
- package/type-stubs/ui-contract.js +1 -0
|
@@ -17,13 +17,17 @@ import type { InteractionDescriptor } from "../types/plugin-state.js";
|
|
|
17
17
|
import {
|
|
18
18
|
applyInteractionInputDefaults,
|
|
19
19
|
hasInteractionFieldErrors,
|
|
20
|
-
inputByKey,
|
|
21
|
-
isInputValueReady,
|
|
22
20
|
interactionArmScope,
|
|
23
21
|
interactionInputKeys,
|
|
24
22
|
mergeInteractionFieldErrors,
|
|
25
23
|
validateInteractionInputDomains,
|
|
26
24
|
} from "../utils/interaction-inputs.js";
|
|
25
|
+
import {
|
|
26
|
+
applyInteractionDraftMutation,
|
|
27
|
+
claimInteractionSubmit,
|
|
28
|
+
clearInteractionRoute,
|
|
29
|
+
getInteractionDraftReadiness,
|
|
30
|
+
} from "../utils/interaction-router.js";
|
|
27
31
|
|
|
28
32
|
/**
|
|
29
33
|
* Anything that can be used as a submit params object. Subset of TS
|
|
@@ -115,7 +119,7 @@ export interface InteractionHandle<
|
|
|
115
119
|
isReady: boolean;
|
|
116
120
|
/**
|
|
117
121
|
* True when this interaction is the currently armed one on its surface.
|
|
118
|
-
* Armed interactions are the ones that
|
|
122
|
+
* Armed interactions are the ones that board primitives use
|
|
119
123
|
* to highlight eligible targets and route clicks.
|
|
120
124
|
*/
|
|
121
125
|
isArmed: boolean;
|
|
@@ -184,16 +188,11 @@ export function useInteractionHandle<
|
|
|
184
188
|
: "open";
|
|
185
189
|
|
|
186
190
|
const isReady = useMemo(() => {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return input
|
|
193
|
-
? isInputValueReady(input, value)
|
|
194
|
-
: value !== null && value !== undefined;
|
|
195
|
-
});
|
|
196
|
-
}, [descriptor, values, inputKeys]);
|
|
191
|
+
return getInteractionDraftReadiness(
|
|
192
|
+
descriptor,
|
|
193
|
+
values as Record<string, unknown>,
|
|
194
|
+
).ready;
|
|
195
|
+
}, [descriptor, values]);
|
|
197
196
|
|
|
198
197
|
const requirePlayer = useCallback(() => {
|
|
199
198
|
if (!controllingPlayerId) {
|
|
@@ -212,8 +211,13 @@ export function useInteractionHandle<
|
|
|
212
211
|
: "Interaction submission is already in progress.",
|
|
213
212
|
);
|
|
214
213
|
}
|
|
214
|
+
if (!claimInteractionSubmit(store, descriptor)) {
|
|
215
|
+
throw new ValidationError(
|
|
216
|
+
"SUBMITTING",
|
|
217
|
+
"Interaction submission is already in progress.",
|
|
218
|
+
);
|
|
219
|
+
}
|
|
215
220
|
submittingRef.current = true;
|
|
216
|
-
store.setSubmitting(interactionKey, true);
|
|
217
221
|
const finalParams = applyInteractionInputDefaults<Params>(
|
|
218
222
|
descriptor,
|
|
219
223
|
params ?? values,
|
|
@@ -224,10 +228,7 @@ export function useInteractionHandle<
|
|
|
224
228
|
interactionId,
|
|
225
229
|
finalParams as Record<string, unknown>,
|
|
226
230
|
);
|
|
227
|
-
store
|
|
228
|
-
if (store.getArmed(armScope) === interactionKey) {
|
|
229
|
-
store.arm(armScope, null);
|
|
230
|
-
}
|
|
231
|
+
clearInteractionRoute(store, descriptor);
|
|
231
232
|
} catch (error) {
|
|
232
233
|
throw validationErrorFromUnknown(error);
|
|
233
234
|
} finally {
|
|
@@ -242,7 +243,6 @@ export function useInteractionHandle<
|
|
|
242
243
|
requirePlayer,
|
|
243
244
|
interactionId,
|
|
244
245
|
interactionKey,
|
|
245
|
-
armScope,
|
|
246
246
|
store,
|
|
247
247
|
status,
|
|
248
248
|
],
|
|
@@ -269,13 +269,8 @@ export function useInteractionHandle<
|
|
|
269
269
|
const validateDraft = useCallback((): DraftValidation<Params> => {
|
|
270
270
|
const rawDraft = { ...values } as Record<string, unknown>;
|
|
271
271
|
const required = inputKeys;
|
|
272
|
-
const missing =
|
|
273
|
-
|
|
274
|
-
const value = rawDraft[key];
|
|
275
|
-
return input
|
|
276
|
-
? !isInputValueReady(input, value)
|
|
277
|
-
: value === null || value === undefined;
|
|
278
|
-
}) as Array<keyof Params & string>;
|
|
272
|
+
const missing = getInteractionDraftReadiness(descriptor, rawDraft)
|
|
273
|
+
.missingInputs as Array<keyof Params & string>;
|
|
279
274
|
const domainFieldErrors = validateInteractionInputDomains(
|
|
280
275
|
descriptor,
|
|
281
276
|
rawDraft,
|
|
@@ -392,9 +387,9 @@ export function useInteractionHandle<
|
|
|
392
387
|
|
|
393
388
|
const setInput = useCallback(
|
|
394
389
|
<K extends keyof Params & string>(key: K, value: Params[K]) => {
|
|
395
|
-
store
|
|
390
|
+
applyInteractionDraftMutation(store, descriptor, [{ key, value }]);
|
|
396
391
|
},
|
|
397
|
-
[store,
|
|
392
|
+
[store, descriptor],
|
|
398
393
|
);
|
|
399
394
|
|
|
400
395
|
const clearInput = useCallback(
|
package/src/index.test.ts
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { readdir, readFile } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { expect, test } from "bun:test";
|
|
4
|
+
import type { ComponentProps } from "react";
|
|
4
5
|
import * as components from "./components/index.js";
|
|
5
6
|
import * as defaults from "./defaults/index.js";
|
|
6
7
|
import * as sdk from "./index.js";
|
|
7
|
-
import type {
|
|
8
|
-
CardCollection,
|
|
9
|
-
ViewCard,
|
|
10
|
-
ViewSlotOccupant,
|
|
11
|
-
} from "@dreamboard/sdk-types";
|
|
8
|
+
import type { ViewSlotOccupant } from "@dreamboard/sdk-types";
|
|
12
9
|
import {
|
|
13
10
|
BoardEdgeIdOf,
|
|
14
11
|
BoardSpaceIdOf,
|
|
@@ -32,17 +29,6 @@ import {
|
|
|
32
29
|
type SquareGridProps,
|
|
33
30
|
type SquarePieceState,
|
|
34
31
|
type SquareVertexState,
|
|
35
|
-
useBoardTopology,
|
|
36
|
-
useCards,
|
|
37
|
-
useHandLayout,
|
|
38
|
-
useHexBoard,
|
|
39
|
-
useInteractionHandle,
|
|
40
|
-
useIsMobile,
|
|
41
|
-
usePanZoom,
|
|
42
|
-
usePluginRuntime,
|
|
43
|
-
usePluginState,
|
|
44
|
-
useSeatInbox,
|
|
45
|
-
useSquareBoard,
|
|
46
32
|
} from "./index.js";
|
|
47
33
|
|
|
48
34
|
async function walkFiles(rootDir: string): Promise<string[]> {
|
|
@@ -72,15 +58,33 @@ async function walkFiles(rootDir: string): Promise<string[]> {
|
|
|
72
58
|
test("top-level ui-sdk exports the headless scaffold support surface", () => {
|
|
73
59
|
expect(RuntimeProvider).toBeDefined();
|
|
74
60
|
expect(PluginStateProvider).toBeDefined();
|
|
75
|
-
expect(usePluginRuntime).toBeDefined();
|
|
76
|
-
expect(usePluginState).toBeDefined();
|
|
77
|
-
expect(useHandLayout).toBeDefined();
|
|
78
|
-
expect(usePanZoom).toBeDefined();
|
|
79
|
-
expect(useIsMobile).toBeDefined();
|
|
80
61
|
expect(calculateViewBox).toBeDefined();
|
|
81
62
|
expect(toTrackBoardData).toBeDefined();
|
|
82
|
-
|
|
83
|
-
|
|
63
|
+
for (const exportName of [
|
|
64
|
+
"useActivePlayers",
|
|
65
|
+
"useBoardInteractions",
|
|
66
|
+
"useBoardTopology",
|
|
67
|
+
"useCards",
|
|
68
|
+
"useGameView",
|
|
69
|
+
"useHandLayout",
|
|
70
|
+
"useHexBoard",
|
|
71
|
+
"useInteractionByKey",
|
|
72
|
+
"useInteractionHandle",
|
|
73
|
+
"useIsMobile",
|
|
74
|
+
"usePanZoom",
|
|
75
|
+
"usePlayerInfo",
|
|
76
|
+
"usePlayerTurnOrder",
|
|
77
|
+
"usePluginActions",
|
|
78
|
+
"usePluginRuntime",
|
|
79
|
+
"usePluginSession",
|
|
80
|
+
"usePluginState",
|
|
81
|
+
"useRuntimeContext",
|
|
82
|
+
"useSeatInbox",
|
|
83
|
+
"useSquareBoard",
|
|
84
|
+
"useToast",
|
|
85
|
+
]) {
|
|
86
|
+
expect(exportName in sdk).toBe(false);
|
|
87
|
+
}
|
|
84
88
|
});
|
|
85
89
|
|
|
86
90
|
test("top-level ui-sdk is the canonical root for visual components", () => {
|
|
@@ -91,7 +95,7 @@ test("top-level ui-sdk is the canonical root for visual components", () => {
|
|
|
91
95
|
expect("ActionButton" in sdk).toBe(true);
|
|
92
96
|
expect("Dialog" in sdk).toBe(true);
|
|
93
97
|
expect("DialogContent" in sdk).toBe(true);
|
|
94
|
-
expect("PromptDialogHost" in sdk).toBe(
|
|
98
|
+
expect("PromptDialogHost" in sdk).toBe(false);
|
|
95
99
|
});
|
|
96
100
|
|
|
97
101
|
test("top-level ui-sdk no longer exports the legacy interaction-button theme primitives", () => {
|
|
@@ -108,6 +112,19 @@ test("top-level ui-sdk no longer exports the legacy interaction-button theme pri
|
|
|
108
112
|
}
|
|
109
113
|
});
|
|
110
114
|
|
|
115
|
+
test("top-level ui-sdk no longer exports secondary interaction shortcuts", () => {
|
|
116
|
+
for (const exportName of [
|
|
117
|
+
"InteractionButton",
|
|
118
|
+
"InteractionDialogForm",
|
|
119
|
+
"InteractionButtonProps",
|
|
120
|
+
"InteractionDialogFormProps",
|
|
121
|
+
]) {
|
|
122
|
+
expect(exportName in sdk).toBe(false);
|
|
123
|
+
}
|
|
124
|
+
expect("Button" in sdk.Interaction).toBe(false);
|
|
125
|
+
expect("DialogForm" in sdk.Interaction).toBe(false);
|
|
126
|
+
});
|
|
127
|
+
|
|
111
128
|
test("top-level ui-sdk publishes the unified Theme contract", () => {
|
|
112
129
|
expect("ThemeProvider" in sdk).toBe(true);
|
|
113
130
|
expect("useTheme" in sdk).toBe(true);
|
|
@@ -128,10 +145,27 @@ test("top-level ui-sdk publishes the UI contract registration scaffold", () => {
|
|
|
128
145
|
});
|
|
129
146
|
|
|
130
147
|
expect(ui.contract.interactions?.["setup.ready"]).toEqual({});
|
|
131
|
-
expect(ui.
|
|
148
|
+
expect(ui.Game).toBeDefined();
|
|
149
|
+
expect("PromptDialogHost" in ui).toBe(false);
|
|
150
|
+
expect("Button" in ui.Interaction).toBe(false);
|
|
151
|
+
expect("DialogForm" in ui.Interaction).toBe(false);
|
|
132
152
|
expect(ui.PlayerRoster).toBeDefined();
|
|
133
153
|
});
|
|
134
154
|
|
|
155
|
+
test("empty UI contract buckets stay string-compatible", () => {
|
|
156
|
+
const ui = sdk.createDreamboardUI({
|
|
157
|
+
inputs: {},
|
|
158
|
+
cards: {},
|
|
159
|
+
});
|
|
160
|
+
const cardInputProps: ComponentProps<typeof ui.Interaction.CardInput> = {
|
|
161
|
+
input: "cardId",
|
|
162
|
+
card: "tech-card-1",
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
expect(ui.Interaction.CardInput).toBeDefined();
|
|
166
|
+
expect(cardInputProps.input).toBe("cardId");
|
|
167
|
+
});
|
|
168
|
+
|
|
135
169
|
test("top-level ui-sdk exposes PlayerRoster as the only player roster primitive", () => {
|
|
136
170
|
expect("PlayerRoster" in sdk).toBe(true);
|
|
137
171
|
for (const exportName of [
|
|
@@ -180,7 +214,7 @@ test("components subpath does not export shell slot internals", () => {
|
|
|
180
214
|
|
|
181
215
|
test("defaults subpath exposes primitive-composed Radix-style defaults", () => {
|
|
182
216
|
expect("GameLayout" in defaults).toBe(true);
|
|
183
|
-
expect("DefaultPromptInbox" in defaults).toBe(
|
|
217
|
+
expect("DefaultPromptInbox" in defaults).toBe(false);
|
|
184
218
|
expect("DefaultInteractionList" in defaults).toBe(true);
|
|
185
219
|
expect("DefaultInteractionForm" in defaults).toBe(true);
|
|
186
220
|
expect("DefaultZone" in defaults).toBe(true);
|
|
@@ -385,18 +419,6 @@ test("tiled board hooks and types accept generated board-state records", () => {
|
|
|
385
419
|
generatedSquareBoard;
|
|
386
420
|
const _squareTopologyInput: Parameters<typeof useBoardTopology>[0] =
|
|
387
421
|
generatedSquareBoard;
|
|
388
|
-
const _useCardsArgs: [Parameters<typeof useCards>[0]] = [
|
|
389
|
-
{
|
|
390
|
-
cardIds: ["card-1"] as const,
|
|
391
|
-
cardsById: {
|
|
392
|
-
"card-1": {
|
|
393
|
-
id: "card-1",
|
|
394
|
-
cardType: "goods",
|
|
395
|
-
properties: {},
|
|
396
|
-
},
|
|
397
|
-
},
|
|
398
|
-
} satisfies CardCollection<string, ViewCard>,
|
|
399
|
-
];
|
|
400
422
|
const _readonlySquareEdge = {
|
|
401
423
|
id: "a1$$a2",
|
|
402
424
|
spaceIds: ["a1", "a2"] as const,
|
|
@@ -454,7 +476,6 @@ test("tiled board hooks and types accept generated board-state records", () => {
|
|
|
454
476
|
_hexTopologyInput,
|
|
455
477
|
_squareHookInput,
|
|
456
478
|
_squareTopologyInput,
|
|
457
|
-
_useCardsArgs,
|
|
458
479
|
_readonlySquareEdge,
|
|
459
480
|
_readonlySquareVertex,
|
|
460
481
|
_squarePiece,
|
|
@@ -469,6 +490,5 @@ test("tiled board hooks and types accept generated board-state records", () => {
|
|
|
469
490
|
_squareVertexId,
|
|
470
491
|
];
|
|
471
492
|
|
|
472
|
-
expect(_useCardsArgs[0].cardsById["card-1"]?.cardType).toBe("goods");
|
|
473
493
|
expect(_trackBoardData.pieces[0]?.spaceId).toBe("start");
|
|
474
494
|
});
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from "./reducer.js";
|
|
2
1
|
export {
|
|
3
2
|
createDreamboardUI,
|
|
4
3
|
type BoardTargetKey,
|
|
@@ -12,6 +11,7 @@ export {
|
|
|
12
11
|
type PromptKey,
|
|
13
12
|
type RegisteredUI,
|
|
14
13
|
type TypedBoard,
|
|
14
|
+
type TypedGame,
|
|
15
15
|
type TypedInteraction,
|
|
16
16
|
type TypedPhase,
|
|
17
17
|
type TypedPlayerRoster,
|
|
@@ -23,34 +23,11 @@ export {
|
|
|
23
23
|
type ZoneKey,
|
|
24
24
|
} from "./ui-contract.js";
|
|
25
25
|
export * from "./primitives/index.js";
|
|
26
|
-
export {
|
|
27
|
-
|
|
28
|
-
useBoardInteractions,
|
|
29
|
-
type BoardInteractionsContext,
|
|
30
|
-
type BoardInteractionsOptions,
|
|
31
|
-
type BoardTargetLayerFactory,
|
|
32
|
-
type BoardTargetLayerOptions,
|
|
33
|
-
} from "./hooks/useBoardInteractions.js";
|
|
34
|
-
export { useBoardTopology } from "./hooks/useBoardTopology.js";
|
|
35
|
-
export { useCards } from "./hooks/useCards.js";
|
|
36
|
-
export { useHexBoard } from "./hooks/useHexBoard.js";
|
|
37
|
-
export { useSquareBoard } from "./hooks/useSquareBoard.js";
|
|
38
|
-
export { useHandLayout } from "./hooks/useHandLayout.js";
|
|
39
|
-
export { useInteractionByKey } from "./hooks/useInteractionByKey.js";
|
|
40
|
-
export { useIsMobile } from "./hooks/useIsMobile.js";
|
|
41
|
-
export { usePanZoom, calculateViewBox } from "./hooks/usePanZoom.js";
|
|
42
|
-
export { usePluginRuntime } from "./hooks/usePluginRuntime.js";
|
|
26
|
+
export type { BoardSelectionResult } from "./hooks/useBoardInteractions.js";
|
|
27
|
+
export { calculateViewBox } from "./hooks/usePanZoom.js";
|
|
43
28
|
export { toTrackBoardData } from "./helpers/track-board.js";
|
|
44
|
-
export {
|
|
45
|
-
|
|
46
|
-
usePluginActions,
|
|
47
|
-
usePluginState,
|
|
48
|
-
} from "./context/PluginStateContext.js";
|
|
49
|
-
export {
|
|
50
|
-
RuntimeContext,
|
|
51
|
-
RuntimeProvider,
|
|
52
|
-
useRuntimeContext,
|
|
53
|
-
} from "./context/RuntimeContext.js";
|
|
29
|
+
export { PluginStateProvider } from "./context/PluginStateContext.js";
|
|
30
|
+
export { RuntimeContext, RuntimeProvider } from "./context/RuntimeContext.js";
|
|
54
31
|
export {
|
|
55
32
|
type ClientParamSchema,
|
|
56
33
|
type ClientParamSchemaMap,
|
|
@@ -102,24 +79,41 @@ export {
|
|
|
102
79
|
normalizeSquareBoardInput,
|
|
103
80
|
} from "./types/tiled-board.js";
|
|
104
81
|
export {
|
|
105
|
-
InteractionField,
|
|
106
82
|
InteractionForm,
|
|
107
83
|
defaultFormInputs,
|
|
108
84
|
hasDefaultInteractionFormFields,
|
|
109
85
|
} from "./components/InteractionForm.js";
|
|
110
|
-
export type {
|
|
111
|
-
InteractionFieldProps,
|
|
112
|
-
InteractionFieldRenderMap,
|
|
113
|
-
InteractionFieldRenderProps,
|
|
114
|
-
InteractionFormProps,
|
|
115
|
-
} from "./components/InteractionForm.js";
|
|
86
|
+
export type { InteractionFormProps } from "./components/InteractionForm.js";
|
|
116
87
|
export * from "./components/index.js";
|
|
117
88
|
export type * from "./hooks/useHandLayout.js";
|
|
118
89
|
export type * from "./hooks/usePanZoom.js";
|
|
119
90
|
export type * from "./hooks/usePluginRuntime.js";
|
|
120
|
-
export type {
|
|
91
|
+
export type {
|
|
92
|
+
InteractionContext,
|
|
93
|
+
InteractionContextOption,
|
|
94
|
+
InteractionDescriptor,
|
|
95
|
+
InputDomainDependencyCase,
|
|
96
|
+
PluginStateSnapshot,
|
|
97
|
+
} from "./types/plugin-state.js";
|
|
98
|
+
export {
|
|
99
|
+
hexColor,
|
|
100
|
+
isHexColor,
|
|
101
|
+
parseHexColor,
|
|
102
|
+
type HexColor,
|
|
103
|
+
} from "./types/hex-color.js";
|
|
121
104
|
export type * from "./types/player-state.js";
|
|
122
105
|
export type * from "./types/runtime-api.js";
|
|
106
|
+
export type {
|
|
107
|
+
DraftValidation,
|
|
108
|
+
InteractionHandle,
|
|
109
|
+
InteractionHandleStatus,
|
|
110
|
+
InteractionParamsShape,
|
|
111
|
+
} from "./hooks/useInteractionHandle.js";
|
|
112
|
+
export type {
|
|
113
|
+
CardCollection,
|
|
114
|
+
ViewCard,
|
|
115
|
+
ViewSlotOccupant,
|
|
116
|
+
} from "@dreamboard/sdk-types";
|
|
123
117
|
export type {
|
|
124
118
|
AnyHexBoardInput,
|
|
125
119
|
AnySquareBoardInput,
|
|
@@ -100,6 +100,25 @@ test("Board.Target exposes reducer-projected target eligibility", () => {
|
|
|
100
100
|
expect(html).not.toContain('data-ambiguous="true"');
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
+
test("Board target kind aliases use the canonical target router surface", () => {
|
|
104
|
+
const runtime = createRuntime(
|
|
105
|
+
createSnapshot([createBoardDescriptor("claimSpace")]),
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
const html = renderToString(
|
|
109
|
+
<GameUIProvider runtime={runtime}>
|
|
110
|
+
<Board.Root>
|
|
111
|
+
<Board.SpaceTarget value="space-1">Space one</Board.SpaceTarget>
|
|
112
|
+
</Board.Root>
|
|
113
|
+
</GameUIProvider>,
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
expect(html).toContain('data-dreamboard-board-target=""');
|
|
117
|
+
expect(html).toContain('data-target-kind="space"');
|
|
118
|
+
expect(html).toContain('data-target-id="space-1"');
|
|
119
|
+
expect(html).toContain('data-eligible="true"');
|
|
120
|
+
});
|
|
121
|
+
|
|
103
122
|
test("Board.Target requires explicit routing when equal-priority matches are ambiguous", () => {
|
|
104
123
|
const runtime = createRuntime(
|
|
105
124
|
createSnapshot([
|
|
@@ -137,3 +156,57 @@ test("Board.Target requires explicit routing when equal-priority matches are amb
|
|
|
137
156
|
expect(explicitHtml).toContain('data-input-name="spaceId"');
|
|
138
157
|
expect(explicitHtml).not.toContain('data-ambiguous="true"');
|
|
139
158
|
});
|
|
159
|
+
|
|
160
|
+
test("Board.State exposes the generated board interaction context", () => {
|
|
161
|
+
const runtime = createRuntime(
|
|
162
|
+
createSnapshot([createBoardDescriptor("move")]),
|
|
163
|
+
);
|
|
164
|
+
const html = renderToString(
|
|
165
|
+
<GameUIProvider runtime={runtime}>
|
|
166
|
+
<Board.Root>
|
|
167
|
+
<Board.State>
|
|
168
|
+
{(board) => (
|
|
169
|
+
<output
|
|
170
|
+
data-interactions={board.interactions.length}
|
|
171
|
+
data-eligible={board.isEligible("space-1", "space")}
|
|
172
|
+
/>
|
|
173
|
+
)}
|
|
174
|
+
</Board.State>
|
|
175
|
+
</Board.Root>
|
|
176
|
+
</GameUIProvider>,
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
expect(html).toContain('data-interactions="1"');
|
|
180
|
+
expect(html).toContain('data-eligible="true"');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test("Board.HexView joins static hex topology with typed space overlays", () => {
|
|
184
|
+
const staticBoard = {
|
|
185
|
+
id: "island",
|
|
186
|
+
layout: "hex",
|
|
187
|
+
orientation: "pointy-top",
|
|
188
|
+
tiles: [
|
|
189
|
+
{ id: "space-1", q: 0, r: 0 },
|
|
190
|
+
{ id: "space-2", q: 1, r: 0 },
|
|
191
|
+
],
|
|
192
|
+
edges: [],
|
|
193
|
+
vertices: [],
|
|
194
|
+
} as const;
|
|
195
|
+
const spaces = [
|
|
196
|
+
{ id: "space-1", terrain: "forest" },
|
|
197
|
+
{ id: "space-2", terrain: "field" },
|
|
198
|
+
] as const;
|
|
199
|
+
|
|
200
|
+
const html = renderToString(
|
|
201
|
+
<Board.HexView board={staticBoard} spaces={spaces}>
|
|
202
|
+
{(view) => (
|
|
203
|
+
<span>
|
|
204
|
+
board:{view.id} first:{view.tiles[0]?.view.terrain}
|
|
205
|
+
</span>
|
|
206
|
+
)}
|
|
207
|
+
</Board.HexView>,
|
|
208
|
+
).replace(/<!-- -->/g, "");
|
|
209
|
+
|
|
210
|
+
expect(html).toContain("board:island");
|
|
211
|
+
expect(html).toContain("first:forest");
|
|
212
|
+
});
|