scorezilla 0.2.0 → 0.3.0-next.1

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.
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Identity preset helpers — opinionated, selectable ways for your game to
3
+ * generate or fetch a `playerId` for score submission.
4
+ *
5
+ * Background: every Scorezilla score carries an opaque `playerId`. The SDK
6
+ * doesn't care whether it's a UUID, a nickname, an email, or a server
7
+ * session token. But _how_ your game decides on that value is a UX +
8
+ * privacy decision the team should make explicitly. These presets are the
9
+ * blessed patterns; pick one per integration.
10
+ *
11
+ * See ADR 0003 (MCP identity axis) for the design rationale:
12
+ * https://github.com/isco-tec/scorezilla/blob/main/docs/adr/0003-mcp-identity-axis.md
13
+ *
14
+ * @module scorezilla/identity
15
+ * @since 0.3.0
16
+ */
17
+ interface AnonymousPlayerOptions {
18
+ /** localStorage key under which the generated UUID is persisted. */
19
+ readonly storageKey: string;
20
+ }
21
+ interface PromptedPlayerOptions {
22
+ /** localStorage key under which the user-entered name is persisted. */
23
+ readonly storageKey: string;
24
+ /** Message shown in `window.prompt()` on first run. */
25
+ readonly prompt: string;
26
+ }
27
+ /**
28
+ * Identity handle returned by the storage-backed presets.
29
+ *
30
+ * `forget()` clears the persisted value from browser storage. It does
31
+ * **not** delete server-side score history for this player — to fully
32
+ * erase a player's data, call the admin "delete player" endpoint.
33
+ */
34
+ interface PlayerHandle {
35
+ readonly id: string;
36
+ readonly forget: () => void;
37
+ }
38
+ /**
39
+ * Marker returned by `useServerAuthoritative()` to signal that the
40
+ * game's backend (not the browser) owns the `playerId` via the
41
+ * HMAC-signed secure path (`scorezilla/server`).
42
+ */
43
+ interface ServerAuthoritativeMarker {
44
+ readonly source: 'server-authoritative';
45
+ }
46
+ /** OAuth providers selectable via {@link useAuthProvider}. */
47
+ type AuthProvider = 'google' | 'github';
48
+ /** Options for the Google provider (`provider: 'google'`). */
49
+ interface GoogleAuthProviderOptions {
50
+ readonly provider: 'google';
51
+ /**
52
+ * Your Google OAuth **client ID** (from the Google Cloud Console). The
53
+ * helper never bundles Scorezilla-owned credentials — you bring your own so
54
+ * revocation and consent stay under your control.
55
+ */
56
+ readonly clientId: string;
57
+ /** localStorage key under which the derived player id is persisted. */
58
+ readonly storageKey: string;
59
+ /**
60
+ * Let Google auto-select a returning account without an explicit tap
61
+ * (GIS `auto_select`). Defaults to `false`.
62
+ */
63
+ readonly autoSelect?: boolean;
64
+ }
65
+ /**
66
+ * Options for the GitHub provider (`provider: 'github'`).
67
+ *
68
+ * **Not available yet** — ships in `scorezilla@0.3.0-next.2`. GitHub OAuth
69
+ * cannot be completed securely in the browser alone (the token exchange needs
70
+ * a client secret and GitHub's token endpoint sends no CORS headers), so the
71
+ * GitHub provider will require a server-side token exchange (your backend or
72
+ * a Scorezilla Workers proxy). Calling it today rejects.
73
+ *
74
+ * @experimental The option fields below are provisional and will be finalized
75
+ * (e.g. `clientId` becoming required, plus a token-exchange-endpoint field)
76
+ * when the provider lands in `0.3.0-next.2` — before the `0.3.0` stable cut.
77
+ */
78
+ interface GitHubAuthProviderOptions {
79
+ readonly provider: 'github';
80
+ /** Reserved (provisional) — your GitHub OAuth app client ID. */
81
+ readonly clientId?: string;
82
+ /** Reserved (provisional) — localStorage key for the derived player id. */
83
+ readonly storageKey?: string;
84
+ }
85
+ /** Discriminated union of {@link useAuthProvider} options, keyed on `provider`. */
86
+ type AuthProviderOptions = GoogleAuthProviderOptions | GitHubAuthProviderOptions;
87
+ /** How an {@link AuthPlayerHandle}'s `id` was obtained on this call. */
88
+ type AuthIdSource = 'signed-in' | 'restored';
89
+ /**
90
+ * Handle returned by {@link useAuthProvider}. `id` is the opaque, stable
91
+ * player id derived from the provider account (e.g. `google:<sub>`).
92
+ * `signOut()` clears the persisted id and, where supported, disables the
93
+ * provider's auto sign-in. It does **not** delete server-side score history.
94
+ */
95
+ interface AuthPlayerHandle {
96
+ readonly id: string;
97
+ readonly provider: AuthProvider;
98
+ /**
99
+ * `'signed-in'` when the id came from a fresh provider sign-in during this
100
+ * call; `'restored'` when it was rehydrated from a prior session in
101
+ * `localStorage` with no provider interaction. A `'restored'` id is **not**
102
+ * a re-verified live session — see {@link useAuthProvider}.
103
+ */
104
+ readonly source: AuthIdSource;
105
+ readonly signOut: () => void;
106
+ }
107
+ /**
108
+ * Anonymous player identity. Generates an opaque UUID on first run and
109
+ * persists it in `localStorage` so the same browser keeps the same ID
110
+ * across page reloads.
111
+ *
112
+ * **Privacy.** Stores a randomly-generated UUID in browser localStorage;
113
+ * the value is sent to the API on every score submission and persisted
114
+ * indefinitely in the player's score-history rows. No PII is collected.
115
+ * `forget()` removes the localStorage entry; for full server-side erasure
116
+ * call the admin "delete player" endpoint.
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * import { Scorezilla } from 'scorezilla';
121
+ * import { useAnonymousPlayer } from 'scorezilla/identity';
122
+ *
123
+ * const player = useAnonymousPlayer({ storageKey: 'mygame:player' });
124
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
125
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
126
+ * ```
127
+ *
128
+ * @since 0.3.0
129
+ * @stability stable
130
+ */
131
+ declare function useAnonymousPlayer(options: AnonymousPlayerOptions): PlayerHandle;
132
+ /**
133
+ * Prompted player identity. On first run shows a `window.prompt()` asking
134
+ * the user for a name, then persists it in `localStorage` for subsequent
135
+ * visits. Returns `null` if there is no browser (SSR), no `window.prompt`,
136
+ * or if the user cancelled / entered an empty value.
137
+ *
138
+ * **Privacy.** The user-entered string is stored in browser localStorage,
139
+ * transmitted to the API on every score submission, and persisted
140
+ * indefinitely on the leaderboard. The persisted value is whatever the
141
+ * user typed — sanitize at the UI layer if you care. `forget()` clears
142
+ * local state but does NOT delete server-side history.
143
+ *
144
+ * **UX caveat.** `window.prompt()` blocks the main thread and looks
145
+ * dated in modern apps. For a polished flow, build your own inline form
146
+ * and pass the result to `submitScore` directly — the preset is here to
147
+ * cover quick prototypes and jam-style integrations.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { Scorezilla } from 'scorezilla';
152
+ * import { usePromptedPlayer } from 'scorezilla/identity';
153
+ *
154
+ * const player = usePromptedPlayer({
155
+ * storageKey: 'mygame:player',
156
+ * prompt: 'Enter a name for the leaderboard:',
157
+ * });
158
+ *
159
+ * if (player) {
160
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
161
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
162
+ * }
163
+ * ```
164
+ *
165
+ * @since 0.3.0
166
+ * @stability stable
167
+ */
168
+ declare function usePromptedPlayer(options: PromptedPlayerOptions): PlayerHandle | null;
169
+ /**
170
+ * Server-authoritative identity marker. Signals that the game's backend
171
+ * is responsible for the `playerId` via the HMAC-signed secure path
172
+ * (`scorezilla/server`). The browser SDK does no identity work — the
173
+ * server picks the value, signs the submission, and posts.
174
+ *
175
+ * The return value is a no-op marker; you don't pass it anywhere. It
176
+ * exists so MCP-returned snippets can emit a single line that
177
+ * unambiguously says "this game uses the secure path; identity is
178
+ * server-authoritative."
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * // Client (no identity helper needed):
183
+ * import { useServerAuthoritative } from 'scorezilla/identity';
184
+ * useServerAuthoritative();
185
+ *
186
+ * // Server (where the real work happens):
187
+ * import { Scorezilla } from 'scorezilla/server';
188
+ * const sz = new Scorezilla({ secretKey: process.env.SCOREZILLA_SECRET_KEY! });
189
+ * await sz.submitScore({ boardId, playerId: serverDerivedId, score });
190
+ * ```
191
+ *
192
+ * @since 0.3.0
193
+ * @stability stable
194
+ */
195
+ declare function useServerAuthoritative(): ServerAuthoritativeMarker;
196
+ /**
197
+ * OAuth-backed player identity. Signs the player in with the chosen provider
198
+ * and resolves a stable, opaque `playerId` derived from their account.
199
+ *
200
+ * Resolves to:
201
+ * - an {@link AuthPlayerHandle} on success — `handle.source` distinguishes a
202
+ * fresh sign-in (`'signed-in'`) from a `localStorage`-restored prior session
203
+ * (`'restored'`); or
204
+ * - `null` when the player **declines / dismisses** sign-in, or it can't be
205
+ * shown (no provider session, blocked cookies). "Didn't sign in" is not an
206
+ * error — fall back to another identity strategy.
207
+ *
208
+ * **Rejects** only on genuine failures: invalid arguments (`TypeError`), an
209
+ * unavailable provider, or the provider flow breaking (script load failure,
210
+ * malformed credential). Identity helpers throw plain `Error`/`TypeError` by
211
+ * design — NOT `ScorezillaError` — so the `scorezilla/identity` subpath stays
212
+ * dependency-free; don't `instanceof ScorezillaError` these.
213
+ *
214
+ * > Despite the `use*` name (shared with the other presets), this is a plain
215
+ * > async function, **not a React hook** — rules-of-hooks don't apply. The
216
+ * > `scorezilla/react` adapter exposes the React-bound surface separately.
217
+ *
218
+ * **Google** (stable since `0.3.0`) wraps Google Identity Services "One Tap".
219
+ * The derived id is `google:<sub>`. It's persisted in `localStorage` under
220
+ * `storageKey`, so returning visitors are recognized without signing in again
221
+ * (`handle.source === 'restored'`); `signOut()` clears it. The host page's CSP
222
+ * must allow `https://accounts.google.com` (`script-src`, plus `frame-src` /
223
+ * `connect-src` for One Tap).
224
+ *
225
+ * **GitHub** ships in `0.3.0-next.2` and currently rejects — see
226
+ * {@link GitHubAuthProviderOptions}.
227
+ *
228
+ * **Privacy.** Only the derived `sub`-based id is stored and transmitted (on
229
+ * score submission) — never the Google credential, email, or profile. The id
230
+ * is persisted in browser localStorage and stored indefinitely in the
231
+ * player's score-history rows. `signOut()` clears local state; for full
232
+ * server-side erasure call the admin "delete player" endpoint.
233
+ *
234
+ * **Bundle.** The Google provider is a separate module that tree-shakes out
235
+ * entirely for consumers who don't call `useAuthProvider` (the package is
236
+ * `sideEffects: false`; a size-limit gate verifies it). The Google Identity
237
+ * Services library itself is never bundled — it's loaded at runtime from
238
+ * `accounts.google.com` the first time sign-in runs.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * import { Scorezilla } from 'scorezilla';
243
+ * import { useAuthProvider } from 'scorezilla/identity';
244
+ *
245
+ * const player = await useAuthProvider({
246
+ * provider: 'google',
247
+ * clientId: 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com',
248
+ * storageKey: 'mygame:player',
249
+ * });
250
+ *
251
+ * if (player) {
252
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
253
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
254
+ * }
255
+ * ```
256
+ *
257
+ * @since 0.3.0
258
+ * @stability stable (google) · preview (github)
259
+ */
260
+ declare function useAuthProvider(options: AuthProviderOptions): Promise<AuthPlayerHandle | null>;
261
+
262
+ export { type AnonymousPlayerOptions, type AuthIdSource, type AuthPlayerHandle, type AuthProvider, type AuthProviderOptions, type GitHubAuthProviderOptions, type GoogleAuthProviderOptions, type PlayerHandle, type PromptedPlayerOptions, type ServerAuthoritativeMarker, useAnonymousPlayer, useAuthProvider, usePromptedPlayer, useServerAuthoritative };
@@ -0,0 +1,262 @@
1
+ /**
2
+ * Identity preset helpers — opinionated, selectable ways for your game to
3
+ * generate or fetch a `playerId` for score submission.
4
+ *
5
+ * Background: every Scorezilla score carries an opaque `playerId`. The SDK
6
+ * doesn't care whether it's a UUID, a nickname, an email, or a server
7
+ * session token. But _how_ your game decides on that value is a UX +
8
+ * privacy decision the team should make explicitly. These presets are the
9
+ * blessed patterns; pick one per integration.
10
+ *
11
+ * See ADR 0003 (MCP identity axis) for the design rationale:
12
+ * https://github.com/isco-tec/scorezilla/blob/main/docs/adr/0003-mcp-identity-axis.md
13
+ *
14
+ * @module scorezilla/identity
15
+ * @since 0.3.0
16
+ */
17
+ interface AnonymousPlayerOptions {
18
+ /** localStorage key under which the generated UUID is persisted. */
19
+ readonly storageKey: string;
20
+ }
21
+ interface PromptedPlayerOptions {
22
+ /** localStorage key under which the user-entered name is persisted. */
23
+ readonly storageKey: string;
24
+ /** Message shown in `window.prompt()` on first run. */
25
+ readonly prompt: string;
26
+ }
27
+ /**
28
+ * Identity handle returned by the storage-backed presets.
29
+ *
30
+ * `forget()` clears the persisted value from browser storage. It does
31
+ * **not** delete server-side score history for this player — to fully
32
+ * erase a player's data, call the admin "delete player" endpoint.
33
+ */
34
+ interface PlayerHandle {
35
+ readonly id: string;
36
+ readonly forget: () => void;
37
+ }
38
+ /**
39
+ * Marker returned by `useServerAuthoritative()` to signal that the
40
+ * game's backend (not the browser) owns the `playerId` via the
41
+ * HMAC-signed secure path (`scorezilla/server`).
42
+ */
43
+ interface ServerAuthoritativeMarker {
44
+ readonly source: 'server-authoritative';
45
+ }
46
+ /** OAuth providers selectable via {@link useAuthProvider}. */
47
+ type AuthProvider = 'google' | 'github';
48
+ /** Options for the Google provider (`provider: 'google'`). */
49
+ interface GoogleAuthProviderOptions {
50
+ readonly provider: 'google';
51
+ /**
52
+ * Your Google OAuth **client ID** (from the Google Cloud Console). The
53
+ * helper never bundles Scorezilla-owned credentials — you bring your own so
54
+ * revocation and consent stay under your control.
55
+ */
56
+ readonly clientId: string;
57
+ /** localStorage key under which the derived player id is persisted. */
58
+ readonly storageKey: string;
59
+ /**
60
+ * Let Google auto-select a returning account without an explicit tap
61
+ * (GIS `auto_select`). Defaults to `false`.
62
+ */
63
+ readonly autoSelect?: boolean;
64
+ }
65
+ /**
66
+ * Options for the GitHub provider (`provider: 'github'`).
67
+ *
68
+ * **Not available yet** — ships in `scorezilla@0.3.0-next.2`. GitHub OAuth
69
+ * cannot be completed securely in the browser alone (the token exchange needs
70
+ * a client secret and GitHub's token endpoint sends no CORS headers), so the
71
+ * GitHub provider will require a server-side token exchange (your backend or
72
+ * a Scorezilla Workers proxy). Calling it today rejects.
73
+ *
74
+ * @experimental The option fields below are provisional and will be finalized
75
+ * (e.g. `clientId` becoming required, plus a token-exchange-endpoint field)
76
+ * when the provider lands in `0.3.0-next.2` — before the `0.3.0` stable cut.
77
+ */
78
+ interface GitHubAuthProviderOptions {
79
+ readonly provider: 'github';
80
+ /** Reserved (provisional) — your GitHub OAuth app client ID. */
81
+ readonly clientId?: string;
82
+ /** Reserved (provisional) — localStorage key for the derived player id. */
83
+ readonly storageKey?: string;
84
+ }
85
+ /** Discriminated union of {@link useAuthProvider} options, keyed on `provider`. */
86
+ type AuthProviderOptions = GoogleAuthProviderOptions | GitHubAuthProviderOptions;
87
+ /** How an {@link AuthPlayerHandle}'s `id` was obtained on this call. */
88
+ type AuthIdSource = 'signed-in' | 'restored';
89
+ /**
90
+ * Handle returned by {@link useAuthProvider}. `id` is the opaque, stable
91
+ * player id derived from the provider account (e.g. `google:<sub>`).
92
+ * `signOut()` clears the persisted id and, where supported, disables the
93
+ * provider's auto sign-in. It does **not** delete server-side score history.
94
+ */
95
+ interface AuthPlayerHandle {
96
+ readonly id: string;
97
+ readonly provider: AuthProvider;
98
+ /**
99
+ * `'signed-in'` when the id came from a fresh provider sign-in during this
100
+ * call; `'restored'` when it was rehydrated from a prior session in
101
+ * `localStorage` with no provider interaction. A `'restored'` id is **not**
102
+ * a re-verified live session — see {@link useAuthProvider}.
103
+ */
104
+ readonly source: AuthIdSource;
105
+ readonly signOut: () => void;
106
+ }
107
+ /**
108
+ * Anonymous player identity. Generates an opaque UUID on first run and
109
+ * persists it in `localStorage` so the same browser keeps the same ID
110
+ * across page reloads.
111
+ *
112
+ * **Privacy.** Stores a randomly-generated UUID in browser localStorage;
113
+ * the value is sent to the API on every score submission and persisted
114
+ * indefinitely in the player's score-history rows. No PII is collected.
115
+ * `forget()` removes the localStorage entry; for full server-side erasure
116
+ * call the admin "delete player" endpoint.
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * import { Scorezilla } from 'scorezilla';
121
+ * import { useAnonymousPlayer } from 'scorezilla/identity';
122
+ *
123
+ * const player = useAnonymousPlayer({ storageKey: 'mygame:player' });
124
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
125
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
126
+ * ```
127
+ *
128
+ * @since 0.3.0
129
+ * @stability stable
130
+ */
131
+ declare function useAnonymousPlayer(options: AnonymousPlayerOptions): PlayerHandle;
132
+ /**
133
+ * Prompted player identity. On first run shows a `window.prompt()` asking
134
+ * the user for a name, then persists it in `localStorage` for subsequent
135
+ * visits. Returns `null` if there is no browser (SSR), no `window.prompt`,
136
+ * or if the user cancelled / entered an empty value.
137
+ *
138
+ * **Privacy.** The user-entered string is stored in browser localStorage,
139
+ * transmitted to the API on every score submission, and persisted
140
+ * indefinitely on the leaderboard. The persisted value is whatever the
141
+ * user typed — sanitize at the UI layer if you care. `forget()` clears
142
+ * local state but does NOT delete server-side history.
143
+ *
144
+ * **UX caveat.** `window.prompt()` blocks the main thread and looks
145
+ * dated in modern apps. For a polished flow, build your own inline form
146
+ * and pass the result to `submitScore` directly — the preset is here to
147
+ * cover quick prototypes and jam-style integrations.
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { Scorezilla } from 'scorezilla';
152
+ * import { usePromptedPlayer } from 'scorezilla/identity';
153
+ *
154
+ * const player = usePromptedPlayer({
155
+ * storageKey: 'mygame:player',
156
+ * prompt: 'Enter a name for the leaderboard:',
157
+ * });
158
+ *
159
+ * if (player) {
160
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
161
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
162
+ * }
163
+ * ```
164
+ *
165
+ * @since 0.3.0
166
+ * @stability stable
167
+ */
168
+ declare function usePromptedPlayer(options: PromptedPlayerOptions): PlayerHandle | null;
169
+ /**
170
+ * Server-authoritative identity marker. Signals that the game's backend
171
+ * is responsible for the `playerId` via the HMAC-signed secure path
172
+ * (`scorezilla/server`). The browser SDK does no identity work — the
173
+ * server picks the value, signs the submission, and posts.
174
+ *
175
+ * The return value is a no-op marker; you don't pass it anywhere. It
176
+ * exists so MCP-returned snippets can emit a single line that
177
+ * unambiguously says "this game uses the secure path; identity is
178
+ * server-authoritative."
179
+ *
180
+ * @example
181
+ * ```ts
182
+ * // Client (no identity helper needed):
183
+ * import { useServerAuthoritative } from 'scorezilla/identity';
184
+ * useServerAuthoritative();
185
+ *
186
+ * // Server (where the real work happens):
187
+ * import { Scorezilla } from 'scorezilla/server';
188
+ * const sz = new Scorezilla({ secretKey: process.env.SCOREZILLA_SECRET_KEY! });
189
+ * await sz.submitScore({ boardId, playerId: serverDerivedId, score });
190
+ * ```
191
+ *
192
+ * @since 0.3.0
193
+ * @stability stable
194
+ */
195
+ declare function useServerAuthoritative(): ServerAuthoritativeMarker;
196
+ /**
197
+ * OAuth-backed player identity. Signs the player in with the chosen provider
198
+ * and resolves a stable, opaque `playerId` derived from their account.
199
+ *
200
+ * Resolves to:
201
+ * - an {@link AuthPlayerHandle} on success — `handle.source` distinguishes a
202
+ * fresh sign-in (`'signed-in'`) from a `localStorage`-restored prior session
203
+ * (`'restored'`); or
204
+ * - `null` when the player **declines / dismisses** sign-in, or it can't be
205
+ * shown (no provider session, blocked cookies). "Didn't sign in" is not an
206
+ * error — fall back to another identity strategy.
207
+ *
208
+ * **Rejects** only on genuine failures: invalid arguments (`TypeError`), an
209
+ * unavailable provider, or the provider flow breaking (script load failure,
210
+ * malformed credential). Identity helpers throw plain `Error`/`TypeError` by
211
+ * design — NOT `ScorezillaError` — so the `scorezilla/identity` subpath stays
212
+ * dependency-free; don't `instanceof ScorezillaError` these.
213
+ *
214
+ * > Despite the `use*` name (shared with the other presets), this is a plain
215
+ * > async function, **not a React hook** — rules-of-hooks don't apply. The
216
+ * > `scorezilla/react` adapter exposes the React-bound surface separately.
217
+ *
218
+ * **Google** (stable since `0.3.0`) wraps Google Identity Services "One Tap".
219
+ * The derived id is `google:<sub>`. It's persisted in `localStorage` under
220
+ * `storageKey`, so returning visitors are recognized without signing in again
221
+ * (`handle.source === 'restored'`); `signOut()` clears it. The host page's CSP
222
+ * must allow `https://accounts.google.com` (`script-src`, plus `frame-src` /
223
+ * `connect-src` for One Tap).
224
+ *
225
+ * **GitHub** ships in `0.3.0-next.2` and currently rejects — see
226
+ * {@link GitHubAuthProviderOptions}.
227
+ *
228
+ * **Privacy.** Only the derived `sub`-based id is stored and transmitted (on
229
+ * score submission) — never the Google credential, email, or profile. The id
230
+ * is persisted in browser localStorage and stored indefinitely in the
231
+ * player's score-history rows. `signOut()` clears local state; for full
232
+ * server-side erasure call the admin "delete player" endpoint.
233
+ *
234
+ * **Bundle.** The Google provider is a separate module that tree-shakes out
235
+ * entirely for consumers who don't call `useAuthProvider` (the package is
236
+ * `sideEffects: false`; a size-limit gate verifies it). The Google Identity
237
+ * Services library itself is never bundled — it's loaded at runtime from
238
+ * `accounts.google.com` the first time sign-in runs.
239
+ *
240
+ * @example
241
+ * ```ts
242
+ * import { Scorezilla } from 'scorezilla';
243
+ * import { useAuthProvider } from 'scorezilla/identity';
244
+ *
245
+ * const player = await useAuthProvider({
246
+ * provider: 'google',
247
+ * clientId: 'YOUR_GOOGLE_CLIENT_ID.apps.googleusercontent.com',
248
+ * storageKey: 'mygame:player',
249
+ * });
250
+ *
251
+ * if (player) {
252
+ * const sz = new Scorezilla({ publicKey: 'pk_…' });
253
+ * await sz.submitScore({ boardId, playerId: player.id, score: 42 });
254
+ * }
255
+ * ```
256
+ *
257
+ * @since 0.3.0
258
+ * @stability stable (google) · preview (github)
259
+ */
260
+ declare function useAuthProvider(options: AuthProviderOptions): Promise<AuthPlayerHandle | null>;
261
+
262
+ export { type AnonymousPlayerOptions, type AuthIdSource, type AuthPlayerHandle, type AuthProvider, type AuthProviderOptions, type GitHubAuthProviderOptions, type GoogleAuthProviderOptions, type PlayerHandle, type PromptedPlayerOptions, type ServerAuthoritativeMarker, useAnonymousPlayer, useAuthProvider, usePromptedPlayer, useServerAuthoritative };