@spacelr/sdk 0.9.1 → 0.9.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/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +34 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -372,12 +372,13 @@ type AuthLostListener = (reason: AuthLostReason) => void;
|
|
|
372
372
|
declare class TokenManager {
|
|
373
373
|
private storage;
|
|
374
374
|
private refreshBufferSeconds;
|
|
375
|
+
private refreshLockName;
|
|
375
376
|
private refreshCallback;
|
|
376
377
|
private refreshPromise;
|
|
377
378
|
private tokenRefreshedListeners;
|
|
378
379
|
private authLostListeners;
|
|
379
380
|
private authLostEmitted;
|
|
380
|
-
constructor(storage?: TokenStorage, refreshBufferSeconds?: number);
|
|
381
|
+
constructor(storage?: TokenStorage, refreshBufferSeconds?: number, refreshLockName?: string);
|
|
381
382
|
setRefreshCallback(callback: RefreshCallback): void;
|
|
382
383
|
getAccessToken(): Promise<string | null>;
|
|
383
384
|
setTokens(tokens: StoredTokens): Promise<void>;
|
|
@@ -398,6 +399,9 @@ declare class TokenManager {
|
|
|
398
399
|
private shouldRefresh;
|
|
399
400
|
private tryRefresh;
|
|
400
401
|
private executeRefresh;
|
|
402
|
+
private doRefresh;
|
|
403
|
+
private safeGetTokens;
|
|
404
|
+
private withCrossTabLock;
|
|
401
405
|
private emitTokenRefreshed;
|
|
402
406
|
}
|
|
403
407
|
|
|
@@ -1702,6 +1706,14 @@ interface SpacelrClient {
|
|
|
1702
1706
|
setTokens(tokens: StoredTokens): Promise<void>;
|
|
1703
1707
|
/** Clear stored tokens and reset auth-loss state. */
|
|
1704
1708
|
clearTokens(): Promise<void>;
|
|
1709
|
+
/**
|
|
1710
|
+
* Whether a session (a stored token set) currently exists in the configured
|
|
1711
|
+
* TokenStorage. Use this to distinguish "genuinely logged out" from
|
|
1712
|
+
* "maybe-restorable" without reading the storage backend directly — so it
|
|
1713
|
+
* works with any TokenStorage (memory, IndexedDB, …), not just the default
|
|
1714
|
+
* localStorage one.
|
|
1715
|
+
*/
|
|
1716
|
+
hasStoredSession(): Promise<boolean>;
|
|
1705
1717
|
/** Disconnect realtime WebSocket (if connected) */
|
|
1706
1718
|
disconnect(): void;
|
|
1707
1719
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -372,12 +372,13 @@ type AuthLostListener = (reason: AuthLostReason) => void;
|
|
|
372
372
|
declare class TokenManager {
|
|
373
373
|
private storage;
|
|
374
374
|
private refreshBufferSeconds;
|
|
375
|
+
private refreshLockName;
|
|
375
376
|
private refreshCallback;
|
|
376
377
|
private refreshPromise;
|
|
377
378
|
private tokenRefreshedListeners;
|
|
378
379
|
private authLostListeners;
|
|
379
380
|
private authLostEmitted;
|
|
380
|
-
constructor(storage?: TokenStorage, refreshBufferSeconds?: number);
|
|
381
|
+
constructor(storage?: TokenStorage, refreshBufferSeconds?: number, refreshLockName?: string);
|
|
381
382
|
setRefreshCallback(callback: RefreshCallback): void;
|
|
382
383
|
getAccessToken(): Promise<string | null>;
|
|
383
384
|
setTokens(tokens: StoredTokens): Promise<void>;
|
|
@@ -398,6 +399,9 @@ declare class TokenManager {
|
|
|
398
399
|
private shouldRefresh;
|
|
399
400
|
private tryRefresh;
|
|
400
401
|
private executeRefresh;
|
|
402
|
+
private doRefresh;
|
|
403
|
+
private safeGetTokens;
|
|
404
|
+
private withCrossTabLock;
|
|
401
405
|
private emitTokenRefreshed;
|
|
402
406
|
}
|
|
403
407
|
|
|
@@ -1702,6 +1706,14 @@ interface SpacelrClient {
|
|
|
1702
1706
|
setTokens(tokens: StoredTokens): Promise<void>;
|
|
1703
1707
|
/** Clear stored tokens and reset auth-loss state. */
|
|
1704
1708
|
clearTokens(): Promise<void>;
|
|
1709
|
+
/**
|
|
1710
|
+
* Whether a session (a stored token set) currently exists in the configured
|
|
1711
|
+
* TokenStorage. Use this to distinguish "genuinely logged out" from
|
|
1712
|
+
* "maybe-restorable" without reading the storage backend directly — so it
|
|
1713
|
+
* works with any TokenStorage (memory, IndexedDB, …), not just the default
|
|
1714
|
+
* localStorage one.
|
|
1715
|
+
*/
|
|
1716
|
+
hasStoredSession(): Promise<boolean>;
|
|
1705
1717
|
/** Disconnect realtime WebSocket (if connected) */
|
|
1706
1718
|
disconnect(): void;
|
|
1707
1719
|
/**
|
package/dist/index.js
CHANGED
|
@@ -428,7 +428,7 @@ var BrowserTokenStorage = class {
|
|
|
428
428
|
|
|
429
429
|
// libs/sdk/src/core/token-manager.ts
|
|
430
430
|
var TokenManager = class {
|
|
431
|
-
constructor(storage, refreshBufferSeconds = 60) {
|
|
431
|
+
constructor(storage, refreshBufferSeconds = 60, refreshLockName = "spacelr_token_refresh") {
|
|
432
432
|
this.refreshCallback = null;
|
|
433
433
|
this.refreshPromise = null;
|
|
434
434
|
this.tokenRefreshedListeners = /* @__PURE__ */ new Set();
|
|
@@ -439,6 +439,7 @@ var TokenManager = class {
|
|
|
439
439
|
this.authLostEmitted = false;
|
|
440
440
|
this.storage = storage ?? new MemoryTokenStorage();
|
|
441
441
|
this.refreshBufferSeconds = refreshBufferSeconds;
|
|
442
|
+
this.refreshLockName = refreshLockName;
|
|
442
443
|
}
|
|
443
444
|
setRefreshCallback(callback) {
|
|
444
445
|
this.refreshCallback = callback;
|
|
@@ -468,7 +469,7 @@ var TokenManager = class {
|
|
|
468
469
|
this.authLostEmitted = false;
|
|
469
470
|
}
|
|
470
471
|
async getStoredTokens() {
|
|
471
|
-
return this.
|
|
472
|
+
return this.safeGetTokens();
|
|
472
473
|
}
|
|
473
474
|
/**
|
|
474
475
|
* Force a refresh using the current stored refresh token.
|
|
@@ -535,9 +536,18 @@ var TokenManager = class {
|
|
|
535
536
|
}
|
|
536
537
|
}
|
|
537
538
|
async executeRefresh(refreshToken) {
|
|
539
|
+
return this.withCrossTabLock(() => this.doRefresh(refreshToken));
|
|
540
|
+
}
|
|
541
|
+
async doRefresh(refreshToken) {
|
|
538
542
|
const callback = this.refreshCallback;
|
|
543
|
+
const current = await this.safeGetTokens();
|
|
544
|
+
if (current && current.refreshToken && current.refreshToken !== refreshToken && !this.isTokenExpired(current)) {
|
|
545
|
+
this.emitTokenRefreshed(current);
|
|
546
|
+
return current;
|
|
547
|
+
}
|
|
548
|
+
const activeRefreshToken = current?.refreshToken || refreshToken;
|
|
539
549
|
try {
|
|
540
|
-
const newTokens = await callback(
|
|
550
|
+
const newTokens = await callback(activeRefreshToken);
|
|
541
551
|
await this.storage.setTokens(newTokens);
|
|
542
552
|
this.emitTokenRefreshed(newTokens);
|
|
543
553
|
return newTokens;
|
|
@@ -546,6 +556,22 @@ var TokenManager = class {
|
|
|
546
556
|
throw error;
|
|
547
557
|
}
|
|
548
558
|
}
|
|
559
|
+
async safeGetTokens() {
|
|
560
|
+
try {
|
|
561
|
+
return await this.storage.getTokens();
|
|
562
|
+
} catch {
|
|
563
|
+
return null;
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
withCrossTabLock(fn) {
|
|
567
|
+
const locks = typeof navigator !== "undefined" ? navigator.locks : void 0;
|
|
568
|
+
if (!locks) return fn();
|
|
569
|
+
try {
|
|
570
|
+
return locks.request(this.refreshLockName, fn);
|
|
571
|
+
} catch {
|
|
572
|
+
return fn();
|
|
573
|
+
}
|
|
574
|
+
}
|
|
549
575
|
emitTokenRefreshed(tokens) {
|
|
550
576
|
for (const listener of this.tokenRefreshedListeners) {
|
|
551
577
|
try {
|
|
@@ -3074,7 +3100,8 @@ function createClient(config) {
|
|
|
3074
3100
|
const tokenStorage = config.tokenStorage ?? (typeof window !== "undefined" && typeof window.localStorage !== "undefined" ? new BrowserTokenStorage() : new MemoryTokenStorage());
|
|
3075
3101
|
const tokenManager = new TokenManager(
|
|
3076
3102
|
tokenStorage,
|
|
3077
|
-
config.refreshBufferSeconds ?? 60
|
|
3103
|
+
config.refreshBufferSeconds ?? 60,
|
|
3104
|
+
`spacelr_token_refresh:${config.projectId}`
|
|
3078
3105
|
);
|
|
3079
3106
|
const httpClient = new HttpClient(config, tokenManager);
|
|
3080
3107
|
const realtime = new RealtimeClient({
|
|
@@ -3101,6 +3128,9 @@ function createClient(config) {
|
|
|
3101
3128
|
clearTokens() {
|
|
3102
3129
|
return tokenManager.clearTokens();
|
|
3103
3130
|
},
|
|
3131
|
+
hasStoredSession() {
|
|
3132
|
+
return tokenManager.getStoredTokens().then((tokens) => !!tokens);
|
|
3133
|
+
},
|
|
3104
3134
|
disconnect() {
|
|
3105
3135
|
realtime.disconnect();
|
|
3106
3136
|
},
|