@dreamboard-games/sdk 0.5.0-alpha.2 → 0.5.0-alpha.21
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/README.md +462 -53
- package/dist/board-element-CqtxU5VZ.d.ts +13 -0
- package/dist/chunk-3RFGPBES.js +1792 -0
- package/dist/chunk-3RFGPBES.js.map +1 -0
- package/dist/chunk-CZRPUWCT.js +1602 -0
- package/dist/chunk-CZRPUWCT.js.map +1 -0
- package/dist/chunk-DMSXVMYY.js +7199 -0
- package/dist/chunk-DMSXVMYY.js.map +1 -0
- package/dist/chunk-U6R7FAH4.js +630 -0
- package/dist/chunk-U6R7FAH4.js.map +1 -0
- package/dist/chunk-YT3RPO5J.js +635 -0
- package/dist/chunk-YT3RPO5J.js.map +1 -0
- package/dist/diagnostics-ZAPEBlJP.d.ts +64 -0
- package/dist/extract-CwJWDrSD.d.ts +6850 -0
- package/dist/index.d.ts +5177 -1
- package/dist/index.js +1990 -6
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +158 -0
- package/dist/react.js +1119 -0
- package/dist/react.js.map +1 -0
- package/dist/reducer.d.ts +1028 -97
- package/dist/reducer.js +4892 -125
- package/dist/reducer.js.map +1 -1
- package/dist/shortcuts-B_RrufOM.d.ts +822 -0
- package/dist/testing.d.ts +529 -569
- package/dist/testing.js +2588 -934
- package/dist/testing.js.map +1 -1
- package/dist/types-BxXRINRF.d.ts +118 -0
- package/package.json +39 -144
- package/dist/HandView-Bi2lxzQP.d.ts +0 -79
- package/dist/ResourceCounter-BFxJknqp.d.ts +0 -98
- package/dist/ThemeProvider-CElaL2ik.d.ts +0 -99
- package/dist/attributes-DbvyMbXw.d.ts +0 -68
- package/dist/browser-interaction.d.ts +0 -910
- package/dist/browser-interaction.js +0 -119
- package/dist/browser-interaction.js.map +0 -1
- package/dist/chunk-32PFKDV7.js +0 -11705
- package/dist/chunk-32PFKDV7.js.map +0 -1
- package/dist/chunk-3BAD4VC2.js +0 -263
- package/dist/chunk-3BAD4VC2.js.map +0 -1
- package/dist/chunk-3SKDNDPG.js +0 -104
- package/dist/chunk-3SKDNDPG.js.map +0 -1
- package/dist/chunk-5YV2WHJ4.js +0 -25
- package/dist/chunk-5YV2WHJ4.js.map +0 -1
- package/dist/chunk-ANRB4XKA.js +0 -90
- package/dist/chunk-ANRB4XKA.js.map +0 -1
- package/dist/chunk-BI4G3PM2.js +0 -1864
- package/dist/chunk-BI4G3PM2.js.map +0 -1
- package/dist/chunk-EVCLTY4Q.js +0 -935
- package/dist/chunk-EVCLTY4Q.js.map +0 -1
- package/dist/chunk-GDPKTBUR.js +0 -564
- package/dist/chunk-GDPKTBUR.js.map +0 -1
- package/dist/chunk-H6VDGFL5.js +0 -2903
- package/dist/chunk-H6VDGFL5.js.map +0 -1
- package/dist/chunk-LR3ZTWQF.js +0 -5960
- package/dist/chunk-LR3ZTWQF.js.map +0 -1
- package/dist/chunk-PF7L4BMG.js +0 -117
- package/dist/chunk-PF7L4BMG.js.map +0 -1
- package/dist/chunk-PN5O6GG2.js +0 -32
- package/dist/chunk-PN5O6GG2.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -10
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-S2JEDVWH.js +0 -7165
- package/dist/chunk-S2JEDVWH.js.map +0 -1
- package/dist/chunk-T3ZKNUZ7.js +0 -1
- package/dist/chunk-T3ZKNUZ7.js.map +0 -1
- package/dist/chunk-UGH54WZ2.js +0 -223
- package/dist/chunk-UGH54WZ2.js.map +0 -1
- package/dist/chunk-VCDWP5VL.js +0 -746
- package/dist/chunk-VCDWP5VL.js.map +0 -1
- package/dist/chunk-VDXOF4FW.js +0 -69
- package/dist/chunk-VDXOF4FW.js.map +0 -1
- package/dist/chunk-WHR5UW3F.js +0 -1988
- package/dist/chunk-WHR5UW3F.js.map +0 -1
- package/dist/chunk-Y75CFE77.js +0 -17
- package/dist/chunk-Y75CFE77.js.map +0 -1
- package/dist/chunk-Z7QCREWI.js +0 -3435
- package/dist/chunk-Z7QCREWI.js.map +0 -1
- package/dist/chunk-ZZGN2ATS.js +0 -1941
- package/dist/chunk-ZZGN2ATS.js.map +0 -1
- package/dist/components-gAbIz7hK.d.ts +0 -1284
- package/dist/definitions-BgmV_GhC.d.ts +0 -300
- package/dist/diagnostics-DIi3ina7.d.ts +0 -50
- package/dist/digest.d.ts +0 -8
- package/dist/game-CsZScpcn.d.ts +0 -763
- package/dist/hex-board-view-aKkblDp6.d.ts +0 -1228
- package/dist/index-CcT9Q7N7.d.ts +0 -193
- package/dist/index.d-DjzoK7zn.d.ts +0 -2101
- package/dist/package-set.d.ts +0 -13
- package/dist/package-set.js +0 -12
- package/dist/package-set.js.map +0 -1
- package/dist/player-state-Cqpyeql0.d.ts +0 -371
- package/dist/plugin-runtime-contract.d.ts +0 -17
- package/dist/plugin-runtime-contract.js +0 -92
- package/dist/plugin-runtime-contract.js.map +0 -1
- package/dist/primitive-props-BNHDkgd7.d.ts +0 -16
- package/dist/protocol-dYgafTYY.d.ts +0 -314
- package/dist/reducer/advanced.d.ts +0 -82
- package/dist/reducer/advanced.js +0 -51
- package/dist/reducer/advanced.js.map +0 -1
- package/dist/reducer-contract.d.ts +0 -11
- package/dist/reducer-contract.js +0 -16
- package/dist/reducer-contract.js.map +0 -1
- package/dist/reference-games/index.d.ts +0 -31
- package/dist/reference-games/index.js +0 -48
- package/dist/reference-games/index.js.map +0 -1
- package/dist/runtime/primitives.d.ts +0 -250
- package/dist/runtime/primitives.js +0 -189
- package/dist/runtime/primitives.js.map +0 -1
- package/dist/runtime/runtime-api.d.ts +0 -2
- package/dist/runtime/runtime-api.js +0 -1
- package/dist/runtime/runtime-api.js.map +0 -1
- package/dist/runtime/workspace-contract.d.ts +0 -392
- package/dist/runtime/workspace-contract.js +0 -28
- package/dist/runtime/workspace-contract.js.map +0 -1
- package/dist/runtime-RJ5orDJU.d.ts +0 -1699
- package/dist/runtime-api-Bz5pwNU_.d.ts +0 -296
- package/dist/runtime-json-CQ9QbLZ5.d.ts +0 -5
- package/dist/runtime.d.ts +0 -83
- package/dist/runtime.js +0 -242
- package/dist/runtime.js.map +0 -1
- package/dist/schema.d.ts +0 -379
- package/dist/stale-contract-artifact-error-XLaweZtF.d.ts +0 -18
- package/dist/testing-compiler.d.ts +0 -37
- package/dist/testing-compiler.js +0 -272
- package/dist/testing-compiler.js.map +0 -1
- package/dist/testing-runtime.d.ts +0 -119
- package/dist/testing-runtime.js +0 -212
- package/dist/testing-runtime.js.map +0 -1
- package/dist/types-DJj5MJkl.d.ts +0 -256
- package/dist/types-DR7DoB1x.d.ts +0 -28
- package/dist/types-JWCYHmu7.d.ts +0 -122
- package/dist/types.d.ts +0 -1958
- package/dist/types.js +0 -14
- package/dist/types.js.map +0 -1
- package/dist/ui/components.d.ts +0 -17
- package/dist/ui/components.js +0 -216
- package/dist/ui/components.js.map +0 -1
- package/dist/ui/defaults.d.ts +0 -19
- package/dist/ui/defaults.js +0 -104
- package/dist/ui/defaults.js.map +0 -1
- package/dist/ui/player-state.d.ts +0 -2
- package/dist/ui/player-state.js +0 -1
- package/dist/ui/player-state.js.map +0 -1
- package/dist/ui/plugin-styles.css +0 -2
- package/dist/ui-contract-GTUPkf8z.d.ts +0 -1168
- package/dist/ui.d.ts +0 -317
- package/dist/ui.js +0 -277
- package/dist/ui.js.map +0 -1
- package/dist/views-BpuWcOyN.d.ts +0 -1641
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
import {
|
|
2
|
+
GameOutcomeSchema,
|
|
3
|
+
InteractionDescriptorSchema,
|
|
4
|
+
ProjectedGameEventDetailSchema,
|
|
5
|
+
ProjectedGameEventSchema,
|
|
6
|
+
SeatProjectionBundleSchema,
|
|
7
|
+
SimultaneousPhaseProjectionSchema,
|
|
8
|
+
SystemActionEventSchema,
|
|
9
|
+
ViewCardSchema
|
|
10
|
+
} from "./chunk-U6R7FAH4.js";
|
|
11
|
+
import {
|
|
12
|
+
BoardProjectionSchema,
|
|
13
|
+
PlayerIdSchema,
|
|
14
|
+
ProjectedTileSchema,
|
|
15
|
+
RuntimeJsonSchema,
|
|
16
|
+
canonicalizePluginRuntimeJson,
|
|
17
|
+
digestPluginRuntimeJson,
|
|
18
|
+
immutableCopy
|
|
19
|
+
} from "./chunk-CZRPUWCT.js";
|
|
20
|
+
|
|
21
|
+
// src/shared/protocol/protocol.ts
|
|
22
|
+
var DREAMBOARD_PLUGIN_PROTOCOL = "dreamboard-plugin";
|
|
23
|
+
var DREAMBOARD_PLUGIN_PROTOCOL_VERSION = 10;
|
|
24
|
+
|
|
25
|
+
// src/shared/protocol/schema.ts
|
|
26
|
+
import * as z from "zod";
|
|
27
|
+
var GameEventDetailSchema = ProjectedGameEventDetailSchema;
|
|
28
|
+
var SystemActionEventSchema2 = SystemActionEventSchema;
|
|
29
|
+
var GameEventSchema = ProjectedGameEventSchema;
|
|
30
|
+
var SeatProjectionBundleSchema2 = SeatProjectionBundleSchema;
|
|
31
|
+
var PluginPlayerSummarySchema = z.object({
|
|
32
|
+
playerId: PlayerIdSchema,
|
|
33
|
+
displayName: z.string(),
|
|
34
|
+
color: z.string().optional()
|
|
35
|
+
}).strict();
|
|
36
|
+
var PluginSessionDescriptorSchema = z.object({
|
|
37
|
+
sessionId: z.string().min(1),
|
|
38
|
+
players: z.array(PluginPlayerSummarySchema),
|
|
39
|
+
assets: z.record(z.string(), z.instanceof(Blob)).optional()
|
|
40
|
+
}).strict();
|
|
41
|
+
var ZoneHandlesSnapshotSchema = z.object({
|
|
42
|
+
tiles: z.array(ProjectedTileSchema),
|
|
43
|
+
cardIds: z.array(z.string()),
|
|
44
|
+
cardViewsById: z.record(z.string(), ViewCardSchema),
|
|
45
|
+
cardBacksById: z.record(z.string(), z.string()),
|
|
46
|
+
playableByCardId: z.record(
|
|
47
|
+
z.string(),
|
|
48
|
+
z.array(InteractionDescriptorSchema)
|
|
49
|
+
)
|
|
50
|
+
}).strict();
|
|
51
|
+
var SimultaneousPhaseSnapshotSchema = SimultaneousPhaseProjectionSchema;
|
|
52
|
+
var GameplayBasisSchema = z.object({
|
|
53
|
+
sessionId: z.string().min(1),
|
|
54
|
+
version: z.number().int().nonnegative(),
|
|
55
|
+
actionSetVersion: z.string().min(1),
|
|
56
|
+
perspectivePlayerId: PlayerIdSchema
|
|
57
|
+
}).strict();
|
|
58
|
+
var GameOutcomeSchema2 = GameOutcomeSchema;
|
|
59
|
+
var ProjectedViewSchema = z.record(z.string(), RuntimeJsonSchema).superRefine((view, context) => {
|
|
60
|
+
if (!Object.hasOwn(view, "boards")) return;
|
|
61
|
+
const boards = BoardProjectionSchema.safeParse(view.boards);
|
|
62
|
+
if (!boards.success) {
|
|
63
|
+
for (const issue of boards.error.issues) {
|
|
64
|
+
context.addIssue({
|
|
65
|
+
code: "custom",
|
|
66
|
+
path: ["boards", ...issue.path],
|
|
67
|
+
message: issue.message
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
var SeatFrameSchema = z.object({
|
|
73
|
+
events: z.array(GameEventSchema).max(32),
|
|
74
|
+
view: ProjectedViewSchema.nullable(),
|
|
75
|
+
flow: z.object({
|
|
76
|
+
currentPhase: z.string().nullable(),
|
|
77
|
+
activePlayers: z.array(PlayerIdSchema),
|
|
78
|
+
simultaneousPhase: SimultaneousPhaseSnapshotSchema.nullable()
|
|
79
|
+
}).strict(),
|
|
80
|
+
availableInteractions: z.array(InteractionDescriptorSchema),
|
|
81
|
+
zones: z.record(
|
|
82
|
+
z.string(),
|
|
83
|
+
z.record(z.string(), ZoneHandlesSnapshotSchema)
|
|
84
|
+
)
|
|
85
|
+
}).strict();
|
|
86
|
+
var PluginGameplayFrameSchema = SeatFrameSchema.extend({
|
|
87
|
+
basis: GameplayBasisSchema
|
|
88
|
+
});
|
|
89
|
+
var InteractionResultSchema = z.discriminatedUnion("accepted", [
|
|
90
|
+
z.object({
|
|
91
|
+
type: z.literal("interaction.result"),
|
|
92
|
+
clientActionId: z.string().min(1),
|
|
93
|
+
accepted: z.literal(true)
|
|
94
|
+
}).strict(),
|
|
95
|
+
z.object({
|
|
96
|
+
type: z.literal("interaction.result"),
|
|
97
|
+
clientActionId: z.string().min(1),
|
|
98
|
+
accepted: z.literal(false),
|
|
99
|
+
errorCode: z.string().min(1),
|
|
100
|
+
message: z.string().optional()
|
|
101
|
+
}).strict()
|
|
102
|
+
]);
|
|
103
|
+
var SubmitInteractionCommandSchema = z.object({
|
|
104
|
+
type: z.literal("interaction.submit"),
|
|
105
|
+
clientActionId: z.string().min(1),
|
|
106
|
+
basis: GameplayBasisSchema,
|
|
107
|
+
interactionId: z.string().min(1),
|
|
108
|
+
params: RuntimeJsonSchema
|
|
109
|
+
}).strict();
|
|
110
|
+
var CancelInteractionCommandSchema = SubmitInteractionCommandSchema.omit({ params: true }).extend({ type: z.literal("interaction.cancel") }).strict();
|
|
111
|
+
var HostToPluginPayloadSchema = z.discriminatedUnion("type", [
|
|
112
|
+
z.object({
|
|
113
|
+
type: z.literal("runtime.init"),
|
|
114
|
+
session: PluginSessionDescriptorSchema
|
|
115
|
+
}).strict(),
|
|
116
|
+
z.object({
|
|
117
|
+
type: z.literal("gameplay.frame"),
|
|
118
|
+
frame: PluginGameplayFrameSchema
|
|
119
|
+
}).strict(),
|
|
120
|
+
InteractionResultSchema
|
|
121
|
+
]);
|
|
122
|
+
var PluginToHostPayloadSchema = z.discriminatedUnion("type", [
|
|
123
|
+
z.object({ type: z.literal("runtime.ready") }).strict(),
|
|
124
|
+
z.object({ type: z.literal("runtime.resume") }).strict(),
|
|
125
|
+
z.object({
|
|
126
|
+
type: z.literal("runtime.ack"),
|
|
127
|
+
sequence: z.number().int().nonnegative(),
|
|
128
|
+
clientReceivedAtMs: z.number().finite().optional(),
|
|
129
|
+
clientRenderedAtMs: z.number().finite().optional()
|
|
130
|
+
}).strict(),
|
|
131
|
+
SubmitInteractionCommandSchema,
|
|
132
|
+
CancelInteractionCommandSchema,
|
|
133
|
+
z.object({
|
|
134
|
+
type: z.literal("runtime.error"),
|
|
135
|
+
message: z.string(),
|
|
136
|
+
code: z.string().optional()
|
|
137
|
+
}).strict()
|
|
138
|
+
]);
|
|
139
|
+
function createPluginProtocolEnvelopeSchema(payloadSchema) {
|
|
140
|
+
return z.object({
|
|
141
|
+
protocol: z.literal(DREAMBOARD_PLUGIN_PROTOCOL),
|
|
142
|
+
version: z.literal(DREAMBOARD_PLUGIN_PROTOCOL_VERSION),
|
|
143
|
+
channelId: z.string().min(1),
|
|
144
|
+
sequence: z.number().int().nonnegative(),
|
|
145
|
+
payload: payloadSchema
|
|
146
|
+
}).strict();
|
|
147
|
+
}
|
|
148
|
+
var HostToPluginEnvelopeSchema = createPluginProtocolEnvelopeSchema(
|
|
149
|
+
HostToPluginPayloadSchema
|
|
150
|
+
);
|
|
151
|
+
var PluginToHostEnvelopeSchema = createPluginProtocolEnvelopeSchema(
|
|
152
|
+
PluginToHostPayloadSchema
|
|
153
|
+
);
|
|
154
|
+
function parsePluginSessionDescriptor(value) {
|
|
155
|
+
return PluginSessionDescriptorSchema.parse(value);
|
|
156
|
+
}
|
|
157
|
+
function parsePluginGameplayFrame(value) {
|
|
158
|
+
return PluginGameplayFrameSchema.parse(value);
|
|
159
|
+
}
|
|
160
|
+
function parseHostToPluginEnvelope(value) {
|
|
161
|
+
return HostToPluginEnvelopeSchema.parse(value);
|
|
162
|
+
}
|
|
163
|
+
function parsePluginToHostEnvelope(value) {
|
|
164
|
+
return PluginToHostEnvelopeSchema.parse(value);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/headless/sources/static.ts
|
|
168
|
+
import { createStore } from "@tanstack/store";
|
|
169
|
+
import * as z2 from "zod";
|
|
170
|
+
var SourceSnapshotSchema = z2.object({
|
|
171
|
+
me: z2.string().min(1),
|
|
172
|
+
players: z2.array(PluginPlayerSummarySchema),
|
|
173
|
+
frame: SeatFrameSchema,
|
|
174
|
+
version: z2.number().int().nonnegative()
|
|
175
|
+
}).strict();
|
|
176
|
+
function staticSource(input) {
|
|
177
|
+
const snapshot = immutableCopy(SourceSnapshotSchema.parse(input));
|
|
178
|
+
if (!snapshot.players.some((player) => player.playerId === snapshot.me))
|
|
179
|
+
throw new Error("Gameplay seat is absent from session.");
|
|
180
|
+
const store = createStore(
|
|
181
|
+
Object.freeze({
|
|
182
|
+
snapshot,
|
|
183
|
+
connection: "ready",
|
|
184
|
+
request: null,
|
|
185
|
+
failure: null
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
return {
|
|
189
|
+
store: {
|
|
190
|
+
get: () => store.get(),
|
|
191
|
+
subscribe: (listener) => store.subscribe(listener)
|
|
192
|
+
},
|
|
193
|
+
dispose() {
|
|
194
|
+
store.setState(
|
|
195
|
+
(state) => Object.freeze({
|
|
196
|
+
snapshot: state.snapshot,
|
|
197
|
+
connection: "closed",
|
|
198
|
+
request: null,
|
|
199
|
+
failure: null
|
|
200
|
+
})
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/shared/protocol/digest.ts
|
|
207
|
+
function computePluginActionSetVersion(input) {
|
|
208
|
+
return digestPluginRuntimeJson({
|
|
209
|
+
digestVersion: "plugin-action-set@6",
|
|
210
|
+
version: input.version,
|
|
211
|
+
availableInteractions: input.availableInteractions
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function digestPluginGameplayFrame(frame) {
|
|
215
|
+
return digestPluginRuntimeJson({
|
|
216
|
+
digestVersion: "plugin-gameplay-frame@6",
|
|
217
|
+
frame
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function digestPluginCommandRequest(command) {
|
|
221
|
+
return digestPluginRuntimeJson({
|
|
222
|
+
digestVersion: "plugin-command-request@6",
|
|
223
|
+
command
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/shared/protocol/projection.ts
|
|
228
|
+
function materializePluginGameplayFrame(input) {
|
|
229
|
+
const dynamicProjection = SeatProjectionBundleSchema2.parse(
|
|
230
|
+
canonicalizePluginRuntimeJson(input.dynamicProjection)
|
|
231
|
+
);
|
|
232
|
+
if (dynamicProjection.referenceBasis.sessionId !== input.sessionId || dynamicProjection.referenceBasis.version !== input.version) {
|
|
233
|
+
throw new Error(
|
|
234
|
+
"Projection reference basis does not match the frame basis."
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
const registry = dynamicProjection.interactionsByRef ?? {};
|
|
238
|
+
const seat = dynamicProjection.seats[input.perspectivePlayerId] ?? null;
|
|
239
|
+
const availableInteractions = seat == null ? [] : hydrateInteractionRefs(
|
|
240
|
+
registry,
|
|
241
|
+
seat.availableInteractionRefs ?? [],
|
|
242
|
+
"availableInteractionRefs"
|
|
243
|
+
);
|
|
244
|
+
const zones = seat?.zones == null ? {} : hydrateZones(registry, seat.zones, "zones");
|
|
245
|
+
const frame = {
|
|
246
|
+
events: seat?.events ?? [],
|
|
247
|
+
basis: {
|
|
248
|
+
sessionId: input.sessionId,
|
|
249
|
+
version: input.version,
|
|
250
|
+
actionSetVersion: input.actionSetVersion,
|
|
251
|
+
perspectivePlayerId: input.perspectivePlayerId
|
|
252
|
+
},
|
|
253
|
+
view: materializeView(seat?.view, seat?.boards),
|
|
254
|
+
flow: {
|
|
255
|
+
currentPhase: input.currentPhase,
|
|
256
|
+
activePlayers: [...input.activePlayers],
|
|
257
|
+
simultaneousPhase: dynamicProjection.simultaneousPhase ?? null
|
|
258
|
+
},
|
|
259
|
+
availableInteractions,
|
|
260
|
+
zones
|
|
261
|
+
};
|
|
262
|
+
return PluginGameplayFrameSchema.parse(frame);
|
|
263
|
+
}
|
|
264
|
+
function materializeView(seatView, seatBoards) {
|
|
265
|
+
const parts = [
|
|
266
|
+
seatView,
|
|
267
|
+
seatBoards === void 0 ? void 0 : { boards: seatBoards }
|
|
268
|
+
].filter((part) => part !== void 0 && part !== null);
|
|
269
|
+
if (parts.length === 0) return null;
|
|
270
|
+
return Object.assign({}, ...parts);
|
|
271
|
+
}
|
|
272
|
+
function hydrateZones(registry, value, path) {
|
|
273
|
+
return Object.fromEntries(
|
|
274
|
+
Object.entries(value).map(([zoneId, hosts]) => [
|
|
275
|
+
zoneId,
|
|
276
|
+
Object.fromEntries(
|
|
277
|
+
Object.entries(hosts).map(([hostId, zone]) => [
|
|
278
|
+
hostId,
|
|
279
|
+
{
|
|
280
|
+
tiles: zone.tiles,
|
|
281
|
+
cardIds: zone.cardIds,
|
|
282
|
+
cardViewsById: zone.cardViewsById,
|
|
283
|
+
cardBacksById: zone.cardBacksById,
|
|
284
|
+
playableByCardId: Object.fromEntries(
|
|
285
|
+
Object.entries(zone.playableByCardId).map(([cardId, refs]) => [
|
|
286
|
+
cardId,
|
|
287
|
+
hydrateInteractionRefs(
|
|
288
|
+
registry,
|
|
289
|
+
refs,
|
|
290
|
+
`${path}.${zoneId}.${hostId}.playableByCardId.${cardId}`
|
|
291
|
+
)
|
|
292
|
+
])
|
|
293
|
+
)
|
|
294
|
+
}
|
|
295
|
+
])
|
|
296
|
+
)
|
|
297
|
+
])
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
function hydrateInteractionRefs(registry, value, path) {
|
|
301
|
+
return value.map((ref, index) => {
|
|
302
|
+
const descriptor = registry[ref];
|
|
303
|
+
if (!descriptor) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
`Seat projection ${path}[${index}] references '${ref}', which is missing from interactionsByRef.`
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
return descriptor;
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// src/headless/sources/lifecycle.ts
|
|
313
|
+
import { createStore as createStore2 } from "@tanstack/store";
|
|
314
|
+
function createSourceLifecycle(options) {
|
|
315
|
+
let context = options.context ? immutableCopy(options.context) : null;
|
|
316
|
+
const store = createStore2(
|
|
317
|
+
Object.freeze({
|
|
318
|
+
snapshot: null,
|
|
319
|
+
connection: "connecting",
|
|
320
|
+
request: null,
|
|
321
|
+
failure: null
|
|
322
|
+
})
|
|
323
|
+
);
|
|
324
|
+
let session = null;
|
|
325
|
+
let assetUrls = null;
|
|
326
|
+
let basis = null;
|
|
327
|
+
let pending = null;
|
|
328
|
+
let timer;
|
|
329
|
+
let recovered = false;
|
|
330
|
+
let closed = false;
|
|
331
|
+
const clearTimer = () => {
|
|
332
|
+
clearTimeout(timer);
|
|
333
|
+
timer = void 0;
|
|
334
|
+
};
|
|
335
|
+
const publish = (state) => {
|
|
336
|
+
if (state.request) Object.freeze(state.request);
|
|
337
|
+
store.setState(() => Object.freeze(state));
|
|
338
|
+
};
|
|
339
|
+
const recovering = () => {
|
|
340
|
+
if (closed) return;
|
|
341
|
+
publish({ ...store.get(), connection: "recovering", failure: null });
|
|
342
|
+
};
|
|
343
|
+
const close = (failure) => {
|
|
344
|
+
if (closed) return;
|
|
345
|
+
closed = true;
|
|
346
|
+
clearTimer();
|
|
347
|
+
for (const url of Object.values(assetUrls ?? {})) URL.revokeObjectURL(url);
|
|
348
|
+
pending?.reject(failure ?? new Error("Gameplay source disposed."));
|
|
349
|
+
pending = null;
|
|
350
|
+
options.close();
|
|
351
|
+
const snapshot = store.get().snapshot;
|
|
352
|
+
publish(
|
|
353
|
+
failure ? {
|
|
354
|
+
connection: "failed",
|
|
355
|
+
snapshot,
|
|
356
|
+
request: null,
|
|
357
|
+
failure: Object.freeze(failure)
|
|
358
|
+
} : { connection: "closed", snapshot, request: null, failure: null }
|
|
359
|
+
);
|
|
360
|
+
};
|
|
361
|
+
const fail = (error) => close(error);
|
|
362
|
+
const arm = () => {
|
|
363
|
+
clearTimer();
|
|
364
|
+
timer = setTimeout(() => {
|
|
365
|
+
if (recovered) {
|
|
366
|
+
fail(new Error("Gameplay source recovery timed out."));
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
recovered = true;
|
|
370
|
+
recovering();
|
|
371
|
+
try {
|
|
372
|
+
options.recover();
|
|
373
|
+
if (pending && !pending.accepted) options.send(pending.command);
|
|
374
|
+
arm();
|
|
375
|
+
} catch (error) {
|
|
376
|
+
fail(asError(error));
|
|
377
|
+
}
|
|
378
|
+
}, options.timeoutMs ?? 1e4);
|
|
379
|
+
};
|
|
380
|
+
const finishBarrier = () => {
|
|
381
|
+
if (!pending?.accepted) return;
|
|
382
|
+
const frame = store.get().snapshot;
|
|
383
|
+
if (!frame || frame.version <= pending.command.basis.version) return;
|
|
384
|
+
clearTimer();
|
|
385
|
+
pending = null;
|
|
386
|
+
publish({
|
|
387
|
+
snapshot: frame,
|
|
388
|
+
request: null,
|
|
389
|
+
connection: "ready",
|
|
390
|
+
failure: null
|
|
391
|
+
});
|
|
392
|
+
};
|
|
393
|
+
const start = async (operation, interactionId, params) => {
|
|
394
|
+
const state = store.get();
|
|
395
|
+
if (closed || state.connection !== "ready" || !basis)
|
|
396
|
+
return Promise.reject(new Error("Gameplay source is not open."));
|
|
397
|
+
if (pending)
|
|
398
|
+
return Promise.reject(
|
|
399
|
+
new Error("A gameplay interaction is already pending.")
|
|
400
|
+
);
|
|
401
|
+
const command = immutableCopy(
|
|
402
|
+
PluginToHostPayloadSchema.parse({
|
|
403
|
+
type: operation === "cancel" ? "interaction.cancel" : "interaction.submit",
|
|
404
|
+
clientActionId: crypto.randomUUID(),
|
|
405
|
+
basis,
|
|
406
|
+
interactionId,
|
|
407
|
+
...operation === "cancel" ? {} : { params }
|
|
408
|
+
})
|
|
409
|
+
);
|
|
410
|
+
recovered = false;
|
|
411
|
+
const promise = new Promise((resolve, reject) => {
|
|
412
|
+
pending = { command, resolve, reject, accepted: false };
|
|
413
|
+
});
|
|
414
|
+
publish({
|
|
415
|
+
...state,
|
|
416
|
+
request: {
|
|
417
|
+
interactionId,
|
|
418
|
+
operation,
|
|
419
|
+
phase: "awaiting-result"
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
arm();
|
|
423
|
+
try {
|
|
424
|
+
options.send(command);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
fail(asError(error));
|
|
427
|
+
}
|
|
428
|
+
return promise;
|
|
429
|
+
};
|
|
430
|
+
const source = {
|
|
431
|
+
store: {
|
|
432
|
+
get: () => store.get(),
|
|
433
|
+
subscribe: (listener) => store.subscribe(listener)
|
|
434
|
+
},
|
|
435
|
+
submit: (interactionId, params) => start("submit", interactionId, params),
|
|
436
|
+
cancel: (interactionId) => start("cancel", interactionId),
|
|
437
|
+
dispose: () => close(null)
|
|
438
|
+
};
|
|
439
|
+
return {
|
|
440
|
+
source,
|
|
441
|
+
retry() {
|
|
442
|
+
if (closed || !pending) return;
|
|
443
|
+
try {
|
|
444
|
+
if (pending.accepted) options.recover();
|
|
445
|
+
else options.send(pending.command);
|
|
446
|
+
} catch (error) {
|
|
447
|
+
fail(asError(error));
|
|
448
|
+
}
|
|
449
|
+
},
|
|
450
|
+
fail,
|
|
451
|
+
recovering,
|
|
452
|
+
session(value) {
|
|
453
|
+
if (closed) return;
|
|
454
|
+
const { assets, ...parsed } = PluginSessionDescriptorSchema.parse(value);
|
|
455
|
+
if ((context?.sessionId ?? session?.sessionId) && parsed.sessionId !== (context?.sessionId ?? session?.sessionId)) {
|
|
456
|
+
fail(new Error("Gameplay session changed."));
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
if (context && !parsed.players.some((player) => player.playerId === context.playerId)) {
|
|
460
|
+
fail(new Error("Gameplay seat is absent from session."));
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
session = immutableCopy(parsed);
|
|
464
|
+
assetUrls ??= Object.fromEntries(
|
|
465
|
+
Object.entries(assets ?? {}).map(([path, blob]) => [
|
|
466
|
+
path,
|
|
467
|
+
URL.createObjectURL(blob)
|
|
468
|
+
])
|
|
469
|
+
);
|
|
470
|
+
},
|
|
471
|
+
frame(value) {
|
|
472
|
+
if (closed) return;
|
|
473
|
+
const parsed = PluginGameplayFrameSchema.parse(value);
|
|
474
|
+
if (!session) {
|
|
475
|
+
fail(new Error("Gameplay frame arrived before session metadata."));
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
context ??= {
|
|
479
|
+
sessionId: session.sessionId,
|
|
480
|
+
playerId: parsed.basis.perspectivePlayerId
|
|
481
|
+
};
|
|
482
|
+
if (parsed.basis.sessionId !== context.sessionId) {
|
|
483
|
+
fail(new Error("Gameplay authority session changed."));
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
const changedSeat = parsed.basis.perspectivePlayerId !== context.playerId;
|
|
487
|
+
if (changedSeat && !options.followHostSeat) {
|
|
488
|
+
fail(new Error("Gameplay perspective changed."));
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
if (!session.players.some(
|
|
492
|
+
(player) => player.playerId === parsed.basis.perspectivePlayerId
|
|
493
|
+
)) {
|
|
494
|
+
fail(new Error("Gameplay seat is absent from session."));
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
if (basis && parsed.basis.version < basis.version) return;
|
|
498
|
+
if (changedSeat) {
|
|
499
|
+
clearTimer();
|
|
500
|
+
pending?.reject(new Error("Gameplay perspective changed."));
|
|
501
|
+
pending = null;
|
|
502
|
+
recovered = false;
|
|
503
|
+
context = { ...context, playerId: parsed.basis.perspectivePlayerId };
|
|
504
|
+
}
|
|
505
|
+
const { basis: nextBasis, ...frame } = immutableCopy(
|
|
506
|
+
withCardImageUrls(parsed, assetUrls)
|
|
507
|
+
);
|
|
508
|
+
basis = nextBasis;
|
|
509
|
+
publish({
|
|
510
|
+
failure: null,
|
|
511
|
+
request: changedSeat ? null : store.get().request,
|
|
512
|
+
snapshot: Object.freeze({
|
|
513
|
+
me: context.playerId,
|
|
514
|
+
players: session.players,
|
|
515
|
+
frame: Object.freeze(frame),
|
|
516
|
+
version: basis.version
|
|
517
|
+
}),
|
|
518
|
+
connection: "ready"
|
|
519
|
+
});
|
|
520
|
+
finishBarrier();
|
|
521
|
+
},
|
|
522
|
+
result(value) {
|
|
523
|
+
if (closed) return;
|
|
524
|
+
const result = InteractionResultSchema.parse(value);
|
|
525
|
+
if (!pending || result.clientActionId !== pending.command.clientActionId || pending.accepted)
|
|
526
|
+
return;
|
|
527
|
+
pending.resolve(
|
|
528
|
+
immutableCopy(
|
|
529
|
+
result.accepted ? { accepted: true } : {
|
|
530
|
+
accepted: false,
|
|
531
|
+
errorCode: result.errorCode,
|
|
532
|
+
...result.message === void 0 ? {} : { message: result.message }
|
|
533
|
+
}
|
|
534
|
+
)
|
|
535
|
+
);
|
|
536
|
+
if (!result.accepted) {
|
|
537
|
+
clearTimer();
|
|
538
|
+
pending = null;
|
|
539
|
+
publish({
|
|
540
|
+
snapshot: store.get().snapshot,
|
|
541
|
+
request: null,
|
|
542
|
+
connection: "ready",
|
|
543
|
+
failure: null
|
|
544
|
+
});
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
pending.accepted = true;
|
|
548
|
+
recovered = false;
|
|
549
|
+
const state = store.get();
|
|
550
|
+
publish({
|
|
551
|
+
connection: state.connection === "recovering" ? "recovering" : "ready",
|
|
552
|
+
snapshot: state.snapshot,
|
|
553
|
+
failure: null,
|
|
554
|
+
request: { ...state.request, phase: "awaiting-frame" }
|
|
555
|
+
});
|
|
556
|
+
arm();
|
|
557
|
+
finishBarrier();
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
}
|
|
561
|
+
function asError(error) {
|
|
562
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
563
|
+
}
|
|
564
|
+
function withCardImageUrls(frame, urls) {
|
|
565
|
+
if (urls === null || Object.keys(urls).length === 0) return frame;
|
|
566
|
+
return {
|
|
567
|
+
...frame,
|
|
568
|
+
zones: Object.fromEntries(
|
|
569
|
+
Object.entries(frame.zones).map(([zoneId, hosts]) => [
|
|
570
|
+
zoneId,
|
|
571
|
+
Object.fromEntries(
|
|
572
|
+
Object.entries(hosts).map(([hostId, zone]) => [
|
|
573
|
+
hostId,
|
|
574
|
+
{
|
|
575
|
+
...zone,
|
|
576
|
+
cardViewsById: Object.fromEntries(
|
|
577
|
+
Object.entries(zone.cardViewsById).map(([cardId, card]) => [
|
|
578
|
+
cardId,
|
|
579
|
+
{
|
|
580
|
+
...card,
|
|
581
|
+
frontImage: card.frontImage === void 0 ? void 0 : urls[card.frontImage] ?? card.frontImage,
|
|
582
|
+
backImage: card.backImage === void 0 ? void 0 : urls[card.backImage] ?? card.backImage
|
|
583
|
+
}
|
|
584
|
+
])
|
|
585
|
+
),
|
|
586
|
+
cardBacksById: Object.fromEntries(
|
|
587
|
+
Object.entries(zone.cardBacksById).map(([cardId, path]) => [
|
|
588
|
+
cardId,
|
|
589
|
+
urls[path] ?? path
|
|
590
|
+
])
|
|
591
|
+
)
|
|
592
|
+
}
|
|
593
|
+
])
|
|
594
|
+
)
|
|
595
|
+
])
|
|
596
|
+
)
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
export {
|
|
601
|
+
DREAMBOARD_PLUGIN_PROTOCOL,
|
|
602
|
+
DREAMBOARD_PLUGIN_PROTOCOL_VERSION,
|
|
603
|
+
GameEventDetailSchema,
|
|
604
|
+
SystemActionEventSchema2 as SystemActionEventSchema,
|
|
605
|
+
GameEventSchema,
|
|
606
|
+
SeatProjectionBundleSchema2 as SeatProjectionBundleSchema,
|
|
607
|
+
PluginPlayerSummarySchema,
|
|
608
|
+
PluginSessionDescriptorSchema,
|
|
609
|
+
ZoneHandlesSnapshotSchema,
|
|
610
|
+
SimultaneousPhaseSnapshotSchema,
|
|
611
|
+
GameplayBasisSchema,
|
|
612
|
+
GameOutcomeSchema2 as GameOutcomeSchema,
|
|
613
|
+
SeatFrameSchema,
|
|
614
|
+
PluginGameplayFrameSchema,
|
|
615
|
+
InteractionResultSchema,
|
|
616
|
+
SubmitInteractionCommandSchema,
|
|
617
|
+
CancelInteractionCommandSchema,
|
|
618
|
+
HostToPluginPayloadSchema,
|
|
619
|
+
PluginToHostPayloadSchema,
|
|
620
|
+
createPluginProtocolEnvelopeSchema,
|
|
621
|
+
HostToPluginEnvelopeSchema,
|
|
622
|
+
PluginToHostEnvelopeSchema,
|
|
623
|
+
parsePluginSessionDescriptor,
|
|
624
|
+
parsePluginGameplayFrame,
|
|
625
|
+
parseHostToPluginEnvelope,
|
|
626
|
+
parsePluginToHostEnvelope,
|
|
627
|
+
SourceSnapshotSchema,
|
|
628
|
+
staticSource,
|
|
629
|
+
createSourceLifecycle,
|
|
630
|
+
computePluginActionSetVersion,
|
|
631
|
+
digestPluginGameplayFrame,
|
|
632
|
+
digestPluginCommandRequest,
|
|
633
|
+
materializePluginGameplayFrame
|
|
634
|
+
};
|
|
635
|
+
//# sourceMappingURL=chunk-YT3RPO5J.js.map
|