trybox 0.1.2 → 0.10.0

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.cts CHANGED
@@ -1,6 +1,4 @@
1
- import { MaybePromise as MaybePromise$1 } from 'bun';
2
-
3
- type AppErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" | "UNKNOWN";
1
+ type ResultErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" | "CIRCUIT_OPEN" | "UNKNOWN";
4
2
  /**
5
3
  * A normalized error shape returned by `run()`.
6
4
  *
@@ -10,14 +8,17 @@ type AppErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" |
10
8
  * - `meta`: Optional payload with extra context (response body, validation fields, etc.).
11
9
  * - `cause`: The original thrown value for debugging.
12
10
  */
13
- type AppError<Code extends string = AppErrorCode | (string & {}), Meta = unknown> = {
11
+ type ResultError<Code extends string = ResultErrorCode | (string & {}), Meta = unknown> = {
14
12
  code: Code;
15
13
  message: string;
16
14
  status?: number;
17
15
  meta?: Meta;
18
16
  cause?: unknown;
19
17
  };
20
- type Rule<E extends AppError = AppError> = (err: unknown) => E | null;
18
+ type NonNull<T> = T extends null ? never : T;
19
+ type RuleReturn<R> = R extends (err: unknown) => infer Out ? NonNull<Out> : never;
20
+ type InferErrorFromRules<TRules extends readonly Rule<any>[]> = TRules extends readonly [] ? ResultError : RuleReturn<TRules[number]> | ResultError<"UNKNOWN">;
21
+ type Rule<E extends ResultError = ResultError> = (err: unknown) => E | null;
21
22
 
22
23
  type RetryDelayFn<E> = (attempt: number, err: E) => number;
23
24
  type MaybePromise<T> = T | Promise<T>;
@@ -37,7 +38,7 @@ type BackoffStrategy = "linear" | "exponential" | "fibonacci" | ((attempt: numbe
37
38
  /**
38
39
  * Retry options for `run`, `runAll` and `runAllOrThrow`.
39
40
  */
40
- type RetryOptions<E extends AppError = AppError> = {
41
+ type RetryOptions<E extends ResultError = ResultError> = {
41
42
  /**
42
43
  * Number of retries to perform (does not include the initial attempt).
43
44
  * @default 0
@@ -86,11 +87,15 @@ type RetryContext = {
86
87
  totalAttempts: number;
87
88
  /** Elapsed time in ms since the start of `run`. */
88
89
  elapsedTime: number;
90
+ /** Timestamp (ms) when the execution started. */
91
+ startTime: number;
92
+ /** The delay (ms) applied before the last attempt, if any. */
93
+ lastDelay?: number;
89
94
  };
90
95
  /**
91
96
  * Main options for `run` and extended to `runAll`/`runAllOrThrow`.
92
97
  */
93
- type RunOptions<T, E extends AppError = AppError> = RetryOptions<E> & {
98
+ type RunOptions<T, E extends ResultError = ResultError> = RetryOptions<E> & {
94
99
  /**
95
100
  * Normalizes an unknown error value to your type `E`.
96
101
  * If not provided, a default normalizer is used.
@@ -136,18 +141,13 @@ type RunOptions<T, E extends AppError = AppError> = RetryOptions<E> & {
136
141
  * Optional structured logger for debug and errors.
137
142
  */
138
143
  logger?: {
139
- debug?: (msg: string, meta?: any) => void;
144
+ debug?: (msg: string, meta?: unknown) => void;
140
145
  error?: (msg: string, error: E) => void;
141
146
  };
142
147
  /**
143
148
  * Callback on abort, useful for reacting to `AbortSignal`.
144
149
  */
145
150
  onAbort?: (signal: AbortSignal) => void;
146
- /**
147
- * Per-call circuit breaker configuration.
148
- * If not defined, can use the default value from `Runner`.
149
- */
150
- circuitBreaker?: CircuitBreakerOptions;
151
151
  };
152
152
  /**
153
153
  * Circuit breaker configuration options:
@@ -163,42 +163,44 @@ type CircuitBreakerOptions = {
163
163
  /**
164
164
  * Execution metrics optionally returned in `RunResult`.
165
165
  */
166
- type Metrics = {
166
+ type Metrics<E extends ResultError = ResultError> = {
167
167
  totalAttempts: number;
168
168
  totalRetries: number;
169
169
  totalDuration: number;
170
- lastError?: AppError;
170
+ lastError?: E;
171
171
  };
172
- type RunResult<T, E extends AppError = AppError> = {
172
+ type RunResult<T, E extends ResultError = ResultError> = {
173
173
  ok: true;
174
174
  data: T;
175
175
  error: null;
176
- metrics?: Metrics;
176
+ metrics?: Metrics<E>;
177
177
  } | {
178
178
  ok: false;
179
179
  data: null;
180
180
  error: E;
181
- metrics?: Metrics;
181
+ metrics?: Metrics<E>;
182
182
  };
183
183
 
184
184
  /**
185
185
  * Executes an async operation and returns a Result instead of throwing.
186
186
  *
187
- * Errors are normalized into an `AppError` (or a custom error type `E`)
187
+ * Errors are normalized into an `ResultError` (or a custom error type `E`)
188
188
  * using the provided `toError` function.
189
189
  *
190
190
  * This utility is framework-agnostic and works in browsers, Node.js,
191
191
  * React effects, and any async context.
192
192
  */
193
- declare function run<T, E extends AppError = AppError>(fn: () => MaybePromise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
193
+ declare function run<T, E extends ResultError = ResultError>(fn: (ctx?: {
194
+ signal: AbortSignal;
195
+ }) => MaybePromise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
194
196
 
195
197
  /**
196
- * Discriminated result per item in `runAllSettled`:
198
+ * Discriminated result per item in `runAll`:
197
199
  * - "ok": successful task with `data`
198
200
  * - "error": failed task with `error`
199
201
  * - "skipped": task not executed due to cancellation/fail-fast/concurrency
200
202
  */
201
- type RunAllItemResult<T, E extends AppError = AppError> = {
203
+ type RunAllItemResult<T, E extends ResultError = ResultError> = {
202
204
  status: "ok";
203
205
  ok: true;
204
206
  data: T;
@@ -219,12 +221,12 @@ type SuccessResult<T> = Extract<RunAllItemResult<T, any>, {
219
221
  status: "ok";
220
222
  }>;
221
223
  /** Helper to discriminate error results. */
222
- type ErrorResult<E> = Extract<RunAllItemResult<any, E extends AppError ? E : AppError>, {
224
+ type ErrorResult<E> = Extract<RunAllItemResult<any, E extends ResultError ? E : ResultError>, {
223
225
  status: "error";
224
226
  }>;
225
227
  /** Type guard that detects `status: "ok"` with `data` typing. */
226
- declare const isSuccess: <T, E extends AppError = AppError>(r: RunAllItemResult<T, E>) => r is SuccessResult<T>;
227
- type RunAllOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
228
+ declare const isSuccess: <T, E extends ResultError = ResultError>(r: RunAllItemResult<T, E>) => r is SuccessResult<T>;
229
+ type RunAllOptions<T, E extends ResultError = ResultError> = RunOptions<T, E> & {
228
230
  /**
229
231
  * Maximum number of concurrent tasks to run.
230
232
  * @default Infinity
@@ -238,53 +240,61 @@ type RunAllOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
238
240
  */
239
241
  mode?: "settle" | "fail-fast";
240
242
  };
241
- declare function runAllSettled<T, E extends AppError = AppError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
243
+ declare function runAll<T, E extends ResultError = ResultError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
242
244
 
243
245
  /**
244
- * Options for `runAll`:
246
+ * Options for `runAllOrThrow`:
245
247
  * - Inherits all options from `RunOptions`
246
248
  * - `concurrency`: limit of simultaneous tasks; if one fails, it throws
247
249
  */
248
- type RunAllOrThrowOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
250
+ type RunAllOrThrowOptions<T, E extends ResultError = ResultError> = RunOptions<T, E> & {
249
251
  /**
250
252
  * Maximum number of concurrent tasks to run.
251
253
  * @default Infinity
252
254
  */
253
255
  concurrency?: number;
254
256
  };
255
- declare function runAll<T, E extends AppError = AppError>(tasks: Array<() => MaybePromise$1<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
257
+ declare function runAllOrThrow<T, E extends ResultError = ResultError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
256
258
 
257
- declare function createNormalizer<E extends AppError>(rules: Rule<E>[], fallback: (err: unknown) => E): (err: unknown) => E;
258
- declare function defaultFallback(err: unknown): AppError;
259
- declare function toAppError(err: unknown): AppError;
259
+ declare function createNormalizer<E extends ResultError>(rules: Rule<E>[], fallback: (err: unknown) => E): (err: unknown) => E;
260
+ declare function defaultFallback(err: unknown): ResultError;
261
+ declare function toResultError(err: unknown): ResultError;
260
262
 
261
263
  declare const rules: {
262
- abort: Rule<AppError<"ABORTED">>;
263
- timeout: Rule<AppError<"TIMEOUT">>;
264
- httpStatus: Rule<AppError<"HTTP">>;
265
- aggregate: Rule<AppError<"UNKNOWN", {
264
+ circuitOpen: Rule<ResultError<"CIRCUIT_OPEN">>;
265
+ abort: Rule<ResultError<"ABORTED">>;
266
+ timeout: Rule<ResultError<"TIMEOUT">>;
267
+ httpStatus: Rule<ResultError<"HTTP">>;
268
+ aggregate: Rule<ResultError<"UNKNOWN", {
266
269
  errors: unknown[];
267
270
  }>>;
268
- string: Rule<AppError<"UNKNOWN">>;
269
- message: Rule<AppError<"UNKNOWN">>;
271
+ string: Rule<ResultError<"UNKNOWN">>;
272
+ message: Rule<ResultError<"UNKNOWN">>;
270
273
  };
271
274
 
272
275
  declare class ErrorRuleBuilder<E> {
273
276
  private readonly matcher;
274
277
  constructor(matcher: (err: unknown) => err is E);
275
- toError<const Out extends AppError>(mapper: (err: E) => Out): Rule<Out>;
278
+ toError<const Out extends ResultError>(mapper: (err: E) => Out): Rule<Out>;
276
279
  }
277
280
  declare const errorRule: {
278
281
  instance<E extends new (...args: any[]) => unknown>(ctor: E): ErrorRuleBuilder<InstanceType<E>>;
279
282
  when<E = unknown>(predicate: (err: unknown) => err is E): ErrorRuleBuilder<E>;
280
283
  };
281
284
 
282
- type CreateRunnerOptions<E extends AppError = AppError> = {
285
+ type RulesMode = "extend" | "replace";
286
+ type CreateRunnerOptions<E extends ResultError = ResultError> = {
283
287
  /**
284
288
  * Custom matchers to use for normalizing errors.
285
289
  * If not provided, the default matchers are used.
286
290
  */
287
291
  rules?: Rule<E>[];
292
+ /**
293
+ * How to treat provided rules in relation to default rules.
294
+ * - "extend": Use default rules after custom rules (default).
295
+ * - "replace": Use only custom rules (and fallback).
296
+ */
297
+ rulesMode?: RulesMode;
288
298
  /**
289
299
  * Custom fallback function to use for normalizing errors.
290
300
  * If not provided, the default fallback is used.
@@ -300,17 +310,19 @@ type CreateRunnerOptions<E extends AppError = AppError> = {
300
310
  /** Optional default mapper for all runs */
301
311
  mapError?: (error: E) => E;
302
312
  /**
303
- * Default circuit breaker for all executions of the instance.
304
- * Can be overridden by `options.circuitBreaker` in each `run`.
313
+ * Circuit breaker configuration (applies to all executions of the Runner).
305
314
  */
306
315
  circuitBreaker?: CircuitBreakerOptions;
307
316
  };
308
- interface Runner<E extends AppError> {
317
+ interface Runner<E extends ResultError> {
309
318
  run<T>(fn: () => Promise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
310
319
  all<T>(fns: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
311
- allOrThrow<T>(fns: Array<() => MaybePromise<T>>, options?: RunOptions<T, E>): Promise<T[]>;
320
+ allOrThrow<T>(fns: Array<() => MaybePromise<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
312
321
  }
313
322
 
314
- declare function trybox(options?: CreateRunnerOptions): Runner<AppError>;
323
+ declare function trybox(options?: Omit<CreateRunnerOptions<ResultError>, "rules">): Runner<ResultError>;
324
+ declare function trybox<const TRules extends readonly Rule<any>[]>(options: {
325
+ rules: TRules;
326
+ } & Omit<CreateRunnerOptions<InferErrorFromRules<TRules>>, "rules">): Runner<InferErrorFromRules<TRules>>;
315
327
 
316
- export { type AppError, type AppErrorCode, type BackoffStrategy, type CircuitBreakerOptions, type ErrorResult, type Metrics, type RetryContext, type RetryOptions, type RunAllItemResult, type RunAllOptions, type RunOptions, type RunResult, type SuccessResult, createNormalizer, trybox as default, defaultFallback, errorRule, isSuccess, rules, run, runAll, runAllSettled, toAppError };
328
+ export { type BackoffStrategy, type CircuitBreakerOptions, type ErrorResult, type Metrics, type ResultError, type ResultErrorCode, type RetryContext, type RetryOptions, type RunAllItemResult, type RunAllOptions, type RunOptions, type RunResult, type SuccessResult, createNormalizer, trybox as default, defaultFallback, errorRule, isSuccess, rules, run, runAll, runAllOrThrow, toResultError };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,4 @@
1
- import { MaybePromise as MaybePromise$1 } from 'bun';
2
-
3
- type AppErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" | "UNKNOWN";
1
+ type ResultErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" | "CIRCUIT_OPEN" | "UNKNOWN";
4
2
  /**
5
3
  * A normalized error shape returned by `run()`.
6
4
  *
@@ -10,14 +8,17 @@ type AppErrorCode = "ABORTED" | "NETWORK" | "TIMEOUT" | "VALIDATION" | "HTTP" |
10
8
  * - `meta`: Optional payload with extra context (response body, validation fields, etc.).
11
9
  * - `cause`: The original thrown value for debugging.
12
10
  */
13
- type AppError<Code extends string = AppErrorCode | (string & {}), Meta = unknown> = {
11
+ type ResultError<Code extends string = ResultErrorCode | (string & {}), Meta = unknown> = {
14
12
  code: Code;
15
13
  message: string;
16
14
  status?: number;
17
15
  meta?: Meta;
18
16
  cause?: unknown;
19
17
  };
20
- type Rule<E extends AppError = AppError> = (err: unknown) => E | null;
18
+ type NonNull<T> = T extends null ? never : T;
19
+ type RuleReturn<R> = R extends (err: unknown) => infer Out ? NonNull<Out> : never;
20
+ type InferErrorFromRules<TRules extends readonly Rule<any>[]> = TRules extends readonly [] ? ResultError : RuleReturn<TRules[number]> | ResultError<"UNKNOWN">;
21
+ type Rule<E extends ResultError = ResultError> = (err: unknown) => E | null;
21
22
 
22
23
  type RetryDelayFn<E> = (attempt: number, err: E) => number;
23
24
  type MaybePromise<T> = T | Promise<T>;
@@ -37,7 +38,7 @@ type BackoffStrategy = "linear" | "exponential" | "fibonacci" | ((attempt: numbe
37
38
  /**
38
39
  * Retry options for `run`, `runAll` and `runAllOrThrow`.
39
40
  */
40
- type RetryOptions<E extends AppError = AppError> = {
41
+ type RetryOptions<E extends ResultError = ResultError> = {
41
42
  /**
42
43
  * Number of retries to perform (does not include the initial attempt).
43
44
  * @default 0
@@ -86,11 +87,15 @@ type RetryContext = {
86
87
  totalAttempts: number;
87
88
  /** Elapsed time in ms since the start of `run`. */
88
89
  elapsedTime: number;
90
+ /** Timestamp (ms) when the execution started. */
91
+ startTime: number;
92
+ /** The delay (ms) applied before the last attempt, if any. */
93
+ lastDelay?: number;
89
94
  };
90
95
  /**
91
96
  * Main options for `run` and extended to `runAll`/`runAllOrThrow`.
92
97
  */
93
- type RunOptions<T, E extends AppError = AppError> = RetryOptions<E> & {
98
+ type RunOptions<T, E extends ResultError = ResultError> = RetryOptions<E> & {
94
99
  /**
95
100
  * Normalizes an unknown error value to your type `E`.
96
101
  * If not provided, a default normalizer is used.
@@ -136,18 +141,13 @@ type RunOptions<T, E extends AppError = AppError> = RetryOptions<E> & {
136
141
  * Optional structured logger for debug and errors.
137
142
  */
138
143
  logger?: {
139
- debug?: (msg: string, meta?: any) => void;
144
+ debug?: (msg: string, meta?: unknown) => void;
140
145
  error?: (msg: string, error: E) => void;
141
146
  };
142
147
  /**
143
148
  * Callback on abort, useful for reacting to `AbortSignal`.
144
149
  */
145
150
  onAbort?: (signal: AbortSignal) => void;
146
- /**
147
- * Per-call circuit breaker configuration.
148
- * If not defined, can use the default value from `Runner`.
149
- */
150
- circuitBreaker?: CircuitBreakerOptions;
151
151
  };
152
152
  /**
153
153
  * Circuit breaker configuration options:
@@ -163,42 +163,44 @@ type CircuitBreakerOptions = {
163
163
  /**
164
164
  * Execution metrics optionally returned in `RunResult`.
165
165
  */
166
- type Metrics = {
166
+ type Metrics<E extends ResultError = ResultError> = {
167
167
  totalAttempts: number;
168
168
  totalRetries: number;
169
169
  totalDuration: number;
170
- lastError?: AppError;
170
+ lastError?: E;
171
171
  };
172
- type RunResult<T, E extends AppError = AppError> = {
172
+ type RunResult<T, E extends ResultError = ResultError> = {
173
173
  ok: true;
174
174
  data: T;
175
175
  error: null;
176
- metrics?: Metrics;
176
+ metrics?: Metrics<E>;
177
177
  } | {
178
178
  ok: false;
179
179
  data: null;
180
180
  error: E;
181
- metrics?: Metrics;
181
+ metrics?: Metrics<E>;
182
182
  };
183
183
 
184
184
  /**
185
185
  * Executes an async operation and returns a Result instead of throwing.
186
186
  *
187
- * Errors are normalized into an `AppError` (or a custom error type `E`)
187
+ * Errors are normalized into an `ResultError` (or a custom error type `E`)
188
188
  * using the provided `toError` function.
189
189
  *
190
190
  * This utility is framework-agnostic and works in browsers, Node.js,
191
191
  * React effects, and any async context.
192
192
  */
193
- declare function run<T, E extends AppError = AppError>(fn: () => MaybePromise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
193
+ declare function run<T, E extends ResultError = ResultError>(fn: (ctx?: {
194
+ signal: AbortSignal;
195
+ }) => MaybePromise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
194
196
 
195
197
  /**
196
- * Discriminated result per item in `runAllSettled`:
198
+ * Discriminated result per item in `runAll`:
197
199
  * - "ok": successful task with `data`
198
200
  * - "error": failed task with `error`
199
201
  * - "skipped": task not executed due to cancellation/fail-fast/concurrency
200
202
  */
201
- type RunAllItemResult<T, E extends AppError = AppError> = {
203
+ type RunAllItemResult<T, E extends ResultError = ResultError> = {
202
204
  status: "ok";
203
205
  ok: true;
204
206
  data: T;
@@ -219,12 +221,12 @@ type SuccessResult<T> = Extract<RunAllItemResult<T, any>, {
219
221
  status: "ok";
220
222
  }>;
221
223
  /** Helper to discriminate error results. */
222
- type ErrorResult<E> = Extract<RunAllItemResult<any, E extends AppError ? E : AppError>, {
224
+ type ErrorResult<E> = Extract<RunAllItemResult<any, E extends ResultError ? E : ResultError>, {
223
225
  status: "error";
224
226
  }>;
225
227
  /** Type guard that detects `status: "ok"` with `data` typing. */
226
- declare const isSuccess: <T, E extends AppError = AppError>(r: RunAllItemResult<T, E>) => r is SuccessResult<T>;
227
- type RunAllOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
228
+ declare const isSuccess: <T, E extends ResultError = ResultError>(r: RunAllItemResult<T, E>) => r is SuccessResult<T>;
229
+ type RunAllOptions<T, E extends ResultError = ResultError> = RunOptions<T, E> & {
228
230
  /**
229
231
  * Maximum number of concurrent tasks to run.
230
232
  * @default Infinity
@@ -238,53 +240,61 @@ type RunAllOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
238
240
  */
239
241
  mode?: "settle" | "fail-fast";
240
242
  };
241
- declare function runAllSettled<T, E extends AppError = AppError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
243
+ declare function runAll<T, E extends ResultError = ResultError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
242
244
 
243
245
  /**
244
- * Options for `runAll`:
246
+ * Options for `runAllOrThrow`:
245
247
  * - Inherits all options from `RunOptions`
246
248
  * - `concurrency`: limit of simultaneous tasks; if one fails, it throws
247
249
  */
248
- type RunAllOrThrowOptions<T, E extends AppError = AppError> = RunOptions<T, E> & {
250
+ type RunAllOrThrowOptions<T, E extends ResultError = ResultError> = RunOptions<T, E> & {
249
251
  /**
250
252
  * Maximum number of concurrent tasks to run.
251
253
  * @default Infinity
252
254
  */
253
255
  concurrency?: number;
254
256
  };
255
- declare function runAll<T, E extends AppError = AppError>(tasks: Array<() => MaybePromise$1<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
257
+ declare function runAllOrThrow<T, E extends ResultError = ResultError>(tasks: Array<() => MaybePromise<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
256
258
 
257
- declare function createNormalizer<E extends AppError>(rules: Rule<E>[], fallback: (err: unknown) => E): (err: unknown) => E;
258
- declare function defaultFallback(err: unknown): AppError;
259
- declare function toAppError(err: unknown): AppError;
259
+ declare function createNormalizer<E extends ResultError>(rules: Rule<E>[], fallback: (err: unknown) => E): (err: unknown) => E;
260
+ declare function defaultFallback(err: unknown): ResultError;
261
+ declare function toResultError(err: unknown): ResultError;
260
262
 
261
263
  declare const rules: {
262
- abort: Rule<AppError<"ABORTED">>;
263
- timeout: Rule<AppError<"TIMEOUT">>;
264
- httpStatus: Rule<AppError<"HTTP">>;
265
- aggregate: Rule<AppError<"UNKNOWN", {
264
+ circuitOpen: Rule<ResultError<"CIRCUIT_OPEN">>;
265
+ abort: Rule<ResultError<"ABORTED">>;
266
+ timeout: Rule<ResultError<"TIMEOUT">>;
267
+ httpStatus: Rule<ResultError<"HTTP">>;
268
+ aggregate: Rule<ResultError<"UNKNOWN", {
266
269
  errors: unknown[];
267
270
  }>>;
268
- string: Rule<AppError<"UNKNOWN">>;
269
- message: Rule<AppError<"UNKNOWN">>;
271
+ string: Rule<ResultError<"UNKNOWN">>;
272
+ message: Rule<ResultError<"UNKNOWN">>;
270
273
  };
271
274
 
272
275
  declare class ErrorRuleBuilder<E> {
273
276
  private readonly matcher;
274
277
  constructor(matcher: (err: unknown) => err is E);
275
- toError<const Out extends AppError>(mapper: (err: E) => Out): Rule<Out>;
278
+ toError<const Out extends ResultError>(mapper: (err: E) => Out): Rule<Out>;
276
279
  }
277
280
  declare const errorRule: {
278
281
  instance<E extends new (...args: any[]) => unknown>(ctor: E): ErrorRuleBuilder<InstanceType<E>>;
279
282
  when<E = unknown>(predicate: (err: unknown) => err is E): ErrorRuleBuilder<E>;
280
283
  };
281
284
 
282
- type CreateRunnerOptions<E extends AppError = AppError> = {
285
+ type RulesMode = "extend" | "replace";
286
+ type CreateRunnerOptions<E extends ResultError = ResultError> = {
283
287
  /**
284
288
  * Custom matchers to use for normalizing errors.
285
289
  * If not provided, the default matchers are used.
286
290
  */
287
291
  rules?: Rule<E>[];
292
+ /**
293
+ * How to treat provided rules in relation to default rules.
294
+ * - "extend": Use default rules after custom rules (default).
295
+ * - "replace": Use only custom rules (and fallback).
296
+ */
297
+ rulesMode?: RulesMode;
288
298
  /**
289
299
  * Custom fallback function to use for normalizing errors.
290
300
  * If not provided, the default fallback is used.
@@ -300,17 +310,19 @@ type CreateRunnerOptions<E extends AppError = AppError> = {
300
310
  /** Optional default mapper for all runs */
301
311
  mapError?: (error: E) => E;
302
312
  /**
303
- * Default circuit breaker for all executions of the instance.
304
- * Can be overridden by `options.circuitBreaker` in each `run`.
313
+ * Circuit breaker configuration (applies to all executions of the Runner).
305
314
  */
306
315
  circuitBreaker?: CircuitBreakerOptions;
307
316
  };
308
- interface Runner<E extends AppError> {
317
+ interface Runner<E extends ResultError> {
309
318
  run<T>(fn: () => Promise<T>, options?: RunOptions<T, E>): Promise<RunResult<T, E>>;
310
319
  all<T>(fns: Array<() => MaybePromise<T>>, options?: RunAllOptions<T, E>): Promise<RunAllItemResult<T, E>[]>;
311
- allOrThrow<T>(fns: Array<() => MaybePromise<T>>, options?: RunOptions<T, E>): Promise<T[]>;
320
+ allOrThrow<T>(fns: Array<() => MaybePromise<T>>, options?: RunAllOrThrowOptions<T, E>): Promise<T[]>;
312
321
  }
313
322
 
314
- declare function trybox(options?: CreateRunnerOptions): Runner<AppError>;
323
+ declare function trybox(options?: Omit<CreateRunnerOptions<ResultError>, "rules">): Runner<ResultError>;
324
+ declare function trybox<const TRules extends readonly Rule<any>[]>(options: {
325
+ rules: TRules;
326
+ } & Omit<CreateRunnerOptions<InferErrorFromRules<TRules>>, "rules">): Runner<InferErrorFromRules<TRules>>;
315
327
 
316
- export { type AppError, type AppErrorCode, type BackoffStrategy, type CircuitBreakerOptions, type ErrorResult, type Metrics, type RetryContext, type RetryOptions, type RunAllItemResult, type RunAllOptions, type RunOptions, type RunResult, type SuccessResult, createNormalizer, trybox as default, defaultFallback, errorRule, isSuccess, rules, run, runAll, runAllSettled, toAppError };
328
+ export { type BackoffStrategy, type CircuitBreakerOptions, type ErrorResult, type Metrics, type ResultError, type ResultErrorCode, type RetryContext, type RetryOptions, type RunAllItemResult, type RunAllOptions, type RunOptions, type RunResult, type SuccessResult, createNormalizer, trybox as default, defaultFallback, errorRule, isSuccess, rules, run, runAll, runAllOrThrow, toResultError };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- function B(r,e){return t=>{for(let u of r){let n=u(t);if(n)return n}return e(t)}}function N(r){return r instanceof Error?{code:r.name==="TypeError"?"NETWORK":"UNKNOWN",message:r.message||"Something went wrong",cause:r}:{code:"UNKNOWN",message:"Something went wrong",cause:r}}function D(r){return r instanceof DOMException&&r.name==="AbortError"?{code:"ABORTED",message:"Request cancelled",cause:r}:r instanceof DOMException&&r.name==="TimeoutError"?{code:"TIMEOUT",message:"Request timed out",cause:r}:N(r)}function w(r){if(r.retries!=null&&r.retries<0)throw new Error("retries must be >= 0");if(r.timeout!=null&&r.timeout<=0)throw new Error("timeout must be > 0");if(r.maxDelay!=null&&r.maxDelay<0)throw new Error("maxDelay must be >= 0");let e=r.circuitBreaker;if(e){if(e.failureThreshold<1)throw new Error("failureThreshold must be >= 1");if(e.resetTimeout<=0)throw new Error("resetTimeout must be > 0");if(e.halfOpenRequests!=null&&e.halfOpenRequests<1)throw new Error("halfOpenRequests must be >= 1")}}var J=r=>new Promise(e=>setTimeout(e,r));function z(r,e,t){return Math.max(e,Math.min(t,r))}function H(r,e,t,u,n,s){let a=typeof r=="function"?r(e,t):typeof r=="number"?r:u,i=V(n??"linear",a,e),p=s!=null?z(i,0,s):i;return Number.isFinite(p)?p:0}function _(r,e){if(r<=0||!e)return r;let t=typeof e=="object"&&e.rng?e.rng:Math.random,u=typeof e=="number"?e:e===true?.5:typeof e=="object"&&e.ratio!=null?e.ratio:.5,n=z(u,0,1);return (typeof e=="object"&&e.mode?e.mode:"full")==="equal"?r*(1-n)+t()*r*n:r+t()*r*n}function V(r,e,t){if(typeof r=="function"){let s=r(t);return s>=0?s:0}let u=e>=0?e:0,n=t>=1?t:1;if(r==="linear")return u;if(r==="exponential")return u*Math.pow(2,n-1);if(r==="fibonacci"){if(n<=2)return u;let s=1,a=1;for(let i=3;i<=n;i++){let p=s+a;s=a,a=p;}return u*a}return u}async function g(r,e={}){let{toError:t=D,mapError:u,onError:n,onSuccess:s,onFinally:a,ignoreAbort:i=true,retries:p=0,retryDelay:y,shouldRetry:f=()=>true,jitter:E={ratio:.5,mode:"full"},backoffStrategy:o,maxDelay:m,timeout:A,signal:R,onRetry:x,logger:b,onAbort:q}=e,G=p>0?300:0;if(w(e),R?.aborted)try{q?.(R);}finally{let T=t(new DOMException("Aborted","AbortError")),l=u?u(T):T;return i||n?.(l),a?.(),{ok:false,data:null,error:l,metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,lastError:l}}}let M=Date.now(),d=0,U;for(;;)try{let T=null,l=A&&A>0?new Promise((O,K)=>{T=setTimeout(()=>K(new DOMException("Timeout","TimeoutError")),A);}):null,I=await(l?Promise.race([r(),l]):r());T&&clearTimeout(T);try{s?.(I);}catch(O){b?.error?.("run:onSuccess failed",t(O));}try{a?.();}catch(O){b?.error?.("run:onFinally failed",t(O));}let h=Date.now()-M,k={totalAttempts:d+1,totalRetries:d,totalDuration:h,lastError:U};return b?.debug?.("run:success",{attempts:k.totalAttempts,duration:k.totalDuration}),{ok:!0,data:I,error:null,metrics:k}}catch(T){let l=t(T);if(u&&(l=u(l)),l?.code==="ABORTED"||T instanceof DOMException&&T.name==="AbortError"||R?.aborted)try{if(R)try{q?.(R);}catch(c){b?.error?.("run:onAbort failed",t(c));}}finally{if(!i)try{n?.(l);}catch(F){b?.error?.("run:onError failed",t(F));}try{a?.();}catch(F){b?.error?.("run:onFinally failed",t(F));}let c=Date.now()-M,W={totalAttempts:d,totalRetries:d,totalDuration:c,lastError:l};return b?.debug?.("run:aborted",{attempt:d,duration:W.totalDuration}),{ok:false,data:null,error:l,metrics:W}}U=l;let h=d+1,k={totalAttempts:h,elapsedTime:Date.now()-M},O=await Promise.resolve(f(h,l,k));if(d<p&&O){d=h;let c=H(y,d,l,G,o,m);(!Number.isFinite(c)||c<0)&&(c=0),c=_(c,E),x?.(d,l,c),b?.debug?.("run:retry",{attempt:d,delay:c}),c>0&&await J(c);continue}try{n?.(l);}catch(c){b?.error?.("run:onError failed",t(c));}try{a?.();}catch(c){b?.error?.("run:onFinally failed",t(c));}let L=Date.now()-M,Q={totalAttempts:d+1,totalRetries:d,totalDuration:L,lastError:l};return b?.error?.("run:error",l),{ok:false,data:null,error:l,metrics:Q}}}var X=r=>r.status==="ok";async function v(r,e={}){let{concurrency:t=1/0,mode:u="settle",...n}=e;if(w(n),r.length===0)return [];let s=Number.isFinite(t)?Math.max(1,Math.floor(t)):1/0,a=new Array(r.length),i=0,p=false,y=(o,m)=>{a[o]=m.ok?{status:"ok",ok:true,data:m.data,error:null}:{status:"error",ok:false,data:null,error:m.error};},f=()=>{for(let o=0;o<r.length;o++)a[o]||(a[o]={status:"skipped",ok:false,data:null,error:null});};if(s>=r.length)return (await Promise.all(r.map(m=>g(m,n)))).forEach((m,A)=>{y(A,m);}),a;let E=async()=>{for(;;){if(p)return;let o=i++;if(o>=r.length)return;let m=r[o];if(!m)continue;let A=await g(m,n);if(y(o,A),!A.ok&&u==="fail-fast"){p=true;return}}};return await Promise.all(Array.from({length:Math.min(s,r.length)},()=>E())),f(),a}async function C(r,e={}){let{concurrency:t=1/0,...u}=e;if(w(u),r.length===0)return [];let n=Number.isFinite(t)?Math.max(1,Math.floor(t)):1/0,s=new Array(r.length);if(n>=r.length)return await Promise.all(r.map(async(f,E)=>{let o=await g(f,u);if(!o.ok)throw o.error;s[E]=o.data;})),s;let a=0,i=false,p=null,y=async()=>{for(;;){if(i)return;let f=a++;if(f>=r.length)return;let E=r[f];if(!E)continue;let o=await g(E,u);if(!o.ok){p??(p=o.error),i=true;return}s[f]=o.data;}};if(await Promise.all(Array.from({length:Math.min(n,r.length)},()=>y())),p)throw p;return s}var Y=r=>r instanceof DOMException&&r.name==="AbortError"?{code:"ABORTED",message:"Request cancelled",cause:r}:r instanceof Error&&r.name==="AbortError"?{code:"ABORTED",message:r.message||"Request cancelled",cause:r}:null,Z=r=>r instanceof DOMException&&r.name==="TimeoutError"?{code:"TIMEOUT",message:"Request timed out",cause:r}:r instanceof Error&&r.name==="TimeoutError"?{code:"TIMEOUT",message:r.message||"Request timed out",cause:r}:null,j=r=>{if(typeof r=="object"&&r!==null){let e=r,t=e.status??e.statusCode;if(typeof t=="number")return {code:"HTTP",message:typeof e.message=="string"?e.message:`HTTP Error ${t}`,status:t,cause:r}}return null},rr=r=>typeof AggregateError<"u"&&r instanceof AggregateError?{code:"UNKNOWN",message:r.message||"Multiple errors occurred",cause:r,meta:{errors:r.errors}}:null,er=r=>typeof r=="string"?{code:"UNKNOWN",message:r,cause:r}:null,tr=r=>typeof r=="object"&&r!==null&&"message"in r&&typeof r.message=="string"?{code:"UNKNOWN",message:r.message,cause:r}:null,or={abort:Y,timeout:Z,httpStatus:j,aggregate:rr,string:er,message:tr};var S=class{constructor(e){this.matcher=e;}toError(e){return t=>this.matcher(t)?e(t):null}},nr={instance(r){return new S(e=>e instanceof r)},when(r){return new S(r)}};var P=(r,e)=>t=>e?e(r?r(t):t):r?r(t):t;function $(r={}){let{rules:e=[],fallback:t=E=>N(E),toError:u,ignoreAbort:n=true,mapError:s,circuitBreaker:a}=r,i=u??(e.length>0?B(e,t):D),p=0,y=null,f=null;return {run(E,o={}){let m=o.circuitBreaker??a,A=Date.now();if(m){if(y&&A<y){let R=i(new Error("Circuit open")),x=P(s,o.mapError)(R);return o.onError?.(x),o.onFinally?.(),Promise.resolve({ok:false,data:null,error:x,metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,lastError:x}})}if(y&&A>=y&&(y=null,p=0,f=m.halfOpenRequests??1),f!=null)if(f<=0){let R=i(new Error("Circuit half-open limit")),x=P(s,o.mapError)(R);return o.onError?.(x),o.onFinally?.(),Promise.resolve({ok:false,data:null,error:x,metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,lastError:x}})}else f--;}return g(E,{toError:i,ignoreAbort:n,...o,mapError:P(s,o.mapError)}).then(R=>(m&&(R.ok?(p=0,y=null,f=null):(p++,p>=m.failureThreshold&&(y=Date.now()+m.resetTimeout,f=null))),R))},allSettled(E,o={}){return v(E,{toError:i,ignoreAbort:n,...o,mapError:P(s,o.mapError)})},all(E,o={}){return C(E,{toError:i,ignoreAbort:n,...o,mapError:P(s,o.mapError)})}}}function ur(r){return $(r)}export{B as createNormalizer,ur as default,N as defaultFallback,nr as errorRule,X as isSuccess,or as rules,g as run,C as runAll,v as runAllSettled,D as toAppError};//# sourceMappingURL=index.js.map
1
+ function K(r,e){return t=>{for(let n of r){let s=n(t);if(s)return s}return e(t)}}function v(r){return r instanceof Error?{code:r.name==="TypeError"?"NETWORK":"UNKNOWN",message:r.message||"Something went wrong",cause:r}:{code:"UNKNOWN",message:"Something went wrong",cause:r}}function N(r){return r instanceof DOMException&&r.name==="AbortError"?{code:"ABORTED",message:"Request cancelled",cause:r}:r instanceof DOMException&&r.name==="TimeoutError"?{code:"TIMEOUT",message:"Request timed out",cause:r}:v(r)}function D(r){if(r.retries!=null&&r.retries<0)throw new Error("retries must be >= 0");if(r.timeout!=null&&r.timeout<=0)throw new Error("timeout must be > 0");if(r.maxDelay!=null&&r.maxDelay<0)throw new Error("maxDelay must be >= 0")}var $=r=>new Promise(e=>setTimeout(e,r));function G(r,e,t){return Math.max(e,Math.min(t,r))}function Q(r,e,t,n,s,l){let u=typeof r=="function"?r(e,t):typeof r=="number"?r:n,E=ur(s??"linear",u,e),i=l!=null?G(E,0,l):E;return Number.isFinite(i)?i:0}function V(r,e){if(r<=0||!e)return r;let t=typeof e=="object"&&e.rng?e.rng:Math.random,n=typeof e=="number"?e:e===true?.5:typeof e=="object"&&e.ratio!=null?e.ratio:.5,s=G(n,0,1);return (typeof e=="object"&&e.mode?e.mode:"full")==="equal"?r*(1-s)+t()*r*s:r+t()*r*s}function ur(r,e,t){if(typeof r=="function"){let l=r(t);return l>=0?l:0}let n=e>=0?e:0,s=t>=1?t:1;if(r==="linear")return n;if(r==="exponential")return n*Math.pow(2,s-1);if(r==="fibonacci"){if(s<=2)return n;let l=1,u=1;for(let E=3;E<=s;E++){let i=l+u;l=u,u=i;}return n*u}return n}async function O(r,e={}){let{toError:t=N,mapError:n,onError:s,onSuccess:l,onFinally:u,ignoreAbort:E=true,retries:i=0,retryDelay:x,shouldRetry:R=()=>true,jitter:y={ratio:.5,mode:"full"},backoffStrategy:o,maxDelay:m,timeout:f,signal:a,onRetry:g,logger:d,onAbort:w}=e,M=i>0?300:0;if(D(e),a?.aborted)try{w?.(a);}finally{let T=t(new DOMException("Aborted","AbortError")),A=n?n(T):T;return E||s?.(A),u?.(),{ok:false,data:null,error:A,metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,lastError:A}}}let P=Date.now(),b=0,H,U=0;for(;;){let T=new AbortController;a&&(a.aborted?T.abort(a.reason):a.addEventListener("abort",()=>T.abort(a.reason),{once:true}));let A=null;f&&f>0&&(A=setTimeout(()=>{T.abort(new DOMException("Timeout","TimeoutError"));},f));try{let I=new Promise((k,F)=>{T.signal.aborted?F(T.signal.reason):T.signal.addEventListener("abort",()=>F(T.signal.reason),{once:!0});}),p=await Promise.race([r({signal:T.signal}),I]);A&&clearTimeout(A);try{l?.(p);}catch(k){d?.error?.("run:onSuccess failed",t(k));}try{u?.();}catch(k){d?.error?.("run:onFinally failed",t(k));}let L=Date.now()-P,h={totalAttempts:b+1,totalRetries:b,totalDuration:L,lastError:H};return d?.debug?.("run:success",{attempts:h.totalAttempts,duration:h.totalDuration}),{ok:!0,data:p,error:null,metrics:h}}catch(I){let p=t(I);if(n&&(p=n(p)),p?.code==="ABORTED"||I instanceof DOMException&&I.name==="AbortError"||a?.aborted)try{if(a)try{w?.(a);}catch(c){d?.error?.("run:onAbort failed",t(c));}}finally{if(!E)try{s?.(p);}catch(q){d?.error?.("run:onError failed",t(q));}try{u?.();}catch(q){d?.error?.("run:onFinally failed",t(q));}let c=Date.now()-P,_={totalAttempts:b+1,totalRetries:b,totalDuration:c,lastError:p};return d?.debug?.("run:aborted",{attempt:b,duration:_.totalDuration}),{ok:false,data:null,error:p,metrics:_}}H=p;let h=b+1,k={totalAttempts:h,elapsedTime:Date.now()-P,startTime:P,lastDelay:U>0?U:void 0},F=await Promise.resolve(R(h,p,k));if(b<i&&F){b=h;let c=Q(x,b,p,M,o,m);(!Number.isFinite(c)||c<0)&&(c=0),c=V(c,y),U=c,g?.(b,p,c),d?.debug?.("run:retry",{attempt:b,delay:c}),c>0&&await $(c);continue}try{s?.(p);}catch(c){d?.error?.("run:onError failed",t(c));}try{u?.();}catch(c){d?.error?.("run:onFinally failed",t(c));}let nr=Date.now()-P,sr={totalAttempts:b+1,totalRetries:b,totalDuration:nr,lastError:p};return d?.error?.("run:error",p),{ok:false,data:null,error:p,metrics:sr}}}}var lr=r=>r.status==="ok";async function W(r,e={}){let{concurrency:t=1/0,mode:n="settle",...s}=e;if(D(s),r.length===0)return [];let l=Number.isFinite(t)?Math.max(1,Math.floor(t)):1/0,u=new Array(r.length),E=0,i=false,x=(o,m)=>{u[o]=m.ok?{status:"ok",ok:true,data:m.data,error:null}:{status:"error",ok:false,data:null,error:m.error};},R=()=>{for(let o=0;o<r.length;o++)u[o]||(u[o]={status:"skipped",ok:false,data:null,error:null});};if(l>=r.length)return (await Promise.all(r.map(m=>O(m,s)))).forEach((m,f)=>{x(f,m);}),u;let y=async()=>{for(;;){if(i)return;let o=E++;if(o>=r.length)return;let m=r[o];if(!m)continue;let f=await O(m,s);if(x(o,f),!f.ok&&n==="fail-fast"){i=true;return}}};return await Promise.all(Array.from({length:Math.min(l,r.length)},()=>y())),R(),u}async function J(r,e={}){let{concurrency:t=1/0,...n}=e;if(D(n),r.length===0)return [];let s=Number.isFinite(t)?Math.max(1,Math.floor(t)):1/0,l=new Array(r.length);if(s>=r.length)return await Promise.all(r.map(async(R,y)=>{let o=await O(R,n);if(!o.ok)throw o.error;l[y]=o.data;})),l;let u=0,E=false,i=null,x=async()=>{for(;;){if(E)return;let R=u++;if(R>=r.length)return;let y=r[R];if(!y)continue;let o=await O(y,n);if(!o.ok){i??(i=o.error),E=true;return}l[R]=o.data;}};if(await Promise.all(Array.from({length:Math.min(s,r.length)},()=>x())),i)throw i;return l}var C=class extends Error{constructor(){super("Circuit open"),this.name="CircuitOpenError";}},X=r=>r instanceof C||r instanceof Error&&r.name==="CircuitOpenError"?{code:"CIRCUIT_OPEN",message:"Circuit open",cause:r}:null,Y=r=>r instanceof DOMException&&r.name==="AbortError"?{code:"ABORTED",message:"Request cancelled",cause:r}:r instanceof Error&&r.name==="AbortError"?{code:"ABORTED",message:r.message||"Request cancelled",cause:r}:null,Z=r=>r instanceof DOMException&&r.name==="TimeoutError"?{code:"TIMEOUT",message:"Request timed out",cause:r}:r instanceof Error&&r.name==="TimeoutError"?{code:"TIMEOUT",message:r.message||"Request timed out",cause:r}:null,j=r=>{if(typeof r=="object"&&r!==null){let e=r,t=e.status??e.statusCode;if(typeof t=="number")return {code:"HTTP",message:typeof e.message=="string"?e.message:`HTTP Error ${t}`,status:t,cause:r}}return null},rr=r=>typeof AggregateError<"u"&&r instanceof AggregateError?{code:"UNKNOWN",message:r.message||"Multiple errors occurred",cause:r,meta:{errors:r.errors}}:null,er=r=>typeof r=="string"?{code:"UNKNOWN",message:r,cause:r}:null,tr=r=>typeof r=="object"&&r!==null&&"message"in r&&typeof r.message=="string"?{code:"UNKNOWN",message:r.message,cause:r}:null,ar={circuitOpen:X,abort:Y,timeout:Z,httpStatus:j,aggregate:rr,string:er,message:tr};function z(){return [X,Y,Z,j,rr,er,tr]}var S=class{constructor(e){this.matcher=e;}toError(e){return t=>this.matcher(t)?e(t):null}},ir={instance(r){return new S(e=>e instanceof r)},when(r){return new S(r)}};var B=(r,e)=>t=>e?e(r?r(t):t):r?r(t):t;function or(r={}){let{rules:e=[],rulesMode:t="extend",fallback:n=f=>v(f),toError:s,ignoreAbort:l=true,mapError:u,circuitBreaker:E}=r,i=[],x=z()||[];e.length>0?t==="extend"?i=[...e,...x]:i=[...e]:t==="extend"?i=x:i=[];let R=s??(i.length>0?K(i,n):N),y=0,o=null,m=null;return {run(f,a={}){let g=E,d=Date.now();if(g&&o&&d<o){let w=R(new C),M=B(u,a.mapError)(w);return a.onError?.(M),a.onFinally?.(),Promise.resolve({ok:false,data:null,error:M,metrics:{totalAttempts:0,totalRetries:0,totalDuration:0,lastError:M}})}return O(f,{toError:R,ignoreAbort:l,...a,mapError:B(u,a.mapError)}).then(w=>(g&&(w.ok?o&&Date.now()>=o?(m&&m>0&&m--,(!m||m<=0)&&(o=null,y=0,m=null)):y=0:o&&Date.now()>=o?(o=Date.now()+g.resetTimeout,m=g.halfOpenRequests??1,y=0):o||(y++,y>=g.failureThreshold&&(o=Date.now()+g.resetTimeout,m=g.halfOpenRequests??1))),w))},all(f,a={}){return W(f,{toError:R,ignoreAbort:l,...a,mapError:B(u,a.mapError)})},allOrThrow(f,a={}){return J(f,{toError:R,ignoreAbort:l,...a,mapError:B(u,a.mapError)})}}}function mr(r={}){return or(r)}export{K as createNormalizer,mr as default,v as defaultFallback,ir as errorRule,lr as isSuccess,ar as rules,O as run,W as runAll,J as runAllOrThrow,N as toResultError};//# sourceMappingURL=index.js.map
2
2
  //# sourceMappingURL=index.js.map