@upyo/retry 0.5.0-dev.193 → 0.5.0-dev.197

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 CHANGED
@@ -219,7 +219,7 @@ var RetryTransport = class {
219
219
  inFlight.set(index, promise);
220
220
  };
221
221
  const startLaunch = () => {
222
- if (launchPromise != null || inputDone || inFlight.size >= this.config.sendMany.maxConcurrent) return;
222
+ if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
223
223
  launchPromise = launchNext().catch((error) => {
224
224
  launchError = error;
225
225
  hasLaunchError = true;
@@ -230,7 +230,6 @@ var RetryTransport = class {
230
230
  try {
231
231
  startLaunch();
232
232
  while (inFlight.size > 0 || completed.has(nextYieldIndex) || launchPromise != null || !inputDone) {
233
- if (hasLaunchError) throw launchError;
234
233
  while (completed.has(nextYieldIndex)) {
235
234
  const result$1 = completed.get(nextYieldIndex);
236
235
  completed.delete(nextYieldIndex);
@@ -240,6 +239,7 @@ var RetryTransport = class {
240
239
  nextYieldIndex++;
241
240
  startLaunch();
242
241
  }
242
+ if (hasLaunchError && inFlight.size <= 0) throw launchError;
243
243
  startLaunch();
244
244
  if (inFlight.size <= 0 && launchPromise == null) break;
245
245
  const launch = launchPromise?.then(() => ({ launched: true }));
@@ -255,13 +255,10 @@ var RetryTransport = class {
255
255
  controller.abort(new DOMException("The operation was aborted.", "AbortError"));
256
256
  launchPromise?.catch(() => {});
257
257
  try {
258
- const closeIterator = async () => {
259
- if (!inputDone) await iterator.return?.();
260
- };
261
- if (pullingInput) launchPromise?.finally(() => {
262
- closeIterator().catch(() => {});
263
- });
264
- else await closeIterator();
258
+ const closeIterator = () => inputDone ? void 0 : iterator.return?.();
259
+ const closePromise = closeIterator();
260
+ if (pullingInput) closePromise?.catch(() => {});
261
+ else await closePromise;
265
262
  } finally {
266
263
  combinedSignal.cleanup();
267
264
  }
@@ -270,6 +267,8 @@ var RetryTransport = class {
270
267
  /**
271
268
  * Disposes the wrapped transport when it supports disposal.
272
269
  *
270
+ * @throws {unknown} If the wrapped transport's async or sync disposal hook
271
+ * throws or rejects.
273
272
  * @since 0.5.0
274
273
  */
275
274
  async [Symbol.asyncDispose]() {
@@ -354,7 +353,11 @@ var RetryTransport = class {
354
353
  attempts
355
354
  });
356
355
  const message = error instanceof Error ? error.message : String(error);
357
- const classification = (0, __upyo_core.classifyReceiptError)(error);
356
+ const classification = error instanceof Error && error.name === "AbortError" ? {
357
+ category: "timeout",
358
+ code: "timeout",
359
+ retryable: true
360
+ } : (0, __upyo_core.classifyReceiptError)(error);
358
361
  return (0, __upyo_core.createFailedReceipt)((0, __upyo_core.createReceiptError)(message, {
359
362
  provider: this.id,
360
363
  category: classification.category,
@@ -383,8 +386,20 @@ function getRetryAfterMilliseconds(failure) {
383
386
  if (isReceiptError(failure)) return failure.retryAfterMilliseconds;
384
387
  return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
385
388
  }
386
- async function* toAsyncIterator(values) {
387
- for await (const value of values) yield value;
389
+ function toAsyncIterator(values) {
390
+ if (Symbol.asyncIterator in values) return values[Symbol.asyncIterator]();
391
+ const iterator = values[Symbol.iterator]();
392
+ return {
393
+ next() {
394
+ return Promise.resolve(iterator.next());
395
+ },
396
+ return(value) {
397
+ return Promise.resolve(iterator.return?.(value) ?? {
398
+ done: true,
399
+ value
400
+ });
401
+ }
402
+ };
388
403
  }
389
404
  function toReceiptError(value) {
390
405
  return isReceiptError(value) ? value : void 0;
package/dist/index.d.cts CHANGED
@@ -232,6 +232,8 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
232
232
  /**
233
233
  * Disposes the wrapped transport when it supports disposal.
234
234
  *
235
+ * @throws {unknown} If the wrapped transport's async or sync disposal hook
236
+ * throws or rejects.
235
237
  * @since 0.5.0
236
238
  */
237
239
  [Symbol.asyncDispose](): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -232,6 +232,8 @@ declare class RetryTransport<TProviderId extends string = string> implements Tra
232
232
  /**
233
233
  * Disposes the wrapped transport when it supports disposal.
234
234
  *
235
+ * @throws {unknown} If the wrapped transport's async or sync disposal hook
236
+ * throws or rejects.
235
237
  * @since 0.5.0
236
238
  */
237
239
  [Symbol.asyncDispose](): Promise<void>;
package/dist/index.js CHANGED
@@ -196,7 +196,7 @@ var RetryTransport = class {
196
196
  inFlight.set(index, promise);
197
197
  };
198
198
  const startLaunch = () => {
199
- if (launchPromise != null || inputDone || inFlight.size >= this.config.sendMany.maxConcurrent) return;
199
+ if (launchPromise != null || inputDone || hasLaunchError || inFlight.size >= this.config.sendMany.maxConcurrent) return;
200
200
  launchPromise = launchNext().catch((error) => {
201
201
  launchError = error;
202
202
  hasLaunchError = true;
@@ -207,7 +207,6 @@ var RetryTransport = class {
207
207
  try {
208
208
  startLaunch();
209
209
  while (inFlight.size > 0 || completed.has(nextYieldIndex) || launchPromise != null || !inputDone) {
210
- if (hasLaunchError) throw launchError;
211
210
  while (completed.has(nextYieldIndex)) {
212
211
  const result$1 = completed.get(nextYieldIndex);
213
212
  completed.delete(nextYieldIndex);
@@ -217,6 +216,7 @@ var RetryTransport = class {
217
216
  nextYieldIndex++;
218
217
  startLaunch();
219
218
  }
219
+ if (hasLaunchError && inFlight.size <= 0) throw launchError;
220
220
  startLaunch();
221
221
  if (inFlight.size <= 0 && launchPromise == null) break;
222
222
  const launch = launchPromise?.then(() => ({ launched: true }));
@@ -232,13 +232,10 @@ var RetryTransport = class {
232
232
  controller.abort(new DOMException("The operation was aborted.", "AbortError"));
233
233
  launchPromise?.catch(() => {});
234
234
  try {
235
- const closeIterator = async () => {
236
- if (!inputDone) await iterator.return?.();
237
- };
238
- if (pullingInput) launchPromise?.finally(() => {
239
- closeIterator().catch(() => {});
240
- });
241
- else await closeIterator();
235
+ const closeIterator = () => inputDone ? void 0 : iterator.return?.();
236
+ const closePromise = closeIterator();
237
+ if (pullingInput) closePromise?.catch(() => {});
238
+ else await closePromise;
242
239
  } finally {
243
240
  combinedSignal.cleanup();
244
241
  }
@@ -247,6 +244,8 @@ var RetryTransport = class {
247
244
  /**
248
245
  * Disposes the wrapped transport when it supports disposal.
249
246
  *
247
+ * @throws {unknown} If the wrapped transport's async or sync disposal hook
248
+ * throws or rejects.
250
249
  * @since 0.5.0
251
250
  */
252
251
  async [Symbol.asyncDispose]() {
@@ -331,7 +330,11 @@ var RetryTransport = class {
331
330
  attempts
332
331
  });
333
332
  const message = error instanceof Error ? error.message : String(error);
334
- const classification = classifyReceiptError(error);
333
+ const classification = error instanceof Error && error.name === "AbortError" ? {
334
+ category: "timeout",
335
+ code: "timeout",
336
+ retryable: true
337
+ } : classifyReceiptError(error);
335
338
  return createFailedReceipt(createReceiptError(message, {
336
339
  provider: this.id,
337
340
  category: classification.category,
@@ -360,8 +363,20 @@ function getRetryAfterMilliseconds(failure) {
360
363
  if (isReceiptError(failure)) return failure.retryAfterMilliseconds;
361
364
  return failure.errors?.find((error) => error.retryAfterMilliseconds != null)?.retryAfterMilliseconds;
362
365
  }
363
- async function* toAsyncIterator(values) {
364
- for await (const value of values) yield value;
366
+ function toAsyncIterator(values) {
367
+ if (Symbol.asyncIterator in values) return values[Symbol.asyncIterator]();
368
+ const iterator = values[Symbol.iterator]();
369
+ return {
370
+ next() {
371
+ return Promise.resolve(iterator.next());
372
+ },
373
+ return(value) {
374
+ return Promise.resolve(iterator.return?.(value) ?? {
375
+ done: true,
376
+ value
377
+ });
378
+ }
379
+ };
365
380
  }
366
381
  function toReceiptError(value) {
367
382
  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.193",
3
+ "version": "0.5.0-dev.197",
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.193+eb1e84b9"
57
+ "@upyo/core": "0.5.0-dev.197+0d26a10d"
58
58
  },
59
59
  "devDependencies": {
60
60
  "tsdown": "^0.12.7",