@upyo/retry 0.5.0-dev.199 → 0.5.0-dev.205
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.cjs +26 -14
- package/dist/index.js +26 -14
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -187,6 +187,7 @@ var RetryTransport = class {
|
|
|
187
187
|
let launchPromise;
|
|
188
188
|
let launchError;
|
|
189
189
|
let hasLaunchError = false;
|
|
190
|
+
let hasQueuedFailure = false;
|
|
190
191
|
let pullingInput = false;
|
|
191
192
|
let closed = false;
|
|
192
193
|
const controller = new AbortController();
|
|
@@ -229,7 +230,7 @@ var RetryTransport = class {
|
|
|
229
230
|
inFlight.set(index, promise);
|
|
230
231
|
};
|
|
231
232
|
const startLaunch = () => {
|
|
232
|
-
if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
233
|
+
if (launchPromise != null || inputDone || hasLaunchError || hasQueuedFailure || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
233
234
|
launchPromise = launchNext().catch((error) => {
|
|
234
235
|
launchError = error;
|
|
235
236
|
hasLaunchError = true;
|
|
@@ -240,6 +241,7 @@ var RetryTransport = class {
|
|
|
240
241
|
try {
|
|
241
242
|
startLaunch();
|
|
242
243
|
while (inFlight.size > 0 || completed.has(nextYieldIndex) || launchPromise != null || !inputDone) {
|
|
244
|
+
combinedSignal.signal.throwIfAborted();
|
|
243
245
|
while (completed.has(nextYieldIndex)) {
|
|
244
246
|
const result$1 = completed.get(nextYieldIndex);
|
|
245
247
|
completed.delete(nextYieldIndex);
|
|
@@ -253,10 +255,11 @@ var RetryTransport = class {
|
|
|
253
255
|
startLaunch();
|
|
254
256
|
if (inFlight.size <= 0 && launchPromise == null) break;
|
|
255
257
|
const launch = launchPromise?.then(() => ({ launched: true }));
|
|
256
|
-
const result = await Promise.race([...inFlight.values(), ...launch == null ? [] : [launch]]);
|
|
258
|
+
const result = await raceWithAbort(Promise.race([...inFlight.values(), ...launch == null ? [] : [launch]]), combinedSignal.signal);
|
|
257
259
|
if ("launched" in result) continue;
|
|
258
260
|
inFlight.delete(result.index);
|
|
259
261
|
completed.set(result.index, result);
|
|
262
|
+
if (!result.successful) hasQueuedFailure = true;
|
|
260
263
|
startLaunch();
|
|
261
264
|
}
|
|
262
265
|
if (hasLaunchError) throw launchError;
|
|
@@ -282,15 +285,20 @@ var RetryTransport = class {
|
|
|
282
285
|
* @since 0.5.0
|
|
283
286
|
*/
|
|
284
287
|
async [Symbol.asyncDispose]() {
|
|
285
|
-
const
|
|
286
|
-
const
|
|
287
|
-
if (typeof
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
const wrappedTransport = Object(this.wrappedTransport);
|
|
289
|
+
const asyncDisposeSymbol = Symbol.asyncDispose;
|
|
290
|
+
if (typeof asyncDisposeSymbol === "symbol") {
|
|
291
|
+
const asyncDispose = wrappedTransport[asyncDisposeSymbol];
|
|
292
|
+
if (typeof asyncDispose === "function") {
|
|
293
|
+
await asyncDispose.call(wrappedTransport);
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const disposeSymbol = Symbol.dispose;
|
|
298
|
+
if (typeof disposeSymbol === "symbol") {
|
|
299
|
+
const dispose = wrappedTransport[disposeSymbol];
|
|
300
|
+
if (typeof dispose === "function") dispose.call(wrappedTransport);
|
|
290
301
|
}
|
|
291
|
-
const disposable = this.wrappedTransport;
|
|
292
|
-
const dispose = disposable[Symbol.dispose];
|
|
293
|
-
if (typeof dispose === "function") dispose.call(disposable);
|
|
294
302
|
}
|
|
295
303
|
withSuccessMetadata(receipt, attempts) {
|
|
296
304
|
return {
|
|
@@ -333,7 +341,7 @@ var RetryTransport = class {
|
|
|
333
341
|
}
|
|
334
342
|
calculateDelay(attempt, failure) {
|
|
335
343
|
const retryAfterMilliseconds = getRetryAfterMilliseconds(failure);
|
|
336
|
-
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds
|
|
344
|
+
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds < 0 ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
337
345
|
if (cappedRetryAfter != null) return cappedRetryAfter;
|
|
338
346
|
const computedDelay = Math.min(this.config.backoff.baseDelayMilliseconds * Math.pow(this.config.backoff.factor, attempt - 1), this.config.backoff.maxDelayMilliseconds);
|
|
339
347
|
if (this.config.jitter === false || this.config.jitter === "none") return computedDelay;
|
|
@@ -397,7 +405,8 @@ function getRetryAfterMilliseconds(failure) {
|
|
|
397
405
|
return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
|
|
398
406
|
}
|
|
399
407
|
function toAsyncIterator(values) {
|
|
400
|
-
|
|
408
|
+
const asyncIterator = values[Symbol.asyncIterator];
|
|
409
|
+
if (typeof asyncIterator === "function") return asyncIterator.call(values);
|
|
401
410
|
const iterator = values[Symbol.iterator]();
|
|
402
411
|
return {
|
|
403
412
|
async next() {
|
|
@@ -412,11 +421,11 @@ function toAsyncIterator(values) {
|
|
|
412
421
|
};
|
|
413
422
|
}
|
|
414
423
|
function raceWithAbort(promise, signal) {
|
|
415
|
-
if (signal.aborted) return Promise.reject(signal
|
|
424
|
+
if (signal.aborted) return Promise.reject(getAbortReason(signal));
|
|
416
425
|
return new Promise((resolve, reject) => {
|
|
417
426
|
const abort = () => {
|
|
418
427
|
cleanup();
|
|
419
|
-
reject(signal
|
|
428
|
+
reject(getAbortReason(signal));
|
|
420
429
|
};
|
|
421
430
|
const cleanup = () => {
|
|
422
431
|
signal.removeEventListener("abort", abort);
|
|
@@ -431,6 +440,9 @@ function raceWithAbort(promise, signal) {
|
|
|
431
440
|
});
|
|
432
441
|
});
|
|
433
442
|
}
|
|
443
|
+
function getAbortReason(signal) {
|
|
444
|
+
return signal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
445
|
+
}
|
|
434
446
|
function toReceiptError(value) {
|
|
435
447
|
return isReceiptError(value) ? value : void 0;
|
|
436
448
|
}
|
package/dist/index.js
CHANGED
|
@@ -164,6 +164,7 @@ var RetryTransport = class {
|
|
|
164
164
|
let launchPromise;
|
|
165
165
|
let launchError;
|
|
166
166
|
let hasLaunchError = false;
|
|
167
|
+
let hasQueuedFailure = false;
|
|
167
168
|
let pullingInput = false;
|
|
168
169
|
let closed = false;
|
|
169
170
|
const controller = new AbortController();
|
|
@@ -206,7 +207,7 @@ var RetryTransport = class {
|
|
|
206
207
|
inFlight.set(index, promise);
|
|
207
208
|
};
|
|
208
209
|
const startLaunch = () => {
|
|
209
|
-
if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
210
|
+
if (launchPromise != null || inputDone || hasLaunchError || hasQueuedFailure || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
210
211
|
launchPromise = launchNext().catch((error) => {
|
|
211
212
|
launchError = error;
|
|
212
213
|
hasLaunchError = true;
|
|
@@ -217,6 +218,7 @@ var RetryTransport = class {
|
|
|
217
218
|
try {
|
|
218
219
|
startLaunch();
|
|
219
220
|
while (inFlight.size > 0 || completed.has(nextYieldIndex) || launchPromise != null || !inputDone) {
|
|
221
|
+
combinedSignal.signal.throwIfAborted();
|
|
220
222
|
while (completed.has(nextYieldIndex)) {
|
|
221
223
|
const result$1 = completed.get(nextYieldIndex);
|
|
222
224
|
completed.delete(nextYieldIndex);
|
|
@@ -230,10 +232,11 @@ var RetryTransport = class {
|
|
|
230
232
|
startLaunch();
|
|
231
233
|
if (inFlight.size <= 0 && launchPromise == null) break;
|
|
232
234
|
const launch = launchPromise?.then(() => ({ launched: true }));
|
|
233
|
-
const result = await Promise.race([...inFlight.values(), ...launch == null ? [] : [launch]]);
|
|
235
|
+
const result = await raceWithAbort(Promise.race([...inFlight.values(), ...launch == null ? [] : [launch]]), combinedSignal.signal);
|
|
234
236
|
if ("launched" in result) continue;
|
|
235
237
|
inFlight.delete(result.index);
|
|
236
238
|
completed.set(result.index, result);
|
|
239
|
+
if (!result.successful) hasQueuedFailure = true;
|
|
237
240
|
startLaunch();
|
|
238
241
|
}
|
|
239
242
|
if (hasLaunchError) throw launchError;
|
|
@@ -259,15 +262,20 @@ var RetryTransport = class {
|
|
|
259
262
|
* @since 0.5.0
|
|
260
263
|
*/
|
|
261
264
|
async [Symbol.asyncDispose]() {
|
|
262
|
-
const
|
|
263
|
-
const
|
|
264
|
-
if (typeof
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
const wrappedTransport = Object(this.wrappedTransport);
|
|
266
|
+
const asyncDisposeSymbol = Symbol.asyncDispose;
|
|
267
|
+
if (typeof asyncDisposeSymbol === "symbol") {
|
|
268
|
+
const asyncDispose = wrappedTransport[asyncDisposeSymbol];
|
|
269
|
+
if (typeof asyncDispose === "function") {
|
|
270
|
+
await asyncDispose.call(wrappedTransport);
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const disposeSymbol = Symbol.dispose;
|
|
275
|
+
if (typeof disposeSymbol === "symbol") {
|
|
276
|
+
const dispose = wrappedTransport[disposeSymbol];
|
|
277
|
+
if (typeof dispose === "function") dispose.call(wrappedTransport);
|
|
267
278
|
}
|
|
268
|
-
const disposable = this.wrappedTransport;
|
|
269
|
-
const dispose = disposable[Symbol.dispose];
|
|
270
|
-
if (typeof dispose === "function") dispose.call(disposable);
|
|
271
279
|
}
|
|
272
280
|
withSuccessMetadata(receipt, attempts) {
|
|
273
281
|
return {
|
|
@@ -310,7 +318,7 @@ var RetryTransport = class {
|
|
|
310
318
|
}
|
|
311
319
|
calculateDelay(attempt, failure) {
|
|
312
320
|
const retryAfterMilliseconds = getRetryAfterMilliseconds(failure);
|
|
313
|
-
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds
|
|
321
|
+
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds < 0 ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
314
322
|
if (cappedRetryAfter != null) return cappedRetryAfter;
|
|
315
323
|
const computedDelay = Math.min(this.config.backoff.baseDelayMilliseconds * Math.pow(this.config.backoff.factor, attempt - 1), this.config.backoff.maxDelayMilliseconds);
|
|
316
324
|
if (this.config.jitter === false || this.config.jitter === "none") return computedDelay;
|
|
@@ -374,7 +382,8 @@ function getRetryAfterMilliseconds(failure) {
|
|
|
374
382
|
return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
|
|
375
383
|
}
|
|
376
384
|
function toAsyncIterator(values) {
|
|
377
|
-
|
|
385
|
+
const asyncIterator = values[Symbol.asyncIterator];
|
|
386
|
+
if (typeof asyncIterator === "function") return asyncIterator.call(values);
|
|
378
387
|
const iterator = values[Symbol.iterator]();
|
|
379
388
|
return {
|
|
380
389
|
async next() {
|
|
@@ -389,11 +398,11 @@ function toAsyncIterator(values) {
|
|
|
389
398
|
};
|
|
390
399
|
}
|
|
391
400
|
function raceWithAbort(promise, signal) {
|
|
392
|
-
if (signal.aborted) return Promise.reject(signal
|
|
401
|
+
if (signal.aborted) return Promise.reject(getAbortReason(signal));
|
|
393
402
|
return new Promise((resolve, reject) => {
|
|
394
403
|
const abort = () => {
|
|
395
404
|
cleanup();
|
|
396
|
-
reject(signal
|
|
405
|
+
reject(getAbortReason(signal));
|
|
397
406
|
};
|
|
398
407
|
const cleanup = () => {
|
|
399
408
|
signal.removeEventListener("abort", abort);
|
|
@@ -408,6 +417,9 @@ function raceWithAbort(promise, signal) {
|
|
|
408
417
|
});
|
|
409
418
|
});
|
|
410
419
|
}
|
|
420
|
+
function getAbortReason(signal) {
|
|
421
|
+
return signal.reason ?? new DOMException("The operation was aborted.", "AbortError");
|
|
422
|
+
}
|
|
411
423
|
function toReceiptError(value) {
|
|
412
424
|
return isReceiptError(value) ? value : void 0;
|
|
413
425
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upyo/retry",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.205",
|
|
4
4
|
"description": "Retry and backoff decorator transport for Upyo email library",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"email",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"sideEffects": false,
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@upyo/core": "0.5.0-dev.
|
|
57
|
+
"@upyo/core": "0.5.0-dev.205+0a836319"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"tsdown": "^0.12.7",
|