scorezilla 0.3.1 → 0.5.0
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/API.md +21 -11
- package/CHANGELOG.md +41 -0
- package/README.md +26 -0
- package/dist/errors-DuRShuw9.d.cts +170 -0
- package/dist/errors-maldlTY-.d.ts +170 -0
- package/dist/headless.cjs +882 -0
- package/dist/headless.cjs.map +1 -0
- package/dist/headless.d.cts +59 -0
- package/dist/headless.d.ts +59 -0
- package/dist/headless.js +879 -0
- package/dist/headless.js.map +1 -0
- package/dist/index.cjs +16 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -13
- package/dist/index.d.ts +20 -13
- package/dist/index.js +16 -13
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +4 -2
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +6 -3
- package/dist/server.d.ts +6 -3
- package/dist/server.js +4 -2
- package/dist/server.js.map +1 -1
- package/dist/{errors-CWTmormh.d.cts → types-C6VO4OWP.d.cts} +28 -171
- package/dist/{errors-CWTmormh.d.ts → types-C6VO4OWP.d.ts} +28 -171
- package/package.json +14 -1
|
@@ -160,6 +160,9 @@ interface RankedEntry {
|
|
|
160
160
|
/** Milliseconds since epoch. */
|
|
161
161
|
submittedAt: number;
|
|
162
162
|
metadata?: Record<string, unknown>;
|
|
163
|
+
/** The player's public display name, when they've set one. Absent on older
|
|
164
|
+
* entries and for players who submit without a name. */
|
|
165
|
+
name?: string;
|
|
163
166
|
}
|
|
164
167
|
/** Payload from `POST /v1/boards/:boardId/scores`. */
|
|
165
168
|
interface SubmitScoreResponse {
|
|
@@ -178,15 +181,36 @@ interface LeaderboardResponse {
|
|
|
178
181
|
limit: number;
|
|
179
182
|
entries: RankedEntry[];
|
|
180
183
|
}
|
|
181
|
-
/**
|
|
182
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Payload from `GET /v1/boards/:boardId/players/:playerId/rank`.
|
|
186
|
+
*
|
|
187
|
+
* Discriminated on `ranked`. "No entry yet" is a normal state, not an error:
|
|
188
|
+
* the API returns `200 { ranked: false }` (not a 404 — a 404 spammed an
|
|
189
|
+
* un-suppressable red console line for every benign "has this player scored?"
|
|
190
|
+
* check). A 404 is now reserved for a genuinely missing board.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* const r = await sz.getPlayerRank({ boardId, playerId });
|
|
195
|
+
* if (r.ranked) console.log(`Rank ${r.rank} of ${r.totalEntries}`);
|
|
196
|
+
* else console.log('No submission yet.');
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
type PlayerRankResponse = {
|
|
183
200
|
boardId: string;
|
|
184
201
|
playerId: string;
|
|
202
|
+
ranked: true;
|
|
185
203
|
rank: number;
|
|
186
204
|
score: number;
|
|
187
205
|
submittedAt: number;
|
|
188
206
|
totalEntries: number;
|
|
189
|
-
}
|
|
207
|
+
} | {
|
|
208
|
+
boardId: string;
|
|
209
|
+
playerId: string;
|
|
210
|
+
ranked: false;
|
|
211
|
+
rank: null;
|
|
212
|
+
score: null;
|
|
213
|
+
};
|
|
190
214
|
/** Payload from `GET /v1/boards/:boardId/players/:playerId/window`. */
|
|
191
215
|
interface WindowAroundResponse {
|
|
192
216
|
boardId: string;
|
|
@@ -196,171 +220,4 @@ interface WindowAroundResponse {
|
|
|
196
220
|
entries: RankedEntry[];
|
|
197
221
|
}
|
|
198
222
|
|
|
199
|
-
|
|
200
|
-
* SDK error type.
|
|
201
|
-
*
|
|
202
|
-
* Every non-2xx API response is normalized into a `ScorezillaError` instance
|
|
203
|
-
* by the transport layer. Network failures and timeouts surface as the same
|
|
204
|
-
* class (with `status: 0`) so callers have a single error type to catch.
|
|
205
|
-
*
|
|
206
|
-
* **Invariant — consumers MUST branch on `code` (and optionally `reason`),
|
|
207
|
-
* never on `message`.** The English-language `message` is for operator
|
|
208
|
-
* logging only and is explicitly **not** part of the SemVer contract; a
|
|
209
|
-
* minor release MAY reword any message. Machine logic that depends on
|
|
210
|
-
* message text will break silently across upgrades.
|
|
211
|
-
*/
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Options for {@link ScorezillaError.from}.
|
|
215
|
-
*
|
|
216
|
-
* The fields mirror what's available after a fetch round-trip: the HTTP
|
|
217
|
-
* status, the parsed JSON body (if any), the request ID from
|
|
218
|
-
* `X-Request-Id`, and an optional `cause` for the underlying
|
|
219
|
-
* network/abort error.
|
|
220
|
-
*/
|
|
221
|
-
interface ScorezillaErrorFromInit {
|
|
222
|
-
status: number;
|
|
223
|
-
body?: ApiError | undefined;
|
|
224
|
-
requestId?: string | undefined;
|
|
225
|
-
cause?: unknown;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Thrown by the SDK for every failure path — non-2xx responses, network
|
|
229
|
-
* errors, aborts, and timeouts.
|
|
230
|
-
*
|
|
231
|
-
* Cross-realm `instanceof` is guaranteed: the class sets `Error.prototype`
|
|
232
|
-
* explicitly so checks survive iframe / worker boundaries.
|
|
233
|
-
*
|
|
234
|
-
* @example
|
|
235
|
-
* ```ts
|
|
236
|
-
* try {
|
|
237
|
-
* await sz.submitScore({ boardId, playerId, score });
|
|
238
|
-
* } catch (e) {
|
|
239
|
-
* if (!(e instanceof ScorezillaError)) throw e;
|
|
240
|
-
*
|
|
241
|
-
* if (e.isRateLimited()) {
|
|
242
|
-
* await sleep((e.retryAfter ?? 30) * 1000);
|
|
243
|
-
* return retry();
|
|
244
|
-
* }
|
|
245
|
-
* if (e.code === 'out_of_bounds') {
|
|
246
|
-
* console.warn(`Score crosses ${e.reason} bound (limit ${e.bound})`);
|
|
247
|
-
* return;
|
|
248
|
-
* }
|
|
249
|
-
* if (e.isAuth()) throw new Error('SDK misconfigured — bad publicKey');
|
|
250
|
-
*
|
|
251
|
-
* // Anything else: surface to your reporter with requestId for support.
|
|
252
|
-
* console.error(`Scorezilla ${e.code} (${e.status}) — request ${e.requestId}`);
|
|
253
|
-
* throw e;
|
|
254
|
-
* }
|
|
255
|
-
* ```
|
|
256
|
-
*
|
|
257
|
-
* @since 0.1.0
|
|
258
|
-
* @stability stable
|
|
259
|
-
*/
|
|
260
|
-
declare class ScorezillaError extends Error {
|
|
261
|
-
/** HTTP status of the response, or {@link STATUS_NETWORK_ERROR} (0) for
|
|
262
|
-
* network / abort / timeout. */
|
|
263
|
-
readonly status: number;
|
|
264
|
-
/** Machine-stable error code from the API. Open union — see
|
|
265
|
-
* {@link ScorezillaErrorCode}. For network errors, this is `'network_error'`;
|
|
266
|
-
* for aborts, `'aborted'`; for timeouts, `'timeout'`. */
|
|
267
|
-
readonly code: ScorezillaErrorCode;
|
|
268
|
-
/** Sub-classifier — present on:
|
|
269
|
-
* - `out_of_bounds`: `'below_min' | 'above_max'`
|
|
270
|
-
* - `usage_cap_exceeded`: `'over_cap' | 'suspended'`
|
|
271
|
-
* and possibly other codes in future minor releases. */
|
|
272
|
-
readonly reason: OutOfBoundsReason | UsageCapReason | string | undefined;
|
|
273
|
-
/** Seconds — present on `rate_limited`. Honored by the transport's retry
|
|
274
|
-
* policy (Step 2.4). */
|
|
275
|
-
readonly retryAfter: number | undefined;
|
|
276
|
-
/** Server-issued request ID, lifted from the `X-Request-Id` response
|
|
277
|
-
* header. Pass this to support when filing bugs. */
|
|
278
|
-
readonly requestId: string | undefined;
|
|
279
|
-
/** The bound value crossed on `out_of_bounds`. */
|
|
280
|
-
readonly bound: number | undefined;
|
|
281
|
-
/** Which rate-limit layer fired on `rate_limited`. */
|
|
282
|
-
readonly layer: string | undefined;
|
|
283
|
-
/** Tenant's billing tier — present on `usage_cap_exceeded`. */
|
|
284
|
-
readonly tier: BillingTier | undefined;
|
|
285
|
-
/** The cap value crossed on `usage_cap_exceeded`. `0` indicates a
|
|
286
|
-
* suspended tenant. `undefined` on all other error codes. */
|
|
287
|
-
readonly cap: number | undefined;
|
|
288
|
-
/** The post-increment submit count on `usage_cap_exceeded`. Always
|
|
289
|
-
* `> cap` when `reason === 'over_cap'`. */
|
|
290
|
-
readonly count: number | undefined;
|
|
291
|
-
/** The period the count belongs to on `usage_cap_exceeded`, in `YYYY-MM`
|
|
292
|
-
* UTC form. */
|
|
293
|
-
readonly period: string | undefined;
|
|
294
|
-
/** ISO-8601 timestamp of midnight UTC on the 1st of the next month —
|
|
295
|
-
* the counter's natural reset point on `usage_cap_exceeded`. */
|
|
296
|
-
readonly resetsAt: string | undefined;
|
|
297
|
-
/** The underlying cause (e.g., a `TypeError: fetch failed`) for
|
|
298
|
-
* network/abort/timeout paths. `undefined` when the error came from a
|
|
299
|
-
* successfully-parsed API error body. */
|
|
300
|
-
readonly cause: unknown;
|
|
301
|
-
constructor(message: string, init: {
|
|
302
|
-
status: number;
|
|
303
|
-
code: ScorezillaErrorCode;
|
|
304
|
-
reason?: string | undefined;
|
|
305
|
-
retryAfter?: number | undefined;
|
|
306
|
-
requestId?: string | undefined;
|
|
307
|
-
bound?: number | undefined;
|
|
308
|
-
layer?: string | undefined;
|
|
309
|
-
tier?: BillingTier | undefined;
|
|
310
|
-
cap?: number | undefined;
|
|
311
|
-
count?: number | undefined;
|
|
312
|
-
period?: string | undefined;
|
|
313
|
-
resetsAt?: string | undefined;
|
|
314
|
-
cause?: unknown;
|
|
315
|
-
});
|
|
316
|
-
/** `true` when this error is a 429 / `rate_limited`. */
|
|
317
|
-
isRateLimited(): boolean;
|
|
318
|
-
/**
|
|
319
|
-
* `true` when this error is a 402 / `usage_cap_exceeded`. The tenant
|
|
320
|
-
* has either hit their tier's monthly submit cap (`reason ===
|
|
321
|
-
* 'over_cap'`) or is suspended (`reason === 'suspended'`).
|
|
322
|
-
*
|
|
323
|
-
* Consumers SHOULD NOT auto-retry on this error — the cap doesn't lift
|
|
324
|
-
* until `resetsAt`. Surface to the developer with an upgrade prompt
|
|
325
|
-
* (over_cap) or contact-support message (suspended).
|
|
326
|
-
*/
|
|
327
|
-
isUsageCapExceeded(): boolean;
|
|
328
|
-
/** `true` when this error is a 402 + reason 'suspended' (vs over-cap). */
|
|
329
|
-
isSuspended(): boolean;
|
|
330
|
-
/** `true` when this error is a 401 / `unauthorized` (or 403 / `forbidden`). */
|
|
331
|
-
isAuth(): boolean;
|
|
332
|
-
/** `true` when this error is a 404 / `not_found`. */
|
|
333
|
-
isNotFound(): boolean;
|
|
334
|
-
/** `true` when this error is a 422 / `out_of_bounds` (score below/above board limit). */
|
|
335
|
-
isOutOfBounds(): boolean;
|
|
336
|
-
/** `true` for the SDK's retryable conditions: pure network errors, 5xx, and
|
|
337
|
-
* 429. Deliberately excludes `timeout` and `aborted` — those are caller-
|
|
338
|
-
* observable terminal states, not transient. Aligned with `shouldRetryError`
|
|
339
|
-
* in `retry.ts` so a consumer mirroring the SDK's retry policy gets the
|
|
340
|
-
* same answer the transport does. */
|
|
341
|
-
isTransient(): boolean;
|
|
342
|
-
/** `true` when this error is a 409 / `conflict` (idempotency-key conflict
|
|
343
|
-
* on retry). */
|
|
344
|
-
isConflict(): boolean;
|
|
345
|
-
/**
|
|
346
|
-
* Build a `ScorezillaError` from a fetch round-trip outcome.
|
|
347
|
-
*
|
|
348
|
-
* Prefer this over `new ScorezillaError(...)` from the transport layer —
|
|
349
|
-
* it does the mapping from API response shape to error fields in one
|
|
350
|
-
* place, so future fields like `correlationId` get added once here.
|
|
351
|
-
*
|
|
352
|
-
* @param init - status, optional parsed body, optional requestId, optional cause
|
|
353
|
-
*/
|
|
354
|
-
static from(init: ScorezillaErrorFromInit): ScorezillaError;
|
|
355
|
-
/**
|
|
356
|
-
* Build a `ScorezillaError` for a transport-level failure (no HTTP
|
|
357
|
-
* response received): network error, abort, or timeout.
|
|
358
|
-
*/
|
|
359
|
-
static network(message: string, cause: unknown): ScorezillaError;
|
|
360
|
-
/** Build a `ScorezillaError` for an `AbortSignal`-triggered cancellation. */
|
|
361
|
-
static aborted(cause: unknown): ScorezillaError;
|
|
362
|
-
/** Build a `ScorezillaError` for a request that exceeded its timeout budget. */
|
|
363
|
-
static timeout(timeoutMs: number): ScorezillaError;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export { type ApiSuccess as A, type BaseConfig as B, type FetchImpl as F, type LeaderboardResponse as L, type OutOfBoundsReason as O, type PlayerRankResponse as P, type RankedEntry as R, type ScorezillaConfig as S, type WindowAroundResponse as W, type SubmitScoreResponse as a, type ApiError as b, type ApiResponse as c, type PublicKeyConfig as d, ScorezillaError as e, type ScorezillaErrorCode as f, type SecretKeyConfig as g };
|
|
223
|
+
export type { ApiError as A, BillingTier as B, FetchImpl as F, LeaderboardResponse as L, OutOfBoundsReason as O, PublicKeyConfig as P, RankedEntry as R, ScorezillaErrorCode as S, UsageCapReason as U, WindowAroundResponse as W, ScorezillaConfig as a, ApiSuccess as b, SubmitScoreResponse as c, PlayerRankResponse as d, ApiResponse as e, BaseConfig as f, SecretKeyConfig as g };
|
|
@@ -160,6 +160,9 @@ interface RankedEntry {
|
|
|
160
160
|
/** Milliseconds since epoch. */
|
|
161
161
|
submittedAt: number;
|
|
162
162
|
metadata?: Record<string, unknown>;
|
|
163
|
+
/** The player's public display name, when they've set one. Absent on older
|
|
164
|
+
* entries and for players who submit without a name. */
|
|
165
|
+
name?: string;
|
|
163
166
|
}
|
|
164
167
|
/** Payload from `POST /v1/boards/:boardId/scores`. */
|
|
165
168
|
interface SubmitScoreResponse {
|
|
@@ -178,15 +181,36 @@ interface LeaderboardResponse {
|
|
|
178
181
|
limit: number;
|
|
179
182
|
entries: RankedEntry[];
|
|
180
183
|
}
|
|
181
|
-
/**
|
|
182
|
-
|
|
184
|
+
/**
|
|
185
|
+
* Payload from `GET /v1/boards/:boardId/players/:playerId/rank`.
|
|
186
|
+
*
|
|
187
|
+
* Discriminated on `ranked`. "No entry yet" is a normal state, not an error:
|
|
188
|
+
* the API returns `200 { ranked: false }` (not a 404 — a 404 spammed an
|
|
189
|
+
* un-suppressable red console line for every benign "has this player scored?"
|
|
190
|
+
* check). A 404 is now reserved for a genuinely missing board.
|
|
191
|
+
*
|
|
192
|
+
* @example
|
|
193
|
+
* ```ts
|
|
194
|
+
* const r = await sz.getPlayerRank({ boardId, playerId });
|
|
195
|
+
* if (r.ranked) console.log(`Rank ${r.rank} of ${r.totalEntries}`);
|
|
196
|
+
* else console.log('No submission yet.');
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
199
|
+
type PlayerRankResponse = {
|
|
183
200
|
boardId: string;
|
|
184
201
|
playerId: string;
|
|
202
|
+
ranked: true;
|
|
185
203
|
rank: number;
|
|
186
204
|
score: number;
|
|
187
205
|
submittedAt: number;
|
|
188
206
|
totalEntries: number;
|
|
189
|
-
}
|
|
207
|
+
} | {
|
|
208
|
+
boardId: string;
|
|
209
|
+
playerId: string;
|
|
210
|
+
ranked: false;
|
|
211
|
+
rank: null;
|
|
212
|
+
score: null;
|
|
213
|
+
};
|
|
190
214
|
/** Payload from `GET /v1/boards/:boardId/players/:playerId/window`. */
|
|
191
215
|
interface WindowAroundResponse {
|
|
192
216
|
boardId: string;
|
|
@@ -196,171 +220,4 @@ interface WindowAroundResponse {
|
|
|
196
220
|
entries: RankedEntry[];
|
|
197
221
|
}
|
|
198
222
|
|
|
199
|
-
|
|
200
|
-
* SDK error type.
|
|
201
|
-
*
|
|
202
|
-
* Every non-2xx API response is normalized into a `ScorezillaError` instance
|
|
203
|
-
* by the transport layer. Network failures and timeouts surface as the same
|
|
204
|
-
* class (with `status: 0`) so callers have a single error type to catch.
|
|
205
|
-
*
|
|
206
|
-
* **Invariant — consumers MUST branch on `code` (and optionally `reason`),
|
|
207
|
-
* never on `message`.** The English-language `message` is for operator
|
|
208
|
-
* logging only and is explicitly **not** part of the SemVer contract; a
|
|
209
|
-
* minor release MAY reword any message. Machine logic that depends on
|
|
210
|
-
* message text will break silently across upgrades.
|
|
211
|
-
*/
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Options for {@link ScorezillaError.from}.
|
|
215
|
-
*
|
|
216
|
-
* The fields mirror what's available after a fetch round-trip: the HTTP
|
|
217
|
-
* status, the parsed JSON body (if any), the request ID from
|
|
218
|
-
* `X-Request-Id`, and an optional `cause` for the underlying
|
|
219
|
-
* network/abort error.
|
|
220
|
-
*/
|
|
221
|
-
interface ScorezillaErrorFromInit {
|
|
222
|
-
status: number;
|
|
223
|
-
body?: ApiError | undefined;
|
|
224
|
-
requestId?: string | undefined;
|
|
225
|
-
cause?: unknown;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Thrown by the SDK for every failure path — non-2xx responses, network
|
|
229
|
-
* errors, aborts, and timeouts.
|
|
230
|
-
*
|
|
231
|
-
* Cross-realm `instanceof` is guaranteed: the class sets `Error.prototype`
|
|
232
|
-
* explicitly so checks survive iframe / worker boundaries.
|
|
233
|
-
*
|
|
234
|
-
* @example
|
|
235
|
-
* ```ts
|
|
236
|
-
* try {
|
|
237
|
-
* await sz.submitScore({ boardId, playerId, score });
|
|
238
|
-
* } catch (e) {
|
|
239
|
-
* if (!(e instanceof ScorezillaError)) throw e;
|
|
240
|
-
*
|
|
241
|
-
* if (e.isRateLimited()) {
|
|
242
|
-
* await sleep((e.retryAfter ?? 30) * 1000);
|
|
243
|
-
* return retry();
|
|
244
|
-
* }
|
|
245
|
-
* if (e.code === 'out_of_bounds') {
|
|
246
|
-
* console.warn(`Score crosses ${e.reason} bound (limit ${e.bound})`);
|
|
247
|
-
* return;
|
|
248
|
-
* }
|
|
249
|
-
* if (e.isAuth()) throw new Error('SDK misconfigured — bad publicKey');
|
|
250
|
-
*
|
|
251
|
-
* // Anything else: surface to your reporter with requestId for support.
|
|
252
|
-
* console.error(`Scorezilla ${e.code} (${e.status}) — request ${e.requestId}`);
|
|
253
|
-
* throw e;
|
|
254
|
-
* }
|
|
255
|
-
* ```
|
|
256
|
-
*
|
|
257
|
-
* @since 0.1.0
|
|
258
|
-
* @stability stable
|
|
259
|
-
*/
|
|
260
|
-
declare class ScorezillaError extends Error {
|
|
261
|
-
/** HTTP status of the response, or {@link STATUS_NETWORK_ERROR} (0) for
|
|
262
|
-
* network / abort / timeout. */
|
|
263
|
-
readonly status: number;
|
|
264
|
-
/** Machine-stable error code from the API. Open union — see
|
|
265
|
-
* {@link ScorezillaErrorCode}. For network errors, this is `'network_error'`;
|
|
266
|
-
* for aborts, `'aborted'`; for timeouts, `'timeout'`. */
|
|
267
|
-
readonly code: ScorezillaErrorCode;
|
|
268
|
-
/** Sub-classifier — present on:
|
|
269
|
-
* - `out_of_bounds`: `'below_min' | 'above_max'`
|
|
270
|
-
* - `usage_cap_exceeded`: `'over_cap' | 'suspended'`
|
|
271
|
-
* and possibly other codes in future minor releases. */
|
|
272
|
-
readonly reason: OutOfBoundsReason | UsageCapReason | string | undefined;
|
|
273
|
-
/** Seconds — present on `rate_limited`. Honored by the transport's retry
|
|
274
|
-
* policy (Step 2.4). */
|
|
275
|
-
readonly retryAfter: number | undefined;
|
|
276
|
-
/** Server-issued request ID, lifted from the `X-Request-Id` response
|
|
277
|
-
* header. Pass this to support when filing bugs. */
|
|
278
|
-
readonly requestId: string | undefined;
|
|
279
|
-
/** The bound value crossed on `out_of_bounds`. */
|
|
280
|
-
readonly bound: number | undefined;
|
|
281
|
-
/** Which rate-limit layer fired on `rate_limited`. */
|
|
282
|
-
readonly layer: string | undefined;
|
|
283
|
-
/** Tenant's billing tier — present on `usage_cap_exceeded`. */
|
|
284
|
-
readonly tier: BillingTier | undefined;
|
|
285
|
-
/** The cap value crossed on `usage_cap_exceeded`. `0` indicates a
|
|
286
|
-
* suspended tenant. `undefined` on all other error codes. */
|
|
287
|
-
readonly cap: number | undefined;
|
|
288
|
-
/** The post-increment submit count on `usage_cap_exceeded`. Always
|
|
289
|
-
* `> cap` when `reason === 'over_cap'`. */
|
|
290
|
-
readonly count: number | undefined;
|
|
291
|
-
/** The period the count belongs to on `usage_cap_exceeded`, in `YYYY-MM`
|
|
292
|
-
* UTC form. */
|
|
293
|
-
readonly period: string | undefined;
|
|
294
|
-
/** ISO-8601 timestamp of midnight UTC on the 1st of the next month —
|
|
295
|
-
* the counter's natural reset point on `usage_cap_exceeded`. */
|
|
296
|
-
readonly resetsAt: string | undefined;
|
|
297
|
-
/** The underlying cause (e.g., a `TypeError: fetch failed`) for
|
|
298
|
-
* network/abort/timeout paths. `undefined` when the error came from a
|
|
299
|
-
* successfully-parsed API error body. */
|
|
300
|
-
readonly cause: unknown;
|
|
301
|
-
constructor(message: string, init: {
|
|
302
|
-
status: number;
|
|
303
|
-
code: ScorezillaErrorCode;
|
|
304
|
-
reason?: string | undefined;
|
|
305
|
-
retryAfter?: number | undefined;
|
|
306
|
-
requestId?: string | undefined;
|
|
307
|
-
bound?: number | undefined;
|
|
308
|
-
layer?: string | undefined;
|
|
309
|
-
tier?: BillingTier | undefined;
|
|
310
|
-
cap?: number | undefined;
|
|
311
|
-
count?: number | undefined;
|
|
312
|
-
period?: string | undefined;
|
|
313
|
-
resetsAt?: string | undefined;
|
|
314
|
-
cause?: unknown;
|
|
315
|
-
});
|
|
316
|
-
/** `true` when this error is a 429 / `rate_limited`. */
|
|
317
|
-
isRateLimited(): boolean;
|
|
318
|
-
/**
|
|
319
|
-
* `true` when this error is a 402 / `usage_cap_exceeded`. The tenant
|
|
320
|
-
* has either hit their tier's monthly submit cap (`reason ===
|
|
321
|
-
* 'over_cap'`) or is suspended (`reason === 'suspended'`).
|
|
322
|
-
*
|
|
323
|
-
* Consumers SHOULD NOT auto-retry on this error — the cap doesn't lift
|
|
324
|
-
* until `resetsAt`. Surface to the developer with an upgrade prompt
|
|
325
|
-
* (over_cap) or contact-support message (suspended).
|
|
326
|
-
*/
|
|
327
|
-
isUsageCapExceeded(): boolean;
|
|
328
|
-
/** `true` when this error is a 402 + reason 'suspended' (vs over-cap). */
|
|
329
|
-
isSuspended(): boolean;
|
|
330
|
-
/** `true` when this error is a 401 / `unauthorized` (or 403 / `forbidden`). */
|
|
331
|
-
isAuth(): boolean;
|
|
332
|
-
/** `true` when this error is a 404 / `not_found`. */
|
|
333
|
-
isNotFound(): boolean;
|
|
334
|
-
/** `true` when this error is a 422 / `out_of_bounds` (score below/above board limit). */
|
|
335
|
-
isOutOfBounds(): boolean;
|
|
336
|
-
/** `true` for the SDK's retryable conditions: pure network errors, 5xx, and
|
|
337
|
-
* 429. Deliberately excludes `timeout` and `aborted` — those are caller-
|
|
338
|
-
* observable terminal states, not transient. Aligned with `shouldRetryError`
|
|
339
|
-
* in `retry.ts` so a consumer mirroring the SDK's retry policy gets the
|
|
340
|
-
* same answer the transport does. */
|
|
341
|
-
isTransient(): boolean;
|
|
342
|
-
/** `true` when this error is a 409 / `conflict` (idempotency-key conflict
|
|
343
|
-
* on retry). */
|
|
344
|
-
isConflict(): boolean;
|
|
345
|
-
/**
|
|
346
|
-
* Build a `ScorezillaError` from a fetch round-trip outcome.
|
|
347
|
-
*
|
|
348
|
-
* Prefer this over `new ScorezillaError(...)` from the transport layer —
|
|
349
|
-
* it does the mapping from API response shape to error fields in one
|
|
350
|
-
* place, so future fields like `correlationId` get added once here.
|
|
351
|
-
*
|
|
352
|
-
* @param init - status, optional parsed body, optional requestId, optional cause
|
|
353
|
-
*/
|
|
354
|
-
static from(init: ScorezillaErrorFromInit): ScorezillaError;
|
|
355
|
-
/**
|
|
356
|
-
* Build a `ScorezillaError` for a transport-level failure (no HTTP
|
|
357
|
-
* response received): network error, abort, or timeout.
|
|
358
|
-
*/
|
|
359
|
-
static network(message: string, cause: unknown): ScorezillaError;
|
|
360
|
-
/** Build a `ScorezillaError` for an `AbortSignal`-triggered cancellation. */
|
|
361
|
-
static aborted(cause: unknown): ScorezillaError;
|
|
362
|
-
/** Build a `ScorezillaError` for a request that exceeded its timeout budget. */
|
|
363
|
-
static timeout(timeoutMs: number): ScorezillaError;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export { type ApiSuccess as A, type BaseConfig as B, type FetchImpl as F, type LeaderboardResponse as L, type OutOfBoundsReason as O, type PlayerRankResponse as P, type RankedEntry as R, type ScorezillaConfig as S, type WindowAroundResponse as W, type SubmitScoreResponse as a, type ApiError as b, type ApiResponse as c, type PublicKeyConfig as d, ScorezillaError as e, type ScorezillaErrorCode as f, type SecretKeyConfig as g };
|
|
223
|
+
export type { ApiError as A, BillingTier as B, FetchImpl as F, LeaderboardResponse as L, OutOfBoundsReason as O, PublicKeyConfig as P, RankedEntry as R, ScorezillaErrorCode as S, UsageCapReason as U, WindowAroundResponse as W, ScorezillaConfig as a, ApiSuccess as b, SubmitScoreResponse as c, PlayerRankResponse as d, ApiResponse as e, BaseConfig as f, SecretKeyConfig as g };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scorezilla",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -80,6 +80,16 @@
|
|
|
80
80
|
"default": "./dist/identity.cjs"
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
|
+
"./headless": {
|
|
84
|
+
"import": {
|
|
85
|
+
"types": "./dist/headless.d.ts",
|
|
86
|
+
"default": "./dist/headless.js"
|
|
87
|
+
},
|
|
88
|
+
"require": {
|
|
89
|
+
"types": "./dist/headless.d.cts",
|
|
90
|
+
"default": "./dist/headless.cjs"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
83
93
|
"./phaser": {
|
|
84
94
|
"import": {
|
|
85
95
|
"types": "./dist/phaser.d.ts",
|
|
@@ -105,6 +115,9 @@
|
|
|
105
115
|
],
|
|
106
116
|
"identity": [
|
|
107
117
|
"./dist/identity.d.ts"
|
|
118
|
+
],
|
|
119
|
+
"headless": [
|
|
120
|
+
"./dist/headless.d.ts"
|
|
108
121
|
]
|
|
109
122
|
}
|
|
110
123
|
},
|