@electric-sql/client 1.1.2 → 1.1.3
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/README.md +74 -12
- package/dist/cjs/index.cjs +43 -8
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +53 -4
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.d.ts +53 -4
- package/dist/index.legacy-esm.js +43 -8
- package/dist/index.legacy-esm.js.map +1 -1
- package/dist/index.mjs +43 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client.ts +45 -4
- package/src/constants.ts +1 -0
- package/src/fetch.ts +75 -9
package/dist/index.mjs
CHANGED
|
@@ -322,6 +322,7 @@ var SUBSET_PARAM_ORDER_BY = `subset__order_by`;
|
|
|
322
322
|
var SUBSET_PARAM_WHERE_PARAMS = `subset__params`;
|
|
323
323
|
var ELECTRIC_PROTOCOL_QUERY_PARAMS = [
|
|
324
324
|
LIVE_QUERY_PARAM,
|
|
325
|
+
LIVE_SSE_QUERY_PARAM,
|
|
325
326
|
SHAPE_HANDLE_QUERY_PARAM,
|
|
326
327
|
OFFSET_QUERY_PARAM,
|
|
327
328
|
LIVE_CACHE_BUSTER_QUERY_PARAM,
|
|
@@ -338,16 +339,33 @@ var ELECTRIC_PROTOCOL_QUERY_PARAMS = [
|
|
|
338
339
|
var HTTP_RETRY_STATUS_CODES = [429];
|
|
339
340
|
var BackoffDefaults = {
|
|
340
341
|
initialDelay: 100,
|
|
341
|
-
maxDelay:
|
|
342
|
-
|
|
342
|
+
maxDelay: 6e4,
|
|
343
|
+
// Cap at 60s - reasonable for long-lived connections
|
|
344
|
+
multiplier: 1.3,
|
|
345
|
+
maxRetries: Infinity
|
|
346
|
+
// Retry forever - clients may go offline and come back
|
|
343
347
|
};
|
|
348
|
+
function parseRetryAfterHeader(retryAfter) {
|
|
349
|
+
if (!retryAfter) return 0;
|
|
350
|
+
const retryAfterSec = Number(retryAfter);
|
|
351
|
+
if (Number.isFinite(retryAfterSec) && retryAfterSec > 0) {
|
|
352
|
+
return retryAfterSec * 1e3;
|
|
353
|
+
}
|
|
354
|
+
const retryDate = Date.parse(retryAfter);
|
|
355
|
+
if (!isNaN(retryDate)) {
|
|
356
|
+
const deltaMs = retryDate - Date.now();
|
|
357
|
+
return Math.max(0, Math.min(deltaMs, 36e5));
|
|
358
|
+
}
|
|
359
|
+
return 0;
|
|
360
|
+
}
|
|
344
361
|
function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults) {
|
|
345
362
|
const {
|
|
346
363
|
initialDelay,
|
|
347
364
|
maxDelay,
|
|
348
365
|
multiplier,
|
|
349
366
|
debug = false,
|
|
350
|
-
onFailedAttempt
|
|
367
|
+
onFailedAttempt,
|
|
368
|
+
maxRetries = Infinity
|
|
351
369
|
} = backoffOptions;
|
|
352
370
|
return (...args) => __async(this, null, function* () {
|
|
353
371
|
var _a;
|
|
@@ -358,7 +376,9 @@ function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults) {
|
|
|
358
376
|
while (true) {
|
|
359
377
|
try {
|
|
360
378
|
const result = yield fetchClient(...args);
|
|
361
|
-
if (result.ok)
|
|
379
|
+
if (result.ok) {
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
362
382
|
const err = yield FetchError.fromResponse(result, url.toString());
|
|
363
383
|
throw err;
|
|
364
384
|
} catch (e) {
|
|
@@ -368,12 +388,27 @@ function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults) {
|
|
|
368
388
|
} else if (e instanceof FetchError && !HTTP_RETRY_STATUS_CODES.includes(e.status) && e.status >= 400 && e.status < 500) {
|
|
369
389
|
throw e;
|
|
370
390
|
} else {
|
|
371
|
-
|
|
372
|
-
|
|
391
|
+
attempt++;
|
|
392
|
+
if (attempt > maxRetries) {
|
|
393
|
+
if (debug) {
|
|
394
|
+
console.log(
|
|
395
|
+
`Max retries reached (${attempt}/${maxRetries}), giving up`
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
throw e;
|
|
399
|
+
}
|
|
400
|
+
const serverMinimumMs = e instanceof FetchError && e.headers ? parseRetryAfterHeader(e.headers[`retry-after`]) : 0;
|
|
401
|
+
const jitter = Math.random() * delay;
|
|
402
|
+
const clientBackoffMs = Math.min(jitter, maxDelay);
|
|
403
|
+
const waitMs = Math.max(serverMinimumMs, clientBackoffMs);
|
|
373
404
|
if (debug) {
|
|
374
|
-
|
|
375
|
-
console.log(
|
|
405
|
+
const source = serverMinimumMs > 0 ? `server+client` : `client`;
|
|
406
|
+
console.log(
|
|
407
|
+
`Retry attempt #${attempt} after ${waitMs}ms (${source}, serverMin=${serverMinimumMs}ms, clientBackoff=${clientBackoffMs}ms)`
|
|
408
|
+
);
|
|
376
409
|
}
|
|
410
|
+
yield new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
411
|
+
delay = Math.min(delay * multiplier, maxDelay);
|
|
377
412
|
}
|
|
378
413
|
}
|
|
379
414
|
}
|