@upyo/pool 0.5.0-dev.168 → 0.5.0-dev.170

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
@@ -328,6 +328,7 @@ var PoolTransport = class {
328
328
  const attemptedIndices = /* @__PURE__ */ new Set();
329
329
  const errorMessages = [];
330
330
  const errors = [];
331
+ let checkCallerAbortBeforeFailure = false;
331
332
  for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
332
333
  if (options?.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
333
334
  const selection = this.strategy.select(message, this.config.transports, attemptedIndices);
@@ -351,24 +352,29 @@ var PoolTransport = class {
351
352
  if (receipt.successful) return receipt;
352
353
  errorMessages.push(...receipt.errorMessages);
353
354
  errors.push(...getReceiptErrors(receipt, selection.entry.transport.id));
355
+ checkCallerAbortBeforeFailure = true;
354
356
  } catch (error) {
355
357
  if (abortedByCaller && isCallerAbort(error, options?.signal)) throw error;
356
358
  const thrownErrors = getThrownReceiptErrors(error, selection.entry.transport.id);
357
359
  if (thrownErrors.length > 0) {
358
360
  errorMessages.push(...thrownErrors.map((item) => item.message));
359
361
  errors.push(...thrownErrors);
362
+ checkCallerAbortBeforeFailure = true;
360
363
  continue;
361
364
  }
362
365
  const timeoutMessage = "Transport send timed out.";
363
- const errorMessage = isAbortError(error) ? timeoutMessage : error instanceof Error ? error.message : String(error);
366
+ const abortError = isAbortError(error);
367
+ const errorMessage = abortError ? timeoutMessage : error instanceof Error ? error.message : String(error);
364
368
  errorMessages.push(errorMessage);
365
369
  errors.push((0, __upyo_core.createReceiptError)(errorMessage, {
366
370
  provider: selection.entry.transport.id,
367
- category: isAbortError(error) ? "timeout" : void 0,
368
- retryable: isAbortError(error) ? true : void 0
371
+ category: abortError ? "timeout" : void 0,
372
+ retryable: abortError ? true : void 0
369
373
  }));
374
+ checkCallerAbortBeforeFailure ||= !abortError;
370
375
  }
371
376
  }
377
+ if (checkCallerAbortBeforeFailure) options?.signal?.throwIfAborted();
372
378
  return (0, __upyo_core.createFailedReceipt)(errorMessages.length > 0 ? errorMessages : ["All transports failed to send the message."], {
373
379
  provider: "pool",
374
380
  errors: errors.length > 0 ? errors : void 0,
@@ -450,7 +456,7 @@ var PoolTransport = class {
450
456
  if (options.signal.aborted) markCallerAbort();
451
457
  else options.signal.addEventListener("abort", markCallerAbort, { once: true });
452
458
  cleanupAbortSource = () => options.signal?.removeEventListener("abort", markCallerAbort);
453
- const combinedSignal = combineSignals(timeoutController.signal, options.signal);
459
+ const combinedSignal = (0, __upyo_core.combineSignals)(timeoutController.signal, options.signal);
454
460
  signal = combinedSignal.signal;
455
461
  cleanupCombinedSignal = combinedSignal.cleanup;
456
462
  }
@@ -471,32 +477,6 @@ var PoolTransport = class {
471
477
  };
472
478
  }
473
479
  };
474
- function combineSignals(timeoutSignal, externalSignal) {
475
- if (typeof AbortSignal.any === "function") return {
476
- signal: AbortSignal.any([timeoutSignal, externalSignal]),
477
- cleanup: () => {}
478
- };
479
- const controller = new AbortController();
480
- const abort = (signal) => {
481
- controller.abort(getAbortReason(signal));
482
- };
483
- const abortTimeout = () => abort(timeoutSignal);
484
- const abortExternal = () => abort(externalSignal);
485
- timeoutSignal.addEventListener("abort", abortTimeout, { once: true });
486
- externalSignal.addEventListener("abort", abortExternal, { once: true });
487
- if (timeoutSignal.aborted) abortTimeout();
488
- else if (externalSignal.aborted) abortExternal();
489
- return {
490
- signal: controller.signal,
491
- cleanup: () => {
492
- timeoutSignal.removeEventListener("abort", abortTimeout);
493
- externalSignal.removeEventListener("abort", abortExternal);
494
- }
495
- };
496
- }
497
- function getAbortReason(signal) {
498
- return signal.reason ?? createAbortError();
499
- }
500
480
  function createAbortError() {
501
481
  return new DOMException("The operation was aborted.", "AbortError");
502
482
  }
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createFailedReceipt, createReceiptError } from "@upyo/core";
1
+ import { combineSignals, createFailedReceipt, createReceiptError } from "@upyo/core";
2
2
 
3
3
  //#region src/config.ts
