@seriousgaming/sdk 0.0.0-stage → 1.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +1 -0
  3. package/README.md +33 -2
  4. package/lib/build/callbacks.d.ts +998 -0
  5. package/lib/build/callbacks.js +32 -0
  6. package/lib/build/context-merge.d.ts +59 -0
  7. package/lib/build/context-merge.js +118 -0
  8. package/lib/build/document.d.ts +36 -0
  9. package/lib/build/document.js +8 -0
  10. package/lib/build/encoding.d.ts +26 -0
  11. package/lib/build/encoding.js +78 -0
  12. package/lib/build/endpoints.d.ts +421 -0
  13. package/lib/build/endpoints.js +46 -0
  14. package/lib/build/hooks.d.ts +74 -0
  15. package/lib/build/hooks.js +1 -0
  16. package/lib/build/index.d.ts +18 -0
  17. package/lib/build/index.js +16 -0
  18. package/lib/build/llm.d.ts +166 -0
  19. package/lib/build/llm.js +17 -0
  20. package/lib/build/resource-schema.d.ts +1048 -0
  21. package/lib/build/resource-schema.js +7 -0
  22. package/lib/build/scheduling.d.ts +112 -0
  23. package/lib/build/scheduling.js +217 -0
  24. package/lib/build/seed.d.ts +51 -0
  25. package/lib/build/seed.js +89 -0
  26. package/lib/build/signatures.d.ts +372 -0
  27. package/lib/build/signatures.js +1 -0
  28. package/lib/build/speech.d.ts +102 -0
  29. package/lib/build/speech.js +11 -0
  30. package/lib/build/tick-validation.d.ts +23 -0
  31. package/lib/build/tick-validation.js +96 -0
  32. package/lib/build/timer.d.ts +74 -0
  33. package/lib/build/timer.js +1 -0
  34. package/lib/build/validators.d.ts +116 -0
  35. package/lib/build/validators.js +1 -0
  36. package/lib/commands.d.ts +357 -0
  37. package/lib/commands.js +14 -0
  38. package/lib/e2e.d.ts +238 -0
  39. package/lib/e2e.js +248 -0
  40. package/lib/projection.d.ts +266 -0
  41. package/lib/projection.js +23 -0
  42. package/lib/testing/index.d.ts +13 -0
  43. package/lib/testing/index.js +13 -0
  44. package/lib/testing/logic-args.d.ts +177 -0
  45. package/lib/testing/logic-args.js +229 -0
  46. package/lib/testing/stub-services.d.ts +41 -0
  47. package/lib/testing/stub-services.js +176 -0
  48. package/lib/ui/CrossTeamDataContext.d.ts +36 -0
  49. package/lib/ui/CrossTeamDataContext.js +32 -0
  50. package/lib/ui/PresentationContext.d.ts +72 -0
  51. package/lib/ui/PresentationContext.js +13 -0
  52. package/lib/ui/PresentationWrapper.d.ts +12 -0
  53. package/lib/ui/PresentationWrapper.js +78 -0
  54. package/lib/ui/SessionUserInterfaceCallbacksContext.d.ts +3 -0
  55. package/lib/ui/SessionUserInterfaceCallbacksContext.js +7 -0
  56. package/lib/ui/SessionUserInterfaceDataContext.d.ts +103 -0
  57. package/lib/ui/SessionUserInterfaceDataContext.js +17 -0
  58. package/lib/ui/SessionUserInterfaceHookFailuresContext.d.ts +44 -0
  59. package/lib/ui/SessionUserInterfaceHookFailuresContext.js +15 -0
  60. package/lib/ui/SessionUserInterfaceHostOverlaysContext.d.ts +23 -0
  61. package/lib/ui/SessionUserInterfaceHostOverlaysContext.js +23 -0
  62. package/lib/ui/SessionUserInterfaceLocaleContext.d.ts +11 -0
  63. package/lib/ui/SessionUserInterfaceLocaleContext.js +13 -0
  64. package/lib/ui/SessionUserInterfaceMetaContext.d.ts +39 -0
  65. package/lib/ui/SessionUserInterfaceMetaContext.js +13 -0
  66. package/lib/ui/SessionUserInterfaceParticipantsContext.d.ts +12 -0
  67. package/lib/ui/SessionUserInterfaceParticipantsContext.js +16 -0
  68. package/lib/ui/SessionUserInterfaceTeamConfigurationContext.d.ts +53 -0
  69. package/lib/ui/SessionUserInterfaceTeamConfigurationContext.js +23 -0
  70. package/lib/ui/SessionUserInterfaceTeamLinksContext.d.ts +56 -0
  71. package/lib/ui/SessionUserInterfaceTeamLinksContext.js +12 -0
  72. package/lib/ui/SessionUserInterfaceTeamsContext.d.ts +13 -0
  73. package/lib/ui/SessionUserInterfaceTeamsContext.js +13 -0
  74. package/lib/ui/SessionUserInterfaceThemeContext.d.ts +9 -0
  75. package/lib/ui/SessionUserInterfaceThemeContext.js +7 -0
  76. package/lib/ui/SessionUserInterfaceThemePreferenceContext.d.ts +3 -0
  77. package/lib/ui/SessionUserInterfaceThemePreferenceContext.js +7 -0
  78. package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.d.ts +42 -0
  79. package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.js +26 -0
  80. package/lib/ui/SessionUserInterfaceWrapper.d.ts +8 -0
  81. package/lib/ui/SessionUserInterfaceWrapper.js +321 -0
  82. package/lib/ui/SettingsEditorCallbacksContext.d.ts +3 -0
  83. package/lib/ui/SettingsEditorCallbacksContext.js +7 -0
  84. package/lib/ui/SettingsEditorContext.d.ts +33 -0
  85. package/lib/ui/SettingsEditorContext.js +16 -0
  86. package/lib/ui/SettingsEditorLocaleContext.d.ts +13 -0
  87. package/lib/ui/SettingsEditorLocaleContext.js +15 -0
  88. package/lib/ui/SettingsEditorThemeContext.d.ts +9 -0
  89. package/lib/ui/SettingsEditorThemeContext.js +7 -0
  90. package/lib/ui/SettingsEditorThemePreferenceContext.d.ts +3 -0
  91. package/lib/ui/SettingsEditorThemePreferenceContext.js +7 -0
  92. package/lib/ui/SettingsEditorWrapper.d.ts +13 -0
  93. package/lib/ui/SettingsEditorWrapper.js +74 -0
  94. package/lib/ui/UserInterfaceCallbacksContext.d.ts +3 -0
  95. package/lib/ui/UserInterfaceCallbacksContext.js +7 -0
  96. package/lib/ui/UserInterfaceDataContext.d.ts +78 -0
  97. package/lib/ui/UserInterfaceDataContext.js +11 -0
  98. package/lib/ui/UserInterfaceLocaleContext.d.ts +13 -0
  99. package/lib/ui/UserInterfaceLocaleContext.js +15 -0
  100. package/lib/ui/UserInterfaceOwnTeamContext.d.ts +25 -0
  101. package/lib/ui/UserInterfaceOwnTeamContext.js +26 -0
  102. package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.d.ts +52 -0
  103. package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.js +13 -0
  104. package/lib/ui/UserInterfaceParticipantContext.d.ts +16 -0
  105. package/lib/ui/UserInterfaceParticipantContext.js +24 -0
  106. package/lib/ui/UserInterfaceParticipantsContext.d.ts +12 -0
  107. package/lib/ui/UserInterfaceParticipantsContext.js +13 -0
  108. package/lib/ui/UserInterfaceRunKindContext.d.ts +31 -0
  109. package/lib/ui/UserInterfaceRunKindContext.js +31 -0
  110. package/lib/ui/UserInterfaceTeamsContext.d.ts +12 -0
  111. package/lib/ui/UserInterfaceTeamsContext.js +13 -0
  112. package/lib/ui/UserInterfaceThemeContext.d.ts +9 -0
  113. package/lib/ui/UserInterfaceThemeContext.js +7 -0
  114. package/lib/ui/UserInterfaceThemePreferenceContext.d.ts +3 -0
  115. package/lib/ui/UserInterfaceThemePreferenceContext.js +7 -0
  116. package/lib/ui/UserInterfaceTimerContext.d.ts +10 -0
  117. package/lib/ui/UserInterfaceTimerContext.js +12 -0
  118. package/lib/ui/UserInterfaceValidationContext.d.ts +25 -0
  119. package/lib/ui/UserInterfaceValidationContext.js +14 -0
  120. package/lib/ui/UserInterfaceViewerRoleContext.d.ts +14 -0
  121. package/lib/ui/UserInterfaceViewerRoleContext.js +17 -0
  122. package/lib/ui/UserInterfaceWrapper.d.ts +8 -0
  123. package/lib/ui/UserInterfaceWrapper.js +219 -0
  124. package/lib/ui/expectedParentOrigin.d.ts +10 -0
  125. package/lib/ui/expectedParentOrigin.js +32 -0
  126. package/lib/ui/index.d.ts +50 -0
  127. package/lib/ui/index.js +52 -0
  128. package/lib/ui/internal/SurfaceGate.d.ts +19 -0
  129. package/lib/ui/internal/SurfaceGate.js +17 -0
  130. package/lib/ui/internal/SurfaceScope.d.ts +17 -0
  131. package/lib/ui/internal/SurfaceScope.js +16 -0
  132. package/lib/ui/internal/createContexts.d.ts +50 -0
  133. package/lib/ui/internal/createContexts.js +32 -0
  134. package/lib/ui/internal/document-attributes.d.ts +9 -0
  135. package/lib/ui/internal/document-attributes.js +87 -0
  136. package/lib/ui/internal/surface-timer.d.ts +3 -0
  137. package/lib/ui/internal/surface-timer.js +11 -0
  138. package/lib/ui/internal/useLatestRef.d.ts +7 -0
  139. package/lib/ui/internal/useLatestRef.js +11 -0
  140. package/lib/ui/internal/useOptimisticMerge.d.ts +19 -0
  141. package/lib/ui/internal/useOptimisticMerge.js +28 -0
  142. package/lib/ui/internal/useSurfaceControls.d.ts +52 -0
  143. package/lib/ui/internal/useSurfaceControls.js +19 -0
  144. package/lib/ui/internal/useTypedPastState.d.ts +17 -0
  145. package/lib/ui/internal/useTypedPastState.js +17 -0
  146. package/lib/ui/mutation-commit.d.ts +32 -0
  147. package/lib/ui/mutation-commit.js +1 -0
  148. package/lib/ui/mutation-outcome.d.ts +66 -0
  149. package/lib/ui/mutation-outcome.js +49 -0
  150. package/lib/ui/request-id.d.ts +18 -0
  151. package/lib/ui/request-id.js +44 -0
  152. package/lib/ui/testing.d.ts +365 -0
  153. package/lib/ui/testing.js +572 -0
  154. package/lib/ui/tick-snapshot.d.ts +28 -0
  155. package/lib/ui/tick-snapshot.js +34 -0
  156. package/lib/ui/ui-protocol.d.ts +799 -0
  157. package/lib/ui/ui-protocol.js +50 -0
  158. package/lib/ui/useAsset.d.ts +80 -0
  159. package/lib/ui/useAsset.js +139 -0
  160. package/lib/ui/useEndpointCallbacks.d.ts +31 -0
  161. package/lib/ui/useEndpointCallbacks.js +68 -0
  162. package/lib/ui/useHostChannel.d.ts +90 -0
  163. package/lib/ui/useHostChannel.js +338 -0
  164. package/lib/ui/useMutationReporter.d.ts +100 -0
  165. package/lib/ui/useMutationReporter.js +97 -0
  166. package/lib/ui/usePastState.d.ts +39 -0
  167. package/lib/ui/usePastState.js +63 -0
  168. package/lib/ui/useViewerStorage.d.ts +54 -0
  169. package/lib/ui/useViewerStorage.js +141 -0
  170. package/package.json +89 -3
