@scalemule/nextjs 0.0.4 → 0.0.6
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/client.d.mts +18 -0
- package/dist/client.d.ts +18 -0
- package/dist/client.js +33 -0
- package/dist/client.mjs +33 -0
- package/dist/index.js +38 -2
- package/dist/index.mjs +38 -2
- package/package.json +1 -1
package/dist/client.d.mts
CHANGED
|
@@ -28,6 +28,12 @@ interface ClientConfig {
|
|
|
28
28
|
enableRateLimitQueue?: boolean;
|
|
29
29
|
/** Enable offline queue (queues requests when offline, syncs when back online) */
|
|
30
30
|
enableOfflineQueue?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Signal that a session will be established asynchronously (e.g. via auth proxy).
|
|
33
|
+
* When true, API requests will wait for the session to be resolved before sending,
|
|
34
|
+
* preventing race conditions where requests fire before the auth token is available.
|
|
35
|
+
*/
|
|
36
|
+
pendingSessionInit?: boolean;
|
|
31
37
|
}
|
|
32
38
|
interface RequestOptions extends RequestInit {
|
|
33
39
|
/** Skip adding auth headers (for public endpoints) */
|
|
@@ -56,6 +62,8 @@ declare class ScaleMuleClient {
|
|
|
56
62
|
private offlineQueue;
|
|
57
63
|
private enableRateLimitQueue;
|
|
58
64
|
private enableOfflineQueue;
|
|
65
|
+
private sessionGate;
|
|
66
|
+
private resolveSessionGate;
|
|
59
67
|
constructor(config: ClientConfig);
|
|
60
68
|
/**
|
|
61
69
|
* Sync offline queue when coming back online
|
|
@@ -85,6 +93,16 @@ declare class ScaleMuleClient {
|
|
|
85
93
|
* Get the application ID (required for realtime features)
|
|
86
94
|
*/
|
|
87
95
|
getApplicationId(): string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Signal that a session is being established asynchronously.
|
|
98
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
99
|
+
*/
|
|
100
|
+
setSessionPending(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
103
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
104
|
+
*/
|
|
105
|
+
resolveSessionPending(): void;
|
|
88
106
|
/**
|
|
89
107
|
* Initialize client by loading persisted session
|
|
90
108
|
*/
|
package/dist/client.d.ts
CHANGED
|
@@ -28,6 +28,12 @@ interface ClientConfig {
|
|
|
28
28
|
enableRateLimitQueue?: boolean;
|
|
29
29
|
/** Enable offline queue (queues requests when offline, syncs when back online) */
|
|
30
30
|
enableOfflineQueue?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Signal that a session will be established asynchronously (e.g. via auth proxy).
|
|
33
|
+
* When true, API requests will wait for the session to be resolved before sending,
|
|
34
|
+
* preventing race conditions where requests fire before the auth token is available.
|
|
35
|
+
*/
|
|
36
|
+
pendingSessionInit?: boolean;
|
|
31
37
|
}
|
|
32
38
|
interface RequestOptions extends RequestInit {
|
|
33
39
|
/** Skip adding auth headers (for public endpoints) */
|
|
@@ -56,6 +62,8 @@ declare class ScaleMuleClient {
|
|
|
56
62
|
private offlineQueue;
|
|
57
63
|
private enableRateLimitQueue;
|
|
58
64
|
private enableOfflineQueue;
|
|
65
|
+
private sessionGate;
|
|
66
|
+
private resolveSessionGate;
|
|
59
67
|
constructor(config: ClientConfig);
|
|
60
68
|
/**
|
|
61
69
|
* Sync offline queue when coming back online
|
|
@@ -85,6 +93,16 @@ declare class ScaleMuleClient {
|
|
|
85
93
|
* Get the application ID (required for realtime features)
|
|
86
94
|
*/
|
|
87
95
|
getApplicationId(): string | null;
|
|
96
|
+
/**
|
|
97
|
+
* Signal that a session is being established asynchronously.
|
|
98
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
99
|
+
*/
|
|
100
|
+
setSessionPending(): void;
|
|
101
|
+
/**
|
|
102
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
103
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
104
|
+
*/
|
|
105
|
+
resolveSessionPending(): void;
|
|
88
106
|
/**
|
|
89
107
|
* Initialize client by loading persisted session
|
|
90
108
|
*/
|
package/dist/client.js
CHANGED
|
@@ -273,6 +273,8 @@ var ScaleMuleClient = class {
|
|
|
273
273
|
this.userId = null;
|
|
274
274
|
this.rateLimitQueue = null;
|
|
275
275
|
this.offlineQueue = null;
|
|
276
|
+
this.sessionGate = null;
|
|
277
|
+
this.resolveSessionGate = null;
|
|
276
278
|
this.apiKey = config.apiKey;
|
|
277
279
|
this.applicationId = config.applicationId || null;
|
|
278
280
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
@@ -287,6 +289,9 @@ var ScaleMuleClient = class {
|
|
|
287
289
|
this.offlineQueue = new OfflineQueue(this.storage);
|
|
288
290
|
this.offlineQueue.setOnlineCallback(() => this.syncOfflineQueue());
|
|
289
291
|
}
|
|
292
|
+
if (config.pendingSessionInit) {
|
|
293
|
+
this.setSessionPending();
|
|
294
|
+
}
|
|
290
295
|
}
|
|
291
296
|
/**
|
|
292
297
|
* Sync offline queue when coming back online
|
|
@@ -352,6 +357,28 @@ var ScaleMuleClient = class {
|
|
|
352
357
|
getApplicationId() {
|
|
353
358
|
return this.applicationId;
|
|
354
359
|
}
|
|
360
|
+
/**
|
|
361
|
+
* Signal that a session is being established asynchronously.
|
|
362
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
363
|
+
*/
|
|
364
|
+
setSessionPending() {
|
|
365
|
+
if (!this.sessionGate) {
|
|
366
|
+
this.sessionGate = new Promise((resolve) => {
|
|
367
|
+
this.resolveSessionGate = resolve;
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
373
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
374
|
+
*/
|
|
375
|
+
resolveSessionPending() {
|
|
376
|
+
if (this.resolveSessionGate) {
|
|
377
|
+
this.resolveSessionGate();
|
|
378
|
+
this.resolveSessionGate = null;
|
|
379
|
+
this.sessionGate = null;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
355
382
|
/**
|
|
356
383
|
* Initialize client by loading persisted session
|
|
357
384
|
*/
|
|
@@ -360,6 +387,9 @@ var ScaleMuleClient = class {
|
|
|
360
387
|
const userId = await this.storage.getItem(USER_ID_STORAGE_KEY);
|
|
361
388
|
if (token) this.sessionToken = token;
|
|
362
389
|
if (userId) this.userId = userId;
|
|
390
|
+
if (token) {
|
|
391
|
+
this.resolveSessionPending();
|
|
392
|
+
}
|
|
363
393
|
if (this.debug) {
|
|
364
394
|
console.log("[ScaleMule] Initialized with session:", !!token);
|
|
365
395
|
}
|
|
@@ -424,6 +454,9 @@ var ScaleMuleClient = class {
|
|
|
424
454
|
* Make an HTTP request to the ScaleMule API
|
|
425
455
|
*/
|
|
426
456
|
async request(path, options = {}) {
|
|
457
|
+
if (this.sessionGate) {
|
|
458
|
+
await this.sessionGate;
|
|
459
|
+
}
|
|
427
460
|
const url = `${this.gatewayUrl}${path}`;
|
|
428
461
|
const headers = this.buildHeaders(options);
|
|
429
462
|
const maxRetries = options.skipRetry ? 0 : options.retries ?? 2;
|
package/dist/client.mjs
CHANGED
|
@@ -271,6 +271,8 @@ var ScaleMuleClient = class {
|
|
|
271
271
|
this.userId = null;
|
|
272
272
|
this.rateLimitQueue = null;
|
|
273
273
|
this.offlineQueue = null;
|
|
274
|
+
this.sessionGate = null;
|
|
275
|
+
this.resolveSessionGate = null;
|
|
274
276
|
this.apiKey = config.apiKey;
|
|
275
277
|
this.applicationId = config.applicationId || null;
|
|
276
278
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
@@ -285,6 +287,9 @@ var ScaleMuleClient = class {
|
|
|
285
287
|
this.offlineQueue = new OfflineQueue(this.storage);
|
|
286
288
|
this.offlineQueue.setOnlineCallback(() => this.syncOfflineQueue());
|
|
287
289
|
}
|
|
290
|
+
if (config.pendingSessionInit) {
|
|
291
|
+
this.setSessionPending();
|
|
292
|
+
}
|
|
288
293
|
}
|
|
289
294
|
/**
|
|
290
295
|
* Sync offline queue when coming back online
|
|
@@ -350,6 +355,28 @@ var ScaleMuleClient = class {
|
|
|
350
355
|
getApplicationId() {
|
|
351
356
|
return this.applicationId;
|
|
352
357
|
}
|
|
358
|
+
/**
|
|
359
|
+
* Signal that a session is being established asynchronously.
|
|
360
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
361
|
+
*/
|
|
362
|
+
setSessionPending() {
|
|
363
|
+
if (!this.sessionGate) {
|
|
364
|
+
this.sessionGate = new Promise((resolve) => {
|
|
365
|
+
this.resolveSessionGate = resolve;
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
371
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
372
|
+
*/
|
|
373
|
+
resolveSessionPending() {
|
|
374
|
+
if (this.resolveSessionGate) {
|
|
375
|
+
this.resolveSessionGate();
|
|
376
|
+
this.resolveSessionGate = null;
|
|
377
|
+
this.sessionGate = null;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
353
380
|
/**
|
|
354
381
|
* Initialize client by loading persisted session
|
|
355
382
|
*/
|
|
@@ -358,6 +385,9 @@ var ScaleMuleClient = class {
|
|
|
358
385
|
const userId = await this.storage.getItem(USER_ID_STORAGE_KEY);
|
|
359
386
|
if (token) this.sessionToken = token;
|
|
360
387
|
if (userId) this.userId = userId;
|
|
388
|
+
if (token) {
|
|
389
|
+
this.resolveSessionPending();
|
|
390
|
+
}
|
|
361
391
|
if (this.debug) {
|
|
362
392
|
console.log("[ScaleMule] Initialized with session:", !!token);
|
|
363
393
|
}
|
|
@@ -422,6 +452,9 @@ var ScaleMuleClient = class {
|
|
|
422
452
|
* Make an HTTP request to the ScaleMule API
|
|
423
453
|
*/
|
|
424
454
|
async request(path, options = {}) {
|
|
455
|
+
if (this.sessionGate) {
|
|
456
|
+
await this.sessionGate;
|
|
457
|
+
}
|
|
425
458
|
const url = `${this.gatewayUrl}${path}`;
|
|
426
459
|
const headers = this.buildHeaders(options);
|
|
427
460
|
const maxRetries = options.skipRetry ? 0 : options.retries ?? 2;
|
package/dist/index.js
CHANGED
|
@@ -278,6 +278,8 @@ var ScaleMuleClient = class {
|
|
|
278
278
|
this.userId = null;
|
|
279
279
|
this.rateLimitQueue = null;
|
|
280
280
|
this.offlineQueue = null;
|
|
281
|
+
this.sessionGate = null;
|
|
282
|
+
this.resolveSessionGate = null;
|
|
281
283
|
this.apiKey = config.apiKey;
|
|
282
284
|
this.applicationId = config.applicationId || null;
|
|
283
285
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
@@ -292,6 +294,9 @@ var ScaleMuleClient = class {
|
|
|
292
294
|
this.offlineQueue = new OfflineQueue(this.storage);
|
|
293
295
|
this.offlineQueue.setOnlineCallback(() => this.syncOfflineQueue());
|
|
294
296
|
}
|
|
297
|
+
if (config.pendingSessionInit) {
|
|
298
|
+
this.setSessionPending();
|
|
299
|
+
}
|
|
295
300
|
}
|
|
296
301
|
/**
|
|
297
302
|
* Sync offline queue when coming back online
|
|
@@ -357,6 +362,28 @@ var ScaleMuleClient = class {
|
|
|
357
362
|
getApplicationId() {
|
|
358
363
|
return this.applicationId;
|
|
359
364
|
}
|
|
365
|
+
/**
|
|
366
|
+
* Signal that a session is being established asynchronously.
|
|
367
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
368
|
+
*/
|
|
369
|
+
setSessionPending() {
|
|
370
|
+
if (!this.sessionGate) {
|
|
371
|
+
this.sessionGate = new Promise((resolve) => {
|
|
372
|
+
this.resolveSessionGate = resolve;
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
378
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
379
|
+
*/
|
|
380
|
+
resolveSessionPending() {
|
|
381
|
+
if (this.resolveSessionGate) {
|
|
382
|
+
this.resolveSessionGate();
|
|
383
|
+
this.resolveSessionGate = null;
|
|
384
|
+
this.sessionGate = null;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
360
387
|
/**
|
|
361
388
|
* Initialize client by loading persisted session
|
|
362
389
|
*/
|
|
@@ -365,6 +392,9 @@ var ScaleMuleClient = class {
|
|
|
365
392
|
const userId = await this.storage.getItem(USER_ID_STORAGE_KEY);
|
|
366
393
|
if (token) this.sessionToken = token;
|
|
367
394
|
if (userId) this.userId = userId;
|
|
395
|
+
if (token) {
|
|
396
|
+
this.resolveSessionPending();
|
|
397
|
+
}
|
|
368
398
|
if (this.debug) {
|
|
369
399
|
console.log("[ScaleMule] Initialized with session:", !!token);
|
|
370
400
|
}
|
|
@@ -429,6 +459,9 @@ var ScaleMuleClient = class {
|
|
|
429
459
|
* Make an HTTP request to the ScaleMule API
|
|
430
460
|
*/
|
|
431
461
|
async request(path, options = {}) {
|
|
462
|
+
if (this.sessionGate) {
|
|
463
|
+
await this.sessionGate;
|
|
464
|
+
}
|
|
432
465
|
const url = `${this.gatewayUrl}${path}`;
|
|
433
466
|
const headers = this.buildHeaders(options);
|
|
434
467
|
const maxRetries = options.skipRetry ? 0 : options.retries ?? 2;
|
|
@@ -765,9 +798,10 @@ function ScaleMuleProvider({
|
|
|
765
798
|
environment,
|
|
766
799
|
gatewayUrl,
|
|
767
800
|
debug,
|
|
768
|
-
storage
|
|
801
|
+
storage,
|
|
802
|
+
pendingSessionInit: !!authProxyUrl
|
|
769
803
|
}),
|
|
770
|
-
[apiKey, applicationId, environment, gatewayUrl, debug, storage]
|
|
804
|
+
[apiKey, applicationId, environment, gatewayUrl, debug, storage, authProxyUrl]
|
|
771
805
|
);
|
|
772
806
|
react.useEffect(() => {
|
|
773
807
|
let mounted = true;
|
|
@@ -801,6 +835,8 @@ function ScaleMuleProvider({
|
|
|
801
835
|
if (mounted && debug) {
|
|
802
836
|
console.debug("[ScaleMule] Auth proxy session check failed");
|
|
803
837
|
}
|
|
838
|
+
} finally {
|
|
839
|
+
client.resolveSessionPending();
|
|
804
840
|
}
|
|
805
841
|
} else if (client.isAuthenticated()) {
|
|
806
842
|
if (cachedUser && mounted) {
|
package/dist/index.mjs
CHANGED
|
@@ -276,6 +276,8 @@ var ScaleMuleClient = class {
|
|
|
276
276
|
this.userId = null;
|
|
277
277
|
this.rateLimitQueue = null;
|
|
278
278
|
this.offlineQueue = null;
|
|
279
|
+
this.sessionGate = null;
|
|
280
|
+
this.resolveSessionGate = null;
|
|
279
281
|
this.apiKey = config.apiKey;
|
|
280
282
|
this.applicationId = config.applicationId || null;
|
|
281
283
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
@@ -290,6 +292,9 @@ var ScaleMuleClient = class {
|
|
|
290
292
|
this.offlineQueue = new OfflineQueue(this.storage);
|
|
291
293
|
this.offlineQueue.setOnlineCallback(() => this.syncOfflineQueue());
|
|
292
294
|
}
|
|
295
|
+
if (config.pendingSessionInit) {
|
|
296
|
+
this.setSessionPending();
|
|
297
|
+
}
|
|
293
298
|
}
|
|
294
299
|
/**
|
|
295
300
|
* Sync offline queue when coming back online
|
|
@@ -355,6 +360,28 @@ var ScaleMuleClient = class {
|
|
|
355
360
|
getApplicationId() {
|
|
356
361
|
return this.applicationId;
|
|
357
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Signal that a session is being established asynchronously.
|
|
365
|
+
* API requests will wait until resolveSessionPending() is called.
|
|
366
|
+
*/
|
|
367
|
+
setSessionPending() {
|
|
368
|
+
if (!this.sessionGate) {
|
|
369
|
+
this.sessionGate = new Promise((resolve) => {
|
|
370
|
+
this.resolveSessionGate = resolve;
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Resolve the pending session gate, allowing queued API requests to proceed.
|
|
376
|
+
* Must be called after setSessionPending(), whether session was established or not.
|
|
377
|
+
*/
|
|
378
|
+
resolveSessionPending() {
|
|
379
|
+
if (this.resolveSessionGate) {
|
|
380
|
+
this.resolveSessionGate();
|
|
381
|
+
this.resolveSessionGate = null;
|
|
382
|
+
this.sessionGate = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
358
385
|
/**
|
|
359
386
|
* Initialize client by loading persisted session
|
|
360
387
|
*/
|
|
@@ -363,6 +390,9 @@ var ScaleMuleClient = class {
|
|
|
363
390
|
const userId = await this.storage.getItem(USER_ID_STORAGE_KEY);
|
|
364
391
|
if (token) this.sessionToken = token;
|
|
365
392
|
if (userId) this.userId = userId;
|
|
393
|
+
if (token) {
|
|
394
|
+
this.resolveSessionPending();
|
|
395
|
+
}
|
|
366
396
|
if (this.debug) {
|
|
367
397
|
console.log("[ScaleMule] Initialized with session:", !!token);
|
|
368
398
|
}
|
|
@@ -427,6 +457,9 @@ var ScaleMuleClient = class {
|
|
|
427
457
|
* Make an HTTP request to the ScaleMule API
|
|
428
458
|
*/
|
|
429
459
|
async request(path, options = {}) {
|
|
460
|
+
if (this.sessionGate) {
|
|
461
|
+
await this.sessionGate;
|
|
462
|
+
}
|
|
430
463
|
const url = `${this.gatewayUrl}${path}`;
|
|
431
464
|
const headers = this.buildHeaders(options);
|
|
432
465
|
const maxRetries = options.skipRetry ? 0 : options.retries ?? 2;
|
|
@@ -763,9 +796,10 @@ function ScaleMuleProvider({
|
|
|
763
796
|
environment,
|
|
764
797
|
gatewayUrl,
|
|
765
798
|
debug,
|
|
766
|
-
storage
|
|
799
|
+
storage,
|
|
800
|
+
pendingSessionInit: !!authProxyUrl
|
|
767
801
|
}),
|
|
768
|
-
[apiKey, applicationId, environment, gatewayUrl, debug, storage]
|
|
802
|
+
[apiKey, applicationId, environment, gatewayUrl, debug, storage, authProxyUrl]
|
|
769
803
|
);
|
|
770
804
|
useEffect(() => {
|
|
771
805
|
let mounted = true;
|
|
@@ -799,6 +833,8 @@ function ScaleMuleProvider({
|
|
|
799
833
|
if (mounted && debug) {
|
|
800
834
|
console.debug("[ScaleMule] Auth proxy session check failed");
|
|
801
835
|
}
|
|
836
|
+
} finally {
|
|
837
|
+
client.resolveSessionPending();
|
|
802
838
|
}
|
|
803
839
|
} else if (client.isAuthenticated()) {
|
|
804
840
|
if (cachedUser && mounted) {
|
package/package.json
CHANGED