@genex-ai/embed-sdk 0.22.3 → 0.23.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/dist/{chunk-IFI2NYBC.js → chunk-CBR3BK66.js} +15 -3
- package/dist/index.d.ts +25 -3
- package/dist/index.js +1 -1
- package/dist/sentry.js +1 -1
- package/package.json +1 -1
|
@@ -298,7 +298,7 @@ var RETRY_FLAG = "genex:embed:retry";
|
|
|
298
298
|
var POPOVER_DISMISSED_FLAG = "genex:guest:popover-dismissed";
|
|
299
299
|
var LOCAL_AUTH_FLAG = "genex:embed:local-auth";
|
|
300
300
|
var PLAYER_ID_KEY = "genex:player";
|
|
301
|
-
var SDK_VERSION = "0.
|
|
301
|
+
var SDK_VERSION = "0.23.0";
|
|
302
302
|
var config2 = null;
|
|
303
303
|
var state = "pending";
|
|
304
304
|
var user = null;
|
|
@@ -548,12 +548,18 @@ function stateFetch(path, init = {}) {
|
|
|
548
548
|
keepalive: init.body !== void 0 && init.body.length <= KEEPALIVE_MAX_BYTES ? true : void 0
|
|
549
549
|
});
|
|
550
550
|
}
|
|
551
|
+
async function refusedAsStaging(res) {
|
|
552
|
+
if (res.status !== 403) return false;
|
|
553
|
+
const body = await res.json().catch(() => null);
|
|
554
|
+
return body?.error === "staging_no_save";
|
|
555
|
+
}
|
|
551
556
|
async function decodeSave(res) {
|
|
552
557
|
if (res.status === 409) {
|
|
553
558
|
const body2 = await res.json().catch(() => ({}));
|
|
554
559
|
return { saved: false, conflict: true, version: body2.version };
|
|
555
560
|
}
|
|
556
561
|
if (!res.ok) {
|
|
562
|
+
if (await refusedAsStaging(res)) return { saved: false, staging: true };
|
|
557
563
|
emit("error", { error: new Error(`genex state save failed (${res.status})`) });
|
|
558
564
|
return { saved: false };
|
|
559
565
|
}
|
|
@@ -566,7 +572,10 @@ async function loadPlayerState() {
|
|
|
566
572
|
return { data: hasPendingPlayerSave ? pendingPlayerSave : null, version: 0, guest: true };
|
|
567
573
|
}
|
|
568
574
|
const res = await stateFetch("/state/me");
|
|
569
|
-
if (!res.ok)
|
|
575
|
+
if (!res.ok) {
|
|
576
|
+
if (await refusedAsStaging(res)) return { data: null, version: 0, staging: true };
|
|
577
|
+
throw new Error(`genex load player state failed (${res.status})`);
|
|
578
|
+
}
|
|
570
579
|
const body = await res.json();
|
|
571
580
|
return { data: body.data, version: body.version };
|
|
572
581
|
}
|
|
@@ -589,7 +598,10 @@ async function loadWorldState() {
|
|
|
589
598
|
await ensurePlayer();
|
|
590
599
|
if (state === "guest") return { data: null, version: 0, guest: true };
|
|
591
600
|
const res = await stateFetch("/state");
|
|
592
|
-
if (!res.ok)
|
|
601
|
+
if (!res.ok) {
|
|
602
|
+
if (await refusedAsStaging(res)) return { data: null, version: 0, staging: true };
|
|
603
|
+
throw new Error(`genex load world state failed (${res.status})`);
|
|
604
|
+
}
|
|
593
605
|
const body = await res.json();
|
|
594
606
|
lastWorldVersion = body.version;
|
|
595
607
|
return { data: body.data, version: body.version };
|
package/dist/index.d.ts
CHANGED
|
@@ -222,11 +222,20 @@ interface PlayerStateResult {
|
|
|
222
222
|
version: number;
|
|
223
223
|
/** True when the current identity is a guest (server storage untouched). */
|
|
224
224
|
guest?: boolean;
|
|
225
|
+
/**
|
|
226
|
+
* True when the build is running on the PREVIEW channel — the owner's draft
|
|
227
|
+
* workspace, any `preview--<slug>` URL. Server saves are off there by design,
|
|
228
|
+
* so nothing was read: keep progress in localStorage and say "preview build",
|
|
229
|
+
* never "offline".
|
|
230
|
+
*/
|
|
231
|
+
staging?: boolean;
|
|
225
232
|
}
|
|
226
233
|
interface WorldStateResult {
|
|
227
234
|
data: unknown;
|
|
228
235
|
version: number;
|
|
229
236
|
guest?: boolean;
|
|
237
|
+
/** True on the preview channel — see PlayerStateResult.staging. */
|
|
238
|
+
staging?: boolean;
|
|
230
239
|
}
|
|
231
240
|
interface SaveStateResult {
|
|
232
241
|
/** True when the write landed on the server. */
|
|
@@ -239,6 +248,13 @@ interface SaveStateResult {
|
|
|
239
248
|
guest?: boolean;
|
|
240
249
|
/** True when the value was queued to auto-flush if this guest signs in mid-game. */
|
|
241
250
|
queued?: boolean;
|
|
251
|
+
/**
|
|
252
|
+
* True when the build is running on the PREVIEW channel (the owner's draft
|
|
253
|
+
* workspace, `preview--<slug>`): the server refused the write by policy, not
|
|
254
|
+
* by failure — nothing is queued, no `error` event fires. Keep the value in
|
|
255
|
+
* localStorage and tell the player it is a preview build.
|
|
256
|
+
*/
|
|
257
|
+
staging?: boolean;
|
|
242
258
|
}
|
|
243
259
|
interface SubmitScoreResult {
|
|
244
260
|
submitted: boolean;
|
|
@@ -355,14 +371,19 @@ declare function on(event: EmbedEvent, cb: (ctx?: EventContext) => void): () =>
|
|
|
355
371
|
* Load THIS player's own save slot (per-player, per-game — another player can
|
|
356
372
|
* never read or clobber it). Resolves { data: null, version: 0 } when they
|
|
357
373
|
* never saved. Guests get their queued pending save (if any) so a round-trip
|
|
358
|
-
* works mid-session; the server is untouched.
|
|
359
|
-
*
|
|
374
|
+
* works mid-session; the server is untouched. On the preview channel (the
|
|
375
|
+
* owner's draft workspace) resolves { data: null, version: 0, staging: true }
|
|
376
|
+
* — server saves are off there by design, and that is not an error. Await-safe
|
|
377
|
+
* from boot: resolves after identity exists, rejects only when the session is
|
|
378
|
+
* blocked.
|
|
360
379
|
*/
|
|
361
380
|
declare function loadPlayerState(): Promise<PlayerStateResult>;
|
|
362
381
|
/**
|
|
363
382
|
* Save THIS player's own slot (any JSON ≤ 256KB; last-write-wins on their own
|
|
364
383
|
* row). Guests: the value is QUEUED in memory and auto-flushed if they sign in
|
|
365
384
|
* mid-game ({ saved: false, guest: true, queued: true }) — no extra game code.
|
|
385
|
+
* On the preview channel: { saved: false, staging: true }, nothing queued
|
|
386
|
+
* (nothing would ever flush it) and no `error` event — keep it in localStorage.
|
|
366
387
|
* Pass { ifVersion } (from the last load/save) to detect same-account
|
|
367
388
|
* two-device races: a losing write resolves { conflict: true, version } —
|
|
368
389
|
* reload, merge, retry. Small saves survive tab close (fetch keepalive).
|
|
@@ -374,7 +395,8 @@ declare function savePlayerState(data: unknown, opts?: {
|
|
|
374
395
|
* Load the game's SHARED world slot (one blob per game — every player reads
|
|
375
396
|
* the same world). Guests resolve { data: null, guest: true } — the server
|
|
376
397
|
* refuses guest reads; in multiplayer, guests receive the live world through
|
|
377
|
-
* the room instead.
|
|
398
|
+
* the room instead. The preview channel resolves { data: null, version: 0,
|
|
399
|
+
* staging: true } for the same reason the player slot does.
|
|
378
400
|
*/
|
|
379
401
|
declare function loadWorldState(): Promise<WorldStateResult>;
|
|
380
402
|
/**
|
package/dist/index.js
CHANGED
package/dist/sentry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genex-ai/embed-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.23.0",
|
|
4
4
|
"description": "Player identity + durable game state for genex games \u2014 signed-in or guest play, per-player save slots, shared world state, and soft-trust leaderboards.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|