@genex-ai/embed-sdk 0.6.0 → 0.6.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.
- package/dist/{chunk-5VYRFOFN.js → chunk-UOC55SJL.js} +17 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/sentry.js +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ var parentOrigin = null;
|
|
|
12
12
|
var initialized = false;
|
|
13
13
|
var redeeming = false;
|
|
14
14
|
var requestingGuest = false;
|
|
15
|
+
var identityEpoch = 0;
|
|
15
16
|
var handshakeTimeoutMs = 1e4;
|
|
16
17
|
var refreshDelayMs = 10 * 6e4;
|
|
17
18
|
var refreshRetryMs = 6e4;
|
|
@@ -419,6 +420,7 @@ async function fetchDashboardOrigins() {
|
|
|
419
420
|
async function redeemTicket(ticket) {
|
|
420
421
|
if (!config || localTestMode || redeeming || state !== "pending" && state !== "guest") return;
|
|
421
422
|
const upgradingFromGuest = state === "guest";
|
|
423
|
+
const epoch = ++identityEpoch;
|
|
422
424
|
redeeming = true;
|
|
423
425
|
try {
|
|
424
426
|
const res = await doFetch(`${config.apiUrl}/api/embed/session`, {
|
|
@@ -426,12 +428,14 @@ async function redeemTicket(ticket) {
|
|
|
426
428
|
headers: { "Content-Type": "application/json" },
|
|
427
429
|
body: JSON.stringify({ ticket })
|
|
428
430
|
});
|
|
431
|
+
if (epoch !== identityEpoch) return;
|
|
429
432
|
if (!res.ok) {
|
|
430
433
|
emit("error", { error: new Error(`ticket redemption failed (${res.status})`) });
|
|
431
434
|
if (!upgradingFromGuest) await handleRedeemFailure();
|
|
432
435
|
return;
|
|
433
436
|
}
|
|
434
437
|
const body = await res.json();
|
|
438
|
+
if (epoch !== identityEpoch) return;
|
|
435
439
|
embedToken = body.embedToken;
|
|
436
440
|
user = body.user;
|
|
437
441
|
colyseusUrls = body.colyseus?.urls;
|
|
@@ -449,6 +453,7 @@ async function redeemTicket(ticket) {
|
|
|
449
453
|
for (const waiter of playerWaiters.splice(0)) waiter.resolve({ user, guest: false });
|
|
450
454
|
emit("authenticated", ctx);
|
|
451
455
|
} catch (error) {
|
|
456
|
+
if (epoch !== identityEpoch) return;
|
|
452
457
|
emit("error", { error });
|
|
453
458
|
if (!upgradingFromGuest) await handleRedeemFailure();
|
|
454
459
|
} finally {
|
|
@@ -458,6 +463,7 @@ async function redeemTicket(ticket) {
|
|
|
458
463
|
async function requestGuestSession() {
|
|
459
464
|
if (!config || localTestMode || requestingGuest || redeeming) return;
|
|
460
465
|
if (state !== "pending" && state !== "guest") return;
|
|
466
|
+
const epoch = ++identityEpoch;
|
|
461
467
|
requestingGuest = true;
|
|
462
468
|
try {
|
|
463
469
|
const res = await doFetch(`${config.apiUrl}/api/embed/guest-session`, {
|
|
@@ -465,17 +471,20 @@ async function requestGuestSession() {
|
|
|
465
471
|
headers: { "Content-Type": "application/json" },
|
|
466
472
|
body: JSON.stringify({ slug: config.slug })
|
|
467
473
|
});
|
|
474
|
+
if (epoch !== identityEpoch) return;
|
|
468
475
|
if (!res.ok) {
|
|
469
476
|
emit("error", { error: new Error(`guest session failed (${res.status})`) });
|
|
470
477
|
enterBlocked();
|
|
471
478
|
return;
|
|
472
479
|
}
|
|
473
480
|
const body = await res.json();
|
|
481
|
+
if (epoch !== identityEpoch) return;
|
|
474
482
|
embedToken = body.embedToken;
|
|
475
483
|
user = body.user;
|
|
476
484
|
colyseusUrls = body.colyseus?.urls;
|
|
477
485
|
enterGuest();
|
|
478
486
|
} catch (error) {
|
|
487
|
+
if (epoch !== identityEpoch) return;
|
|
479
488
|
emit("error", { error });
|
|
480
489
|
enterBlocked();
|
|
481
490
|
} finally {
|
|
@@ -553,18 +562,22 @@ function scheduleRefresh() {
|
|
|
553
562
|
}
|
|
554
563
|
async function refreshToken() {
|
|
555
564
|
if (!config || state !== "authenticated" && state !== "guest" || !embedToken) return;
|
|
565
|
+
const epoch = identityEpoch;
|
|
566
|
+
const tokenAtStart = embedToken;
|
|
556
567
|
let status;
|
|
557
568
|
try {
|
|
558
569
|
const res = await doFetch(`${config.apiUrl}/api/embed/session/refresh`, {
|
|
559
570
|
method: "POST",
|
|
560
|
-
headers: { Authorization: `Bearer ${
|
|
571
|
+
headers: { Authorization: `Bearer ${tokenAtStart}` },
|
|
561
572
|
// Best-effort completion if the tab starts unloading mid-refresh; zero
|
|
562
573
|
// security consequence either way (worst case the token just expires).
|
|
563
574
|
keepalive: true
|
|
564
575
|
});
|
|
565
576
|
status = res.status;
|
|
577
|
+
if (epoch !== identityEpoch || embedToken !== tokenAtStart) return;
|
|
566
578
|
if (res.ok) {
|
|
567
579
|
const body = await res.json();
|
|
580
|
+
if (epoch !== identityEpoch || embedToken !== tokenAtStart) return;
|
|
568
581
|
embedToken = body.embedToken;
|
|
569
582
|
scheduleRefresh();
|
|
570
583
|
return;
|
|
@@ -572,6 +585,7 @@ async function refreshToken() {
|
|
|
572
585
|
} catch {
|
|
573
586
|
status = void 0;
|
|
574
587
|
}
|
|
588
|
+
if (epoch !== identityEpoch || embedToken !== tokenAtStart) return;
|
|
575
589
|
if (status === 401) {
|
|
576
590
|
if (state === "guest") {
|
|
577
591
|
void requestGuestSession();
|
|
@@ -588,6 +602,7 @@ async function refreshToken() {
|
|
|
588
602
|
}
|
|
589
603
|
function enterBlocked() {
|
|
590
604
|
if (state === "blocked") return;
|
|
605
|
+
identityEpoch++;
|
|
591
606
|
state = "blocked";
|
|
592
607
|
user = null;
|
|
593
608
|
embedToken = void 0;
|
|
@@ -731,6 +746,7 @@ function __resetForTests(overrides) {
|
|
|
731
746
|
initialized = false;
|
|
732
747
|
redeeming = false;
|
|
733
748
|
requestingGuest = false;
|
|
749
|
+
identityEpoch++;
|
|
734
750
|
listeners.clear();
|
|
735
751
|
authWaiters = [];
|
|
736
752
|
playerWaiters = [];
|
package/dist/index.d.ts
CHANGED
|
@@ -116,7 +116,7 @@ declare function getUser(): EmbedUser | null;
|
|
|
116
116
|
*/
|
|
117
117
|
declare function getEmbedToken(): string | undefined;
|
|
118
118
|
/**
|
|
119
|
-
* The credential for multiplayer: pass as `connect({ ..., auth: getColyseusAuth() })`
|
|
119
|
+
* The credential for multiplayer: pass as `connect({ ..., auth: () => getColyseusAuth() })`
|
|
120
120
|
* AFTER `await waitForPlayer()` — the relay rejects tokenless joins, but
|
|
121
121
|
* accepts guest tokens. Read it fresh at every connect() call (tokens rotate
|
|
122
122
|
* ~every 10 minutes). NEVER log this value.
|
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.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Player identity + durable game state for genex games — 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",
|