@upyo/retry 0.5.0-dev.195 → 0.5.0-dev.199
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 +69 -28
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +69 -28
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -113,6 +113,7 @@ var RetryTransport = class {
|
|
|
113
113
|
* @param transport The transport to wrap.
|
|
114
114
|
* @param config Retry configuration.
|
|
115
115
|
* @throws {RangeError} If retry configuration is invalid.
|
|
116
|
+
* @since 0.5.0
|
|
116
117
|
*/
|
|
117
118
|
constructor(transport, config = {}) {
|
|
118
119
|
this.wrappedTransport = transport;
|
|
@@ -126,25 +127,16 @@ var RetryTransport = class {
|
|
|
126
127
|
* @param options Optional transport options.
|
|
127
128
|
* @returns The final delivery receipt.
|
|
128
129
|
* @throws {DOMException} If the operation is aborted.
|
|
130
|
+
* @since 0.5.0
|
|
129
131
|
*/
|
|
130
132
|
async send(message, options) {
|
|
131
133
|
options?.signal?.throwIfAborted();
|
|
132
134
|
let lastThrownError;
|
|
133
135
|
for (let attempt = 1; attempt <= this.config.maxAttempts; attempt++) {
|
|
134
136
|
options?.signal?.throwIfAborted();
|
|
137
|
+
let receipt;
|
|
135
138
|
try {
|
|
136
|
-
|
|
137
|
-
if (receipt.successful) return this.withSuccessMetadata(receipt, attempt);
|
|
138
|
-
const failedReceipt = this.withFailureMetadata(receipt, attempt);
|
|
139
|
-
if (attempt >= this.config.maxAttempts || !this.shouldRetryReceipt(failedReceipt)) return failedReceipt;
|
|
140
|
-
await this.waitBeforeRetry({
|
|
141
|
-
attempt,
|
|
142
|
-
nextAttempt: attempt + 1,
|
|
143
|
-
maxAttempts: this.config.maxAttempts,
|
|
144
|
-
delayMilliseconds: this.calculateDelay(attempt, failedReceipt),
|
|
145
|
-
receipt: failedReceipt,
|
|
146
|
-
reason: "retry"
|
|
147
|
-
}, options?.signal);
|
|
139
|
+
receipt = await this.wrappedTransport.send(message, options);
|
|
148
140
|
} catch (error) {
|
|
149
141
|
options?.signal?.throwIfAborted();
|
|
150
142
|
lastThrownError = error;
|
|
@@ -157,7 +149,20 @@ var RetryTransport = class {
|
|
|
157
149
|
error,
|
|
158
150
|
reason: "retry"
|
|
159
151
|
}, options?.signal);
|
|
152
|
+
continue;
|
|
160
153
|
}
|
|
154
|
+
options?.signal?.throwIfAborted();
|
|
155
|
+
if (receipt.successful) return this.withSuccessMetadata(receipt, attempt);
|
|
156
|
+
const failedReceipt = this.withFailureMetadata(receipt, attempt);
|
|
157
|
+
if (attempt >= this.config.maxAttempts || !this.shouldRetryReceipt(failedReceipt)) return failedReceipt;
|
|
158
|
+
await this.waitBeforeRetry({
|
|
159
|
+
attempt,
|
|
160
|
+
nextAttempt: attempt + 1,
|
|
161
|
+
maxAttempts: this.config.maxAttempts,
|
|
162
|
+
delayMilliseconds: this.calculateDelay(attempt, failedReceipt),
|
|
163
|
+
receipt: failedReceipt,
|
|
164
|
+
reason: "retry"
|
|
165
|
+
}, options?.signal);
|
|
161
166
|
}
|
|
162
167
|
return this.createThrownFailure(lastThrownError, this.config.maxAttempts);
|
|
163
168
|
}
|
|
@@ -170,6 +175,7 @@ var RetryTransport = class {
|
|
|
170
175
|
* @param options Optional transport options.
|
|
171
176
|
* @returns An async iterable of receipts.
|
|
172
177
|
* @throws {DOMException} If the operation is aborted.
|
|
178
|
+
* @since 0.5.0
|
|
173
179
|
*/
|
|
174
180
|
async *sendMany(messages, options) {
|
|
175
181
|
const iterator = toAsyncIterator(messages);
|
|
@@ -193,12 +199,16 @@ var RetryTransport = class {
|
|
|
193
199
|
if (inputDone) return;
|
|
194
200
|
combinedSignal.signal.throwIfAborted();
|
|
195
201
|
pullingInput = true;
|
|
196
|
-
let
|
|
202
|
+
let inputPull;
|
|
197
203
|
try {
|
|
198
|
-
|
|
199
|
-
}
|
|
200
|
-
|
|
204
|
+
inputPull = Promise.resolve(iterator.next());
|
|
205
|
+
} catch (error) {
|
|
206
|
+
inputPull = Promise.reject(error);
|
|
201
207
|
}
|
|
208
|
+
inputPull = inputPull.finally(() => {
|
|
209
|
+
pullingInput = false;
|
|
210
|
+
});
|
|
211
|
+
const next = await raceWithAbort(inputPull, combinedSignal.signal);
|
|
202
212
|
if (closed) return;
|
|
203
213
|
if (next.done) {
|
|
204
214
|
inputDone = true;
|
|
@@ -219,7 +229,7 @@ var RetryTransport = class {
|
|
|
219
229
|
inFlight.set(index, promise);
|
|
220
230
|
};
|
|
221
231
|
const startLaunch = () => {
|
|
222
|
-
if (launchPromise != null || inputDone || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
232
|
+
if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
223
233
|
launchPromise = launchNext().catch((error) => {
|
|
224
234
|
launchError = error;
|
|
225
235
|
hasLaunchError = true;
|
|
@@ -239,7 +249,7 @@ var RetryTransport = class {
|
|
|
239
249
|
nextYieldIndex++;
|
|
240
250
|
startLaunch();
|
|
241
251
|
}
|
|
242
|
-
if (hasLaunchError) throw launchError;
|
|
252
|
+
if (hasLaunchError && inFlight.size <= 0) throw launchError;
|
|
243
253
|
startLaunch();
|
|
244
254
|
if (inFlight.size <= 0 && launchPromise == null) break;
|
|
245
255
|
const launch = launchPromise?.then(() => ({ launched: true }));
|
|
@@ -255,13 +265,10 @@ var RetryTransport = class {
|
|
|
255
265
|
controller.abort(new DOMException("The operation was aborted.", "AbortError"));
|
|
256
266
|
launchPromise?.catch(() => {});
|
|
257
267
|
try {
|
|
258
|
-
const closeIterator =
|
|
259
|
-
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
closeIterator().catch(() => {});
|
|
263
|
-
});
|
|
264
|
-
else await closeIterator();
|
|
268
|
+
const closeIterator = () => inputDone ? void 0 : iterator.return?.();
|
|
269
|
+
const closePromise = closeIterator();
|
|
270
|
+
if (pullingInput) closePromise?.catch(() => {});
|
|
271
|
+
else await closePromise;
|
|
265
272
|
} finally {
|
|
266
273
|
combinedSignal.cleanup();
|
|
267
274
|
}
|
|
@@ -270,6 +277,8 @@ var RetryTransport = class {
|
|
|
270
277
|
/**
|
|
271
278
|
* Disposes the wrapped transport when it supports disposal.
|
|
272
279
|
*
|
|
280
|
+
* @throws {unknown} If the wrapped transport's async or sync disposal hook
|
|
281
|
+
* throws or rejects.
|
|
273
282
|
* @since 0.5.0
|
|
274
283
|
*/
|
|
275
284
|
async [Symbol.asyncDispose]() {
|
|
@@ -324,7 +333,7 @@ var RetryTransport = class {
|
|
|
324
333
|
}
|
|
325
334
|
calculateDelay(attempt, failure) {
|
|
326
335
|
const retryAfterMilliseconds = getRetryAfterMilliseconds(failure);
|
|
327
|
-
const cappedRetryAfter = retryAfterMilliseconds == null ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
336
|
+
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds <= 0 ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
328
337
|
if (cappedRetryAfter != null) return cappedRetryAfter;
|
|
329
338
|
const computedDelay = Math.min(this.config.backoff.baseDelayMilliseconds * Math.pow(this.config.backoff.factor, attempt - 1), this.config.backoff.maxDelayMilliseconds);
|
|
330
339
|
if (this.config.jitter === false || this.config.jitter === "none") return computedDelay;
|
|
@@ -387,8 +396,40 @@ function getRetryAfterMilliseconds(failure) {
|
|
|
387
396
|
if (isReceiptError(failure)) return failure.retryAfterMilliseconds;
|
|
388
397
|
return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
|
|
389
398
|
}
|
|
390
|
-
|
|
391
|
-
|
|
399
|
+
function toAsyncIterator(values) {
|
|
400
|
+
if (Symbol.asyncIterator in values) return values[Symbol.asyncIterator]();
|
|
401
|
+
const iterator = values[Symbol.iterator]();
|
|
402
|
+
return {
|
|
403
|
+
async next() {
|
|
404
|
+
return await Promise.resolve(iterator.next());
|
|
405
|
+
},
|
|
406
|
+
async return(value) {
|
|
407
|
+
return await Promise.resolve(iterator.return?.(value) ?? {
|
|
408
|
+
done: true,
|
|
409
|
+
value
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
function raceWithAbort(promise, signal) {
|
|
415
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
416
|
+
return new Promise((resolve, reject) => {
|
|
417
|
+
const abort = () => {
|
|
418
|
+
cleanup();
|
|
419
|
+
reject(signal.reason);
|
|
420
|
+
};
|
|
421
|
+
const cleanup = () => {
|
|
422
|
+
signal.removeEventListener("abort", abort);
|
|
423
|
+
};
|
|
424
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
425
|
+
promise.then((value) => {
|
|
426
|
+
cleanup();
|
|
427
|
+
resolve(value);
|
|
428
|
+
}, (error) => {
|
|
429
|
+
cleanup();
|
|
430
|
+
reject(error);
|
|
431
|
+
});
|
|
432
|
+
});
|
|
392
433
|
}
|
|
393
434
|
function toReceiptError(value) {
|
|
394
435
|
return isReceiptError(value) ? value : void 0;
|
package/dist/index.d.cts
CHANGED
|
@@ -207,6 +207,7 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
207
207
|
* @param transport The transport to wrap.
|
|
208
208
|
* @param config Retry configuration.
|
|
209
209
|
* @throws {RangeError} If retry configuration is invalid.
|
|
210
|
+
* @since 0.5.0
|
|
210
211
|
*/
|
|
211
212
|
constructor(transport: Transport<TProviderId>, config?: RetryConfig<TProviderId>);
|
|
212
213
|
/**
|
|
@@ -216,6 +217,7 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
216
217
|
* @param options Optional transport options.
|
|
217
218
|
* @returns The final delivery receipt.
|
|
218
219
|
* @throws {DOMException} If the operation is aborted.
|
|
220
|
+
* @since 0.5.0
|
|
219
221
|
*/
|
|
220
222
|
send(message: Message, options?: TransportOptions): Promise<Receipt<TProviderId>>;
|
|
221
223
|
/**
|
|
@@ -227,11 +229,14 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
227
229
|
* @param options Optional transport options.
|
|
228
230
|
* @returns An async iterable of receipts.
|
|
229
231
|
* @throws {DOMException} If the operation is aborted.
|
|
232
|
+
* @since 0.5.0
|
|
230
233
|
*/
|
|
231
234
|
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<TProviderId>>;
|
|
232
235
|
/**
|
|
233
236
|
* Disposes the wrapped transport when it supports disposal.
|
|
234
237
|
*
|
|
238
|
+
* @throws {unknown} If the wrapped transport's async or sync disposal hook
|
|
239
|
+
* throws or rejects.
|
|
235
240
|
* @since 0.5.0
|
|
236
241
|
*/
|
|
237
242
|
[Symbol.asyncDispose](): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,7 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
207
207
|
* @param transport The transport to wrap.
|
|
208
208
|
* @param config Retry configuration.
|
|
209
209
|
* @throws {RangeError} If retry configuration is invalid.
|
|
210
|
+
* @since 0.5.0
|
|
210
211
|
*/
|
|
211
212
|
constructor(transport: Transport<TProviderId>, config?: RetryConfig<TProviderId>);
|
|
212
213
|
/**
|
|
@@ -216,6 +217,7 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
216
217
|
* @param options Optional transport options.
|
|
217
218
|
* @returns The final delivery receipt.
|
|
218
219
|
* @throws {DOMException} If the operation is aborted.
|
|
220
|
+
* @since 0.5.0
|
|
219
221
|
*/
|
|
220
222
|
send(message: Message, options?: TransportOptions): Promise<Receipt<TProviderId>>;
|
|
221
223
|
/**
|
|
@@ -227,11 +229,14 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
|
|
|
227
229
|
* @param options Optional transport options.
|
|
228
230
|
* @returns An async iterable of receipts.
|
|
229
231
|
* @throws {DOMException} If the operation is aborted.
|
|
232
|
+
* @since 0.5.0
|
|
230
233
|
*/
|
|
231
234
|
sendMany(messages: Iterable<Message> | AsyncIterable<Message>, options?: TransportOptions): AsyncIterable<Receipt<TProviderId>>;
|
|
232
235
|
/**
|
|
233
236
|
* Disposes the wrapped transport when it supports disposal.
|
|
234
237
|
*
|
|
238
|
+
* @throws {unknown} If the wrapped transport's async or sync disposal hook
|
|
239
|
+
* throws or rejects.
|
|
235
240
|
* @since 0.5.0
|
|
236
241
|
*/
|
|
237
242
|
[Symbol.asyncDispose](): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -90,6 +90,7 @@ var RetryTransport = class {
|
|
|
90
90
|
* @param transport The transport to wrap.
|
|
91
91
|
* @param config Retry configuration.
|
|
92
92
|
* @throws {RangeError} If retry configuration is invalid.
|
|
93
|
+
* @since 0.5.0
|
|
93
94
|
*/
|
|
94
95
|
constructor(transport, config = {}) {
|
|
95
96
|
this.wrappedTransport = transport;
|
|
@@ -103,25 +104,16 @@ var RetryTransport = class {
|
|
|
103
104
|
* @param options Optional transport options.
|
|
104
105
|
* @returns The final delivery receipt.
|
|
105
106
|
* @throws {DOMException} If the operation is aborted.
|
|
107
|
+
* @since 0.5.0
|
|
106
108
|
*/
|
|
107
109
|
async send(message, options) {
|
|
108
110
|
options?.signal?.throwIfAborted();
|
|
109
111
|
let lastThrownError;
|
|
110
112
|
for (let attempt = 1; attempt <= this.config.maxAttempts; attempt++) {
|
|
111
113
|
options?.signal?.throwIfAborted();
|
|
114
|
+
let receipt;
|
|
112
115
|
try {
|
|
113
|
-
|
|
114
|
-
if (receipt.successful) return this.withSuccessMetadata(receipt, attempt);
|
|
115
|
-
const failedReceipt = this.withFailureMetadata(receipt, attempt);
|
|
116
|
-
if (attempt >= this.config.maxAttempts || !this.shouldRetryReceipt(failedReceipt)) return failedReceipt;
|
|
117
|
-
await this.waitBeforeRetry({
|
|
118
|
-
attempt,
|
|
119
|
-
nextAttempt: attempt + 1,
|
|
120
|
-
maxAttempts: this.config.maxAttempts,
|
|
121
|
-
delayMilliseconds: this.calculateDelay(attempt, failedReceipt),
|
|
122
|
-
receipt: failedReceipt,
|
|
123
|
-
reason: "retry"
|
|
124
|
-
}, options?.signal);
|
|
116
|
+
receipt = await this.wrappedTransport.send(message, options);
|
|
125
117
|
} catch (error) {
|
|
126
118
|
options?.signal?.throwIfAborted();
|
|
127
119
|
lastThrownError = error;
|
|
@@ -134,7 +126,20 @@ var RetryTransport = class {
|
|
|
134
126
|
error,
|
|
135
127
|
reason: "retry"
|
|
136
128
|
}, options?.signal);
|
|
129
|
+
continue;
|
|
137
130
|
}
|
|
131
|
+
options?.signal?.throwIfAborted();
|
|
132
|
+
if (receipt.successful) return this.withSuccessMetadata(receipt, attempt);
|
|
133
|
+
const failedReceipt = this.withFailureMetadata(receipt, attempt);
|
|
134
|
+
if (attempt >= this.config.maxAttempts || !this.shouldRetryReceipt(failedReceipt)) return failedReceipt;
|
|
135
|
+
await this.waitBeforeRetry({
|
|
136
|
+
attempt,
|
|
137
|
+
nextAttempt: attempt + 1,
|
|
138
|
+
maxAttempts: this.config.maxAttempts,
|
|
139
|
+
delayMilliseconds: this.calculateDelay(attempt, failedReceipt),
|
|
140
|
+
receipt: failedReceipt,
|
|
141
|
+
reason: "retry"
|
|
142
|
+
}, options?.signal);
|
|
138
143
|
}
|
|
139
144
|
return this.createThrownFailure(lastThrownError, this.config.maxAttempts);
|
|
140
145
|
}
|
|
@@ -147,6 +152,7 @@ var RetryTransport = class {
|
|
|
147
152
|
* @param options Optional transport options.
|
|
148
153
|
* @returns An async iterable of receipts.
|
|
149
154
|
* @throws {DOMException} If the operation is aborted.
|
|
155
|
+
* @since 0.5.0
|
|
150
156
|
*/
|
|
151
157
|
async *sendMany(messages, options) {
|
|
152
158
|
const iterator = toAsyncIterator(messages);
|
|
@@ -170,12 +176,16 @@ var RetryTransport = class {
|
|
|
170
176
|
if (inputDone) return;
|
|
171
177
|
combinedSignal.signal.throwIfAborted();
|
|
172
178
|
pullingInput = true;
|
|
173
|
-
let
|
|
179
|
+
let inputPull;
|
|
174
180
|
try {
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
181
|
+
inputPull = Promise.resolve(iterator.next());
|
|
182
|
+
} catch (error) {
|
|
183
|
+
inputPull = Promise.reject(error);
|
|
178
184
|
}
|
|
185
|
+
inputPull = inputPull.finally(() => {
|
|
186
|
+
pullingInput = false;
|
|
187
|
+
});
|
|
188
|
+
const next = await raceWithAbort(inputPull, combinedSignal.signal);
|
|
179
189
|
if (closed) return;
|
|
180
190
|
if (next.done) {
|
|
181
191
|
inputDone = true;
|
|
@@ -196,7 +206,7 @@ var RetryTransport = class {
|
|
|
196
206
|
inFlight.set(index, promise);
|
|
197
207
|
};
|
|
198
208
|
const startLaunch = () => {
|
|
199
|
-
if (launchPromise != null || inputDone || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
209
|
+
if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
|
|
200
210
|
launchPromise = launchNext().catch((error) => {
|
|
201
211
|
launchError = error;
|
|
202
212
|
hasLaunchError = true;
|
|
@@ -216,7 +226,7 @@ var RetryTransport = class {
|
|
|
216
226
|
nextYieldIndex++;
|
|
217
227
|
startLaunch();
|
|
218
228
|
}
|
|
219
|
-
if (hasLaunchError) throw launchError;
|
|
229
|
+
if (hasLaunchError && inFlight.size <= 0) throw launchError;
|
|
220
230
|
startLaunch();
|
|
221
231
|
if (inFlight.size <= 0 && launchPromise == null) break;
|
|
222
232
|
const launch = launchPromise?.then(() => ({ launched: true }));
|
|
@@ -232,13 +242,10 @@ var RetryTransport = class {
|
|
|
232
242
|
controller.abort(new DOMException("The operation was aborted.", "AbortError"));
|
|
233
243
|
launchPromise?.catch(() => {});
|
|
234
244
|
try {
|
|
235
|
-
const closeIterator =
|
|
236
|
-
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
closeIterator().catch(() => {});
|
|
240
|
-
});
|
|
241
|
-
else await closeIterator();
|
|
245
|
+
const closeIterator = () => inputDone ? void 0 : iterator.return?.();
|
|
246
|
+
const closePromise = closeIterator();
|
|
247
|
+
if (pullingInput) closePromise?.catch(() => {});
|
|
248
|
+
else await closePromise;
|
|
242
249
|
} finally {
|
|
243
250
|
combinedSignal.cleanup();
|
|
244
251
|
}
|
|
@@ -247,6 +254,8 @@ var RetryTransport = class {
|
|
|
247
254
|
/**
|
|
248
255
|
* Disposes the wrapped transport when it supports disposal.
|
|
249
256
|
*
|
|
257
|
+
* @throws {unknown} If the wrapped transport's async or sync disposal hook
|
|
258
|
+
* throws or rejects.
|
|
250
259
|
* @since 0.5.0
|
|
251
260
|
*/
|
|
252
261
|
async [Symbol.asyncDispose]() {
|
|
@@ -301,7 +310,7 @@ var RetryTransport = class {
|
|
|
301
310
|
}
|
|
302
311
|
calculateDelay(attempt, failure) {
|
|
303
312
|
const retryAfterMilliseconds = getRetryAfterMilliseconds(failure);
|
|
304
|
-
const cappedRetryAfter = retryAfterMilliseconds == null ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
313
|
+
const cappedRetryAfter = retryAfterMilliseconds == null || !Number.isFinite(retryAfterMilliseconds) || retryAfterMilliseconds <= 0 ? void 0 : Math.min(retryAfterMilliseconds, this.config.backoff.maxDelayMilliseconds);
|
|
305
314
|
if (cappedRetryAfter != null) return cappedRetryAfter;
|
|
306
315
|
const computedDelay = Math.min(this.config.backoff.baseDelayMilliseconds * Math.pow(this.config.backoff.factor, attempt - 1), this.config.backoff.maxDelayMilliseconds);
|
|
307
316
|
if (this.config.jitter === false || this.config.jitter === "none") return computedDelay;
|
|
@@ -364,8 +373,40 @@ function getRetryAfterMilliseconds(failure) {
|
|
|
364
373
|
if (isReceiptError(failure)) return failure.retryAfterMilliseconds;
|
|
365
374
|
return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
|
|
366
375
|
}
|
|
367
|
-
|
|
368
|
-
|
|
376
|
+
function toAsyncIterator(values) {
|
|
377
|
+
if (Symbol.asyncIterator in values) return values[Symbol.asyncIterator]();
|
|
378
|
+
const iterator = values[Symbol.iterator]();
|
|
379
|
+
return {
|
|
380
|
+
async next() {
|
|
381
|
+
return await Promise.resolve(iterator.next());
|
|
382
|
+
},
|
|
383
|
+
async return(value) {
|
|
384
|
+
return await Promise.resolve(iterator.return?.(value) ?? {
|
|
385
|
+
done: true,
|
|
386
|
+
value
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
function raceWithAbort(promise, signal) {
|
|
392
|
+
if (signal.aborted) return Promise.reject(signal.reason);
|
|
393
|
+
return new Promise((resolve, reject) => {
|
|
394
|
+
const abort = () => {
|
|
395
|
+
cleanup();
|
|
396
|
+
reject(signal.reason);
|
|
397
|
+
};
|
|
398
|
+
const cleanup = () => {
|
|
399
|
+
signal.removeEventListener("abort", abort);
|
|
400
|
+
};
|
|
401
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
402
|
+
promise.then((value) => {
|
|
403
|
+
cleanup();
|
|
404
|
+
resolve(value);
|
|
405
|
+
}, (error) => {
|
|
406
|
+
cleanup();
|
|
407
|
+
reject(error);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
369
410
|
}
|
|
370
411
|
function toReceiptError(value) {
|
|
371
412
|
return isReceiptError(value) ? value : void 0;
|
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.199",
|
|
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.199+f10145fc"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"tsdown": "^0.12.7",
|