@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.
- package/LICENSE +202 -0
- package/NOTICE +1 -0
- package/README.md +33 -2
- package/lib/build/callbacks.d.ts +998 -0
- package/lib/build/callbacks.js +32 -0
- package/lib/build/context-merge.d.ts +59 -0
- package/lib/build/context-merge.js +118 -0
- package/lib/build/document.d.ts +36 -0
- package/lib/build/document.js +8 -0
- package/lib/build/encoding.d.ts +26 -0
- package/lib/build/encoding.js +78 -0
- package/lib/build/endpoints.d.ts +421 -0
- package/lib/build/endpoints.js +46 -0
- package/lib/build/hooks.d.ts +74 -0
- package/lib/build/hooks.js +1 -0
- package/lib/build/index.d.ts +18 -0
- package/lib/build/index.js +16 -0
- package/lib/build/llm.d.ts +166 -0
- package/lib/build/llm.js +17 -0
- package/lib/build/resource-schema.d.ts +1048 -0
- package/lib/build/resource-schema.js +7 -0
- package/lib/build/scheduling.d.ts +112 -0
- package/lib/build/scheduling.js +217 -0
- package/lib/build/seed.d.ts +51 -0
- package/lib/build/seed.js +89 -0
- package/lib/build/signatures.d.ts +372 -0
- package/lib/build/signatures.js +1 -0
- package/lib/build/speech.d.ts +102 -0
- package/lib/build/speech.js +11 -0
- package/lib/build/tick-validation.d.ts +23 -0
- package/lib/build/tick-validation.js +96 -0
- package/lib/build/timer.d.ts +74 -0
- package/lib/build/timer.js +1 -0
- package/lib/build/validators.d.ts +116 -0
- package/lib/build/validators.js +1 -0
- package/lib/commands.d.ts +357 -0
- package/lib/commands.js +14 -0
- package/lib/e2e.d.ts +238 -0
- package/lib/e2e.js +248 -0
- package/lib/projection.d.ts +266 -0
- package/lib/projection.js +23 -0
- package/lib/testing/index.d.ts +13 -0
- package/lib/testing/index.js +13 -0
- package/lib/testing/logic-args.d.ts +177 -0
- package/lib/testing/logic-args.js +229 -0
- package/lib/testing/stub-services.d.ts +41 -0
- package/lib/testing/stub-services.js +176 -0
- package/lib/ui/CrossTeamDataContext.d.ts +36 -0
- package/lib/ui/CrossTeamDataContext.js +32 -0
- package/lib/ui/PresentationContext.d.ts +72 -0
- package/lib/ui/PresentationContext.js +13 -0
- package/lib/ui/PresentationWrapper.d.ts +12 -0
- package/lib/ui/PresentationWrapper.js +78 -0
- package/lib/ui/SessionUserInterfaceCallbacksContext.d.ts +3 -0
- package/lib/ui/SessionUserInterfaceCallbacksContext.js +7 -0
- package/lib/ui/SessionUserInterfaceDataContext.d.ts +103 -0
- package/lib/ui/SessionUserInterfaceDataContext.js +17 -0
- package/lib/ui/SessionUserInterfaceHookFailuresContext.d.ts +44 -0
- package/lib/ui/SessionUserInterfaceHookFailuresContext.js +15 -0
- package/lib/ui/SessionUserInterfaceHostOverlaysContext.d.ts +23 -0
- package/lib/ui/SessionUserInterfaceHostOverlaysContext.js +23 -0
- package/lib/ui/SessionUserInterfaceLocaleContext.d.ts +11 -0
- package/lib/ui/SessionUserInterfaceLocaleContext.js +13 -0
- package/lib/ui/SessionUserInterfaceMetaContext.d.ts +39 -0
- package/lib/ui/SessionUserInterfaceMetaContext.js +13 -0
- package/lib/ui/SessionUserInterfaceParticipantsContext.d.ts +12 -0
- package/lib/ui/SessionUserInterfaceParticipantsContext.js +16 -0
- package/lib/ui/SessionUserInterfaceTeamConfigurationContext.d.ts +53 -0
- package/lib/ui/SessionUserInterfaceTeamConfigurationContext.js +23 -0
- package/lib/ui/SessionUserInterfaceTeamLinksContext.d.ts +56 -0
- package/lib/ui/SessionUserInterfaceTeamLinksContext.js +12 -0
- package/lib/ui/SessionUserInterfaceTeamsContext.d.ts +13 -0
- package/lib/ui/SessionUserInterfaceTeamsContext.js +13 -0
- package/lib/ui/SessionUserInterfaceThemeContext.d.ts +9 -0
- package/lib/ui/SessionUserInterfaceThemeContext.js +7 -0
- package/lib/ui/SessionUserInterfaceThemePreferenceContext.d.ts +3 -0
- package/lib/ui/SessionUserInterfaceThemePreferenceContext.js +7 -0
- package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.d.ts +42 -0
- package/lib/ui/SessionUserInterfaceWalkthroughLinkContext.js +26 -0
- package/lib/ui/SessionUserInterfaceWrapper.d.ts +8 -0
- package/lib/ui/SessionUserInterfaceWrapper.js +321 -0
- package/lib/ui/SettingsEditorCallbacksContext.d.ts +3 -0
- package/lib/ui/SettingsEditorCallbacksContext.js +7 -0
- package/lib/ui/SettingsEditorContext.d.ts +33 -0
- package/lib/ui/SettingsEditorContext.js +16 -0
- package/lib/ui/SettingsEditorLocaleContext.d.ts +13 -0
- package/lib/ui/SettingsEditorLocaleContext.js +15 -0
- package/lib/ui/SettingsEditorThemeContext.d.ts +9 -0
- package/lib/ui/SettingsEditorThemeContext.js +7 -0
- package/lib/ui/SettingsEditorThemePreferenceContext.d.ts +3 -0
- package/lib/ui/SettingsEditorThemePreferenceContext.js +7 -0
- package/lib/ui/SettingsEditorWrapper.d.ts +13 -0
- package/lib/ui/SettingsEditorWrapper.js +74 -0
- package/lib/ui/UserInterfaceCallbacksContext.d.ts +3 -0
- package/lib/ui/UserInterfaceCallbacksContext.js +7 -0
- package/lib/ui/UserInterfaceDataContext.d.ts +78 -0
- package/lib/ui/UserInterfaceDataContext.js +11 -0
- package/lib/ui/UserInterfaceLocaleContext.d.ts +13 -0
- package/lib/ui/UserInterfaceLocaleContext.js +15 -0
- package/lib/ui/UserInterfaceOwnTeamContext.d.ts +25 -0
- package/lib/ui/UserInterfaceOwnTeamContext.js +26 -0
- package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.d.ts +52 -0
- package/lib/ui/UserInterfaceOwnTeamJoinLinkContext.js +13 -0
- package/lib/ui/UserInterfaceParticipantContext.d.ts +16 -0
- package/lib/ui/UserInterfaceParticipantContext.js +24 -0
- package/lib/ui/UserInterfaceParticipantsContext.d.ts +12 -0
- package/lib/ui/UserInterfaceParticipantsContext.js +13 -0
- package/lib/ui/UserInterfaceRunKindContext.d.ts +31 -0
- package/lib/ui/UserInterfaceRunKindContext.js +31 -0
- package/lib/ui/UserInterfaceTeamsContext.d.ts +12 -0
- package/lib/ui/UserInterfaceTeamsContext.js +13 -0
- package/lib/ui/UserInterfaceThemeContext.d.ts +9 -0
- package/lib/ui/UserInterfaceThemeContext.js +7 -0
- package/lib/ui/UserInterfaceThemePreferenceContext.d.ts +3 -0
- package/lib/ui/UserInterfaceThemePreferenceContext.js +7 -0
- package/lib/ui/UserInterfaceTimerContext.d.ts +10 -0
- package/lib/ui/UserInterfaceTimerContext.js +12 -0
- package/lib/ui/UserInterfaceValidationContext.d.ts +25 -0
- package/lib/ui/UserInterfaceValidationContext.js +14 -0
- package/lib/ui/UserInterfaceViewerRoleContext.d.ts +14 -0
- package/lib/ui/UserInterfaceViewerRoleContext.js +17 -0
- package/lib/ui/UserInterfaceWrapper.d.ts +8 -0
- package/lib/ui/UserInterfaceWrapper.js +219 -0
- package/lib/ui/expectedParentOrigin.d.ts +10 -0
- package/lib/ui/expectedParentOrigin.js +32 -0
- package/lib/ui/index.d.ts +50 -0
- package/lib/ui/index.js +52 -0
- package/lib/ui/internal/SurfaceGate.d.ts +19 -0
- package/lib/ui/internal/SurfaceGate.js +17 -0
- package/lib/ui/internal/SurfaceScope.d.ts +17 -0
- package/lib/ui/internal/SurfaceScope.js +16 -0
- package/lib/ui/internal/createContexts.d.ts +50 -0
- package/lib/ui/internal/createContexts.js +32 -0
- package/lib/ui/internal/document-attributes.d.ts +9 -0
- package/lib/ui/internal/document-attributes.js +87 -0
- package/lib/ui/internal/surface-timer.d.ts +3 -0
- package/lib/ui/internal/surface-timer.js +11 -0
- package/lib/ui/internal/useLatestRef.d.ts +7 -0
- package/lib/ui/internal/useLatestRef.js +11 -0
- package/lib/ui/internal/useOptimisticMerge.d.ts +19 -0
- package/lib/ui/internal/useOptimisticMerge.js +28 -0
- package/lib/ui/internal/useSurfaceControls.d.ts +52 -0
- package/lib/ui/internal/useSurfaceControls.js +19 -0
- package/lib/ui/internal/useTypedPastState.d.ts +17 -0
- package/lib/ui/internal/useTypedPastState.js +17 -0
- package/lib/ui/mutation-commit.d.ts +32 -0
- package/lib/ui/mutation-commit.js +1 -0
- package/lib/ui/mutation-outcome.d.ts +66 -0
- package/lib/ui/mutation-outcome.js +49 -0
- package/lib/ui/request-id.d.ts +18 -0
- package/lib/ui/request-id.js +44 -0
- package/lib/ui/testing.d.ts +365 -0
- package/lib/ui/testing.js +572 -0
- package/lib/ui/tick-snapshot.d.ts +28 -0
- package/lib/ui/tick-snapshot.js +34 -0
- package/lib/ui/ui-protocol.d.ts +799 -0
- package/lib/ui/ui-protocol.js +50 -0
- package/lib/ui/useAsset.d.ts +80 -0
- package/lib/ui/useAsset.js +139 -0
- package/lib/ui/useEndpointCallbacks.d.ts +31 -0
- package/lib/ui/useEndpointCallbacks.js +68 -0
- package/lib/ui/useHostChannel.d.ts +90 -0
- package/lib/ui/useHostChannel.js +338 -0
- package/lib/ui/useMutationReporter.d.ts +100 -0
- package/lib/ui/useMutationReporter.js +97 -0
- package/lib/ui/usePastState.d.ts +39 -0
- package/lib/ui/usePastState.js +63 -0
- package/lib/ui/useViewerStorage.d.ts +54 -0
- package/lib/ui/useViewerStorage.js +141 -0
- package/package.json +89 -3
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { ContextDeletePath, ContextUpdate } from '../build/context-merge.js';
|
|
2
|
+
import type { MutationCommit } from './mutation-commit.js';
|
|
3
|
+
/**
|
|
4
|
+
* What a write can do beyond merging fields.
|
|
5
|
+
*/
|
|
6
|
+
export type SetDataOptions = {
|
|
7
|
+
/**
|
|
8
|
+
* Paths to remove, applied after the patch merges. A merge cannot express
|
|
9
|
+
* deletion, so this is how an entry leaves a collection: removing the key
|
|
10
|
+
* rather than leaving a `null` behind that every reader has to skip and
|
|
11
|
+
* every snapshot carries for the rest of the session.
|
|
12
|
+
*
|
|
13
|
+
* ```typescript
|
|
14
|
+
* setData({}, { deletes: [`pinboard.Notes.${noteId}`] });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
deletes?: ContextDeletePath[];
|
|
18
|
+
};
|
|
19
|
+
type UserInterfaceDataContextValue<T, A> = {
|
|
20
|
+
data: T;
|
|
21
|
+
/**
|
|
22
|
+
* The settings resources this surface declared in `settings`, keyed by
|
|
23
|
+
* identifier (§8). Fixed when play starts, and read-only.
|
|
24
|
+
*/
|
|
25
|
+
settings: A;
|
|
26
|
+
/**
|
|
27
|
+
* The number of ticks this team has completed: `0` until the first tick
|
|
28
|
+
* commits, and `N - 1` while round N is played. `data` is the board the
|
|
29
|
+
* last completed tick left. Use it as the upper bound (exclusive)
|
|
30
|
+
* of a review scrubber: `getPastState({ fromTick: t })` returns a board for
|
|
31
|
+
* `0 <= t < completedTicks` and nothing at or above it. It decreases on undo,
|
|
32
|
+
* which is also the cue to evict any cached snapshots above the new head.
|
|
33
|
+
*/
|
|
34
|
+
completedTicks: number;
|
|
35
|
+
/**
|
|
36
|
+
* Whether a round is being processed right now.
|
|
37
|
+
*
|
|
38
|
+
* Set while the host is running a tick, and cleared when it commits. A
|
|
39
|
+
* surface uses it to say what is happening: at a large cohort a lockstep
|
|
40
|
+
* tick takes long enough to notice, and a participant did not press the
|
|
41
|
+
* button, so an unexplained pause reads as the screen having broken.
|
|
42
|
+
*
|
|
43
|
+
* It does **not** mean writes are closed, and a host must not start
|
|
44
|
+
* refusing them on account of having sent it. What a mid-tick write then
|
|
45
|
+
* does depends on how the runtime serialises (SPECIFICATION.md §9.7): one
|
|
46
|
+
* that queues applies it after the tick commits, so the next tick consumes
|
|
47
|
+
* it; one using optimistic concurrency re-applies it against the tick's
|
|
48
|
+
* result, or reports a `conflict` once its own retries are spent. Either
|
|
49
|
+
* way the write is not dropped, but it belongs to the round *after* the
|
|
50
|
+
* one the participant was looking at.
|
|
51
|
+
*
|
|
52
|
+
* So disabling a submit control on this is about which round a decision
|
|
53
|
+
* counts for, not about losing it. Both choices are conformant.
|
|
54
|
+
*/
|
|
55
|
+
isRoundProcessing: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Deep-merge an update into this UI's context: send only the fields you
|
|
58
|
+
* changed — object values merge recursively, arrays and scalars replace.
|
|
59
|
+
* Resolves once the host confirms the write; rejects with a
|
|
60
|
+
* `MutationError` when it is refused (by a validator, say) or loses a race
|
|
61
|
+
* with a tick.
|
|
62
|
+
*
|
|
63
|
+
* Await it. The local view merges the change the moment it is sent, so a
|
|
64
|
+
* write the host refuses leaves the participant looking at a decision the
|
|
65
|
+
* game never received, with nothing on screen to say so. `useMutationReporter`
|
|
66
|
+
* does the awaiting and hands you the failure to render. An unawaited write
|
|
67
|
+
* still compiles, and is a hazard rather than a convenience.
|
|
68
|
+
*
|
|
69
|
+
* Resolves with the tick the write committed into, when the host reports
|
|
70
|
+
* one. Compare it against the `completedTicks` you were rendering: a higher
|
|
71
|
+
* value means the round advanced first, so the write belongs to the round
|
|
72
|
+
* after the one the participant was looking at.
|
|
73
|
+
*/
|
|
74
|
+
setData: (update: ContextUpdate<T>, options?: SetDataOptions) => Promise<MutationCommit>;
|
|
75
|
+
};
|
|
76
|
+
declare const UserInterfaceDataContext: import("react").Context<UserInterfaceDataContextValue<unknown, unknown> | undefined>;
|
|
77
|
+
declare function useUserInterfaceData<T, A>(): UserInterfaceDataContextValue<T, A>;
|
|
78
|
+
export { useUserInterfaceData, UserInterfaceDataContext };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
// The actual context; we use `any` internally, but types are enforced in the hook
|
|
3
|
+
const UserInterfaceDataContext = createContext(undefined);
|
|
4
|
+
function useUserInterfaceData() {
|
|
5
|
+
const ctx = useContext(UserInterfaceDataContext);
|
|
6
|
+
if (!ctx) {
|
|
7
|
+
throw new Error('useUserInterfaceData must be used inside a UserInterfaceWrapper');
|
|
8
|
+
}
|
|
9
|
+
return ctx; // generic cast
|
|
10
|
+
}
|
|
11
|
+
export { useUserInterfaceData, UserInterfaceDataContext };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type UserInterfaceLocale = {
|
|
2
|
+
locale: string;
|
|
3
|
+
};
|
|
4
|
+
export declare const UserInterfaceLocaleContext: import("react").Context<UserInterfaceLocale | undefined>;
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the current locale in a user interface component.
|
|
7
|
+
* The locale is provided by the dev server based on the game's
|
|
8
|
+
* supported locales.
|
|
9
|
+
*
|
|
10
|
+
* @returns Current locale object with locale string
|
|
11
|
+
* @throws Error if used outside UserInterfaceWrapper
|
|
12
|
+
*/
|
|
13
|
+
export declare const useUserInterfaceLocale: () => UserInterfaceLocale;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRequiredContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createRequiredContext({
|
|
3
|
+
hookName: 'useUserInterfaceLocale',
|
|
4
|
+
wrapperName: 'UserInterfaceWrapper',
|
|
5
|
+
});
|
|
6
|
+
export const UserInterfaceLocaleContext = Context;
|
|
7
|
+
/**
|
|
8
|
+
* Hook to access the current locale in a user interface component.
|
|
9
|
+
* The locale is provided by the dev server based on the game's
|
|
10
|
+
* supported locales.
|
|
11
|
+
*
|
|
12
|
+
* @returns Current locale object with locale string
|
|
13
|
+
* @throws Error if used outside UserInterfaceWrapper
|
|
14
|
+
*/
|
|
15
|
+
export const useUserInterfaceLocale = useValue;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TeamInfo } from './SessionUserInterfaceTeamsContext.js';
|
|
2
|
+
export declare const UserInterfaceOwnTeamContext: import("react").Context<TeamInfo | null>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook returning the team whose surface this user interface is rendering.
|
|
5
|
+
*
|
|
6
|
+
* Distinct from {@link ./UserInterfaceTeamsContext.useUserInterfaceTeams}, which
|
|
7
|
+
* lists *every* team in the session with no marker of which one is the caller's.
|
|
8
|
+
*
|
|
9
|
+
* Before #332 the only route to own-team identity was
|
|
10
|
+
* `useUserInterfaceParticipant()?.teamId`, which #319 made `null` for an
|
|
11
|
+
* observing facilitator. A player UI that needed its own `teamId` — to split a
|
|
12
|
+
* `useUserInterfaceCrossTeamData()` result into 'mine' and 'theirs', to label a board, or to
|
|
13
|
+
* key a write — therefore worked when played and broke when observed. The host
|
|
14
|
+
* always knows which team's surface it mounted, so it now says so directly and
|
|
15
|
+
* the value is present for participants and observers alike.
|
|
16
|
+
*
|
|
17
|
+
* Returns `null` only when the host supplies neither an own team nor a
|
|
18
|
+
* participant to derive one from, which in practice means an observer on a host
|
|
19
|
+
* that predates this message. Guard for it if you target such a host; against
|
|
20
|
+
* the dev server and any runtime implementing the current protocol it is always
|
|
21
|
+
* populated on a player surface.
|
|
22
|
+
*
|
|
23
|
+
* @returns The caller's own team, or `null` when the host does not supply one
|
|
24
|
+
*/
|
|
25
|
+
export declare const useUserInterfaceOwnTeam: () => TeamInfo | null;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createDefaultedContext(null);
|
|
3
|
+
export const UserInterfaceOwnTeamContext = Context;
|
|
4
|
+
/**
|
|
5
|
+
* Hook returning the team whose surface this user interface is rendering.
|
|
6
|
+
*
|
|
7
|
+
* Distinct from {@link ./UserInterfaceTeamsContext.useUserInterfaceTeams}, which
|
|
8
|
+
* lists *every* team in the session with no marker of which one is the caller's.
|
|
9
|
+
*
|
|
10
|
+
* Before #332 the only route to own-team identity was
|
|
11
|
+
* `useUserInterfaceParticipant()?.teamId`, which #319 made `null` for an
|
|
12
|
+
* observing facilitator. A player UI that needed its own `teamId` — to split a
|
|
13
|
+
* `useUserInterfaceCrossTeamData()` result into 'mine' and 'theirs', to label a board, or to
|
|
14
|
+
* key a write — therefore worked when played and broke when observed. The host
|
|
15
|
+
* always knows which team's surface it mounted, so it now says so directly and
|
|
16
|
+
* the value is present for participants and observers alike.
|
|
17
|
+
*
|
|
18
|
+
* Returns `null` only when the host supplies neither an own team nor a
|
|
19
|
+
* participant to derive one from, which in practice means an observer on a host
|
|
20
|
+
* that predates this message. Guard for it if you target such a host; against
|
|
21
|
+
* the dev server and any runtime implementing the current protocol it is always
|
|
22
|
+
* populated on a player surface.
|
|
23
|
+
*
|
|
24
|
+
* @returns The caller's own team, or `null` when the host does not supply one
|
|
25
|
+
*/
|
|
26
|
+
export const useUserInterfaceOwnTeam = useValue;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How to join *this* surface's team.
|
|
3
|
+
*
|
|
4
|
+
* Every player surface receives this, participants and observers alike, so a
|
|
5
|
+
* lobby screen or a tablet left on a table can draw a join code without the
|
|
6
|
+
* facilitator's surface being the only place the link exists.
|
|
7
|
+
*
|
|
8
|
+
* It is deliberately not the facilitator's `TeamLinks`. That type lists every
|
|
9
|
+
* team and carries `observeUrl`, and both belong to the session surface alone.
|
|
10
|
+
* This one names no team because there is nothing to name: it is the team whose
|
|
11
|
+
* surface is rendering.
|
|
12
|
+
*
|
|
13
|
+
* The session PIN is not here and never travels to a player surface. A join URL
|
|
14
|
+
* alone admits nobody to a session that requires one, so what a player screen
|
|
15
|
+
* can give away is bounded by whether the operator set a PIN.
|
|
16
|
+
*/
|
|
17
|
+
export type OwnTeamJoinLink = {
|
|
18
|
+
/**
|
|
19
|
+
* The join URL to render.
|
|
20
|
+
*
|
|
21
|
+
* A host may have several forms of the same link (a shortened one, a
|
|
22
|
+
* longer one on another domain, a canonical one carrying opaque ids), and
|
|
23
|
+
* choosing between them is the host's business, exactly as it is for the
|
|
24
|
+
* facilitator's copy. It sends the form it wants used, and it may send a
|
|
25
|
+
* player surface a different form than it sends the facilitator. Encode
|
|
26
|
+
* *this* one in a QR code: the host chose the short form because a denser
|
|
27
|
+
* code is harder to scan across a table.
|
|
28
|
+
*/
|
|
29
|
+
joinUrl: string;
|
|
30
|
+
/**
|
|
31
|
+
* An alternative for the one failure a game can help with: some networks
|
|
32
|
+
* block URL shorteners. On a facilitator surface the person who discovers
|
|
33
|
+
* that is standing right there; on a kiosk it is a walk-up with nobody to
|
|
34
|
+
* ask, so offer a way through rather than a dead code. Absent when the host
|
|
35
|
+
* has no distinct alternative.
|
|
36
|
+
*
|
|
37
|
+
* Show it on request rather than beside `joinUrl` with equal weight. Two
|
|
38
|
+
* URLs on a lobby card is worse than one.
|
|
39
|
+
*/
|
|
40
|
+
fallbackJoinUrl?: string;
|
|
41
|
+
};
|
|
42
|
+
export declare const UserInterfaceOwnTeamJoinLinkContext: import("react").Context<OwnTeamJoinLink | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Hook returning how to join this surface's own team.
|
|
45
|
+
*
|
|
46
|
+
* Does not gate first paint, so it is `null` until the host delivers it. Render
|
|
47
|
+
* a placeholder for that first frame rather than assuming a link exists, and
|
|
48
|
+
* keep rendering one on a host that never sends it.
|
|
49
|
+
*
|
|
50
|
+
* @returns The own team's join link, or `null` before it arrives
|
|
51
|
+
*/
|
|
52
|
+
export declare const useUserInterfaceOwnTeamJoinLink: () => OwnTeamJoinLink | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createDefaultedContext(null);
|
|
3
|
+
export const UserInterfaceOwnTeamJoinLinkContext = Context;
|
|
4
|
+
/**
|
|
5
|
+
* Hook returning how to join this surface's own team.
|
|
6
|
+
*
|
|
7
|
+
* Does not gate first paint, so it is `null` until the host delivers it. Render
|
|
8
|
+
* a placeholder for that first frame rather than assuming a link exists, and
|
|
9
|
+
* keep rendering one on a host that never sends it.
|
|
10
|
+
*
|
|
11
|
+
* @returns The own team's join link, or `null` before it arrives
|
|
12
|
+
*/
|
|
13
|
+
export const useUserInterfaceOwnTeamJoinLink = useValue;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Participant } from '../build/callbacks.js';
|
|
2
|
+
export declare const UserInterfaceParticipantContext: import("react").Context<Participant | null | undefined>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access the current participant in a user interface component.
|
|
5
|
+
* The participant is provided by the platform and contains information about
|
|
6
|
+
* the person currently viewing this UI.
|
|
7
|
+
*
|
|
8
|
+
* Returns `null` when the surface is being observed rather than played (see
|
|
9
|
+
* {@link ./UserInterfaceViewerRoleContext.useUserInterfaceViewerRole}): an observer is a
|
|
10
|
+
* facilitator watching the team without joining, so there is no caller
|
|
11
|
+
* identity. Guard for `null` before reading its fields.
|
|
12
|
+
*
|
|
13
|
+
* @returns Current participant object, or `null` when observing
|
|
14
|
+
* @throws Error if used outside UserInterfaceWrapper
|
|
15
|
+
*/
|
|
16
|
+
export declare const useUserInterfaceParticipant: () => Participant | null;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createRequiredContext } from './internal/createContexts.js';
|
|
2
|
+
// The provided value is `Participant | null`: a real identity for
|
|
3
|
+
// a participant, `null` for an observer (who has no caller identity). The
|
|
4
|
+
// `undefined` sentinel is reserved for "read outside the wrapper", so the hook
|
|
5
|
+
// still throws on misuse while returning `null` legitimately under observation.
|
|
6
|
+
const { Context, useValue } = createRequiredContext({
|
|
7
|
+
hookName: 'useUserInterfaceParticipant',
|
|
8
|
+
wrapperName: 'UserInterfaceWrapper',
|
|
9
|
+
});
|
|
10
|
+
export const UserInterfaceParticipantContext = Context;
|
|
11
|
+
/**
|
|
12
|
+
* Hook to access the current participant in a user interface component.
|
|
13
|
+
* The participant is provided by the platform and contains information about
|
|
14
|
+
* the person currently viewing this UI.
|
|
15
|
+
*
|
|
16
|
+
* Returns `null` when the surface is being observed rather than played (see
|
|
17
|
+
* {@link ./UserInterfaceViewerRoleContext.useUserInterfaceViewerRole}): an observer is a
|
|
18
|
+
* facilitator watching the team without joining, so there is no caller
|
|
19
|
+
* identity. Guard for `null` before reading its fields.
|
|
20
|
+
*
|
|
21
|
+
* @returns Current participant object, or `null` when observing
|
|
22
|
+
* @throws Error if used outside UserInterfaceWrapper
|
|
23
|
+
*/
|
|
24
|
+
export const useUserInterfaceParticipant = useValue;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Participant } from '../build/callbacks.js';
|
|
2
|
+
export declare const UserInterfaceParticipantsContext: import("react").Context<Participant[]>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access the list of participants currently known for this team.
|
|
5
|
+
*
|
|
6
|
+
* Updates reactively as participants join or leave.
|
|
7
|
+
* The list includes the caller's own entry and every other participant on the
|
|
8
|
+
* same team.
|
|
9
|
+
*
|
|
10
|
+
* @returns Array of participants for this team
|
|
11
|
+
*/
|
|
12
|
+
export declare const useUserInterfaceParticipants: () => Participant[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createDefaultedContext([]);
|
|
3
|
+
export const UserInterfaceParticipantsContext = Context;
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access the list of participants currently known for this team.
|
|
6
|
+
*
|
|
7
|
+
* Updates reactively as participants join or leave.
|
|
8
|
+
* The list includes the caller's own entry and every other participant on the
|
|
9
|
+
* same team.
|
|
10
|
+
*
|
|
11
|
+
* @returns Array of participants for this team
|
|
12
|
+
*/
|
|
13
|
+
export const useUserInterfaceParticipants = useValue;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RunKind } from '../build/signatures.js';
|
|
2
|
+
export type { RunKind };
|
|
3
|
+
export declare const UserInterfaceRunKindContext: import("react").Context<RunKind>;
|
|
4
|
+
/**
|
|
5
|
+
* Hook returning whether this surface belongs to the game being played or to a
|
|
6
|
+
* walkthrough beside it (§5.7).
|
|
7
|
+
*
|
|
8
|
+
* A walkthrough is a solo run of something built for a group: one team, one
|
|
9
|
+
* participant, from tick 0, isolated from the session it sits beside. Use this
|
|
10
|
+
* to fill in the social context that is genuinely absent — rival teams on a
|
|
11
|
+
* leaderboard, teammates in a presence list — and to hide anything that would
|
|
12
|
+
* spoil the real run. Do not use it to change how the surface plays: the
|
|
13
|
+
* walkthrough exists to demonstrate the game, and one that behaves differently
|
|
14
|
+
* demonstrates a different game.
|
|
15
|
+
*
|
|
16
|
+
* The value the engine reads is the same one this returns, and neither changes
|
|
17
|
+
* for the life of the run, so a decision taken here cannot disagree with one
|
|
18
|
+
* taken in logic.
|
|
19
|
+
*
|
|
20
|
+
* Always present, defaulting to `'session'` so a host that predates
|
|
21
|
+
* walkthroughs (and never sends `setRunKind`) reads the case every existing
|
|
22
|
+
* game already behaves correctly on.
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* const runKind = useRunKind();
|
|
26
|
+
* const rivals = runKind === 'walkthrough' ? demonstrationRivals : data.market.rivals;
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @returns The kind of run this surface belongs to
|
|
30
|
+
*/
|
|
31
|
+
export declare const useRunKind: () => RunKind;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createDefaultedContext('session');
|
|
3
|
+
export const UserInterfaceRunKindContext = Context;
|
|
4
|
+
/**
|
|
5
|
+
* Hook returning whether this surface belongs to the game being played or to a
|
|
6
|
+
* walkthrough beside it (§5.7).
|
|
7
|
+
*
|
|
8
|
+
* A walkthrough is a solo run of something built for a group: one team, one
|
|
9
|
+
* participant, from tick 0, isolated from the session it sits beside. Use this
|
|
10
|
+
* to fill in the social context that is genuinely absent — rival teams on a
|
|
11
|
+
* leaderboard, teammates in a presence list — and to hide anything that would
|
|
12
|
+
* spoil the real run. Do not use it to change how the surface plays: the
|
|
13
|
+
* walkthrough exists to demonstrate the game, and one that behaves differently
|
|
14
|
+
* demonstrates a different game.
|
|
15
|
+
*
|
|
16
|
+
* The value the engine reads is the same one this returns, and neither changes
|
|
17
|
+
* for the life of the run, so a decision taken here cannot disagree with one
|
|
18
|
+
* taken in logic.
|
|
19
|
+
*
|
|
20
|
+
* Always present, defaulting to `'session'` so a host that predates
|
|
21
|
+
* walkthroughs (and never sends `setRunKind`) reads the case every existing
|
|
22
|
+
* game already behaves correctly on.
|
|
23
|
+
*
|
|
24
|
+
* ```tsx
|
|
25
|
+
* const runKind = useRunKind();
|
|
26
|
+
* const rivals = runKind === 'walkthrough' ? demonstrationRivals : data.market.rivals;
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @returns The kind of run this surface belongs to
|
|
30
|
+
*/
|
|
31
|
+
export const useRunKind = useValue;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { TeamInfo } from './SessionUserInterfaceTeamsContext.js';
|
|
2
|
+
export declare const UserInterfaceTeamsContext: import("react").Context<TeamInfo[]>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access basic metadata about all teams in the session.
|
|
5
|
+
*
|
|
6
|
+
* Each entry contains the team's identifier and display name. This gives
|
|
7
|
+
* player UIs awareness of the broader session without exposing other teams'
|
|
8
|
+
* game state.
|
|
9
|
+
*
|
|
10
|
+
* @returns Array of team info objects
|
|
11
|
+
*/
|
|
12
|
+
export declare const useUserInterfaceTeams: () => TeamInfo[];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createDefaultedContext([]);
|
|
3
|
+
export const UserInterfaceTeamsContext = Context;
|
|
4
|
+
/**
|
|
5
|
+
* Hook to access basic metadata about all teams in the session.
|
|
6
|
+
*
|
|
7
|
+
* Each entry contains the team's identifier and display name. This gives
|
|
8
|
+
* player UIs awareness of the broader session without exposing other teams'
|
|
9
|
+
* game state.
|
|
10
|
+
*
|
|
11
|
+
* @returns Array of team info objects
|
|
12
|
+
*/
|
|
13
|
+
export const useUserInterfaceTeams = useValue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type SurfaceModeColors } from './internal/createContexts.js';
|
|
2
|
+
export type UserInterfaceModeColors = SurfaceModeColors;
|
|
3
|
+
export type UserInterfaceTheme = {
|
|
4
|
+
mode: 'dark' | 'light';
|
|
5
|
+
dark: UserInterfaceModeColors;
|
|
6
|
+
light: UserInterfaceModeColors;
|
|
7
|
+
};
|
|
8
|
+
export declare const UserInterfaceThemeContext: import("react").Context<UserInterfaceTheme | undefined>;
|
|
9
|
+
export declare const useUserInterfaceTheme: () => UserInterfaceTheme;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createRequiredContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createRequiredContext({
|
|
3
|
+
hookName: 'useUserInterfaceTheme',
|
|
4
|
+
wrapperName: 'UserInterfaceWrapper',
|
|
5
|
+
});
|
|
6
|
+
export const UserInterfaceThemeContext = Context;
|
|
7
|
+
export const useUserInterfaceTheme = useValue;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { createRequiredContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createRequiredContext({
|
|
3
|
+
hookName: 'useUserInterfaceThemePreference',
|
|
4
|
+
wrapperName: 'UserInterfaceWrapper',
|
|
5
|
+
});
|
|
6
|
+
export const UserInterfaceThemePreferenceContext = Context;
|
|
7
|
+
export const useUserInterfaceThemePreference = useValue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TimerState } from '../build/timer.js';
|
|
2
|
+
export declare const UserInterfaceTimerContext: import("react").Context<TimerState>;
|
|
3
|
+
/**
|
|
4
|
+
* Hook to access the host's automatic tick timer state from inside a user
|
|
5
|
+
* interface component. Always returns a value — when `enabled` is false,
|
|
6
|
+
* no countdown should be displayed.
|
|
7
|
+
*
|
|
8
|
+
* @returns Current timer snapshot
|
|
9
|
+
*/
|
|
10
|
+
export declare const useUserInterfaceTimer: () => TimerState;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
import { DEFAULT_SURFACE_TIMER } from './internal/surface-timer.js';
|
|
3
|
+
const { Context, useValue } = createDefaultedContext(DEFAULT_SURFACE_TIMER);
|
|
4
|
+
export const UserInterfaceTimerContext = Context;
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the host's automatic tick timer state from inside a user
|
|
7
|
+
* interface component. Always returns a value — when `enabled` is false,
|
|
8
|
+
* no countdown should be displayed.
|
|
9
|
+
*
|
|
10
|
+
* @returns Current timer snapshot
|
|
11
|
+
*/
|
|
12
|
+
export const useUserInterfaceTimer = useValue;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ValidationRejection } from '../build/validators.js';
|
|
2
|
+
/**
|
|
3
|
+
* Value exposed to consumers of {@link useUserInterfaceValidationRejections}.
|
|
4
|
+
*
|
|
5
|
+
* `rejections` is the list of `{ validatorIdentifier, message }` records from
|
|
6
|
+
* the most recent UI mutation the host gated as invalid. The runtime returns
|
|
7
|
+
* every rejection on a single submission (form-style, not short-circuit), so
|
|
8
|
+
* consumers always render the full list rather than a single message.
|
|
9
|
+
*
|
|
10
|
+
* `clearRejections` empties the buffer — call it after rendering the messages
|
|
11
|
+
* (e.g. when the user dismisses a toast, or when the form value changes).
|
|
12
|
+
*/
|
|
13
|
+
export interface UserInterfaceValidationContextValue {
|
|
14
|
+
rejections: ValidationRejection[];
|
|
15
|
+
clearRejections: () => void;
|
|
16
|
+
}
|
|
17
|
+
export declare const UserInterfaceValidationContext: import("react").Context<UserInterfaceValidationContextValue | undefined>;
|
|
18
|
+
/**
|
|
19
|
+
* Subscribe to validator rejections from the host. Rejections are surfaced
|
|
20
|
+
* when a UI-submitted mutation (via `setData`) violates one or more
|
|
21
|
+
* validators declared in the game (§15 of the SDK specification). They are
|
|
22
|
+
* delivered as a single batch per submission; the runtime collects every
|
|
23
|
+
* failing validator's verdict and returns them together.
|
|
24
|
+
*/
|
|
25
|
+
export declare const useUserInterfaceValidationRejections: () => UserInterfaceValidationContextValue;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createRequiredContext } from './internal/createContexts.js';
|
|
2
|
+
const { Context, useValue } = createRequiredContext({
|
|
3
|
+
hookName: 'useUserInterfaceValidationRejections',
|
|
4
|
+
wrapperName: 'UserInterfaceWrapper',
|
|
5
|
+
});
|
|
6
|
+
export const UserInterfaceValidationContext = Context;
|
|
7
|
+
/**
|
|
8
|
+
* Subscribe to validator rejections from the host. Rejections are surfaced
|
|
9
|
+
* when a UI-submitted mutation (via `setData`) violates one or more
|
|
10
|
+
* validators declared in the game (§15 of the SDK specification). They are
|
|
11
|
+
* delivered as a single batch per submission; the runtime collects every
|
|
12
|
+
* failing validator's verdict and returns them together.
|
|
13
|
+
*/
|
|
14
|
+
export const useUserInterfaceValidationRejections = useValue;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ViewerRole } from '../build/signatures.js';
|
|
2
|
+
export type { ViewerRole };
|
|
3
|
+
export declare const UserInterfaceViewerRoleContext: import("react").Context<ViewerRole>;
|
|
4
|
+
/**
|
|
5
|
+
* Hook returning whether the current viewer is a `'participant'` or an
|
|
6
|
+
* `'observer'`. Use it to adapt a player or shell UI for observation — for
|
|
7
|
+
* example to show a debrief overlay, reveal otherwise-hidden state, or gate a
|
|
8
|
+
* genuinely read-only view. When it returns `'observer'`,
|
|
9
|
+
* {@link ./UserInterfaceParticipantContext.useUserInterfaceParticipant}
|
|
10
|
+
* returns `null`.
|
|
11
|
+
*
|
|
12
|
+
* @returns The current viewer role
|
|
13
|
+
*/
|
|
14
|
+
export declare const useUserInterfaceViewerRole: () => ViewerRole;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createDefaultedContext } from './internal/createContexts.js';
|
|
2
|
+
// Always present, defaulting to 'participant' so a host that never sends
|
|
3
|
+
// `setViewerRole` reads the safe common case. Delivered to player and shell
|
|
4
|
+
// user interfaces only; the facilitator surfaces are never observed.
|
|
5
|
+
const { Context, useValue } = createDefaultedContext('participant');
|
|
6
|
+
export const UserInterfaceViewerRoleContext = Context;
|
|
7
|
+
/**
|
|
8
|
+
* Hook returning whether the current viewer is a `'participant'` or an
|
|
9
|
+
* `'observer'`. Use it to adapt a player or shell UI for observation — for
|
|
10
|
+
* example to show a debrief overlay, reveal otherwise-hidden state, or gate a
|
|
11
|
+
* genuinely read-only view. When it returns `'observer'`,
|
|
12
|
+
* {@link ./UserInterfaceParticipantContext.useUserInterfaceParticipant}
|
|
13
|
+
* returns `null`.
|
|
14
|
+
*
|
|
15
|
+
* @returns The current viewer role
|
|
16
|
+
*/
|
|
17
|
+
export const useUserInterfaceViewerRole = useValue;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
interface UserInterfaceWrapperProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
fallback?: ReactNode;
|
|
5
|
+
targetWindow?: Window;
|
|
6
|
+
}
|
|
7
|
+
declare function UserInterfaceWrapper({ children, fallback, targetWindow, }: UserInterfaceWrapperProps): import("react").JSX.Element;
|
|
8
|
+
export default UserInterfaceWrapper;
|