@@ -0,0 +1,421 @@
1
+ import { type MutationOutcome } from '../ui/mutation-outcome.js';
2
+ import type { Participant, SignatureCallbacks, TeamInfo } from './callbacks.js';
3
+ import type { ContextDeletePath } from './context-merge.js';
4
+ import type { EndpointActionType, EndpointDefinition } from './resource-schema.js';
5
+ import type { LogicMeta, SessionMode, ViewerRole } from './signatures.js';
6
+ import type { TimerState } from './timer.js';
7
+ /**
8
+ * Host-issued identity of the caller invoking an endpoint. Every field is set
9
+ * by the host from session bookkeeping — iframe-supplied values are never part
10
+ * of the trust chain.
11
+ */
12
+ export interface EndpointCaller {
13
+ /**
14
+ * Session this call belongs to. Absent on a call from the scenario editor,
15
+ * which edits a scenario rather than a session and runs with none (§6.5).
16
+ */
17
+ sessionId?: string;
18
+ /**
19
+ * The caller's own team: present for a participant or an observer, absent
20
+ * for a facilitator, an author or an external caller, who are on no team.
21
+ *
22
+ * Not the team the call acts on. That is `team`, set on every team-scoped
23
+ * call whoever makes it, so a facilitator's call to a team-scoped endpoint
24
+ * has `team` and no `caller.teamId`, and a participant's has both, equal.
25
+ */
26
+ teamId?: string;
27
+ /** Participant identifier, when the caller is a participant. */
28
+ playerId?: string;
29
+ /** Who is calling: see {@link EndpointCallerRole}. */
30
+ role: EndpointCallerRole;
31
+ /**
32
+ * Identifier of the user interface that invoked the endpoint. Absent when
33
+ * no surface made the call, as for an `external` caller.
34
+ */
35
+ userInterfaceIdentifier?: string;
36
+ /**
37
+ * Who is behind an `external` call, as the host authenticated them: an AI
38
+ * agent, an API key, an integration. Absent on every other role, and on
39
+ * an external call from a host that cannot say.
40
+ *
41
+ * The role alone says only that the caller is outside the game, which is
42
+ * too little for an endpoint that should answer one agent differently from
43
+ * another, or for anyone reading back afterwards who changed what.
44
+ */
45
+ principal?: EndpointPrincipal;
46
+ }
47
+ /**
48
+ * Who is calling an endpoint (§6.12).
49
+ *
50
+ * - `participant`: a participant's game or waiting room UI.
51
+ * - `observer`: a game UI rendered for an observer (§13.3).
52
+ * - `facilitator`: the session UI, the setup UI, the CLI, or any other
53
+ * system-trusted path inside a session.
54
+ * - `author`: the scenario editor, used by someone creating a scenario, who
55
+ * need not be a facilitator and has no session.
56
+ * - `external`: a caller outside the game, such as a facilitator's AI agent or
57
+ * a platform API, which only an endpoint whose `visibility` is `external`
58
+ * receives.
59
+ */
60
+ export type EndpointCallerRole = ViewerRole | 'facilitator' | 'author' | 'external';
61
+ /** The host's account of who made an `external` call (§6.12). */
62
+ export interface EndpointPrincipal {
63
+ /** What kind of caller this is, e.g. `agent`, `apiKey`, `integration`. */
64
+ kind: string;
65
+ /** Stable for that caller across calls. Opaque: the host's, not the game's. */
66
+ id: string;
67
+ /** A display name, where the host has one. */
68
+ name?: string;
69
+ }
70
+ /**
71
+ * One team's values, for a session-scoped endpoint (§6.12).
72
+ *
73
+ * A session-scoped call acts on the whole session, so it has no board of its
74
+ * own and a `team`, `team-readable` or `private` declaration has no single copy
75
+ * to resolve against. Those arrive here instead, one entry per team.
76
+ */
77
+ export interface EndpointTeamEntry<TContext> extends TeamInfo {
78
+ /** Exactly this endpoint's non-shared declarations, for this team. */
79
+ context: TContext;
80
+ }
81
+ /**
82
+ * Where the session stands when an endpoint is called (§6.12).
83
+ *
84
+ * An endpoint runs between ticks rather than as part of one, so it has no
85
+ * `RunMeta` and nothing else tells it what round it is, whether the waiting
86
+ * room is open or whether the game has finished. A caller outside the game,
87
+ * an agent most of all, commonly asks exactly that before it acts.
88
+ */
89
+ export interface EndpointSession {
90
+ mode: SessionMode;
91
+ /**
92
+ * Ticks the session has completed: the shared clock, or in independent
93
+ * mode the furthest any team has reached. Each team's own is on its entry.
94
+ */
95
+ completedTicks: number;
96
+ /** The game's tick limit, or null when completion is not a tick count. */
97
+ maxTicks: number | null;
98
+ waitingRoomOpen: boolean;
99
+ /** True only once every team is complete. */
100
+ complete: boolean;
101
+ /** Every team, in stable-index order. Status only: no context. */
102
+ teams: EndpointTeamStatus[];
103
+ }
104
+ /** One team's standing, for {@link EndpointSession}. */
105
+ export interface EndpointTeamStatus extends TeamInfo {
106
+ /** Ticks this team has completed. Equal to the session's outside independent mode. */
107
+ completedTicks: number;
108
+ complete: boolean;
109
+ /** The automatic timer this team runs on, or null when there is none. */
110
+ timer: TimerState | null;
111
+ /**
112
+ * The team's participants. Present only when the endpoint declares
113
+ * `roster: true`: the list grows with the cohort, and most endpoints do not
114
+ * need it.
115
+ */
116
+ participants?: Participant[];
117
+ }
118
+ /**
119
+ * A session action an endpoint returns for the runtime to carry out (§6.12).
120
+ *
121
+ * Each is an operation a facilitator's session surface can already perform,
122
+ * and the runtime holds it to the same rules: a tick past the limit is refused
123
+ * here exactly as it is from the console. Returned rather than called, so a
124
+ * handler stays a function of its arguments and nothing happens until the
125
+ * whole result has been checked.
126
+ *
127
+ * `teamId` defaults to the call's own team on a team-scoped endpoint. On a
128
+ * session-scoped one an omitted `teamId` means the whole session where the
129
+ * action has a session-wide form (`tick`, the timer actions) and is refused
130
+ * where it has none (`renameTeam`).
131
+ */
132
+ export type EndpointAction = {
133
+ type: 'tick';
134
+ teamId?: string;
135
+ } | {
136
+ type: 'setWaitingRoom';
137
+ open: boolean;
138
+ } | {
139
+ type: 'pauseTimer';
140
+ teamId?: string;
141
+ } | {
142
+ type: 'resumeTimer';
143
+ teamId?: string;
144
+ } | {
145
+ type: 'extendTick';
146
+ byMs: number;
147
+ teamId?: string;
148
+ } | {
149
+ type: 'renameTeam';
150
+ name: string;
151
+ teamId?: string;
152
+ } | {
153
+ type: 'moveParticipant';
154
+ participantId: string;
155
+ teamId: string;
156
+ } | {
157
+ type: 'addTeam';
158
+ name?: string;
159
+ } | {
160
+ type: 'setLocale';
161
+ locale: string;
162
+ };
163
+ /** What an endpoint call acts on (§6.12). Absent in a bundle means `team`. */
164
+ export type EndpointScope = NonNullable<EndpointDefinition['scope']>;
165
+ /** The arguments every endpoint receives, whatever its scope. */
166
+ export interface EndpointBaseArgs<TRequest, TContext, TCallbacks = SignatureCallbacks, TSettings = Record<string, never>> {
167
+ /** Request payload, validated against the endpoint's `requestSchema`. */
168
+ request: TRequest;
169
+ /** Scoped snapshot of the capabilities listed in the endpoint's `reads`. */
170
+ context: TContext;
171
+ /** Guarded subset of runtime callbacks for the endpoint's declared `uses`. */
172
+ callbacks: TCallbacks;
173
+ /** Host-issued identity of the caller invoking this endpoint. */
174
+ caller: EndpointCaller;
175
+ /**
176
+ * The settings resources this endpoint declared in `settings`, keyed by
177
+ * identifier (§8). Read-only.
178
+ */
179
+ settings: TSettings;
180
+ /**
181
+ * The facts true of the whole run: its locale, its seed, whether it is the
182
+ * game being played or a walkthrough beside it, and when this call started
183
+ * (`now`, the same for `Plan` and `Respond`).
184
+ *
185
+ * An endpoint is invoked by a surface rather than as part of a tick, so
186
+ * this is {@link LogicMeta} rather than the `RunMeta` an engine receives.
187
+ */
188
+ meta: LogicMeta;
189
+ /**
190
+ * The participants this call covers, taken as the call is made (§6.12):
191
+ * the addressed team's on a team-scoped endpoint, every participant in the
192
+ * session on a session-scoped one. Read-only, and a copy per call.
193
+ * `Respond` reads the roster again once the effects land, as it does
194
+ * `context` and `session`.
195
+ *
196
+ * Always present, unlike `session.teams[].participants`, which `roster:
197
+ * true` adds so a team-scoped endpoint can see other teams' rosters.
198
+ */
199
+ participants: readonly Readonly<Participant>[];
200
+ /** Where the session stands as the call is made. */
201
+ session: EndpointSession;
202
+ }
203
+ /** What a team-scoped endpoint receives beyond the base arguments. */
204
+ export interface TeamEndpointArgs {
205
+ /**
206
+ * The team whose board `context` was read from. The runtime sets it on
207
+ * every team-scoped call, whoever made it.
208
+ *
209
+ * Separate from `caller`, which says who is calling: a facilitator's agent
210
+ * or the CLI calls on a team's behalf without being on it, so it has no
211
+ * `caller.teamId`. Carries the index and display name an endpoint needs to
212
+ * answer in words, having no other route to a team's name.
213
+ */
214
+ team: TeamInfo;
215
+ }
216
+ /** What a session-scoped endpoint receives beyond the base arguments. */
217
+ export interface SessionEndpointArgs<TTeamContext> {
218
+ /**
219
+ * Every team's values, when the endpoint declared at least one non-shared
220
+ * capability (§6.12). Stable-index order.
221
+ *
222
+ * Absent when every declaration is shared: a shared capability holds one
223
+ * value for the session, so it arrives on `context` where a single value is
224
+ * the right shape.
225
+ */
226
+ teams?: EndpointTeamEntry<TTeamContext>[];
227
+ }
228
+ /**
229
+ * Argument shape passed to an endpoint handler. The handler's input is the
230
+ * entire surface: nothing else leaks in — no headers, no cookies, no fetch.
231
+ *
232
+ * `TScope` picks the half that differs: a team-scoped handler is always told
233
+ * its `team`, and a session-scoped one may receive `teams`. Neither is typed on
234
+ * the other, so reaching for the wrong one fails to compile rather than reading
235
+ * `undefined` at run time.
236
+ */
237
+ export type EndpointHandlerArgs<TRequest, TContext, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>> = EndpointBaseArgs<TRequest, TContext, TCallbacks, TSettings> & (TScope extends 'session' ? SessionEndpointArgs<TTeamContext> : TeamEndpointArgs);
238
+ /**
239
+ * Function signature for an endpoint that declares no `writes`. The runtime
240
+ * never persists anything on its behalf: the returned value is validated
241
+ * against the endpoint's `responseSchema` and surfaced to the caller as-is.
242
+ */
243
+ export type EndpointHandler<TRequest = unknown, TResponse = unknown, TContext = unknown, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>> = (args: EndpointHandlerArgs<TRequest, TContext, TCallbacks, TTeamContext, TScope, TSettings>) => Promise<TResponse>;
244
+ /**
245
+ * What an endpoint that declares `writes` returns: the response its caller
246
+ * receives, and the state it changes.
247
+ *
248
+ * The two are separate because they are held to different contracts. `response`
249
+ * is validated against the endpoint's `responseSchema`; `capabilities` is held to
250
+ * its declared `writes`, and a capability outside that set is a fault rather
251
+ * than a silent no-op.
252
+ */
253
+ export interface EndpointWriteResult<TResponse, TWrites> {
254
+ /** Validated against the endpoint's `responseSchema`, then returned as-is. */
255
+ response: TResponse;
256
+ /** The capabilities this call changes. Merged into the board on return. */
257
+ capabilities: TWrites;
258
+ /**
259
+ * Paths to remove once `capabilities` has merged, each under a capability
260
+ * in `writes`, with the same rules as a UI's `deletes`.
261
+ */
262
+ deletes?: ContextDeletePath[];
263
+ }
264
+ /**
265
+ * Function signature for an endpoint that declares `writes`.
266
+ *
267
+ * Unlike a participant's own write, an endpoint's is not put to the game's
268
+ * validators: they exist so a game can refuse a context update a participant
269
+ * submitted directly, and an endpoint is the game's own code, which checks its
270
+ * own writes. The pairing is deliberate — a validator can refuse a change
271
+ * outright while a strict endpoint remains the one sanctioned way to make it.
272
+ */
273
+ export type WritingEndpointHandler<TRequest = unknown, TResponse = unknown, TWrites = unknown, TContext = unknown, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>> = (args: EndpointHandlerArgs<TRequest, TContext, TCallbacks, TTeamContext, TScope, TSettings>) => Promise<EndpointWriteResult<TResponse, TWrites>>;
274
+ /**
275
+ * What an endpoint that declares `actions`, or a session-scoped endpoint that
276
+ * writes team capabilities, returns (§6.12).
277
+ *
278
+ * Every part beside `response` is optional, and the runtime applies what is
279
+ * there in one step, in this order: `capabilities` and its `deletes`, then
280
+ * `teams`, then `actions`. So an endpoint can set a price and then tick on it,
281
+ * and nothing else lands in between.
282
+ */
283
+ export interface EndpointResult<TResponse, TWrites = never, TAction extends EndpointAction = never, TTeamWrites = never> {
284
+ /** Validated against the endpoint's `responseSchema`, then returned as-is. */
285
+ response: TResponse;
286
+ /**
287
+ * A team-scoped endpoint's change to its board, or a session-scoped
288
+ * endpoint's change to the shared store.
289
+ */
290
+ capabilities?: TWrites;
291
+ /**
292
+ * Paths to remove from the same board once `capabilities` has merged, each
293
+ * under a capability in `writes` (a shared one, for a session-scoped
294
+ * endpoint). Same rules as a UI's `deletes`.
295
+ */
296
+ deletes?: ContextDeletePath[];
297
+ /**
298
+ * A session-scoped endpoint's change to individual teams' boards, keyed by
299
+ * team id. Each is held to the endpoint's non-shared `writes`, and every
300
+ * one lands, or none does.
301
+ */
302
+ teams?: Record<string, TTeamWrites>;
303
+ /** Session actions to carry out after the writes. Only declared ones. */
304
+ actions?: TAction[];
305
+ }
306
+ /**
307
+ * Function signature for an endpoint that returns an {@link EndpointResult}:
308
+ * one that declares `actions`, or a session-scoped one that writes team
309
+ * capabilities.
310
+ */
311
+ export type EffectfulEndpointHandler<TRequest = unknown, TResponse = unknown, TContext = unknown, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>, TWrites = never, TAction extends EndpointAction = never, TTeamWrites = never> = (args: EndpointHandlerArgs<TRequest, TContext, TCallbacks, TTeamContext, TScope, TSettings>) => Promise<EndpointResult<TResponse, TWrites, TAction, TTeamWrites>>;
312
+ /**
313
+ * What `Plan` returns, for an endpoint that answers in two phases: its effects
314
+ * alone (§6.12). The response is `Respond`'s to write, once they have landed.
315
+ */
316
+ export type EndpointPlan<TWrites = never, TAction extends EndpointAction = never, TTeamWrites = never> = Omit<EndpointResult<never, TWrites, TAction, TTeamWrites>, 'response'>;
317
+ /** What one of `Plan`'s actions came to, for `Respond` (§6.12). */
318
+ export interface EndpointOutcome {
319
+ type: EndpointActionType;
320
+ /** The tick a `tick` action committed. */
321
+ committedAtTick?: number;
322
+ }
323
+ /**
324
+ * `Plan`: the first phase of an endpoint that answers in two. It decides what
325
+ * happens and returns no response; `Respond` writes that once the effects have
326
+ * landed. An endpoint that answers in one exports `Handle` instead.
327
+ */
328
+ export type EndpointPlanner<TRequest = unknown, TContext = unknown, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>, TWrites = never, TAction extends EndpointAction = never, TTeamWrites = never> = (args: EndpointHandlerArgs<TRequest, TContext, TCallbacks, TTeamContext, TScope, TSettings>) => Promise<EndpointPlan<TWrites, TAction, TTeamWrites>>;
329
+ /**
330
+ * `Respond`: the second phase, called once `Plan`'s effects have landed. It
331
+ * receives every argument `Plan` did, read afresh, plus what `Plan` returned
332
+ * and what each action came to. Its return is the response, validated against
333
+ * `responseSchema`. It changes nothing.
334
+ *
335
+ * `context`, `teams` and `session` are read after the effects, so an endpoint
336
+ * that ticked sees the round it started rather than the one before.
337
+ */
338
+ export type EndpointResponder<TRequest = unknown, TResponse = unknown, TContext = unknown, TCallbacks = SignatureCallbacks, TTeamContext = never, TScope extends EndpointScope = 'team', TSettings = Record<string, never>, TWrites = never, TAction extends EndpointAction = never, TTeamWrites = never> = (args: EndpointHandlerArgs<TRequest, TContext, TCallbacks, TTeamContext, TScope, TSettings> & {
339
+ /** What `Plan` returned. */
340
+ plan: EndpointPlan<TWrites, TAction, TTeamWrites>;
341
+ /** One entry per action in `plan.actions`, in order. */
342
+ outcomes: EndpointOutcome[];
343
+ }) => Promise<TResponse>;
344
+ /**
345
+ * One effect of an endpoint's result, in the order the runtime applies them
346
+ * (§6.12): the endpoint's own `capabilities`, then each team's patch under
347
+ * `teams`, then each action by its position in `actions`.
348
+ */
349
+ export type EffectStep = {
350
+ kind: 'capabilities';
351
+ } | {
352
+ kind: 'teams';
353
+ teamId: string;
354
+ } | {
355
+ kind: 'action';
356
+ index: number;
357
+ type: EndpointActionType;
358
+ };
359
+ /**
360
+ * Why an endpoint call failed (§6.12).
361
+ *
362
+ * Every {@link MutationOutcome} kind, for a refusal the call shares with any
363
+ * other operation (`denied` for an allowlist, visibility or team refusal,
364
+ * `conflict` for a result a tick overtook, and an applied step's own outcome,
365
+ * such as `tick-failed`), plus three that only an endpoint can produce:
366
+ *
367
+ * - `invalid-request` - the request failed `requestSchema`, or a file field
368
+ * could not be resolved. The handler did not run.
369
+ * - `handler-error` - `Handle`, `Plan` or `Respond` threw, or ran past the
370
+ * execution bound.
371
+ * - `invalid-response` - what the handler returned broke its declaration: the
372
+ * response failed `responseSchema`, or the result named a write, a team or
373
+ * an action the endpoint does not declare, or had the wrong shape.
374
+ */
375
+ export type EndpointFailureOutcome = MutationOutcome | {
376
+ kind: 'invalid-request';
377
+ message: string;
378
+ } | {
379
+ kind: 'handler-error';
380
+ message: string;
381
+ } | {
382
+ kind: 'invalid-response';
383
+ message: string;
384
+ };
385
+ /**
386
+ * A failed endpoint call (§6.12), itemised so a caller can tell 'nothing
387
+ * happened' from 'the writes landed, then an action failed'.
388
+ */
389
+ export interface EndpointFailure {
390
+ outcome: EndpointFailureOutcome;
391
+ /**
392
+ * The effect steps that committed before the failure, in order. Empty
393
+ * when nothing changed. Non-empty means the session moved: those steps
394
+ * stay applied, and the response was not delivered.
395
+ */
396
+ applied: EffectStep[];
397
+ /** The step that failed, when the failure was applying one. */
398
+ failedStep?: EffectStep;
399
+ }
400
+ /** How an endpoint call settled: its response, or an {@link EndpointFailure}. */
401
+ export type EndpointCallResult = {
402
+ ok: true;
403
+ response: unknown;
404
+ } | ({
405
+ ok: false;
406
+ } & EndpointFailure);
407
+ /**
408
+ * Error a surface's endpoint call (`callbacks.endpoints.<id>(request)`)
409
+ * rejects with. Inspect {@link outcome} (or the shorthand {@link kind}) for
410
+ * why, and {@link applied} for what had already changed.
411
+ */
412
+ export declare class EndpointError extends Error {
413
+ readonly outcome: EndpointFailureOutcome;
414
+ readonly applied: EffectStep[];
415
+ readonly failedStep?: EffectStep;
416
+ constructor(failure: EndpointFailure);
417
+ /** Shorthand for `outcome.kind`. */
418
+ get kind(): EndpointFailureOutcome['kind'];
419
+ /** The failure as plain data, as it travels on the wire. */
420
+ get failure(): EndpointFailure;
421
+ }
@@ -0,0 +1,46 @@
1
+ import { describeMutationOutcome } from '../ui/mutation-outcome.js';
2
+ const actionsMatchSchema = true;
3
+ void actionsMatchSchema;
4
+ function describeEndpointFailure(outcome) {
5
+ switch (outcome.kind) {
6
+ case 'invalid-request':
7
+ case 'handler-error':
8
+ case 'invalid-response':
9
+ return outcome.message;
10
+ default:
11
+ return describeMutationOutcome(outcome);
12
+ }
13
+ }
14
+ /**
15
+ * Error a surface's endpoint call (`callbacks.endpoints.<id>(request)`)
16
+ * rejects with. Inspect {@link outcome} (or the shorthand {@link kind}) for
17
+ * why, and {@link applied} for what had already changed.
18
+ */
19
+ export class EndpointError extends Error {
20
+ outcome;
21
+ applied;
22
+ failedStep;
23
+ constructor(failure) {
24
+ super(describeEndpointFailure(failure.outcome));
25
+ this.name = 'EndpointError';
26
+ this.outcome = failure.outcome;
27
+ this.applied = failure.applied;
28
+ if (failure.failedStep)
29
+ this.failedStep = failure.failedStep;
30
+ // Restore the prototype chain so `instanceof` works after transpilation
31
+ // to ES5-targeted output.
32
+ Object.setPrototypeOf(this, EndpointError.prototype);
33
+ }
34
+ /** Shorthand for `outcome.kind`. */
35
+ get kind() {
36
+ return this.outcome.kind;
37
+ }
38
+ /** The failure as plain data, as it travels on the wire. */
39
+ get failure() {
40
+ return {
41
+ outcome: this.outcome,
42
+ applied: this.applied,
43
+ ...(this.failedStep ? { failedStep: this.failedStep } : {}),
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,74 @@
1
+ import { Participant, SignatureCallbacks } from './callbacks.js';
2
+ import { HookSignal } from './resource-schema.js';
3
+ import { LogicMeta, LogicResult } from './signatures.js';
4
+ /**
5
+ * The live, identifiable subject of a participant lifecycle hook — the same
6
+ * record every surface sees, not a reduced view of it. Defined in
7
+ * `./callbacks.ts`; re-exported here because hooks are where most consumers
8
+ * meet it.
9
+ */
10
+ export type { Participant };
11
+ /**
12
+ * Maps each hook signal to its payload shape. Adding a new signal extends this
13
+ * map; the {@link HookFunction} type then surfaces the new payload fields
14
+ * automatically.
15
+ */
16
+ export interface HookPayloadMap {
17
+ participantJoin: {
18
+ participant: Participant;
19
+ };
20
+ participantMove: {
21
+ participant: Participant;
22
+ fromTeamId: string;
23
+ toTeamId: string;
24
+ /**
25
+ * Which team's context this invocation owns. The signal is dispatched
26
+ * once per affected team, and `participant.teamId` is post-change on
27
+ * both, so it cannot distinguish them.
28
+ */
29
+ phase: 'departure' | 'arrival';
30
+ };
31
+ }
32
+ /**
33
+ * Payload for a hook subscribed to signal `S`. Defaults to the union across
34
+ * all signals so callers that haven't pinned a signal still get a valid type.
35
+ */
36
+ export type HookPayload<S extends HookSignal = HookSignal> = HookPayloadMap[S];
37
+ /**
38
+ * Argument shape passed to a hook function. The signal-specific payload fields
39
+ * are spread alongside `context`, `settings`, and `callbacks` so consumers can
40
+ * destructure them directly (e.g. `({ context, participant }) => ...`).
41
+ */
42
+ export type HookFunctionArgs<S extends HookSignal, TContext, TSettings, TCallbacks = SignatureCallbacks> = HookPayload<S> & {
43
+ context: TContext;
44
+ /**
45
+ * The settings resources this resource declared in `settings`, keyed by
46
+ * identifier: resolved from their defaults, the active scenario and the
47
+ * session's overrides, and fixed when play starts (§8). Read-only.
48
+ */
49
+ settings: TSettings;
50
+ callbacks: TCallbacks;
51
+ /**
52
+ * The facts true of the whole run: its locale, its seed, whether it is the
53
+ * game being played or a walkthrough beside it, and when this dispatch
54
+ * started (`now`).
55
+ *
56
+ * A hook fires outside the tick loop, so this is {@link LogicMeta} rather
57
+ * than the `RunMeta` an engine receives: there is no tick being executed.
58
+ */
59
+ meta: LogicMeta;
60
+ /**
61
+ * The roster after the lifecycle change this hook reports, taken when the
62
+ * dispatch started (§14.3): the participants on the team whose context
63
+ * this call owns for a `participantJoin`, and every participant in the
64
+ * session for a `participantMove`, so a departure and an arrival read the
65
+ * same list. Read-only, and a copy per call.
66
+ */
67
+ participants: readonly Readonly<Participant>[];
68
+ };
69
+ /**
70
+ * Function signature for a hook. Returns its writes under `capabilities`, the
71
+ * same shape an engine returns: hooks fire after the runtime applies the
72
+ * lifecycle change, then the runtime merges and persists what they return.
73
+ */
74
+ export type HookFunction<S extends HookSignal = HookSignal, TContext = unknown, TSettings = unknown, TCallbacks = SignatureCallbacks> = (args: HookFunctionArgs<S, TContext, TSettings, TCallbacks>) => Promise<LogicResult<TContext>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ export type { RunKind, LogicMeta, RunMeta, TeamRunMeta, LogicFunctionArgs, InitializationFunction, RunFunction, StepFunction, TickControllerResult, TickControllerFunctionArgs, GetTickControllerFunction, AggregateFunctionTeam, AggregateFunctionShared, RunAggregateFunctionArgs, RunAggregateResult, RunAggregateFunction, InitAggregateFunction, LogicResult, EngineResult, RunResult, RunAggregateTickResult, EngineFunctionArgs, } from './signatures.js';
2
+ export type { ApiUse, EndpointActionType, HookSignal, Schema, PackageDefinition, EngineDefinition, CapabilityDefinition, SettingsDefinition, SetupDefinition, ScenarioEditorDefinition, ScenarioDefinition, UserInterfaceDefinition, GameDefinition, GameSettings, GameSettingConstraint, GameSettingsConstraints, SessionUserInterfaceDefinition, SDKSessionUserInterface, WaitingRoomUserInterfaceDefinition, SDKWaitingRoomUserInterface, PresentationDefinition, SDKPresentation, FacilitatorGuideDefinition, SDKFacilitatorGuide, TickControllerDefinition, ResolvedPackageManifest, HookDefinition, ValidatorDefinition, ValidatorGate, EndpointDefinition, LogicLayout, SDKPackage, SDKEngine, SDKCapability, SDKSettings, SDKScenario, SDKUserInterface, SDKSetup, SDKScenarioEditor, SDKGame, PackageManifest, SDKTickController, SDKHook, SDKValidator, SDKEndpoint, GlobalSettings, } from './resource-schema.js';
3
+ export { getText } from './llm.js';
4
+ export type { ContentBlock, LLMMessage, JSONSchema, LLMTier, LLMTool, LLMGenerateOptions, LLMStopReason, LLMUsage, LLMResponse, LLMGenerateFunction, } from './llm.js';
5
+ export { UndeclaredApiUseError } from './callbacks.js';
6
+ export type { ReadAssetResponse, TeamInfo, TeamStateEntry, PastStateEntry, PastStateQuery, ThemePreference, HostOverlay, SignatureCallbacks, UngatedSignatureCallbacks, LogicCallbacks, UserInterfaceCallbacks, WaitingRoomUserInterfaceCallbacks, SessionUserInterfaceCallbacks, SettingsEditorCallbacks, } from './callbacks.js';
7
+ export type { ExtractTextResponse, ExtractTextFunction } from './document.js';
8
+ export type { GenerateSpeechVoice, GenerateSpeechFormat, GenerateSpeechRequest, GenerateSpeechResponse, GenerateSpeechFunction, } from './speech.js';
9
+ export { nextDailyAt, nextWeeklyAt, nextDailyFromSchedule, scheduledTick, intervalTick, } from './scheduling.js';
10
+ export type { ScheduleOptions } from './scheduling.js';
11
+ export type { TimerState } from './timer.js';
12
+ export { deriveSeed, seededRandom } from './seed.js';
13
+ export type { ContextDeletePath, ContextUpdate } from './context-merge.js';
14
+ export type { Participant, HookPayloadMap, HookPayload, HookFunctionArgs, HookFunction, } from './hooks.js';
15
+ export type { ValidationResult, ValidatorActor, ValidatorFunctionArgs, ValidatorFunction, RequestTickFunctionArgs, RequestTickFunction, ValidationRejection, } from './validators.js';
16
+ export type { EffectfulEndpointHandler, EffectStep, EndpointAction, EndpointBaseArgs, EndpointCaller, EndpointCallerRole, EndpointCallResult, EndpointFailure, EndpointFailureOutcome, EndpointPrincipal, EndpointResult, EndpointSession, EndpointTeamStatus, EndpointHandlerArgs, EndpointOutcome, EndpointPlan, EndpointPlanner, EndpointResponder, EndpointScope, EndpointTeamEntry, EndpointHandler, EndpointWriteResult, SessionEndpointArgs, TeamEndpointArgs, WritingEndpointHandler, } from './endpoints.js';
17
+ export { EndpointError } from './endpoints.js';
18
+ export { encodeUtf8, decodeUtf8 } from './encoding.js';
@@ -0,0 +1,16 @@
1
+ // Public API surface for @seriousgaming/sdk.
2
+ //
3
+ // Every export here is explicit so the published surface is reviewable and a
4
+ // rename/removal in the generated schema (see ./resource-schema.js) fails the
5
+ // build rather than silently changing public types with no semver signal.
6
+ // Runtime plumbing (the `uses` guard, the context merge and projection, the
7
+ // tick-result check, the manifest version) is not here: it lives in
8
+ // @seriousgaming/sdk-tools/runtime, and the modules the
9
+ // SDK's own builders and UI wrappers still need are private to this package.
10
+ // See public-api.test.ts for the snapshot.
11
+ export { getText } from './llm.js';
12
+ export { UndeclaredApiUseError } from './callbacks.js';
13
+ export { nextDailyAt, nextWeeklyAt, nextDailyFromSchedule, scheduledTick, intervalTick, } from './scheduling.js';
14
+ export { deriveSeed, seededRandom } from './seed.js';
15
+ export { EndpointError } from './endpoints.js';
16
+ export { encodeUtf8, decodeUtf8 } from './encoding.js';