4
4
  /**
@@ -305,6 +305,7 @@ var PoolTransport = class {
305
305
  const attemptedIndices = /* @__PURE__ */ new Set();
306
306
  const errorMessages = [];
307
307
  const errors = [];
308
+ let checkCallerAbortBeforeFailure = false;
308
309
  for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
309
310
  if (options?.signal?.aborted) throw new DOMException("The operation was aborted.", "AbortError");
310
311
  const selection = this.strategy.select(message, this.config.transports, attemptedIndices);
@@ -328,24 +329,29 @@ var PoolTransport = class {
328
329
  if (receipt.successful) return receipt;
329
330
  errorMessages.push(...receipt.errorMessages);
330
331
  errors.push(...getReceiptErrors(receipt, selection.entry.transport.id));
332
+ checkCallerAbortBeforeFailure = true;
331
333
  } catch (error) {
332
334
  if (abortedByCaller && isCallerAbort(error, options?.signal)) throw error;
333
335
  const thrownErrors = getThrownReceiptErrors(error, selection.entry.transport.id);
334
336
  if (thrownErrors.length > 0) {
335
337
  errorMessages.push(...thrownErrors.map((item) => item.message));
336
338
  errors.push(...thrownErrors);
339
+ checkCallerAbortBeforeFailure = true;
337
340
  continue;
338
341
  }
339
342
  const timeoutMessage = "Transport send timed out.";
340
- const errorMessage = isAbortError(error) ? timeoutMessage : error instanceof Error ? error.message : String(error);
343
+ const abortError = isAbortError(error);
344
+ const errorMessage = abortError ? timeoutMessage : error instanceof Error ? error.message : String(error);
341
345
  errorMessages.push(errorMessage);
342
346
  errors.push(createReceiptError(errorMessage, {
343
347
  provider: selection.entry.transport.id,
344
- category: isAbortError(error) ? "timeout" : void 0,
345
- retryable: isAbortError(error) ? true : void 0
348
+ category: abortError ? "timeout" : void 0,
349
+ retryable: abortError ? true : void 0
346
350
  }));
351
+ checkCallerAbortBeforeFailure ||= !abortError;
347
352
  }
348
353
  }
354
+ if (checkCallerAbortBeforeFailure) options?.signal?.throwIfAborted();
349
355
  return createFailedReceipt(errorMessages.length > 0 ? errorMessages : ["All transports failed to send the message."], {
350
356
  provider: "pool",
351
357
  errors: errors.length > 0 ? errors : void 0,
@@ -448,32 +454,6 @@ var PoolTransport = class {
448
454
  };
449
455
  }
450
456
  };
451
- function combineSignals(timeoutSignal, externalSignal) {
452
- if (typeof AbortSignal.any === "function") return {
453
- signal: AbortSignal.any([timeoutSignal, externalSignal]),
454
- cleanup: () => {}
455
- };
456
- const controller = new AbortController();
457
- const abort = (signal) => {
458
- controller.abort(getAbortReason(signal));
459
- };
460
- const abortTimeout = () => abort(timeoutSignal);
461
- const abortExternal = () => abort(externalSignal);
462
- timeoutSignal.addEventListener("abort", abortTimeout, { once: true });
463
- externalSignal.addEventListener("abort", abortExternal, { once: true });
464
- if (timeoutSignal.aborted) abortTimeout();
465
- else if (externalSignal.aborted) abortExternal();
466
- return {
467
- signal: controller.signal,
468
- cleanup: () => {
469
- timeoutSignal.removeEventListener("abort", abortTimeout);
470
- externalSignal.removeEventListener("abort", abortExternal);
471
- }
472
- };
473
- }
474
- function getAbortReason(signal) {
475
- return signal.reason ?? createAbortError();
476
- }
477
457
  function createAbortError() {
478
458
  return new DOMException("The operation was aborted.", "AbortError");
479
459
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upyo/pool",
3
- "version": "0.5.0-dev.168",
3
+ "version": "0.5.0-dev.170",
4
4
  "description": "Pool transport for Upyo email library—provides load balancing and failover for multiple email providers",
5
5
  "keywords": [
6
6
  "email",
@@ -56,12 +56,12 @@
56
56
  },
57
57
  "sideEffects": false,
58
58
  "peerDependencies": {
59
- "@upyo/core": "0.5.0-dev.168+1e808a3a"
59
+ "@upyo/core": "0.5.0-dev.170+643994fd"
60
60
  },
61
61
  "devDependencies": {
62
62
  "tsdown": "^0.12.7",
63
63
  "typescript": "5.8.3",
64
- "@upyo/mock": "0.5.0-dev.168+1e808a3a"
64
+ "@upyo/mock": "0.5.0-dev.170+643994fd"
65
65
  },
66
66
  "scripts": {
67
67
  "prepublish": "mise run --no-deps :build"