@zap-studio/retry 0.3.0 → 0.3.1

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.d.mts CHANGED
@@ -1,56 +1,55 @@
1
- import { r as RetryError } from "./errors-fWo_KyVO.mjs";
1
+ import { r as RetryError } from "./errors-BVZjP1Q5.mjs";
2
2
  import { RetryDecision, RetryDecisionInput, RetryExhaustedInput, RetryPolicy, RetryRunOptions, RetryRunResult } from "./types.mjs";
3
-
4
3
  //#region src/index.d.ts
5
4
  /**
6
- * Base class for implementing retry policies and running retry orchestration.
7
- *
8
- * Extend this class and implement {@link BaseRetryPolicy.next} to define retry
9
- * behavior, then call {@link BaseRetryPolicy.run} to execute operations with that
10
- * policy.
11
- */
5
+ * Base class for implementing retry policies and running retry orchestration.
6
+ *
7
+ * Extend this class and implement {@link BaseRetryPolicy.next} to define retry
8
+ * behavior, then call {@link BaseRetryPolicy.run} to execute operations with that
9
+ * policy.
10
+ */
12
11
  declare abstract class BaseRetryPolicy<TError = unknown, TData = unknown> implements RetryPolicy<TError, TData> {
13
12
  /**
14
- * Returns the retry decision for a failed attempt.
15
- *
16
- * @param input - Attempt context used to compute retry behavior.
17
- * @throws Any error thrown by a concrete retry policy implementation.
18
- */
13
+ * Returns the retry decision for a failed attempt.
14
+ *
15
+ * @param input - Attempt context used to compute retry behavior.
16
+ * @throws {Error} Any error thrown by a concrete retry policy implementation.
17
+ */
19
18
  abstract next(input: RetryDecisionInput<TError, TData>): RetryDecision;
20
19
  /**
21
- * Builds the terminal error thrown or returned when retries are exhausted.
22
- *
23
- * Override this when you need custom terminal error types.
24
- *
25
- * @param input - Exhaustion context.
26
- * @returns `RetryError` by default.
27
- * @throws Any error thrown by an overriding policy implementation.
28
- */
20
+ * Builds the terminal error thrown or returned when retries are exhausted.
21
+ *
22
+ * Override this when you need custom terminal error types.
23
+ *
24
+ * @param input - Exhaustion context.
25
+ * @returns `RetryError` by default.
26
+ * @throws {Error} Any error thrown by an overriding policy implementation.
27
+ */
29
28
  onExhausted(input: RetryExhaustedInput<TError, TData>): RetryError;
30
29
  /**
31
- * Runs retry orchestration in non-throw mode.
32
- *
33
- * @param execute - Async function to execute per attempt.
34
- * @param options - Runner settings with `throwOnExhausted: false`.
35
- * @returns A discriminated result union containing success value or terminal error.
36
- * @throws Any error thrown by `next`, `onExhausted`, or a custom `sleep`.
37
- */
30
+ * Runs retry orchestration in non-throw mode.
31
+ *
32
+ * @param execute - Async function to execute per attempt.
33
+ * @param options - Runner settings with `throwOnExhausted: false`.
34
+ * @returns A discriminated result union containing success value or terminal error.
35
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or a custom `sleep`.
36
+ */
38
37
  run<T>(execute: (attempt: number) => Promise<T>, options: RetryRunOptions & {
39
38
  throwOnExhausted: false;
40
39
  }): Promise<RetryRunResult<T>>;
41
40
  /**
42
- * Runs retry orchestration and throws terminal error on exhaustion.
43
- *
44
- * @param execute - Async function to execute per attempt.
45
- * @param options - Optional runner settings.
46
- * @returns The successful execution value.
47
- * @throws {RetryError} When retries are exhausted and `onExhausted` returns the
48
- * terminal retry error. The default implementation returns `RetryError` with the last
49
- * execution failure available on `RetryError.lastError`.
50
- * @throws {AbortError} When `options.signal` is already aborted or aborts while retrying.
51
- * @throws Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`
52
- * function.
53
- */
41
+ * Runs retry orchestration and throws terminal error on exhaustion.
42
+ *
43
+ * @param execute - Async function to execute per attempt.
44
+ * @param options - Optional runner settings.
45
+ * @returns The successful execution value.
46
+ * @throws {RetryError} When retries are exhausted and `onExhausted` returns the
47
+ * terminal retry error. The default implementation returns `RetryError` with the last
48
+ * execution failure available on `RetryError.lastError`.
49
+ * @throws {AbortError} When `options.signal` is already aborted or aborts while retrying.
50
+ * @throws {Error} Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`
51
+ * function.
52
+ */
54
53
  run<T>(execute: (attempt: number) => Promise<T>, options?: RetryRunOptions & {
55
54
  throwOnExhausted?: true;
56
55
  }): Promise<T>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;;uBA0BsB,eAAA,+CAA8D,WAAA,CAClF,MAAA,EACA,KAAA;;;;;;;WAQgB,IAAA,CAAK,KAAA,EAAO,kBAAA,CAAmB,MAAA,EAAQ,KAAA,IAAS,aAAA;;;;;;;;;;EAWhE,WAAA,CAAmB,KAAA,EAAO,mBAAA,CAAoB,MAAA,EAAQ,KAAA,IAAS,UAAA;;;;;;;;;EAgB/D,GAAA,GAAA,CACE,OAAA,GAAU,OAAA,aAAoB,OAAA,CAAQ,CAAA,GACtC,OAAA,EAAS,eAAA;IAAoB,gBAAA;EAAA,IAC5B,OAAA,CAAQ,cAAA,CAAe,CAAA;;;;;;;;;;;;;;EAe1B,GAAA,GAAA,CACE,OAAA,GAAU,OAAA,aAAoB,OAAA,CAAQ,CAAA,GACtC,OAAA,GAAU,eAAA;IAAoB,gBAAA;EAAA,IAC7B,OAAA,CAAQ,CAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;;;;uBA0BsB,gBACpB,kBACA,4BACW,YAAY,QAAQ;;;;;;;WAOf,KAAK,OAAO,mBAAmB,QAAQ,SAAS;;;;;;;;;;EAYhE,YAAmB,OAAO,oBAAoB,QAAQ,SAAS;;;;;;;;;EAgB/D,IAAiB,GACf,UAAU,oBAAoB,QAAQ,IACtC,SAAS;IAAoB;MAC5B,QAAQ,eAAe;;;;;;;;;;;;;;EAe1B,IAAiB,GACf,UAAU,oBAAoB,QAAQ,IACtC,UAAU;IAAoB;MAC7B,QAAQ"}
package/dist/index.mjs CHANGED
@@ -23,13 +23,13 @@ var BaseRetryPolicy = class {
23
23
  *
24
24
  * @param input - Exhaustion context.
25
25
  * @returns `RetryError` by default.
26
- * @throws Any error thrown by an overriding policy implementation.
26
+ * @throws {Error} Any error thrown by an overriding policy implementation.
27
27
  */
28
28
  onExhausted(input) {
29
29
  return new RetryError("Retry policy exhausted all attempts.", {
30
30
  attempts: input.attempts,
31
- lastError: input.error,
32
- lastData: input.data
31
+ lastData: input.data,
32
+ lastError: input.error
33
33
  });
34
34
  }
35
35
  /**
@@ -40,11 +40,11 @@ var BaseRetryPolicy = class {
40
40
  * @param execute - Async function to execute per attempt.
41
41
  * @param options - Runner settings.
42
42
  * @returns Success value or terminal result object based on option mode.
43
- * @throws Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`
43
+ * @throws {Error} Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`
44
44
  * function. When `throwOnExhausted` is `false`, exhaustion itself is returned
45
45
  * as `{ ok: false }` instead of thrown.
46
46
  * Cancellation is returned as `{ ok: false, error: AbortError }` in non-throw
47
- * mode (not wrapped in `RetryError`).
47
+ * mode.
48
48
  *
49
49
  * @example
50
50
  * const result = await policy.run(doWork, { throwOnExhausted: false });
@@ -52,9 +52,9 @@ var BaseRetryPolicy = class {
52
52
  */
53
53
  async run(execute, options = {}) {
54
54
  const sleep = options.sleep ?? defaultSleep;
55
- const signal = options.signal;
56
- if (options.throwOnExhausted === false) return runResultMode(this, execute, sleep, signal);
57
- return runThrowMode(this, execute, sleep, signal);
55
+ const { signal } = options;
56
+ if (options.throwOnExhausted === false) return await runResultMode(this, execute, sleep, signal);
57
+ return await runThrowMode(this, execute, sleep, signal);
58
58
  }
59
59
  };
60
60
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Retry runner base class and shared orchestration implementation.\n *\n * @module @zap-studio/retry\n */\n\nimport { RetryError } from \"./errors.js\";\nimport { runResultMode } from \"./result-mode.js\";\nimport { defaultSleep } from \"./sleep.js\";\nimport { runThrowMode } from \"./throw-mode.js\";\nimport type {\n RetryDecision,\n RetryDecisionInput,\n RetryExhaustedInput,\n RetryPolicy,\n RetryRunOptions,\n RetryRunResult,\n} from \"./types.js\";\n\n/**\n * Base class for implementing retry policies and running retry orchestration.\n *\n * Extend this class and implement {@link BaseRetryPolicy.next} to define retry\n * behavior, then call {@link BaseRetryPolicy.run} to execute operations with that\n * policy.\n */\nexport abstract class BaseRetryPolicy<TError = unknown, TData = unknown> implements RetryPolicy<\n TError,\n TData\n> {\n /**\n * Returns the retry decision for a failed attempt.\n *\n * @param input - Attempt context used to compute retry behavior.\n * @throws Any error thrown by a concrete retry policy implementation.\n */\n public abstract next(input: RetryDecisionInput<TError, TData>): RetryDecision;\n\n /**\n * Builds the terminal error thrown or returned when retries are exhausted.\n *\n * Override this when you need custom terminal error types.\n *\n * @param input - Exhaustion context.\n * @returns `RetryError` by default.\n * @throws Any error thrown by an overriding policy implementation.\n */\n public onExhausted(input: RetryExhaustedInput<TError, TData>): RetryError {\n return new RetryError(\"Retry policy exhausted all attempts.\", {\n attempts: input.attempts,\n lastError: input.error,\n lastData: input.data,\n });\n }\n\n /**\n * Runs retry orchestration in non-throw mode.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Runner settings with `throwOnExhausted: false`.\n * @returns A discriminated result union containing success value or terminal error.\n * @throws Any error thrown by `next`, `onExhausted`, or a custom `sleep`.\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options: RetryRunOptions & { throwOnExhausted: false },\n ): Promise<RetryRunResult<T>>;\n\n /**\n * Runs retry orchestration and throws terminal error on exhaustion.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Optional runner settings.\n * @returns The successful execution value.\n * @throws {RetryError} When retries are exhausted and `onExhausted` returns the\n * terminal retry error. The default implementation returns `RetryError` with the last\n * execution failure available on `RetryError.lastError`.\n * @throws {AbortError} When `options.signal` is already aborted or aborts while retrying.\n * @throws Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`\n * function.\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options?: RetryRunOptions & { throwOnExhausted?: true },\n ): Promise<T>;\n\n /**\n * Runs retry orchestration in non-throw mode.\n *\n * When `throwOnExhausted` is `false`, returns a discriminated result union.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Runner settings.\n * @returns Success value or terminal result object based on option mode.\n * @throws Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`\n * function. When `throwOnExhausted` is `false`, exhaustion itself is returned\n * as `{ ok: false }` instead of thrown.\n * Cancellation is returned as `{ ok: false, error: AbortError }` in non-throw\n * mode (not wrapped in `RetryError`).\n *\n * @example\n * const result = await policy.run(doWork, { throwOnExhausted: false });\n * if (!result.ok) console.error(result.error);\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options: RetryRunOptions = {},\n ): Promise<T | RetryRunResult<T>> {\n const sleep = options.sleep ?? defaultSleep;\n const signal = options.signal;\n if (options.throwOnExhausted === false) {\n return runResultMode(this, execute, sleep, signal);\n }\n\n return runThrowMode(this, execute, sleep, signal);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAsB,kBAAtB,MAGE;;;;;;;;;;CAkBA,YAAmB,OAAuD;AACxE,SAAO,IAAI,WAAW,wCAAwC;GAC5D,UAAU,MAAM;GAChB,WAAW,MAAM;GACjB,UAAU,MAAM;GACjB,CAAC;;;;;;;;;;;;;;;;;;;;CAoDJ,MAAa,IACX,SACA,UAA2B,EAAE,EACG;EAChC,MAAM,QAAQ,QAAQ,SAAS;EAC/B,MAAM,SAAS,QAAQ;AACvB,MAAI,QAAQ,qBAAqB,MAC/B,QAAO,cAAc,MAAM,SAAS,OAAO,OAAO;AAGpD,SAAO,aAAa,MAAM,SAAS,OAAO,OAAO"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Retry runner base class and shared orchestration implementation.\n *\n * @module @zap-studio/retry\n */\n\nimport { RetryError } from \"./errors.js\";\nimport { runResultMode } from \"./result-mode.js\";\nimport { defaultSleep } from \"./sleep.js\";\nimport { runThrowMode } from \"./throw-mode.js\";\nimport type {\n RetryDecision,\n RetryDecisionInput,\n RetryExhaustedInput,\n RetryPolicy,\n RetryRunOptions,\n RetryRunResult,\n} from \"./types.js\";\n\n/**\n * Base class for implementing retry policies and running retry orchestration.\n *\n * Extend this class and implement {@link BaseRetryPolicy.next} to define retry\n * behavior, then call {@link BaseRetryPolicy.run} to execute operations with that\n * policy.\n */\nexport abstract class BaseRetryPolicy<\n TError = unknown,\n TData = unknown,\n> implements RetryPolicy<TError, TData> {\n /**\n * Returns the retry decision for a failed attempt.\n *\n * @param input - Attempt context used to compute retry behavior.\n * @throws {Error} Any error thrown by a concrete retry policy implementation.\n */\n public abstract next(input: RetryDecisionInput<TError, TData>): RetryDecision;\n\n /**\n * Builds the terminal error thrown or returned when retries are exhausted.\n *\n * Override this when you need custom terminal error types.\n *\n * @param input - Exhaustion context.\n * @returns `RetryError` by default.\n * @throws {Error} Any error thrown by an overriding policy implementation.\n */\n // oxlint-disable-next-line class-methods-use-this -- RetryPolicy requires an instance hook that subclasses may override.\n public onExhausted(input: RetryExhaustedInput<TError, TData>): RetryError {\n return new RetryError(\"Retry policy exhausted all attempts.\", {\n attempts: input.attempts,\n lastData: input.data,\n lastError: input.error,\n });\n }\n\n /**\n * Runs retry orchestration in non-throw mode.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Runner settings with `throwOnExhausted: false`.\n * @returns A discriminated result union containing success value or terminal error.\n * @throws {Error} Any error thrown by `next`, `onExhausted`, or a custom `sleep`.\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options: RetryRunOptions & { throwOnExhausted: false }\n ): Promise<RetryRunResult<T>>;\n\n /**\n * Runs retry orchestration and throws terminal error on exhaustion.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Optional runner settings.\n * @returns The successful execution value.\n * @throws {RetryError} When retries are exhausted and `onExhausted` returns the\n * terminal retry error. The default implementation returns `RetryError` with the last\n * execution failure available on `RetryError.lastError`.\n * @throws {AbortError} When `options.signal` is already aborted or aborts while retrying.\n * @throws {Error} Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`\n * function.\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options?: RetryRunOptions & { throwOnExhausted?: true }\n ): Promise<T>;\n\n /**\n * Runs retry orchestration in non-throw mode.\n *\n * When `throwOnExhausted` is `false`, returns a discriminated result union.\n *\n * @param execute - Async function to execute per attempt.\n * @param options - Runner settings.\n * @returns Success value or terminal result object based on option mode.\n * @throws {Error} Any error thrown by `next`, by `onExhausted`, or by a custom `sleep`\n * function. When `throwOnExhausted` is `false`, exhaustion itself is returned\n * as `{ ok: false }` instead of thrown.\n * Cancellation is returned as `{ ok: false, error: AbortError }` in non-throw\n * mode.\n *\n * @example\n * const result = await policy.run(doWork, { throwOnExhausted: false });\n * if (!result.ok) console.error(result.error);\n */\n public async run<T>(\n execute: (attempt: number) => Promise<T>,\n options: RetryRunOptions = {}\n ): Promise<T | RetryRunResult<T>> {\n const sleep = options.sleep ?? defaultSleep;\n const { signal } = options;\n if (options.throwOnExhausted === false) {\n return await runResultMode(this, execute, sleep, signal);\n }\n\n return await runThrowMode(this, execute, sleep, signal);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA0BA,IAAsB,kBAAtB,MAGwC;;;;;;;;;;CAmBtC,YAAmB,OAAuD;EACxE,OAAO,IAAI,WAAW,wCAAwC;GAC5D,UAAU,MAAM;GAChB,UAAU,MAAM;GAChB,WAAW,MAAM;EACnB,CAAC;CACH;;;;;;;;;;;;;;;;;;;CAmDA,MAAa,IACX,SACA,UAA2B,CAAC,GACI;EAChC,MAAM,QAAQ,QAAQ,SAAS;EAC/B,MAAM,EAAE,WAAW;EACnB,IAAI,QAAQ,qBAAqB,OAC/B,OAAO,MAAM,cAAc,MAAM,SAAS,OAAO,MAAM;EAGzD,OAAO,MAAM,aAAa,MAAM,SAAS,OAAO,MAAM;CACxD;AACF"}
@@ -1,24 +1,19 @@
1
- import { r as RetryError } from "./errors-fWo_KyVO.mjs";
2
- import { RetryDecision, RetryDecisionInput, RetryExhaustedInput, RetryRunResult } from "./types.mjs";
3
-
1
+ import { RetryPolicy, RetryRunResult } from "./types.mjs";
4
2
  //#region src/result-mode.d.ts
5
3
  /**
6
- * Runs the non-throw retry loop, returning
7
- * `RetryRunResult`.
8
- *
9
- * @param policy - Object providing `next` and `onExhausted` (same contract as
10
- * `BaseRetryPolicy`).
11
- * @param execute - Async work callback per attempt.
12
- * @param sleep - Delay function between retries.
13
- * @param signal - Optional cancel signal.
14
- * @returns Terminal success or failure object.
15
- * @throws Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`
16
- * failure.
17
- */
18
- declare function runResultMode<T, TError, TData>(policy: {
19
- next: (input: RetryDecisionInput<TError, TData>) => RetryDecision;
20
- onExhausted: (input: RetryExhaustedInput<TError, TData>) => RetryError;
21
- }, execute: (attempt: number) => Promise<T>, sleep: (delayMs: number) => Promise<void>, signal?: AbortSignal): Promise<RetryRunResult<T>>;
4
+ * Runs the non-throw retry loop, returning
5
+ * `RetryRunResult`.
6
+ *
7
+ * @param policy - Object providing `next` and `onExhausted` (same contract as
8
+ * `BaseRetryPolicy`).
9
+ * @param execute - Async work callback per attempt.
10
+ * @param sleep - Delay function between retries.
11
+ * @param signal - Optional cancel signal.
12
+ * @returns Terminal success or failure object.
13
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`
14
+ * failure.
15
+ */
16
+ declare const runResultMode: <T, TError, TData>(policy: RetryPolicy<TError, TData>, execute: (attempt: number) => Promise<T>, sleep: (delayMs: number) => Promise<void>, signal?: AbortSignal) => Promise<RetryRunResult<T>>;
22
17
  //#endregion
23
18
  export { runResultMode };
24
19
  //# sourceMappingURL=result-mode.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"result-mode.d.mts","names":[],"sources":["../src/result-mode.ts"],"mappings":";;;;;;AA6BA;;;;;;;;;;;iBAAsB,aAAA,kBAAA,CACpB,MAAA;EACE,IAAA,GAAO,KAAA,EAAO,kBAAA,CAAmB,MAAA,EAAQ,KAAA,MAAW,aAAA;EACpD,WAAA,GAAc,KAAA,EAAO,mBAAA,CAAoB,MAAA,EAAQ,KAAA,MAAW,UAAA;AAAA,GAE9D,OAAA,GAAU,OAAA,aAAoB,OAAA,CAAQ,CAAA,GACtC,KAAA,GAAQ,OAAA,aAAoB,OAAA,QAC5B,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,cAAA,CAAe,CAAA"}
1
+ {"version":3,"file":"result-mode.d.mts","names":[],"sources":["../src/result-mode.ts"],"mappings":";;;;;;;;;;;;;;;cA0Ka,gBAAuB,GAAG,QAAQ,OAC7C,QAAQ,YAAY,QAAQ,QAC5B,UAAU,oBAAoB,QAAQ,IACtC,QAAQ,oBAAoB,eAC5B,SAAS,gBACR,QAAQ,eAAe"}
@@ -7,38 +7,21 @@ import { sleepWithAbortSignal, toAbortError } from "./abort.mjs";
7
7
  * @module @zap-studio/retry/result-mode
8
8
  */
9
9
  /**
10
- * Runs the non-throw retry loop, returning
11
- * `RetryRunResult`.
10
+ * When `signal` is already aborted, builds the terminal `{ ok: false }` object
11
+ * with a normalized `AbortError` on `error`.
12
12
  *
13
- * @param policy - Object providing `next` and `onExhausted` (same contract as
14
- * `BaseRetryPolicy`).
15
- * @param execute - Async work callback per attempt.
16
- * @param sleep - Delay function between retries.
17
- * @param signal - Optional cancel signal.
18
- * @returns Terminal success or failure object.
19
- * @throws Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`
20
- * failure.
13
+ * @param signal - Optional abort signal; only acts when `aborted` is set.
14
+ * @param attempts - Number of finished attempts to report in the result.
15
+ * @returns Failure result or `undefined` if not aborted.
21
16
  */
22
- async function runResultMode(policy, execute, sleep, signal) {
23
- let attempt = 1;
24
- while (true) {
25
- const earlyAbortResult = abortResult(signal, Math.max(0, attempt - 1));
26
- if (earlyAbortResult) return earlyAbortResult;
27
- const execution = await runAttempt(execute, attempt);
28
- if (execution.ok) return {
29
- ok: true,
30
- value: execution.value
31
- };
32
- const failure = await handleFailure(policy, {
33
- attempt,
34
- error: execution.error,
35
- sleep,
36
- signal
37
- });
38
- if (failure) return failure;
39
- attempt += 1;
40
- }
41
- }
17
+ const buildAbortResult = (signal, attempts) => {
18
+ if (signal?.aborted !== true) return;
19
+ return {
20
+ attempts,
21
+ error: toAbortError(signal.reason),
22
+ ok: false
23
+ };
24
+ };
42
25
  /**
43
26
  * Runs one `execute(attempt)` call and returns either a success value or a
44
27
  * captured error without rethrowing.
@@ -47,7 +30,7 @@ async function runResultMode(policy, execute, sleep, signal) {
47
30
  * @param attempt - One-based attempt number passed to `execute`.
48
31
  * @returns A tagged success with `value` or a tagged failure with `error`.
49
32
  */
50
- async function runAttempt(execute, attempt) {
33
+ const runAttempt = async (execute, attempt) => {
51
34
  try {
52
35
  return {
53
36
  ok: true,
@@ -55,11 +38,37 @@ async function runAttempt(execute, attempt) {
55
38
  };
56
39
  } catch (error) {
57
40
  return {
58
- ok: false,
59
- error
41
+ error,
42
+ ok: false
60
43
  };
61
44
  }
62
- }
45
+ };
46
+ /**
47
+ * Awaits inter-attempt delay in result mode, mapping an abort during wait to
48
+ * a terminal result instead of throwing when `throwOnExhausted` is false.
49
+ *
50
+ * @param sleep - Custom or default sleep implementation.
51
+ * @param delayMs - Milliseconds to wait.
52
+ * @param signal - If set, `sleep` is raced with the abort signal.
53
+ * @param attempts - Attempt count to attach if the wait ends in abort.
54
+ * @returns A terminal result when canceled during the wait, otherwise
55
+ * `undefined`.
56
+ * @throws {Error} The underlying `sleep` rejection when it is not an abort.
57
+ */
58
+ const waitForDelay = async (sleep, delayMs, signal, attempts) => {
59
+ if (signal === void 0) {
60
+ await sleep(delayMs);
61
+ return;
62
+ }
63
+ try {
64
+ await sleepWithAbortSignal(sleep, delayMs, signal);
65
+ return;
66
+ } catch (error) {
67
+ const aborted = buildAbortResult(signal, attempts);
68
+ if (aborted !== void 0) return aborted;
69
+ throw error;
70
+ }
71
+ };
63
72
  /**
64
73
  * After a failed attempt, applies abort rules, `next`, optional delay, and
65
74
  * either returns a terminal `RetryRunResult` or `undefined` to continue.
@@ -73,72 +82,63 @@ async function runAttempt(execute, attempt) {
73
82
  * @param params.signal - Optional abort signal.
74
83
  * @returns Terminal non-throw result if the loop should stop, otherwise
75
84
  * `undefined` to schedule another attempt.
76
- * @throws Any error thrown by `next`, `onExhausted`, or a custom `sleep` when
85
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or a custom `sleep` when
77
86
  * the error is not an abort.
78
87
  */
79
- async function handleFailure(policy, params) {
88
+ const handleFailure = async (policy, params) => {
80
89
  const { attempt, error, sleep, signal } = params;
81
- const postExecuteAbortResult = abortResult(signal, attempt);
82
- if (postExecuteAbortResult) return postExecuteAbortResult;
90
+ const abortResult = buildAbortResult(signal, attempt);
91
+ if (abortResult !== void 0) return abortResult;
83
92
  const decision = policy.next({
84
93
  attempt,
85
94
  error
86
95
  });
87
96
  if (!decision.shouldRetry) return {
88
- ok: false,
97
+ attempts: attempt,
89
98
  error: policy.onExhausted({
90
99
  attempts: attempt,
91
100
  error
92
101
  }),
93
- attempts: attempt
102
+ ok: false
94
103
  };
95
104
  if (decision.delayMs > 0) {
96
- const sleepAbortResult = await waitForDelay(sleep, decision.delayMs, signal, attempt);
97
- if (sleepAbortResult) return sleepAbortResult;
105
+ const delayAbortResult = await waitForDelay(sleep, decision.delayMs, signal, attempt);
106
+ if (delayAbortResult !== void 0) return delayAbortResult;
98
107
  }
99
- }
100
- /**
101
- * When `signal` is already aborted, builds the terminal `{ ok: false }` object
102
- * with a normalized `AbortError` on `error` (not wrapped in `RetryError`).
103
- *
104
- * @param signal - Optional abort signal; only acts when `aborted` is set.
105
- * @param attempts - Number of finished attempts to report in the result.
106
- * @returns Failure result or `undefined` if not aborted.
107
- */
108
- function abortResult(signal, attempts) {
109
- if (!signal?.aborted) return;
110
- return {
111
- ok: false,
112
- error: toAbortError(signal.reason),
113
- attempts
114
- };
115
- }
108
+ };
116
109
  /**
117
- * Awaits inter-attempt delay in result mode, mapping an abort during wait to
118
- * a terminal result instead of throwing when `throwOnExhausted` is false.
110
+ * Runs the non-throw retry loop, returning
111
+ * `RetryRunResult`.
119
112
  *
120
- * @param sleep - Custom or default sleep implementation.
121
- * @param delayMs - Milliseconds to wait.
122
- * @param signal - If set, `sleep` is raced with the abort signal.
123
- * @param attempts - Attempt count to attach if the wait ends in abort.
124
- * @returns A terminal result when canceled during the wait, otherwise
125
- * `undefined`.
126
- * @throws The underlying `sleep` rejection when it is not an abort.
113
+ * @param policy - Object providing `next` and `onExhausted` (same contract as
114
+ * `BaseRetryPolicy`).
115
+ * @param execute - Async work callback per attempt.
116
+ * @param sleep - Delay function between retries.
117
+ * @param signal - Optional cancel signal.
118
+ * @returns Terminal success or failure object.
119
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`
120
+ * failure.
127
121
  */
128
- async function waitForDelay(sleep, delayMs, signal, attempts) {
129
- if (!signal) {
130
- await sleep(delayMs);
131
- return;
132
- }
133
- try {
134
- await sleepWithAbortSignal(sleep, delayMs, signal);
135
- return;
136
- } catch (error) {
137
- const aborted = abortResult(signal, attempts);
138
- if (aborted) return aborted;
139
- throw error;
122
+ const runResultMode = async (policy, execute, sleep, signal) => {
123
+ let attempt = 1;
124
+ while (true) {
125
+ const abortResult = buildAbortResult(signal, Math.max(0, attempt - 1));
126
+ if (abortResult !== void 0) return abortResult;
127
+ const execution = await runAttempt(execute, attempt);
128
+ if (execution.ok) return {
129
+ ok: true,
130
+ value: execution.value
131
+ };
132
+ const failure = await handleFailure(policy, {
133
+ attempt,
134
+ error: execution.error,
135
+ signal,
136
+ sleep
137
+ });
138
+ if (failure !== void 0) return failure;
139
+ attempt += 1;
140
140
  }
141
- }
141
+ };
142
142
  //#endregion
143
143
  export { runResultMode };
144
144
 
@@ -1 +1 @@
1
- {"version":3,"file":"result-mode.mjs","names":[],"sources":["../src/result-mode.ts"],"sourcesContent":["/**\n * Result-mode execution path for `BaseRetryPolicy.run` when\n * `throwOnExhausted: false` is set.\n *\n * @module @zap-studio/retry/result-mode\n */\n\nimport { sleepWithAbortSignal, toAbortError } from \"./abort.js\";\nimport type { RetryError } from \"./errors.js\";\nimport type {\n RetryDecision,\n RetryDecisionInput,\n RetryExhaustedInput,\n RetryRunResult,\n} from \"./types.js\";\n\n/**\n * Runs the non-throw retry loop, returning\n * `RetryRunResult`.\n *\n * @param policy - Object providing `next` and `onExhausted` (same contract as\n * `BaseRetryPolicy`).\n * @param execute - Async work callback per attempt.\n * @param sleep - Delay function between retries.\n * @param signal - Optional cancel signal.\n * @returns Terminal success or failure object.\n * @throws Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`\n * failure.\n */\nexport async function runResultMode<T, TError, TData>(\n policy: {\n next: (input: RetryDecisionInput<TError, TData>) => RetryDecision;\n onExhausted: (input: RetryExhaustedInput<TError, TData>) => RetryError;\n },\n execute: (attempt: number) => Promise<T>,\n sleep: (delayMs: number) => Promise<void>,\n signal?: AbortSignal,\n): Promise<RetryRunResult<T>> {\n let attempt = 1;\n\n while (true) {\n const earlyAbortResult = abortResult(signal, Math.max(0, attempt - 1));\n if (earlyAbortResult) return earlyAbortResult;\n\n const execution = await runAttempt(execute, attempt);\n if (execution.ok) {\n return { ok: true, value: execution.value };\n }\n\n const failure = await handleFailure(policy, {\n attempt,\n error: execution.error as TError,\n sleep,\n signal,\n });\n if (failure) return failure;\n\n attempt += 1;\n }\n}\n\n/**\n * Runs one `execute(attempt)` call and returns either a success value or a\n * captured error without rethrowing.\n *\n * @param execute - User work callback.\n * @param attempt - One-based attempt number passed to `execute`.\n * @returns A tagged success with `value` or a tagged failure with `error`.\n */\nasync function runAttempt<T>(\n execute: (attempt: number) => Promise<T>,\n attempt: number,\n): Promise<{ ok: true; value: T } | { ok: false; error: unknown }> {\n try {\n return {\n ok: true,\n value: await execute(attempt),\n };\n } catch (error) {\n return {\n ok: false,\n error,\n };\n }\n}\n\n/**\n * After a failed attempt, applies abort rules, `next`, optional delay, and\n * either returns a terminal `RetryRunResult` or `undefined` to continue.\n *\n * @param policy - Retry policy hooks (`next`, `onExhausted`) matching\n * `BaseRetryPolicy`.\n * @param params - Failure context for the current attempt.\n * @param params.attempt - Current attempt number.\n * @param params.error - Error thrown by the attempt.\n * @param params.sleep - Delay function between retries.\n * @param params.signal - Optional abort signal.\n * @returns Terminal non-throw result if the loop should stop, otherwise\n * `undefined` to schedule another attempt.\n * @throws Any error thrown by `next`, `onExhausted`, or a custom `sleep` when\n * the error is not an abort.\n */\nasync function handleFailure<TError, TData>(\n policy: {\n next: (input: RetryDecisionInput<TError, TData>) => RetryDecision;\n onExhausted: (input: RetryExhaustedInput<TError, TData>) => RetryError;\n },\n params: {\n attempt: number;\n error: TError;\n sleep: (delayMs: number) => Promise<void>;\n signal: AbortSignal | undefined;\n },\n): Promise<RetryRunResult<never> | undefined> {\n const { attempt, error, sleep, signal } = params;\n const postExecuteAbortResult = abortResult(signal, attempt);\n if (postExecuteAbortResult) return postExecuteAbortResult;\n\n const decision = policy.next({\n attempt,\n error,\n });\n\n if (!decision.shouldRetry) {\n const terminalError = policy.onExhausted({\n attempts: attempt,\n error,\n });\n\n return {\n ok: false,\n error: terminalError,\n attempts: attempt,\n };\n }\n\n if (decision.delayMs > 0) {\n const sleepAbortResult = await waitForDelay(sleep, decision.delayMs, signal, attempt);\n if (sleepAbortResult) return sleepAbortResult;\n }\n\n return;\n}\n\n/**\n * When `signal` is already aborted, builds the terminal `{ ok: false }` object\n * with a normalized `AbortError` on `error` (not wrapped in `RetryError`).\n *\n * @param signal - Optional abort signal; only acts when `aborted` is set.\n * @param attempts - Number of finished attempts to report in the result.\n * @returns Failure result or `undefined` if not aborted.\n */\nfunction abortResult(\n signal: AbortSignal | undefined,\n attempts: number,\n): RetryRunResult<never> | undefined {\n if (!signal?.aborted) {\n return;\n }\n\n return {\n ok: false,\n error: toAbortError(signal.reason),\n attempts,\n };\n}\n\n/**\n * Awaits inter-attempt delay in result mode, mapping an abort during wait to\n * a terminal result instead of throwing when `throwOnExhausted` is false.\n *\n * @param sleep - Custom or default sleep implementation.\n * @param delayMs - Milliseconds to wait.\n * @param signal - If set, `sleep` is raced with the abort signal.\n * @param attempts - Attempt count to attach if the wait ends in abort.\n * @returns A terminal result when canceled during the wait, otherwise\n * `undefined`.\n * @throws The underlying `sleep` rejection when it is not an abort.\n */\nasync function waitForDelay(\n sleep: (delayMs: number) => Promise<void>,\n delayMs: number,\n signal: AbortSignal | undefined,\n attempts: number,\n): Promise<RetryRunResult<never> | undefined> {\n if (!signal) {\n await sleep(delayMs);\n return;\n }\n\n try {\n await sleepWithAbortSignal(sleep, delayMs, signal);\n return;\n } catch (error) {\n const aborted = abortResult(signal, attempts);\n if (aborted) {\n return aborted;\n }\n throw error;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA6BA,eAAsB,cACpB,QAIA,SACA,OACA,QAC4B;CAC5B,IAAI,UAAU;AAEd,QAAO,MAAM;EACX,MAAM,mBAAmB,YAAY,QAAQ,KAAK,IAAI,GAAG,UAAU,EAAE,CAAC;AACtE,MAAI,iBAAkB,QAAO;EAE7B,MAAM,YAAY,MAAM,WAAW,SAAS,QAAQ;AACpD,MAAI,UAAU,GACZ,QAAO;GAAE,IAAI;GAAM,OAAO,UAAU;GAAO;EAG7C,MAAM,UAAU,MAAM,cAAc,QAAQ;GAC1C;GACA,OAAO,UAAU;GACjB;GACA;GACD,CAAC;AACF,MAAI,QAAS,QAAO;AAEpB,aAAW;;;;;;;;;;;AAYf,eAAe,WACb,SACA,SACiE;AACjE,KAAI;AACF,SAAO;GACL,IAAI;GACJ,OAAO,MAAM,QAAQ,QAAQ;GAC9B;UACM,OAAO;AACd,SAAO;GACL,IAAI;GACJ;GACD;;;;;;;;;;;;;;;;;;;AAoBL,eAAe,cACb,QAIA,QAM4C;CAC5C,MAAM,EAAE,SAAS,OAAO,OAAO,WAAW;CAC1C,MAAM,yBAAyB,YAAY,QAAQ,QAAQ;AAC3D,KAAI,uBAAwB,QAAO;CAEnC,MAAM,WAAW,OAAO,KAAK;EAC3B;EACA;EACD,CAAC;AAEF,KAAI,CAAC,SAAS,YAMZ,QAAO;EACL,IAAI;EACJ,OAPoB,OAAO,YAAY;GACvC,UAAU;GACV;GACD,CAAC;EAKA,UAAU;EACX;AAGH,KAAI,SAAS,UAAU,GAAG;EACxB,MAAM,mBAAmB,MAAM,aAAa,OAAO,SAAS,SAAS,QAAQ,QAAQ;AACrF,MAAI,iBAAkB,QAAO;;;;;;;;;;;AAcjC,SAAS,YACP,QACA,UACmC;AACnC,KAAI,CAAC,QAAQ,QACX;AAGF,QAAO;EACL,IAAI;EACJ,OAAO,aAAa,OAAO,OAAO;EAClC;EACD;;;;;;;;;;;;;;AAeH,eAAe,aACb,OACA,SACA,QACA,UAC4C;AAC5C,KAAI,CAAC,QAAQ;AACX,QAAM,MAAM,QAAQ;AACpB;;AAGF,KAAI;AACF,QAAM,qBAAqB,OAAO,SAAS,OAAO;AAClD;UACO,OAAO;EACd,MAAM,UAAU,YAAY,QAAQ,SAAS;AAC7C,MAAI,QACF,QAAO;AAET,QAAM"}
1
+ {"version":3,"file":"result-mode.mjs","names":[],"sources":["../src/result-mode.ts"],"sourcesContent":["/**\n * Result-mode execution path for `BaseRetryPolicy.run` when\n * `throwOnExhausted: false` is set.\n *\n * @module @zap-studio/retry/result-mode\n */\n\nimport { sleepWithAbortSignal, toAbortError } from \"./abort.js\";\nimport type { RetryPolicy, RetryRunResult } from \"./types.js\";\n\n/**\n * When `signal` is already aborted, builds the terminal `{ ok: false }` object\n * with a normalized `AbortError` on `error`.\n *\n * @param signal - Optional abort signal; only acts when `aborted` is set.\n * @param attempts - Number of finished attempts to report in the result.\n * @returns Failure result or `undefined` if not aborted.\n */\nconst buildAbortResult = (\n signal: AbortSignal | undefined,\n attempts: number\n): RetryRunResult<never> | undefined => {\n if (signal?.aborted !== true) {\n return undefined;\n }\n\n return {\n attempts,\n error: toAbortError(signal.reason),\n ok: false,\n };\n};\n\n/**\n * Runs one `execute(attempt)` call and returns either a success value or a\n * captured error without rethrowing.\n *\n * @param execute - User work callback.\n * @param attempt - One-based attempt number passed to `execute`.\n * @returns A tagged success with `value` or a tagged failure with `error`.\n */\nconst runAttempt = async <T>(\n execute: (attempt: number) => Promise<T>,\n attempt: number\n): Promise<{ ok: true; value: T } | { ok: false; error: unknown }> => {\n try {\n return {\n ok: true,\n value: await execute(attempt),\n };\n } catch (error) {\n return {\n error,\n ok: false,\n };\n }\n};\n\n/**\n * Awaits inter-attempt delay in result mode, mapping an abort during wait to\n * a terminal result instead of throwing when `throwOnExhausted` is false.\n *\n * @param sleep - Custom or default sleep implementation.\n * @param delayMs - Milliseconds to wait.\n * @param signal - If set, `sleep` is raced with the abort signal.\n * @param attempts - Attempt count to attach if the wait ends in abort.\n * @returns A terminal result when canceled during the wait, otherwise\n * `undefined`.\n * @throws {Error} The underlying `sleep` rejection when it is not an abort.\n */\nconst waitForDelay = async (\n sleep: (delayMs: number) => Promise<void>,\n delayMs: number,\n signal: AbortSignal | undefined,\n attempts: number\n): Promise<RetryRunResult<never> | undefined> => {\n if (signal === undefined) {\n await sleep(delayMs);\n return undefined;\n }\n\n try {\n await sleepWithAbortSignal(sleep, delayMs, signal);\n return undefined;\n } catch (error) {\n const aborted = buildAbortResult(signal, attempts);\n if (aborted !== undefined) {\n return aborted;\n }\n throw error;\n }\n};\n\n/**\n * After a failed attempt, applies abort rules, `next`, optional delay, and\n * either returns a terminal `RetryRunResult` or `undefined` to continue.\n *\n * @param policy - Retry policy hooks (`next`, `onExhausted`) matching\n * `BaseRetryPolicy`.\n * @param params - Failure context for the current attempt.\n * @param params.attempt - Current attempt number.\n * @param params.error - Error thrown by the attempt.\n * @param params.sleep - Delay function between retries.\n * @param params.signal - Optional abort signal.\n * @returns Terminal non-throw result if the loop should stop, otherwise\n * `undefined` to schedule another attempt.\n * @throws {Error} Any error thrown by `next`, `onExhausted`, or a custom `sleep` when\n * the error is not an abort.\n */\nconst handleFailure = async <TError, TData>(\n policy: RetryPolicy<TError, TData>,\n params: {\n attempt: number;\n error: TError;\n sleep: (delayMs: number) => Promise<void>;\n signal: AbortSignal | undefined;\n }\n): Promise<RetryRunResult<never> | undefined> => {\n const { attempt, error, sleep, signal } = params;\n const abortResult = buildAbortResult(signal, attempt);\n if (abortResult !== undefined) {\n return abortResult;\n }\n\n const decision = policy.next({\n attempt,\n error,\n });\n\n if (!decision.shouldRetry) {\n const terminalError = policy.onExhausted({\n attempts: attempt,\n error,\n });\n\n return {\n attempts: attempt,\n error: terminalError,\n ok: false,\n };\n }\n\n if (decision.delayMs > 0) {\n const delayAbortResult = await waitForDelay(\n sleep,\n decision.delayMs,\n signal,\n attempt\n );\n if (delayAbortResult !== undefined) {\n return delayAbortResult;\n }\n }\n\n return undefined;\n};\n\n/**\n * Runs the non-throw retry loop, returning\n * `RetryRunResult`.\n *\n * @param policy - Object providing `next` and `onExhausted` (same contract as\n * `BaseRetryPolicy`).\n * @param execute - Async work callback per attempt.\n * @param sleep - Delay function between retries.\n * @param signal - Optional cancel signal.\n * @returns Terminal success or failure object.\n * @throws {Error} Any error thrown by `next`, `onExhausted`, or a non-abort `sleep`\n * failure.\n */\nexport const runResultMode = async <T, TError, TData>(\n policy: RetryPolicy<TError, TData>,\n execute: (attempt: number) => Promise<T>,\n sleep: (delayMs: number) => Promise<void>,\n signal?: AbortSignal\n): Promise<RetryRunResult<T>> => {\n let attempt = 1;\n\n while (true) {\n const abortResult = buildAbortResult(signal, Math.max(0, attempt - 1));\n if (abortResult !== undefined) {\n return abortResult;\n }\n\n // oxlint-disable-next-line no-await-in-loop -- Retry attempts must run sequentially.\n const execution = await runAttempt(execute, attempt);\n if (execution.ok) {\n return { ok: true, value: execution.value };\n }\n\n // oxlint-disable-next-line no-await-in-loop -- Failure handling belongs to the current sequential attempt.\n const failure = await handleFailure(policy, {\n attempt,\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Policy error generic represents the caller's thrown error domain.\n error: execution.error as TError,\n signal,\n sleep,\n });\n if (failure !== undefined) {\n return failure;\n }\n\n attempt += 1;\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAkBA,MAAM,oBACJ,QACA,aACsC;CACtC,IAAI,QAAQ,YAAY,MACtB;CAGF,OAAO;EACL;EACA,OAAO,aAAa,OAAO,MAAM;EACjC,IAAI;CACN;AACF;;;;;;;;;AAUA,MAAM,aAAa,OACjB,SACA,YACoE;CACpE,IAAI;EACF,OAAO;GACL,IAAI;GACJ,OAAO,MAAM,QAAQ,OAAO;EAC9B;CACF,SAAS,OAAO;EACd,OAAO;GACL;GACA,IAAI;EACN;CACF;AACF;;;;;;;;;;;;;AAcA,MAAM,eAAe,OACnB,OACA,SACA,QACA,aAC+C;CAC/C,IAAI,WAAW,KAAA,GAAW;EACxB,MAAM,MAAM,OAAO;EACnB;CACF;CAEA,IAAI;EACF,MAAM,qBAAqB,OAAO,SAAS,MAAM;EACjD;CACF,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,QAAQ;EACjD,IAAI,YAAY,KAAA,GACd,OAAO;EAET,MAAM;CACR;AACF;;;;;;;;;;;;;;;;;AAkBA,MAAM,gBAAgB,OACpB,QACA,WAM+C;CAC/C,MAAM,EAAE,SAAS,OAAO,OAAO,WAAW;CAC1C,MAAM,cAAc,iBAAiB,QAAQ,OAAO;CACpD,IAAI,gBAAgB,KAAA,GAClB,OAAO;CAGT,MAAM,WAAW,OAAO,KAAK;EAC3B;EACA;CACF,CAAC;CAED,IAAI,CAAC,SAAS,aAMZ,OAAO;EACL,UAAU;EACV,OAPoB,OAAO,YAAY;GACvC,UAAU;GACV;EACF,CAIqB;EACnB,IAAI;CACN;CAGF,IAAI,SAAS,UAAU,GAAG;EACxB,MAAM,mBAAmB,MAAM,aAC7B,OACA,SAAS,SACT,QACA,OACF;EACA,IAAI,qBAAqB,KAAA,GACvB,OAAO;CAEX;AAGF;;;;;;;;;;;;;;AAeA,MAAa,gBAAgB,OAC3B,QACA,SACA,OACA,WAC+B;CAC/B,IAAI,UAAU;CAEd,OAAO,MAAM;EACX,MAAM,cAAc,iBAAiB,QAAQ,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;EACrE,IAAI,gBAAgB,KAAA,GAClB,OAAO;EAIT,MAAM,YAAY,MAAM,WAAW,SAAS,OAAO;EACnD,IAAI,UAAU,IACZ,OAAO;GAAE,IAAI;GAAM,OAAO,UAAU;EAAM;EAI5C,MAAM,UAAU,MAAM,cAAc,QAAQ;GAC1C;GAEA,OAAO,UAAU;GACjB;GACA;EACF,CAAC;EACD,IAAI,YAAY,KAAA,GACd,OAAO;EAGT,WAAW;CACb;AACF"}
package/dist/sleep.d.mts CHANGED
@@ -1,17 +1,17 @@
1
1
  //#region src/sleep.d.ts
2
2
  /**
3
- * Default delay implementation used by `BaseRetryPolicy.run` when no custom
4
- * `sleep` is provided.
5
- *
6
- * @module @zap-studio/retry/sleep
7
- */
3
+ * Default delay implementation used by `BaseRetryPolicy.run` when no custom
4
+ * `sleep` is provided.
5
+ *
6
+ * @module @zap-studio/retry/sleep
7
+ */
8
8
  /**
9
- * Awaits a timer-based delay, unless `delayMs` is non-positive.
10
- *
11
- * @param delayMs - Milliseconds to wait before resolving.
12
- * @returns Promise that resolves when the delay completes.
13
- */
14
- declare function defaultSleep(delayMs: number): Promise<void>;
9
+ * Awaits a timer-based delay, unless `delayMs` is non-positive.
10
+ *
11
+ * @param delayMs - Milliseconds to wait before resolving.
12
+ * @returns Promise that resolves when the delay completes.
13
+ */
14
+ declare const defaultSleep: (delayMs: number) => Promise<void>;
15
15
  //#endregion
16
16
  export { defaultSleep };
17
17
  //# sourceMappingURL=sleep.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sleep.d.mts","names":[],"sources":["../src/sleep.ts"],"mappings":";;AAaA;;;;;;;;;;;iBAAsB,YAAA,CAAa,OAAA,WAAkB,OAAA"}
1
+ {"version":3,"file":"sleep.d.mts","names":[],"sources":["../src/sleep.ts"],"mappings":";;;;;;;;;;;;;cAaa,eAAsB,oBAAkB"}
package/dist/sleep.mjs CHANGED
@@ -11,10 +11,12 @@
11
11
  * @param delayMs - Milliseconds to wait before resolving.
12
12
  * @returns Promise that resolves when the delay completes.
13
13
  */
14
- async function defaultSleep(delayMs) {
14
+ const defaultSleep = async (delayMs) => {
15
15
  if (delayMs <= 0) return;
16
- await new Promise((resolve) => setTimeout(resolve, delayMs));
17
- }
16
+ await new Promise((resolve) => {
17
+ setTimeout(resolve, delayMs);
18
+ });
19
+ };
18
20
  //#endregion
19
21
  export { defaultSleep };
20
22
 
@@ -1 +1 @@
1
- {"version":3,"file":"sleep.mjs","names":[],"sources":["../src/sleep.ts"],"sourcesContent":["/**\n * Default delay implementation used by `BaseRetryPolicy.run` when no custom\n * `sleep` is provided.\n *\n * @module @zap-studio/retry/sleep\n */\n\n/**\n * Awaits a timer-based delay, unless `delayMs` is non-positive.\n *\n * @param delayMs - Milliseconds to wait before resolving.\n * @returns Promise that resolves when the delay completes.\n */\nexport async function defaultSleep(delayMs: number): Promise<void> {\n if (delayMs <= 0) {\n return;\n }\n\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,eAAsB,aAAa,SAAgC;AACjE,KAAI,WAAW,EACb;AAGF,OAAM,IAAI,SAAS,YAAY,WAAW,SAAS,QAAQ,CAAC"}
1
+ {"version":3,"file":"sleep.mjs","names":[],"sources":["../src/sleep.ts"],"sourcesContent":["/**\n * Default delay implementation used by `BaseRetryPolicy.run` when no custom\n * `sleep` is provided.\n *\n * @module @zap-studio/retry/sleep\n */\n\n/**\n * Awaits a timer-based delay, unless `delayMs` is non-positive.\n *\n * @param delayMs - Milliseconds to wait before resolving.\n * @returns Promise that resolves when the delay completes.\n */\nexport const defaultSleep = async (delayMs: number): Promise<void> => {\n if (delayMs <= 0) {\n return;\n }\n\n // oxlint-disable-next-line promise/avoid-new -- Timer sleep requires adapting callback API to a promise.\n await new Promise<void>((resolve) => {\n setTimeout(resolve, delayMs);\n });\n};\n"],"mappings":";;;;;;;;;;;;;AAaA,MAAa,eAAe,OAAO,YAAmC;CACpE,IAAI,WAAW,GACb;CAIF,MAAM,IAAI,SAAe,YAAY;EACnC,WAAW,SAAS,OAAO;CAC7B,CAAC;AACH"}
@@ -1,26 +1,21 @@
1
- import { r as RetryError } from "./errors-fWo_KyVO.mjs";
2
- import { RetryDecision, RetryDecisionInput, RetryExhaustedInput } from "./types.mjs";
3
-
1
+ import { RetryPolicy } from "./types.mjs";
4
2
  //#region src/throw-mode.d.ts
5
3
  /**
6
- * Runs the throw-mode retry loop: throws `RetryError` on exhaustion and
7
- * `AbortError` when `signal` aborts.
8
- *
9
- * @param policy - Object providing `next` and `onExhausted` (same contract as
10
- * `BaseRetryPolicy`).
11
- * @param execute - Async work callback per attempt.
12
- * @param sleep - Delay function between retries.
13
- * @param signal - Optional cancel signal.
14
- * @returns Resolves to the first successful return value.
15
- * @throws {RetryError} When retries are exhausted and `onExhausted` returns
16
- * the terminal error.
17
- * @throws {AbortError} When `signal` is already aborted or aborts while waiting.
18
- * @throws Any error thrown by `next`, `onExhausted`, or `sleep`.
19
- */
20
- declare function runThrowMode<T, TError, TData>(policy: {
21
- next: (input: RetryDecisionInput<TError, TData>) => RetryDecision;
22
- onExhausted: (input: RetryExhaustedInput<TError, TData>) => RetryError;
23
- }, execute: (attempt: number) => Promise<T>, sleep: (delayMs: number) => Promise<void>, signal?: AbortSignal): Promise<T>;
4
+ * Runs the throw-mode retry loop: throws `RetryError` on exhaustion and
5
+ * `AbortError` when `signal` aborts.
6
+ *
7
+ * @param policy - Object providing `next` and `onExhausted` (same contract as
8
+ * `BaseRetryPolicy`).
9
+ * @param execute - Async work callback per attempt.
10
+ * @param sleep - Delay function between retries.
11
+ * @param signal - Optional cancel signal.
12
+ * @returns Resolves to the first successful return value.
13
+ * @throws {RetryError} When retries are exhausted and `onExhausted` returns
14
+ * the terminal error.
15
+ * @throws {AbortError} When `signal` is already aborted or aborts while waiting.
16
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or `sleep`.
17
+ */
18
+ declare const runThrowMode: <T, TError, TData>(policy: RetryPolicy<TError, TData>, execute: (attempt: number) => Promise<T>, sleep: (delayMs: number) => Promise<void>, signal?: AbortSignal) => Promise<T>;
24
19
  //#endregion
25
20
  export { runThrowMode };
26
21
  //# sourceMappingURL=throw-mode.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"throw-mode.d.mts","names":[],"sources":["../src/throw-mode.ts"],"mappings":";;;;;;AA0BA;;;;;;;;;;;;;iBAAsB,YAAA,kBAAA,CACpB,MAAA;EACE,IAAA,GAAO,KAAA,EAAO,kBAAA,CAAmB,MAAA,EAAQ,KAAA,MAAW,aAAA;EACpD,WAAA,GAAc,KAAA,EAAO,mBAAA,CAAoB,MAAA,EAAQ,KAAA,MAAW,UAAA;AAAA,GAE9D,OAAA,GAAU,OAAA,aAAoB,OAAA,CAAQ,CAAA,GACtC,KAAA,GAAQ,OAAA,aAAoB,OAAA,QAC5B,MAAA,GAAS,WAAA,GACR,OAAA,CAAQ,CAAA"}
1
+ {"version":3,"file":"throw-mode.d.mts","names":[],"sources":["../src/throw-mode.ts"],"mappings":";;;;;;;;;;;;;;;;;cAyBa,eAAsB,GAAG,QAAQ,OAC5C,QAAQ,YAAY,QAAQ,QAC5B,UAAU,oBAAoB,QAAQ,IACtC,QAAQ,oBAAoB,eAC5B,SAAS,gBACR,QAAQ"}
@@ -19,9 +19,9 @@ import { sleepWithAbortSignal, throwIfAborted } from "./abort.mjs";
19
19
  * @throws {RetryError} When retries are exhausted and `onExhausted` returns
20
20
  * the terminal error.
21
21
  * @throws {AbortError} When `signal` is already aborted or aborts while waiting.
22
- * @throws Any error thrown by `next`, `onExhausted`, or `sleep`.
22
+ * @throws {Error} Any error thrown by `next`, `onExhausted`, or `sleep`.
23
23
  */
24
- async function runThrowMode(policy, execute, sleep, signal) {
24
+ const runThrowMode = async (policy, execute, sleep, signal) => {
25
25
  let attempt = 1;
26
26
  while (true) {
27
27
  throwIfAborted(signal);
@@ -38,12 +38,11 @@ async function runThrowMode(policy, execute, sleep, signal) {
38
38
  attempts: attempt,
39
39
  error: typedError
40
40
  });
41
- if (decision.delayMs > 0) if (signal) await sleepWithAbortSignal(sleep, decision.delayMs, signal);
42
- else await sleep(decision.delayMs);
41
+ if (decision.delayMs > 0) await (signal === void 0 ? sleep(decision.delayMs) : sleepWithAbortSignal(sleep, decision.delayMs, signal));
43
42
  attempt += 1;
44
43
  }
45
44
  }
46
- }
45
+ };
47
46
  //#endregion
48
47
  export { runThrowMode };
49
48