@fetchkit/ffetch 5.2.1 → 5.4.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.
Files changed (46) hide show
  1. package/README.md +34 -17
  2. package/dist/chunk-X64PXWPN.min.js +2 -0
  3. package/dist/chunk-X64PXWPN.min.js.map +1 -0
  4. package/dist/{chunk-RV6LC73N.js → chunk-ZIJ2DZYZ.js} +7 -1
  5. package/dist/chunk-ZIJ2DZYZ.js.map +1 -0
  6. package/dist/{error-XBHPSMAQ.js → error-H4GGJSCM.js} +4 -2
  7. package/dist/error-HT5UPPWM.min.js +2 -0
  8. package/dist/index.cjs +53 -37
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +4 -1
  11. package/dist/index.d.ts +4 -1
  12. package/dist/index.js +49 -39
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.min.js +1 -1
  15. package/dist/index.min.js.map +1 -1
  16. package/dist/plugins/bulkhead.cjs +137 -0
  17. package/dist/plugins/bulkhead.cjs.map +1 -0
  18. package/dist/plugins/bulkhead.d.cts +15 -0
  19. package/dist/plugins/bulkhead.d.ts +15 -0
  20. package/dist/plugins/bulkhead.js +96 -0
  21. package/dist/plugins/bulkhead.js.map +1 -0
  22. package/dist/plugins/circuit.cjs +14 -8
  23. package/dist/plugins/circuit.cjs.map +1 -1
  24. package/dist/plugins/circuit.d.cts +16 -3
  25. package/dist/plugins/circuit.d.ts +16 -3
  26. package/dist/plugins/circuit.js +15 -9
  27. package/dist/plugins/circuit.js.map +1 -1
  28. package/dist/plugins/context-id.cjs +74 -0
  29. package/dist/plugins/context-id.cjs.map +1 -0
  30. package/dist/plugins/context-id.d.cts +10 -0
  31. package/dist/plugins/context-id.d.ts +10 -0
  32. package/dist/plugins/context-id.js +49 -0
  33. package/dist/plugins/context-id.js.map +1 -0
  34. package/dist/plugins/hedge.cjs +127 -0
  35. package/dist/plugins/hedge.cjs.map +1 -0
  36. package/dist/plugins/hedge.d.cts +12 -0
  37. package/dist/plugins/hedge.d.ts +12 -0
  38. package/dist/plugins/hedge.js +102 -0
  39. package/dist/plugins/hedge.js.map +1 -0
  40. package/package.json +17 -2
  41. package/dist/chunk-RV6LC73N.js.map +0 -1
  42. package/dist/chunk-UP35S5ZH.min.js +0 -2
  43. package/dist/chunk-UP35S5ZH.min.js.map +0 -1
  44. package/dist/error-7EEQP46E.min.js +0 -2
  45. /package/dist/{error-7EEQP46E.min.js.map → error-H4GGJSCM.js.map} +0 -0
  46. /package/dist/{error-XBHPSMAQ.js.map → error-HT5UPPWM.min.js.map} +0 -0
package/dist/index.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import {
2
2
  AbortError,
3
+ BulkheadFullError,
3
4
  CircuitOpenError,
4
5
  HttpError,
5
6
  NetworkError,
6
7
  RetryLimitError,
7
8
  TimeoutError
8
- } from "./chunk-RV6LC73N.js";
9
+ } from "./chunk-ZIJ2DZYZ.js";
9
10
 
10
11
  // src/retry.ts
11
12
  var defaultDelay = (ctx) => {
@@ -205,18 +206,19 @@ function createClient(opts = {}) {
205
206
  controller = new AbortController();
206
207
  }
207
208
  pluginContext.metadata.signals.combined = combinedSignal;
208
- const retryWithHooks = async () => {
209
+ const retryWithHooks = async (dispatchCtx, dispatchSignal) => {
210
+ const requestForAttempt = dispatchCtx.request;
209
211
  let attempt = 0;
210
212
  const shouldRetryWithHook = (ctx) => {
211
213
  attempt = ctx.attempt;
212
- pluginContext.metadata.retry.attempt = attempt;
213
- pluginContext.metadata.retry.lastError = ctx.error;
214
- pluginContext.metadata.retry.lastResponse = ctx.response;
214
+ dispatchCtx.metadata.retry.attempt = attempt;
215
+ dispatchCtx.metadata.retry.lastError = ctx.error;
216
+ dispatchCtx.metadata.retry.lastResponse = ctx.response;
215
217
  const retrying = effectiveShouldRetry(ctx);
216
- pluginContext.metadata.retry.shouldRetryResult = retrying;
218
+ dispatchCtx.metadata.retry.shouldRetryResult = retrying;
217
219
  if (retrying && attempt <= effectiveRetries) {
218
220
  effectiveHooks.onRetry?.(
219
- request,
221
+ requestForAttempt,
220
222
  attempt - 1,
221
223
  ctx.error,
222
224
  ctx.response
@@ -229,21 +231,21 @@ function createClient(opts = {}) {
229
231
  let res = await retry(
230
232
  async () => {
231
233
  if (userSignal?.aborted) {
232
- effectiveHooks.onAbort?.(request);
234
+ effectiveHooks.onAbort?.(requestForAttempt);
233
235
  throw new AbortError("Request was aborted by user");
234
236
  }
235
237
  if (timeoutSignal?.aborted) {
236
- effectiveHooks.onTimeout?.(request);
238
+ effectiveHooks.onTimeout?.(requestForAttempt);
237
239
  throw new TimeoutError("signal timed out");
238
240
  }
239
- if (typeof combinedSignal?.throwIfAborted === "function") {
240
- combinedSignal.throwIfAborted();
241
- } else if (combinedSignal?.aborted) {
241
+ if (typeof dispatchSignal?.throwIfAborted === "function") {
242
+ dispatchSignal.throwIfAborted();
243
+ } else if (dispatchSignal?.aborted) {
242
244
  if (userSignal?.aborted) {
243
- effectiveHooks.onAbort?.(request);
245
+ effectiveHooks.onAbort?.(requestForAttempt);
244
246
  throw new AbortError("Request was aborted by user");
245
247
  } else if (timeoutSignal?.aborted) {
246
- effectiveHooks.onTimeout?.(request);
248
+ effectiveHooks.onTimeout?.(requestForAttempt);
247
249
  throw new TimeoutError("signal timed out");
248
250
  } else {
249
251
  throw new AbortError(
@@ -252,23 +254,23 @@ function createClient(opts = {}) {
252
254
  );
253
255
  }
254
256
  }
255
- const reqWithSignal = new Request(request, {
256
- signal: combinedSignal
257
+ const reqWithSignal = new Request(requestForAttempt, {
258
+ signal: dispatchSignal
257
259
  });
258
260
  try {
259
261
  const handler = init.fetchHandler ?? fetchHandler ?? fetch;
260
262
  const response = await handler(reqWithSignal);
261
263
  lastResponse = response;
262
- pluginContext.metadata.retry.lastResponse = response;
264
+ dispatchCtx.metadata.retry.lastResponse = response;
263
265
  return response;
264
266
  } catch (err) {
265
- pluginContext.metadata.retry.lastError = err;
267
+ dispatchCtx.metadata.retry.lastError = err;
266
268
  if (err instanceof DOMException && err.name === "AbortError") {
267
269
  if (timeoutSignal?.aborted && (!userSignal || !userSignal.aborted)) {
268
- effectiveHooks.onTimeout?.(request);
270
+ effectiveHooks.onTimeout?.(requestForAttempt);
269
271
  throw new TimeoutError("signal timed out", err);
270
272
  } else if (userSignal?.aborted) {
271
- effectiveHooks.onAbort?.(request);
273
+ effectiveHooks.onAbort?.(requestForAttempt);
272
274
  throw new AbortError("Request was aborted by user");
273
275
  } else {
274
276
  throw new AbortError(
@@ -287,16 +289,16 @@ function createClient(opts = {}) {
287
289
  effectiveRetries,
288
290
  effectiveRetryDelay,
289
291
  shouldRetryWithHook,
290
- request,
291
- combinedSignal
292
+ requestForAttempt,
293
+ dispatchSignal
292
294
  );
293
295
  if (effectiveHooks.transformResponse) {
294
- res = await effectiveHooks.transformResponse(res, request);
296
+ res = await effectiveHooks.transformResponse(res, requestForAttempt);
295
297
  }
296
- await effectiveHooks.after?.(request, res);
297
- await effectiveHooks.onComplete?.(request, res, void 0);
298
+ await effectiveHooks.after?.(requestForAttempt, res);
299
+ await effectiveHooks.onComplete?.(requestForAttempt, res, void 0);
298
300
  if (effectiveThrowOnHttpError && (res.status >= 400 && res.status < 500 && res.status !== 429 || res.status >= 500 || res.status === 429)) {
299
- const { HttpError: HttpError2 } = await import("./error-XBHPSMAQ.js");
301
+ const { HttpError: HttpError2 } = await import("./error-H4GGJSCM.js");
300
302
  throw new HttpError2(
301
303
  `HTTP error: ${res.status} ${res.statusText}`,
302
304
  res
@@ -304,11 +306,11 @@ function createClient(opts = {}) {
304
306
  }
305
307
  return res;
306
308
  } catch (err) {
307
- pluginContext.metadata.retry.lastError = err;
309
+ dispatchCtx.metadata.retry.lastError = err;
308
310
  if (lastResponse) {
309
311
  const resp = lastResponse;
310
312
  if (effectiveThrowOnHttpError && (resp.status >= 400 && resp.status < 500 && resp.status !== 429 || resp.status >= 500 || resp.status === 429)) {
311
- const { HttpError: HttpError2 } = await import("./error-XBHPSMAQ.js");
313
+ const { HttpError: HttpError2 } = await import("./error-H4GGJSCM.js");
312
314
  throw new HttpError2(
313
315
  `HTTP error: ${resp.status} ${resp.statusText}`,
314
316
  resp
@@ -317,32 +319,39 @@ function createClient(opts = {}) {
317
319
  return resp;
318
320
  }
319
321
  if (err instanceof TimeoutError) {
320
- await effectiveHooks.onTimeout?.(request);
321
- await effectiveHooks.onError?.(request, err);
322
- await effectiveHooks.onComplete?.(request, void 0, err);
322
+ await effectiveHooks.onTimeout?.(requestForAttempt);
323
+ await effectiveHooks.onError?.(requestForAttempt, err);
324
+ await effectiveHooks.onComplete?.(requestForAttempt, void 0, err);
323
325
  throw err;
324
326
  }
325
327
  if (err instanceof AbortError) {
326
- await effectiveHooks.onAbort?.(request);
327
- await effectiveHooks.onError?.(request, err);
328
- await effectiveHooks.onComplete?.(request, void 0, err);
328
+ await effectiveHooks.onAbort?.(requestForAttempt);
329
+ await effectiveHooks.onError?.(requestForAttempt, err);
330
+ await effectiveHooks.onComplete?.(requestForAttempt, void 0, err);
329
331
  throw err;
330
332
  }
331
333
  if (err instanceof NetworkError) {
332
- await effectiveHooks.onError?.(request, err);
333
- await effectiveHooks.onComplete?.(request, void 0, err);
334
+ await effectiveHooks.onError?.(requestForAttempt, err);
335
+ await effectiveHooks.onComplete?.(requestForAttempt, void 0, err);
334
336
  throw err;
335
337
  }
336
338
  const retryErr = new RetryLimitError(
337
339
  typeof err === "object" && err && "message" in err && typeof err.message === "string" ? err.message : "Retry limit reached",
338
340
  err
339
341
  );
340
- await effectiveHooks.onError?.(request, retryErr);
341
- await effectiveHooks.onComplete?.(request, void 0, retryErr);
342
+ await effectiveHooks.onError?.(requestForAttempt, retryErr);
343
+ await effectiveHooks.onComplete?.(
344
+ requestForAttempt,
345
+ void 0,
346
+ retryErr
347
+ );
342
348
  throw retryErr;
343
349
  }
344
350
  };
345
- const baseDispatch = async () => retryWithHooks();
351
+ const baseDispatch = async (ctx) => {
352
+ const dispatchSignal = ctx === pluginContext ? combinedSignal : ctx.request.signal;
353
+ return retryWithHooks(ctx, dispatchSignal);
354
+ };
346
355
  let dispatch = baseDispatch;
347
356
  for (let i = plugins.length - 1; i >= 0; i--) {
348
357
  const plugin = plugins[i];
@@ -403,6 +412,7 @@ function createClient(opts = {}) {
403
412
  }
404
413
  export {
405
414
  AbortError,
415
+ BulkheadFullError,
406
416
  CircuitOpenError,
407
417
  HttpError,
408
418
  NetworkError,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/retry.ts","../src/should-retry.ts","../src/client.ts"],"sourcesContent":["import type { RetryContext } from './types.js'\n\nexport type RetryDelay = number | ((ctx: RetryContext) => number)\n\nexport const defaultDelay: RetryDelay = (ctx) => {\n const retryAfter = ctx.response?.headers.get('Retry-After')\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10)\n if (!isNaN(seconds)) return seconds * 1000\n const date = Date.parse(retryAfter)\n if (!isNaN(date)) return Math.max(0, date - Date.now())\n }\n return 2 ** ctx.attempt * 200 + Math.random() * 100\n}\n\nfunction waitForRetryDelay(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise((resolve) => {\n if (!signal) {\n setTimeout(resolve, ms)\n return\n }\n\n if (signal.aborted) {\n resolve()\n return\n }\n\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport async function retry(\n fn: () => Promise<Response>,\n retries: number,\n delay: RetryDelay,\n shouldRetry: (ctx: RetryContext) => boolean = () => true,\n request: Request,\n signal?: AbortSignal\n): Promise<Response> {\n let lastErr: unknown\n let lastRes: Response | undefined\n\n for (let i = 0; i <= retries; i++) {\n const ctx: RetryContext = {\n attempt: i + 1,\n request,\n response: lastRes,\n error: lastErr,\n }\n try {\n lastRes = await fn()\n ctx.response = lastRes\n ctx.error = undefined\n if (i < retries && shouldRetry(ctx)) {\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n continue\n }\n return lastRes\n } catch (err) {\n lastErr = err\n ctx.error = err\n if (i === retries || !shouldRetry(ctx)) throw err\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n }\n }\n throw lastErr\n}\n","import { AbortError, CircuitOpenError, TimeoutError } from './error.js'\nimport type { RetryContext } from './types.js'\n\nexport function shouldRetry(ctx: RetryContext): boolean {\n const { error, response } = ctx\n if (\n error instanceof AbortError ||\n error instanceof CircuitOpenError ||\n error instanceof TimeoutError\n )\n return false\n if (!response) return true // network error\n return response.status >= 500 || response.status === 429\n}\n","import type {\r\n FFetchOptions,\r\n FFetch,\r\n FFetchRequestInit,\r\n PendingRequest,\r\n} from './types.js'\r\nimport { retry, defaultDelay } from './retry.js'\r\nimport { shouldRetry as defaultShouldRetry } from './should-retry.js'\r\nimport {\r\n type PluginDispatch,\r\n type PluginRequestContext,\r\n type PluginExtensions,\r\n type PluginRequestPromiseExtensions,\r\n type ClientPlugin,\r\n type PluginExtensionBase,\r\n type PluginRequestPromiseExtensionBase,\r\n} from './plugins.js'\r\nimport {\r\n TimeoutError,\r\n AbortError,\r\n RetryLimitError,\r\n NetworkError,\r\n} from './error.js'\r\n\r\nexport function createClient<\r\n TPlugins extends readonly ClientPlugin<\r\n PluginExtensionBase,\r\n PluginRequestPromiseExtensionBase\r\n >[] = readonly ClientPlugin<\r\n PluginExtensionBase,\r\n PluginRequestPromiseExtensionBase\r\n >[],\r\n>(\r\n opts: FFetchOptions<TPlugins> = {} as FFetchOptions<TPlugins>\r\n): FFetch<\r\n PluginExtensions<TPlugins>,\r\n PluginRequestPromiseExtensions<TPlugins>\r\n> {\r\n const {\r\n timeout: clientDefaultTimeout = 5_000,\r\n retries: clientDefaultRetries = 0,\r\n retryDelay: clientDefaultRetryDelay = defaultDelay,\r\n shouldRetry: clientDefaultShouldRetry = defaultShouldRetry,\r\n hooks: clientDefaultHooks = {},\r\n fetchHandler,\r\n plugins: inputPlugins = [] as unknown as TPlugins,\r\n } = opts\r\n\r\n const extensionDescriptors: PropertyDescriptorMap = Object.create(null)\r\n\r\n const plugins = inputPlugins\r\n .map((plugin, index) => ({ plugin, index }))\r\n .sort((a, b) => {\r\n const aOrder = a.plugin.order ?? 0\r\n const bOrder = b.plugin.order ?? 0\r\n if (aOrder !== bOrder) return aOrder - bOrder\r\n return a.index - b.index\r\n })\r\n .map((entry) => entry.plugin)\r\n\r\n for (const plugin of plugins) {\r\n plugin.setup?.({\r\n defineExtension: (key, descriptor) => {\r\n const propertyKey = key as PropertyKey\r\n if (propertyKey in extensionDescriptors) {\r\n throw new Error(\r\n `Plugin extension collision for property \"${String(propertyKey)}\"`\r\n )\r\n }\r\n if ('get' in descriptor) {\r\n extensionDescriptors[propertyKey] = {\r\n get: descriptor.get,\r\n enumerable: descriptor.enumerable ?? true,\r\n configurable: false,\r\n }\r\n return\r\n }\r\n extensionDescriptors[propertyKey] = {\r\n value: descriptor.value,\r\n writable: false,\r\n enumerable: descriptor.enumerable ?? true,\r\n configurable: false,\r\n }\r\n },\r\n })\r\n }\r\n\r\n const pendingRequests: PendingRequest[] = []\r\n\r\n // Helper to abort all pending requests\r\n function abortAll() {\r\n for (const entry of pendingRequests) {\r\n entry.controller?.abort()\r\n }\r\n }\r\n\r\n const client = (input: RequestInfo | URL, init: FFetchRequestInit = {}) => {\r\n const execute = async () => {\r\n let request = new Request(input, init)\r\n\r\n // Merge hooks: per-request hooks override client hooks, but fallback to client hooks\r\n const effectiveHooks = { ...clientDefaultHooks, ...(init.hooks || {}) }\r\n if (effectiveHooks.transformRequest) {\r\n request = await effectiveHooks.transformRequest(request)\r\n }\r\n await effectiveHooks.before?.(request)\r\n\r\n // Determine retry config (per-request overrides client default)\r\n const effectiveRetries = init.retries ?? clientDefaultRetries\r\n const effectiveRetryDelay =\r\n typeof init.retryDelay !== 'undefined'\r\n ? init.retryDelay\r\n : clientDefaultRetryDelay\r\n const effectiveShouldRetry = init.shouldRetry ?? clientDefaultShouldRetry\r\n\r\n // AbortSignal.timeout/any logic\r\n const effectiveTimeout = init.timeout ?? clientDefaultTimeout\r\n const userSignal = init.signal\r\n const transformedSignal = request.signal\r\n\r\n const pluginContext: PluginRequestContext = {\r\n request,\r\n init,\r\n state: Object.create(null),\r\n metadata: {\r\n startedAt: Date.now(),\r\n timeoutMs: effectiveTimeout,\r\n signals: {\r\n user:\r\n userSignal === undefined || userSignal === null\r\n ? undefined\r\n : userSignal,\r\n transformed: transformedSignal,\r\n },\r\n retry: {\r\n configuredRetries: effectiveRetries,\r\n configuredDelay: effectiveRetryDelay,\r\n attempt: 0,\r\n },\r\n },\r\n }\r\n\r\n for (const plugin of plugins) {\r\n await plugin.preRequest?.(pluginContext)\r\n }\r\n\r\n // Determine throwOnHttpError (per-request overrides client default)\r\n const effectiveThrowOnHttpError =\r\n typeof init.throwOnHttpError !== 'undefined'\r\n ? init.throwOnHttpError\r\n : (opts.throwOnHttpError ?? false)\r\n\r\n // Create timeout signal (manual implementation if AbortSignal.timeout not available)\r\n function createTimeoutSignal(timeout: number): AbortSignal {\r\n if (typeof AbortSignal?.timeout === 'function') {\r\n return AbortSignal.timeout(timeout)\r\n }\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeout)\r\n controller.signal.addEventListener(\r\n 'abort',\r\n () => clearTimeout(timeoutId),\r\n { once: true }\r\n )\r\n return controller.signal\r\n }\r\n\r\n let timeoutSignal: AbortSignal | undefined = undefined\r\n let combinedSignal: AbortSignal | undefined = undefined\r\n let controller: AbortController | undefined = undefined\r\n\r\n if (effectiveTimeout > 0) {\r\n timeoutSignal = createTimeoutSignal(effectiveTimeout)\r\n pluginContext.metadata.signals.timeout = timeoutSignal\r\n }\r\n\r\n const signals: AbortSignal[] = []\r\n if (userSignal) signals.push(userSignal)\r\n if (transformedSignal && transformedSignal !== userSignal) {\r\n signals.push(transformedSignal)\r\n }\r\n if (timeoutSignal) signals.push(timeoutSignal)\r\n\r\n if (signals.length === 1) {\r\n combinedSignal = signals[0]\r\n controller = new AbortController()\r\n } else {\r\n if (typeof AbortSignal.any !== 'function') {\r\n throw new Error(\r\n 'AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.'\r\n )\r\n }\r\n combinedSignal = AbortSignal.any(signals)\r\n controller = new AbortController()\r\n }\r\n pluginContext.metadata.signals.combined = combinedSignal\r\n\r\n const retryWithHooks = async () => {\r\n let attempt = 0\r\n const shouldRetryWithHook = (ctx: import('./types').RetryContext) => {\r\n attempt = ctx.attempt\r\n pluginContext.metadata.retry.attempt = attempt\r\n pluginContext.metadata.retry.lastError = ctx.error\r\n pluginContext.metadata.retry.lastResponse = ctx.response\r\n const retrying = effectiveShouldRetry(ctx)\r\n pluginContext.metadata.retry.shouldRetryResult = retrying\r\n if (retrying && attempt <= effectiveRetries) {\r\n effectiveHooks.onRetry?.(\r\n request,\r\n attempt - 1,\r\n ctx.error,\r\n ctx.response\r\n )\r\n }\r\n return retrying\r\n }\r\n\r\n let lastResponse: Response | undefined = undefined\r\n try {\r\n let res = await retry(\r\n async () => {\r\n if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n }\r\n if (timeoutSignal?.aborted) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out')\r\n }\r\n if (typeof combinedSignal?.throwIfAborted === 'function') {\r\n combinedSignal.throwIfAborted()\r\n } else if (combinedSignal?.aborted) {\r\n if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n } else if (timeoutSignal?.aborted) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out')\r\n } else {\r\n throw new AbortError(\r\n 'Request was aborted',\r\n new DOMException('Aborted', 'AbortError')\r\n )\r\n }\r\n }\r\n const reqWithSignal = new Request(request, {\r\n signal: combinedSignal,\r\n })\r\n try {\r\n const handler = init.fetchHandler ?? fetchHandler ?? fetch\r\n const response = await handler(reqWithSignal)\r\n lastResponse = response\r\n pluginContext.metadata.retry.lastResponse = response\r\n return response\r\n } catch (err) {\r\n pluginContext.metadata.retry.lastError = err\r\n if (err instanceof DOMException && err.name === 'AbortError') {\r\n if (\r\n timeoutSignal?.aborted &&\r\n (!userSignal || !userSignal.aborted)\r\n ) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out', err)\r\n } else if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n } else {\r\n throw new AbortError(\r\n 'Request was aborted',\r\n new DOMException('Aborted', 'AbortError')\r\n )\r\n }\r\n } else if (\r\n err instanceof TypeError &&\r\n /NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(\r\n err.message\r\n )\r\n ) {\r\n throw new NetworkError(err.message, err)\r\n }\r\n throw err\r\n }\r\n },\r\n effectiveRetries,\r\n effectiveRetryDelay,\r\n shouldRetryWithHook,\r\n request,\r\n combinedSignal\r\n )\r\n if (effectiveHooks.transformResponse) {\r\n res = await effectiveHooks.transformResponse(res, request)\r\n }\r\n await effectiveHooks.after?.(request, res)\r\n await effectiveHooks.onComplete?.(request, res, undefined)\r\n if (\r\n effectiveThrowOnHttpError &&\r\n ((res.status >= 400 && res.status < 500 && res.status !== 429) ||\r\n res.status >= 500 ||\r\n res.status === 429)\r\n ) {\r\n const { HttpError } = await import('./error.js')\r\n throw new HttpError(\r\n `HTTP error: ${res.status} ${res.statusText}`,\r\n res\r\n )\r\n }\r\n return res\r\n } catch (err: unknown) {\r\n pluginContext.metadata.retry.lastError = err\r\n if (lastResponse) {\r\n const resp = lastResponse as Response\r\n if (\r\n effectiveThrowOnHttpError &&\r\n ((resp.status >= 400 &&\r\n resp.status < 500 &&\r\n resp.status !== 429) ||\r\n resp.status >= 500 ||\r\n resp.status === 429)\r\n ) {\r\n const { HttpError } = await import('./error.js')\r\n throw new HttpError(\r\n `HTTP error: ${resp.status} ${resp.statusText}`,\r\n resp\r\n )\r\n }\r\n return resp\r\n }\r\n if (err instanceof TimeoutError) {\r\n await effectiveHooks.onTimeout?.(request)\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n if (err instanceof AbortError) {\r\n await effectiveHooks.onAbort?.(request)\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n if (err instanceof NetworkError) {\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n const retryErr = new RetryLimitError(\r\n typeof err === 'object' &&\r\n err &&\r\n 'message' in err &&\r\n typeof (err as { message?: unknown }).message === 'string'\r\n ? (err as { message: string }).message\r\n : 'Retry limit reached',\r\n err\r\n )\r\n await effectiveHooks.onError?.(request, retryErr)\r\n await effectiveHooks.onComplete?.(request, undefined, retryErr)\r\n throw retryErr\r\n }\r\n }\r\n\r\n const baseDispatch: PluginDispatch = async () => retryWithHooks()\r\n\r\n let dispatch = baseDispatch\r\n for (let i = plugins.length - 1; i >= 0; i--) {\r\n const plugin = plugins[i]\r\n if (plugin.wrapDispatch) {\r\n dispatch = plugin.wrapDispatch(dispatch)\r\n }\r\n }\r\n\r\n const actualPromise = dispatch(pluginContext)\r\n .then(async (response) => {\r\n for (const plugin of plugins) {\r\n await plugin.onSuccess?.(pluginContext, response)\r\n }\r\n return response\r\n })\r\n .catch(async (err: unknown) => {\r\n for (const plugin of plugins) {\r\n await plugin.onError?.(pluginContext, err)\r\n }\r\n throw err\r\n })\r\n\r\n const pendingEntry: PendingRequest = {\r\n promise: actualPromise,\r\n request,\r\n controller,\r\n }\r\n pendingRequests.push(pendingEntry)\r\n\r\n return actualPromise.finally(async () => {\r\n for (const plugin of plugins) {\r\n await plugin.onFinally?.(pluginContext)\r\n }\r\n\r\n const index = pendingRequests.indexOf(pendingEntry)\r\n if (index > -1) {\r\n pendingRequests.splice(index, 1)\r\n }\r\n })\r\n }\r\n\r\n let promise = execute() as Promise<Response>\r\n for (const plugin of plugins) {\r\n if (plugin.decoratePromise) {\r\n promise = plugin.decoratePromise(promise)\r\n }\r\n }\r\n return promise as Promise<Response> &\r\n PluginRequestPromiseExtensions<TPlugins>\r\n }\r\n\r\n Object.defineProperty(client, 'pendingRequests', {\r\n get() {\r\n return pendingRequests\r\n },\r\n enumerable: false,\r\n configurable: false,\r\n })\r\n\r\n Object.defineProperty(client, 'abortAll', {\r\n value: abortAll,\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n })\r\n\r\n Object.defineProperties(client, extensionDescriptors)\r\n\r\n return client as FFetch<\r\n PluginExtensions<TPlugins>,\r\n PluginRequestPromiseExtensions<TPlugins>\r\n >\r\n}\r\n"],"mappings":"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","names":["shouldRetry","controller","HttpError"]}
1
+ {"version":3,"sources":["../src/retry.ts","../src/should-retry.ts","../src/client.ts"],"sourcesContent":["import type { RetryContext } from './types.js'\n\nexport type RetryDelay = number | ((ctx: RetryContext) => number)\n\nexport const defaultDelay: RetryDelay = (ctx) => {\n const retryAfter = ctx.response?.headers.get('Retry-After')\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10)\n if (!isNaN(seconds)) return seconds * 1000\n const date = Date.parse(retryAfter)\n if (!isNaN(date)) return Math.max(0, date - Date.now())\n }\n return 2 ** ctx.attempt * 200 + Math.random() * 100\n}\n\nfunction waitForRetryDelay(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise((resolve) => {\n if (!signal) {\n setTimeout(resolve, ms)\n return\n }\n\n if (signal.aborted) {\n resolve()\n return\n }\n\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport async function retry(\n fn: () => Promise<Response>,\n retries: number,\n delay: RetryDelay,\n shouldRetry: (ctx: RetryContext) => boolean = () => true,\n request: Request,\n signal?: AbortSignal\n): Promise<Response> {\n let lastErr: unknown\n let lastRes: Response | undefined\n\n for (let i = 0; i <= retries; i++) {\n const ctx: RetryContext = {\n attempt: i + 1,\n request,\n response: lastRes,\n error: lastErr,\n }\n try {\n lastRes = await fn()\n ctx.response = lastRes\n ctx.error = undefined\n if (i < retries && shouldRetry(ctx)) {\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n continue\n }\n return lastRes\n } catch (err) {\n lastErr = err\n ctx.error = err\n if (i === retries || !shouldRetry(ctx)) throw err\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n }\n }\n throw lastErr\n}\n","import { AbortError, CircuitOpenError, TimeoutError } from './error.js'\nimport type { RetryContext } from './types.js'\n\nexport function shouldRetry(ctx: RetryContext): boolean {\n const { error, response } = ctx\n if (\n error instanceof AbortError ||\n error instanceof CircuitOpenError ||\n error instanceof TimeoutError\n )\n return false\n if (!response) return true // network error\n return response.status >= 500 || response.status === 429\n}\n","import type {\n FFetchOptions,\n FFetch,\n FFetchRequestInit,\n PendingRequest,\n} from './types.js'\nimport { retry, defaultDelay } from './retry.js'\nimport { shouldRetry as defaultShouldRetry } from './should-retry.js'\nimport {\n type PluginDispatch,\n type PluginRequestContext,\n type PluginExtensions,\n type PluginRequestPromiseExtensions,\n type ClientPlugin,\n type PluginExtensionBase,\n type PluginRequestPromiseExtensionBase,\n} from './plugins.js'\nimport {\n TimeoutError,\n AbortError,\n RetryLimitError,\n NetworkError,\n} from './error.js'\n\nexport function createClient<\n TPlugins extends readonly ClientPlugin<\n PluginExtensionBase,\n PluginRequestPromiseExtensionBase\n >[] = readonly ClientPlugin<\n PluginExtensionBase,\n PluginRequestPromiseExtensionBase\n >[],\n>(\n opts: FFetchOptions<TPlugins> = {} as FFetchOptions<TPlugins>\n): FFetch<\n PluginExtensions<TPlugins>,\n PluginRequestPromiseExtensions<TPlugins>\n> {\n const {\n timeout: clientDefaultTimeout = 5_000,\n retries: clientDefaultRetries = 0,\n retryDelay: clientDefaultRetryDelay = defaultDelay,\n shouldRetry: clientDefaultShouldRetry = defaultShouldRetry,\n hooks: clientDefaultHooks = {},\n fetchHandler,\n plugins: inputPlugins = [] as unknown as TPlugins,\n } = opts\n\n const extensionDescriptors: PropertyDescriptorMap = Object.create(null)\n\n const plugins = inputPlugins\n .map((plugin, index) => ({ plugin, index }))\n .sort((a, b) => {\n const aOrder = a.plugin.order ?? 0\n const bOrder = b.plugin.order ?? 0\n if (aOrder !== bOrder) return aOrder - bOrder\n return a.index - b.index\n })\n .map((entry) => entry.plugin)\n\n for (const plugin of plugins) {\n plugin.setup?.({\n defineExtension: (key, descriptor) => {\n const propertyKey = key as PropertyKey\n if (propertyKey in extensionDescriptors) {\n throw new Error(\n `Plugin extension collision for property \"${String(propertyKey)}\"`\n )\n }\n if ('get' in descriptor) {\n extensionDescriptors[propertyKey] = {\n get: descriptor.get,\n enumerable: descriptor.enumerable ?? true,\n configurable: false,\n }\n return\n }\n extensionDescriptors[propertyKey] = {\n value: descriptor.value,\n writable: false,\n enumerable: descriptor.enumerable ?? true,\n configurable: false,\n }\n },\n })\n }\n\n const pendingRequests: PendingRequest[] = []\n\n // Helper to abort all pending requests\n function abortAll() {\n for (const entry of pendingRequests) {\n entry.controller?.abort()\n }\n }\n\n const client = (input: RequestInfo | URL, init: FFetchRequestInit = {}) => {\n const execute = async () => {\n let request = new Request(input, init)\n\n // Merge hooks: per-request hooks override client hooks, but fallback to client hooks\n const effectiveHooks = { ...clientDefaultHooks, ...(init.hooks || {}) }\n if (effectiveHooks.transformRequest) {\n request = await effectiveHooks.transformRequest(request)\n }\n await effectiveHooks.before?.(request)\n\n // Determine retry config (per-request overrides client default)\n const effectiveRetries = init.retries ?? clientDefaultRetries\n const effectiveRetryDelay =\n typeof init.retryDelay !== 'undefined'\n ? init.retryDelay\n : clientDefaultRetryDelay\n const effectiveShouldRetry = init.shouldRetry ?? clientDefaultShouldRetry\n\n // AbortSignal.timeout/any logic\n const effectiveTimeout = init.timeout ?? clientDefaultTimeout\n const userSignal = init.signal\n const transformedSignal = request.signal\n\n const pluginContext: PluginRequestContext = {\n request,\n init,\n state: Object.create(null),\n metadata: {\n startedAt: Date.now(),\n timeoutMs: effectiveTimeout,\n signals: {\n user:\n userSignal === undefined || userSignal === null\n ? undefined\n : userSignal,\n transformed: transformedSignal,\n },\n retry: {\n configuredRetries: effectiveRetries,\n configuredDelay: effectiveRetryDelay,\n attempt: 0,\n },\n },\n }\n\n for (const plugin of plugins) {\n await plugin.preRequest?.(pluginContext)\n }\n\n // Determine throwOnHttpError (per-request overrides client default)\n const effectiveThrowOnHttpError =\n typeof init.throwOnHttpError !== 'undefined'\n ? init.throwOnHttpError\n : (opts.throwOnHttpError ?? false)\n\n // Create timeout signal (manual implementation if AbortSignal.timeout not available)\n function createTimeoutSignal(timeout: number): AbortSignal {\n if (typeof AbortSignal?.timeout === 'function') {\n return AbortSignal.timeout(timeout)\n }\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n controller.signal.addEventListener(\n 'abort',\n () => clearTimeout(timeoutId),\n { once: true }\n )\n return controller.signal\n }\n\n let timeoutSignal: AbortSignal | undefined = undefined\n let combinedSignal: AbortSignal | undefined = undefined\n let controller: AbortController | undefined = undefined\n\n if (effectiveTimeout > 0) {\n timeoutSignal = createTimeoutSignal(effectiveTimeout)\n pluginContext.metadata.signals.timeout = timeoutSignal\n }\n\n const signals: AbortSignal[] = []\n if (userSignal) signals.push(userSignal)\n if (transformedSignal && transformedSignal !== userSignal) {\n signals.push(transformedSignal)\n }\n if (timeoutSignal) signals.push(timeoutSignal)\n\n if (signals.length === 1) {\n combinedSignal = signals[0]\n controller = new AbortController()\n } else {\n if (typeof AbortSignal.any !== 'function') {\n throw new Error(\n 'AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.'\n )\n }\n combinedSignal = AbortSignal.any(signals)\n controller = new AbortController()\n }\n pluginContext.metadata.signals.combined = combinedSignal\n\n const retryWithHooks = async (\n dispatchCtx: PluginRequestContext,\n dispatchSignal: AbortSignal | undefined\n ) => {\n const requestForAttempt = dispatchCtx.request\n let attempt = 0\n const shouldRetryWithHook = (ctx: import('./types').RetryContext) => {\n attempt = ctx.attempt\n dispatchCtx.metadata.retry.attempt = attempt\n dispatchCtx.metadata.retry.lastError = ctx.error\n dispatchCtx.metadata.retry.lastResponse = ctx.response\n const retrying = effectiveShouldRetry(ctx)\n dispatchCtx.metadata.retry.shouldRetryResult = retrying\n if (retrying && attempt <= effectiveRetries) {\n effectiveHooks.onRetry?.(\n requestForAttempt,\n attempt - 1,\n ctx.error,\n ctx.response\n )\n }\n return retrying\n }\n\n let lastResponse: Response | undefined = undefined\n try {\n let res = await retry(\n async () => {\n if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n }\n if (timeoutSignal?.aborted) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out')\n }\n if (typeof dispatchSignal?.throwIfAborted === 'function') {\n dispatchSignal.throwIfAborted()\n } else if (dispatchSignal?.aborted) {\n if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n } else if (timeoutSignal?.aborted) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out')\n } else {\n throw new AbortError(\n 'Request was aborted',\n new DOMException('Aborted', 'AbortError')\n )\n }\n }\n const reqWithSignal = new Request(requestForAttempt, {\n signal: dispatchSignal,\n })\n try {\n const handler = init.fetchHandler ?? fetchHandler ?? fetch\n const response = await handler(reqWithSignal)\n lastResponse = response\n dispatchCtx.metadata.retry.lastResponse = response\n return response\n } catch (err) {\n dispatchCtx.metadata.retry.lastError = err\n if (err instanceof DOMException && err.name === 'AbortError') {\n if (\n timeoutSignal?.aborted &&\n (!userSignal || !userSignal.aborted)\n ) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out', err)\n } else if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n } else {\n throw new AbortError(\n 'Request was aborted',\n new DOMException('Aborted', 'AbortError')\n )\n }\n } else if (\n err instanceof TypeError &&\n /NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(\n err.message\n )\n ) {\n throw new NetworkError(err.message, err)\n }\n throw err\n }\n },\n effectiveRetries,\n effectiveRetryDelay,\n shouldRetryWithHook,\n requestForAttempt,\n dispatchSignal\n )\n if (effectiveHooks.transformResponse) {\n res = await effectiveHooks.transformResponse(res, requestForAttempt)\n }\n await effectiveHooks.after?.(requestForAttempt, res)\n await effectiveHooks.onComplete?.(requestForAttempt, res, undefined)\n if (\n effectiveThrowOnHttpError &&\n ((res.status >= 400 && res.status < 500 && res.status !== 429) ||\n res.status >= 500 ||\n res.status === 429)\n ) {\n const { HttpError } = await import('./error.js')\n throw new HttpError(\n `HTTP error: ${res.status} ${res.statusText}`,\n res\n )\n }\n return res\n } catch (err: unknown) {\n dispatchCtx.metadata.retry.lastError = err\n if (lastResponse) {\n const resp = lastResponse as Response\n if (\n effectiveThrowOnHttpError &&\n ((resp.status >= 400 &&\n resp.status < 500 &&\n resp.status !== 429) ||\n resp.status >= 500 ||\n resp.status === 429)\n ) {\n const { HttpError } = await import('./error.js')\n throw new HttpError(\n `HTTP error: ${resp.status} ${resp.statusText}`,\n resp\n )\n }\n return resp\n }\n if (err instanceof TimeoutError) {\n await effectiveHooks.onTimeout?.(requestForAttempt)\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n if (err instanceof AbortError) {\n await effectiveHooks.onAbort?.(requestForAttempt)\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n if (err instanceof NetworkError) {\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n const retryErr = new RetryLimitError(\n typeof err === 'object' &&\n err &&\n 'message' in err &&\n typeof (err as { message?: unknown }).message === 'string'\n ? (err as { message: string }).message\n : 'Retry limit reached',\n err\n )\n await effectiveHooks.onError?.(requestForAttempt, retryErr)\n await effectiveHooks.onComplete?.(\n requestForAttempt,\n undefined,\n retryErr\n )\n throw retryErr\n }\n }\n\n const baseDispatch: PluginDispatch = async (ctx) => {\n const dispatchSignal =\n ctx === pluginContext ? combinedSignal : ctx.request.signal\n return retryWithHooks(ctx, dispatchSignal)\n }\n\n let dispatch = baseDispatch\n for (let i = plugins.length - 1; i >= 0; i--) {\n const plugin = plugins[i]\n if (plugin.wrapDispatch) {\n dispatch = plugin.wrapDispatch(dispatch)\n }\n }\n\n const actualPromise = dispatch(pluginContext)\n .then(async (response) => {\n for (const plugin of plugins) {\n await plugin.onSuccess?.(pluginContext, response)\n }\n return response\n })\n .catch(async (err: unknown) => {\n for (const plugin of plugins) {\n await plugin.onError?.(pluginContext, err)\n }\n throw err\n })\n\n const pendingEntry: PendingRequest = {\n promise: actualPromise,\n request,\n controller,\n }\n pendingRequests.push(pendingEntry)\n\n return actualPromise.finally(async () => {\n for (const plugin of plugins) {\n await plugin.onFinally?.(pluginContext)\n }\n\n const index = pendingRequests.indexOf(pendingEntry)\n if (index > -1) {\n pendingRequests.splice(index, 1)\n }\n })\n }\n\n let promise = execute() as Promise<Response>\n for (const plugin of plugins) {\n if (plugin.decoratePromise) {\n promise = plugin.decoratePromise(promise)\n }\n }\n return promise as Promise<Response> &\n PluginRequestPromiseExtensions<TPlugins>\n }\n\n Object.defineProperty(client, 'pendingRequests', {\n get() {\n return pendingRequests\n },\n enumerable: false,\n configurable: false,\n })\n\n Object.defineProperty(client, 'abortAll', {\n value: abortAll,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n\n Object.defineProperties(client, extensionDescriptors)\n\n return client as FFetch<\n PluginExtensions<TPlugins>,\n PluginRequestPromiseExtensions<TPlugins>\n >\n}\n"],"mappings":"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","names":["shouldRetry","controller","HttpError"]}
package/dist/index.min.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as E,b as B,c as h,d as L,e as H,f as Y}from"./chunk-UP35S5ZH.min.js";var z=c=>{let a=c.response?.headers.get("Retry-After");if(a){let o=parseInt(a,10);if(!isNaN(o))return o*1e3;let w=Date.parse(a);if(!isNaN(w))return Math.max(0,w-Date.now())}return 2**c.attempt*200+Math.random()*100};function _(c,a){return c<=0?Promise.resolve():new Promise(o=>{if(!a){setTimeout(o,c);return}if(a.aborted){o();return}let w=()=>{clearTimeout(D),o()},D=setTimeout(()=>{a.removeEventListener("abort",w),o()},c);a.addEventListener("abort",w,{once:!0})})}async function G(c,a,o,w=()=>!0,D,F){let T,A;for(let b=0;b<=a;b++){let u={attempt:b+1,request:D,response:A,error:T};try{if(A=await c(),u.response=A,u.error=void 0,b<a&&w(u)){let m=typeof o=="function"?o(u):o;await _(m,F);continue}return A}catch(m){if(T=m,u.error=m,b===a||!w(u))throw m;let v=typeof o=="function"?o(u):o;await _(v,F)}}throw T}function J(c){let{error:a,response:o}=c;return a instanceof h||a instanceof B||a instanceof E?!1:o?o.status>=500||o.status===429:!0}function Z(c={}){let{timeout:a=5e3,retries:o=0,retryDelay:w=z,shouldRetry:D=J,hooks:F={},fetchHandler:T,plugins:A=[]}=c,b=Object.create(null),u=A.map((p,i)=>({plugin:p,index:i})).sort((p,i)=>{let R=p.plugin.order??0,d=i.plugin.order??0;return R!==d?R-d:p.index-i.index}).map(p=>p.plugin);for(let p of u)p.setup?.({defineExtension:(i,R)=>{let d=i;if(d in b)throw new Error(`Plugin extension collision for property "${String(d)}"`);if("get"in R){b[d]={get:R.get,enumerable:R.enumerable??!0,configurable:!1};return}b[d]={value:R.value,writable:!1,enumerable:R.enumerable??!0,configurable:!1}}});let m=[];function v(){for(let p of m)p.controller?.abort()}let O=(p,i={})=>{let d=(async()=>{let t=new Request(p,i),r={...F,...i.hooks||{}};r.transformRequest&&(t=await r.transformRequest(t)),await r.before?.(t);let j=i.retries??o,$=typeof i.retryDelay<"u"?i.retryDelay:w,Q=i.shouldRetry??D,N=i.timeout??a,y=i.signal,k=t.signal,l={request:t,init:i,state:Object.create(null),metadata:{startedAt:Date.now(),timeoutMs:N,signals:{user:y??void 0,transformed:k},retry:{configuredRetries:j,configuredDelay:$,attempt:0}}};for(let n of u)await n.preRequest?.(l);let W=typeof i.throwOnHttpError<"u"?i.throwOnHttpError:c.throwOnHttpError??!1;function V(n){if(typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(n);let f=new AbortController,C=setTimeout(()=>f.abort(),n);return f.signal.addEventListener("abort",()=>clearTimeout(C),{once:!0}),f.signal}let x,P,I;N>0&&(x=V(N),l.metadata.signals.timeout=x);let q=[];if(y&&q.push(y),k&&k!==y&&q.push(k),x&&q.push(x),q.length===1)P=q[0],I=new AbortController;else{if(typeof AbortSignal.any!="function")throw new Error("AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.");P=AbortSignal.any(q),I=new AbortController}l.metadata.signals.combined=P;let X=async()=>{let n=0,f=e=>{n=e.attempt,l.metadata.retry.attempt=n,l.metadata.retry.lastError=e.error,l.metadata.retry.lastResponse=e.response;let g=Q(e);return l.metadata.retry.shouldRetryResult=g,g&&n<=j&&r.onRetry?.(t,n-1,e.error,e.response),g},C;try{let e=await G(async()=>{if(y?.aborted)throw r.onAbort?.(t),new h("Request was aborted by user");if(x?.aborted)throw r.onTimeout?.(t),new E("signal timed out");if(typeof P?.throwIfAborted=="function")P.throwIfAborted();else if(P?.aborted)throw y?.aborted?(r.onAbort?.(t),new h("Request was aborted by user")):x?.aborted?(r.onTimeout?.(t),new E("signal timed out")):new h("Request was aborted",new DOMException("Aborted","AbortError"));let g=new Request(t,{signal:P});try{let S=await(i.fetchHandler??T??fetch)(g);return C=S,l.metadata.retry.lastResponse=S,S}catch(s){throw l.metadata.retry.lastError=s,s instanceof DOMException&&s.name==="AbortError"?x?.aborted&&(!y||!y.aborted)?(r.onTimeout?.(t),new E("signal timed out",s)):y?.aborted?(r.onAbort?.(t),new h("Request was aborted by user")):new h("Request was aborted",new DOMException("Aborted","AbortError")):s instanceof TypeError&&/NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(s.message)?new H(s.message,s):s}},j,$,f,t,P);if(r.transformResponse&&(e=await r.transformResponse(e,t)),await r.after?.(t,e),await r.onComplete?.(t,e,void 0),W&&(e.status>=400&&e.status<500&&e.status!==429||e.status>=500||e.status===429)){let{HttpError:g}=await import("./error-7EEQP46E.min.js");throw new g(`HTTP error: ${e.status} ${e.statusText}`,e)}return e}catch(e){if(l.metadata.retry.lastError=e,C){let s=C;if(W&&(s.status>=400&&s.status<500&&s.status!==429||s.status>=500||s.status===429)){let{HttpError:S}=await import("./error-7EEQP46E.min.js");throw new S(`HTTP error: ${s.status} ${s.statusText}`,s)}return s}if(e instanceof E)throw await r.onTimeout?.(t),await r.onError?.(t,e),await r.onComplete?.(t,void 0,e),e;if(e instanceof h)throw await r.onAbort?.(t),await r.onError?.(t,e),await r.onComplete?.(t,void 0,e),e;if(e instanceof H)throw await r.onError?.(t,e),await r.onComplete?.(t,void 0,e),e;let g=new L(typeof e=="object"&&e&&"message"in e&&typeof e.message=="string"?e.message:"Retry limit reached",e);throw await r.onError?.(t,g),await r.onComplete?.(t,void 0,g),g}},M=async()=>X();for(let n=u.length-1;n>=0;n--){let f=u[n];f.wrapDispatch&&(M=f.wrapDispatch(M))}let K=M(l).then(async n=>{for(let f of u)await f.onSuccess?.(l,n);return n}).catch(async n=>{for(let f of u)await f.onError?.(l,n);throw n}),U={promise:K,request:t,controller:I};return m.push(U),K.finally(async()=>{for(let f of u)await f.onFinally?.(l);let n=m.indexOf(U);n>-1&&m.splice(n,1)})})();for(let t of u)t.decoratePromise&&(d=t.decoratePromise(d));return d};return Object.defineProperty(O,"pendingRequests",{get(){return m},enumerable:!1,configurable:!1}),Object.defineProperty(O,"abortAll",{value:v,writable:!1,enumerable:!1,configurable:!1}),Object.defineProperties(O,b),O}export{h as AbortError,B as CircuitOpenError,Y as HttpError,H as NetworkError,L as RetryLimitError,E as TimeoutError,Z as createClient};
1
+ import{a as E,b as $,c as te,d as b,e as W,f as v,g as re}from"./chunk-X64PXWPN.min.js";var J=f=>{let u=f.response?.headers.get("Retry-After");if(u){let o=parseInt(u,10);if(!isNaN(o))return o*1e3;let g=Date.parse(u);if(!isNaN(g))return Math.max(0,g-Date.now())}return 2**f.attempt*200+Math.random()*100};function G(f,u){return f<=0?Promise.resolve():new Promise(o=>{if(!u){setTimeout(o,f);return}if(u.aborted){o();return}let g=()=>{clearTimeout(D),o()},D=setTimeout(()=>{u.removeEventListener("abort",g),o()},f);u.addEventListener("abort",g,{once:!0})})}async function Q(f,u,o,g=()=>!0,D,C){let T,A;for(let w=0;w<=u;w++){let l={attempt:w+1,request:D,response:A,error:T};try{if(A=await f(),l.response=A,l.error=void 0,w<u&&g(l)){let p=typeof o=="function"?o(l):o;await G(p,C);continue}return A}catch(p){if(T=p,l.error=p,w===u||!g(l))throw p;let j=typeof o=="function"?o(l):o;await G(j,C)}}throw T}function V(f){let{error:u,response:o}=f;return u instanceof b||u instanceof $||u instanceof E?!1:o?o.status>=500||o.status===429:!0}function ne(f={}){let{timeout:u=5e3,retries:o=0,retryDelay:g=J,shouldRetry:D=V,hooks:C={},fetchHandler:T,plugins:A=[]}=f,w=Object.create(null),l=A.map((c,a)=>({plugin:c,index:a})).sort((c,a)=>{let h=c.plugin.order??0,m=a.plugin.order??0;return h!==m?h-m:c.index-a.index}).map(c=>c.plugin);for(let c of l)c.setup?.({defineExtension:(a,h)=>{let m=a;if(m in w)throw new Error(`Plugin extension collision for property "${String(m)}"`);if("get"in h){w[m]={get:h.get,enumerable:h.enumerable??!0,configurable:!1};return}w[m]={value:h.value,writable:!1,enumerable:h.enumerable??!0,configurable:!1}}});let p=[];function j(){for(let c of p)c.controller?.abort()}let O=(c,a={})=>{let m=(async()=>{let R=new Request(c,a),r={...C,...a.hooks||{}};r.transformRequest&&(R=await r.transformRequest(R)),await r.before?.(R);let N=a.retries??o,K=typeof a.retryDelay<"u"?a.retryDelay:g,X=a.shouldRetry??D,B=a.timeout??u,d=a.signal,S=R.signal,P={request:R,init:a,state:Object.create(null),metadata:{startedAt:Date.now(),timeoutMs:B,signals:{user:d??void 0,transformed:S},retry:{configuredRetries:N,configuredDelay:K,attempt:0}}};for(let t of l)await t.preRequest?.(P);let U=typeof a.throwOnHttpError<"u"?a.throwOnHttpError:f.throwOnHttpError??!1;function Y(t){if(typeof AbortSignal?.timeout=="function")return AbortSignal.timeout(t);let s=new AbortController,n=setTimeout(()=>s.abort(),t);return s.signal.addEventListener("abort",()=>clearTimeout(n),{once:!0}),s.signal}let x,k,I;B>0&&(x=Y(B),P.metadata.signals.timeout=x);let q=[];if(d&&q.push(d),S&&S!==d&&q.push(S),x&&q.push(x),q.length===1)k=q[0],I=new AbortController;else{if(typeof AbortSignal.any!="function")throw new Error("AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.");k=AbortSignal.any(q),I=new AbortController}P.metadata.signals.combined=k;let Z=async(t,s)=>{let n=t.request,H=0,ee=e=>{H=e.attempt,t.metadata.retry.attempt=H,t.metadata.retry.lastError=e.error,t.metadata.retry.lastResponse=e.response;let y=X(e);return t.metadata.retry.shouldRetryResult=y,y&&H<=N&&r.onRetry?.(n,H-1,e.error,e.response),y},L;try{let e=await Q(async()=>{if(d?.aborted)throw r.onAbort?.(n),new b("Request was aborted by user");if(x?.aborted)throw r.onTimeout?.(n),new E("signal timed out");if(typeof s?.throwIfAborted=="function")s.throwIfAborted();else if(s?.aborted)throw d?.aborted?(r.onAbort?.(n),new b("Request was aborted by user")):x?.aborted?(r.onTimeout?.(n),new E("signal timed out")):new b("Request was aborted",new DOMException("Aborted","AbortError"));let y=new Request(n,{signal:s});try{let F=await(a.fetchHandler??T??fetch)(y);return L=F,t.metadata.retry.lastResponse=F,F}catch(i){throw t.metadata.retry.lastError=i,i instanceof DOMException&&i.name==="AbortError"?x?.aborted&&(!d||!d.aborted)?(r.onTimeout?.(n),new E("signal timed out",i)):d?.aborted?(r.onAbort?.(n),new b("Request was aborted by user")):new b("Request was aborted",new DOMException("Aborted","AbortError")):i instanceof TypeError&&/NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(i.message)?new v(i.message,i):i}},N,K,ee,n,s);if(r.transformResponse&&(e=await r.transformResponse(e,n)),await r.after?.(n,e),await r.onComplete?.(n,e,void 0),U&&(e.status>=400&&e.status<500&&e.status!==429||e.status>=500||e.status===429)){let{HttpError:y}=await import("./error-HT5UPPWM.min.js");throw new y(`HTTP error: ${e.status} ${e.statusText}`,e)}return e}catch(e){if(t.metadata.retry.lastError=e,L){let i=L;if(U&&(i.status>=400&&i.status<500&&i.status!==429||i.status>=500||i.status===429)){let{HttpError:F}=await import("./error-HT5UPPWM.min.js");throw new F(`HTTP error: ${i.status} ${i.statusText}`,i)}return i}if(e instanceof E)throw await r.onTimeout?.(n),await r.onError?.(n,e),await r.onComplete?.(n,void 0,e),e;if(e instanceof b)throw await r.onAbort?.(n),await r.onError?.(n,e),await r.onComplete?.(n,void 0,e),e;if(e instanceof v)throw await r.onError?.(n,e),await r.onComplete?.(n,void 0,e),e;let y=new W(typeof e=="object"&&e&&"message"in e&&typeof e.message=="string"?e.message:"Retry limit reached",e);throw await r.onError?.(n,y),await r.onComplete?.(n,void 0,y),y}},M=async t=>{let s=t===P?k:t.request.signal;return Z(t,s)};for(let t=l.length-1;t>=0;t--){let s=l[t];s.wrapDispatch&&(M=s.wrapDispatch(M))}let _=M(P).then(async t=>{for(let s of l)await s.onSuccess?.(P,t);return t}).catch(async t=>{for(let s of l)await s.onError?.(P,t);throw t}),z={promise:_,request:R,controller:I};return p.push(z),_.finally(async()=>{for(let s of l)await s.onFinally?.(P);let t=p.indexOf(z);t>-1&&p.splice(t,1)})})();for(let R of l)R.decoratePromise&&(m=R.decoratePromise(m));return m};return Object.defineProperty(O,"pendingRequests",{get(){return p},enumerable:!1,configurable:!1}),Object.defineProperty(O,"abortAll",{value:j,writable:!1,enumerable:!1,configurable:!1}),Object.defineProperties(O,w),O}export{b as AbortError,te as BulkheadFullError,$ as CircuitOpenError,re as HttpError,v as NetworkError,W as RetryLimitError,E as TimeoutError,ne as createClient};
2
2
  //# sourceMappingURL=index.min.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/retry.ts","../src/should-retry.ts","../src/client.ts"],"sourcesContent":["import type { RetryContext } from './types.js'\n\nexport type RetryDelay = number | ((ctx: RetryContext) => number)\n\nexport const defaultDelay: RetryDelay = (ctx) => {\n const retryAfter = ctx.response?.headers.get('Retry-After')\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10)\n if (!isNaN(seconds)) return seconds * 1000\n const date = Date.parse(retryAfter)\n if (!isNaN(date)) return Math.max(0, date - Date.now())\n }\n return 2 ** ctx.attempt * 200 + Math.random() * 100\n}\n\nfunction waitForRetryDelay(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise((resolve) => {\n if (!signal) {\n setTimeout(resolve, ms)\n return\n }\n\n if (signal.aborted) {\n resolve()\n return\n }\n\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport async function retry(\n fn: () => Promise<Response>,\n retries: number,\n delay: RetryDelay,\n shouldRetry: (ctx: RetryContext) => boolean = () => true,\n request: Request,\n signal?: AbortSignal\n): Promise<Response> {\n let lastErr: unknown\n let lastRes: Response | undefined\n\n for (let i = 0; i <= retries; i++) {\n const ctx: RetryContext = {\n attempt: i + 1,\n request,\n response: lastRes,\n error: lastErr,\n }\n try {\n lastRes = await fn()\n ctx.response = lastRes\n ctx.error = undefined\n if (i < retries && shouldRetry(ctx)) {\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n continue\n }\n return lastRes\n } catch (err) {\n lastErr = err\n ctx.error = err\n if (i === retries || !shouldRetry(ctx)) throw err\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n }\n }\n throw lastErr\n}\n","import { AbortError, CircuitOpenError, TimeoutError } from './error.js'\nimport type { RetryContext } from './types.js'\n\nexport function shouldRetry(ctx: RetryContext): boolean {\n const { error, response } = ctx\n if (\n error instanceof AbortError ||\n error instanceof CircuitOpenError ||\n error instanceof TimeoutError\n )\n return false\n if (!response) return true // network error\n return response.status >= 500 || response.status === 429\n}\n","import type {\r\n FFetchOptions,\r\n FFetch,\r\n FFetchRequestInit,\r\n PendingRequest,\r\n} from './types.js'\r\nimport { retry, defaultDelay } from './retry.js'\r\nimport { shouldRetry as defaultShouldRetry } from './should-retry.js'\r\nimport {\r\n type PluginDispatch,\r\n type PluginRequestContext,\r\n type PluginExtensions,\r\n type PluginRequestPromiseExtensions,\r\n type ClientPlugin,\r\n type PluginExtensionBase,\r\n type PluginRequestPromiseExtensionBase,\r\n} from './plugins.js'\r\nimport {\r\n TimeoutError,\r\n AbortError,\r\n RetryLimitError,\r\n NetworkError,\r\n} from './error.js'\r\n\r\nexport function createClient<\r\n TPlugins extends readonly ClientPlugin<\r\n PluginExtensionBase,\r\n PluginRequestPromiseExtensionBase\r\n >[] = readonly ClientPlugin<\r\n PluginExtensionBase,\r\n PluginRequestPromiseExtensionBase\r\n >[],\r\n>(\r\n opts: FFetchOptions<TPlugins> = {} as FFetchOptions<TPlugins>\r\n): FFetch<\r\n PluginExtensions<TPlugins>,\r\n PluginRequestPromiseExtensions<TPlugins>\r\n> {\r\n const {\r\n timeout: clientDefaultTimeout = 5_000,\r\n retries: clientDefaultRetries = 0,\r\n retryDelay: clientDefaultRetryDelay = defaultDelay,\r\n shouldRetry: clientDefaultShouldRetry = defaultShouldRetry,\r\n hooks: clientDefaultHooks = {},\r\n fetchHandler,\r\n plugins: inputPlugins = [] as unknown as TPlugins,\r\n } = opts\r\n\r\n const extensionDescriptors: PropertyDescriptorMap = Object.create(null)\r\n\r\n const plugins = inputPlugins\r\n .map((plugin, index) => ({ plugin, index }))\r\n .sort((a, b) => {\r\n const aOrder = a.plugin.order ?? 0\r\n const bOrder = b.plugin.order ?? 0\r\n if (aOrder !== bOrder) return aOrder - bOrder\r\n return a.index - b.index\r\n })\r\n .map((entry) => entry.plugin)\r\n\r\n for (const plugin of plugins) {\r\n plugin.setup?.({\r\n defineExtension: (key, descriptor) => {\r\n const propertyKey = key as PropertyKey\r\n if (propertyKey in extensionDescriptors) {\r\n throw new Error(\r\n `Plugin extension collision for property \"${String(propertyKey)}\"`\r\n )\r\n }\r\n if ('get' in descriptor) {\r\n extensionDescriptors[propertyKey] = {\r\n get: descriptor.get,\r\n enumerable: descriptor.enumerable ?? true,\r\n configurable: false,\r\n }\r\n return\r\n }\r\n extensionDescriptors[propertyKey] = {\r\n value: descriptor.value,\r\n writable: false,\r\n enumerable: descriptor.enumerable ?? true,\r\n configurable: false,\r\n }\r\n },\r\n })\r\n }\r\n\r\n const pendingRequests: PendingRequest[] = []\r\n\r\n // Helper to abort all pending requests\r\n function abortAll() {\r\n for (const entry of pendingRequests) {\r\n entry.controller?.abort()\r\n }\r\n }\r\n\r\n const client = (input: RequestInfo | URL, init: FFetchRequestInit = {}) => {\r\n const execute = async () => {\r\n let request = new Request(input, init)\r\n\r\n // Merge hooks: per-request hooks override client hooks, but fallback to client hooks\r\n const effectiveHooks = { ...clientDefaultHooks, ...(init.hooks || {}) }\r\n if (effectiveHooks.transformRequest) {\r\n request = await effectiveHooks.transformRequest(request)\r\n }\r\n await effectiveHooks.before?.(request)\r\n\r\n // Determine retry config (per-request overrides client default)\r\n const effectiveRetries = init.retries ?? clientDefaultRetries\r\n const effectiveRetryDelay =\r\n typeof init.retryDelay !== 'undefined'\r\n ? init.retryDelay\r\n : clientDefaultRetryDelay\r\n const effectiveShouldRetry = init.shouldRetry ?? clientDefaultShouldRetry\r\n\r\n // AbortSignal.timeout/any logic\r\n const effectiveTimeout = init.timeout ?? clientDefaultTimeout\r\n const userSignal = init.signal\r\n const transformedSignal = request.signal\r\n\r\n const pluginContext: PluginRequestContext = {\r\n request,\r\n init,\r\n state: Object.create(null),\r\n metadata: {\r\n startedAt: Date.now(),\r\n timeoutMs: effectiveTimeout,\r\n signals: {\r\n user:\r\n userSignal === undefined || userSignal === null\r\n ? undefined\r\n : userSignal,\r\n transformed: transformedSignal,\r\n },\r\n retry: {\r\n configuredRetries: effectiveRetries,\r\n configuredDelay: effectiveRetryDelay,\r\n attempt: 0,\r\n },\r\n },\r\n }\r\n\r\n for (const plugin of plugins) {\r\n await plugin.preRequest?.(pluginContext)\r\n }\r\n\r\n // Determine throwOnHttpError (per-request overrides client default)\r\n const effectiveThrowOnHttpError =\r\n typeof init.throwOnHttpError !== 'undefined'\r\n ? init.throwOnHttpError\r\n : (opts.throwOnHttpError ?? false)\r\n\r\n // Create timeout signal (manual implementation if AbortSignal.timeout not available)\r\n function createTimeoutSignal(timeout: number): AbortSignal {\r\n if (typeof AbortSignal?.timeout === 'function') {\r\n return AbortSignal.timeout(timeout)\r\n }\r\n const controller = new AbortController()\r\n const timeoutId = setTimeout(() => controller.abort(), timeout)\r\n controller.signal.addEventListener(\r\n 'abort',\r\n () => clearTimeout(timeoutId),\r\n { once: true }\r\n )\r\n return controller.signal\r\n }\r\n\r\n let timeoutSignal: AbortSignal | undefined = undefined\r\n let combinedSignal: AbortSignal | undefined = undefined\r\n let controller: AbortController | undefined = undefined\r\n\r\n if (effectiveTimeout > 0) {\r\n timeoutSignal = createTimeoutSignal(effectiveTimeout)\r\n pluginContext.metadata.signals.timeout = timeoutSignal\r\n }\r\n\r\n const signals: AbortSignal[] = []\r\n if (userSignal) signals.push(userSignal)\r\n if (transformedSignal && transformedSignal !== userSignal) {\r\n signals.push(transformedSignal)\r\n }\r\n if (timeoutSignal) signals.push(timeoutSignal)\r\n\r\n if (signals.length === 1) {\r\n combinedSignal = signals[0]\r\n controller = new AbortController()\r\n } else {\r\n if (typeof AbortSignal.any !== 'function') {\r\n throw new Error(\r\n 'AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.'\r\n )\r\n }\r\n combinedSignal = AbortSignal.any(signals)\r\n controller = new AbortController()\r\n }\r\n pluginContext.metadata.signals.combined = combinedSignal\r\n\r\n const retryWithHooks = async () => {\r\n let attempt = 0\r\n const shouldRetryWithHook = (ctx: import('./types').RetryContext) => {\r\n attempt = ctx.attempt\r\n pluginContext.metadata.retry.attempt = attempt\r\n pluginContext.metadata.retry.lastError = ctx.error\r\n pluginContext.metadata.retry.lastResponse = ctx.response\r\n const retrying = effectiveShouldRetry(ctx)\r\n pluginContext.metadata.retry.shouldRetryResult = retrying\r\n if (retrying && attempt <= effectiveRetries) {\r\n effectiveHooks.onRetry?.(\r\n request,\r\n attempt - 1,\r\n ctx.error,\r\n ctx.response\r\n )\r\n }\r\n return retrying\r\n }\r\n\r\n let lastResponse: Response | undefined = undefined\r\n try {\r\n let res = await retry(\r\n async () => {\r\n if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n }\r\n if (timeoutSignal?.aborted) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out')\r\n }\r\n if (typeof combinedSignal?.throwIfAborted === 'function') {\r\n combinedSignal.throwIfAborted()\r\n } else if (combinedSignal?.aborted) {\r\n if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n } else if (timeoutSignal?.aborted) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out')\r\n } else {\r\n throw new AbortError(\r\n 'Request was aborted',\r\n new DOMException('Aborted', 'AbortError')\r\n )\r\n }\r\n }\r\n const reqWithSignal = new Request(request, {\r\n signal: combinedSignal,\r\n })\r\n try {\r\n const handler = init.fetchHandler ?? fetchHandler ?? fetch\r\n const response = await handler(reqWithSignal)\r\n lastResponse = response\r\n pluginContext.metadata.retry.lastResponse = response\r\n return response\r\n } catch (err) {\r\n pluginContext.metadata.retry.lastError = err\r\n if (err instanceof DOMException && err.name === 'AbortError') {\r\n if (\r\n timeoutSignal?.aborted &&\r\n (!userSignal || !userSignal.aborted)\r\n ) {\r\n effectiveHooks.onTimeout?.(request)\r\n throw new TimeoutError('signal timed out', err)\r\n } else if (userSignal?.aborted) {\r\n effectiveHooks.onAbort?.(request)\r\n throw new AbortError('Request was aborted by user')\r\n } else {\r\n throw new AbortError(\r\n 'Request was aborted',\r\n new DOMException('Aborted', 'AbortError')\r\n )\r\n }\r\n } else if (\r\n err instanceof TypeError &&\r\n /NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(\r\n err.message\r\n )\r\n ) {\r\n throw new NetworkError(err.message, err)\r\n }\r\n throw err\r\n }\r\n },\r\n effectiveRetries,\r\n effectiveRetryDelay,\r\n shouldRetryWithHook,\r\n request,\r\n combinedSignal\r\n )\r\n if (effectiveHooks.transformResponse) {\r\n res = await effectiveHooks.transformResponse(res, request)\r\n }\r\n await effectiveHooks.after?.(request, res)\r\n await effectiveHooks.onComplete?.(request, res, undefined)\r\n if (\r\n effectiveThrowOnHttpError &&\r\n ((res.status >= 400 && res.status < 500 && res.status !== 429) ||\r\n res.status >= 500 ||\r\n res.status === 429)\r\n ) {\r\n const { HttpError } = await import('./error.js')\r\n throw new HttpError(\r\n `HTTP error: ${res.status} ${res.statusText}`,\r\n res\r\n )\r\n }\r\n return res\r\n } catch (err: unknown) {\r\n pluginContext.metadata.retry.lastError = err\r\n if (lastResponse) {\r\n const resp = lastResponse as Response\r\n if (\r\n effectiveThrowOnHttpError &&\r\n ((resp.status >= 400 &&\r\n resp.status < 500 &&\r\n resp.status !== 429) ||\r\n resp.status >= 500 ||\r\n resp.status === 429)\r\n ) {\r\n const { HttpError } = await import('./error.js')\r\n throw new HttpError(\r\n `HTTP error: ${resp.status} ${resp.statusText}`,\r\n resp\r\n )\r\n }\r\n return resp\r\n }\r\n if (err instanceof TimeoutError) {\r\n await effectiveHooks.onTimeout?.(request)\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n if (err instanceof AbortError) {\r\n await effectiveHooks.onAbort?.(request)\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n if (err instanceof NetworkError) {\r\n await effectiveHooks.onError?.(request, err)\r\n await effectiveHooks.onComplete?.(request, undefined, err)\r\n throw err\r\n }\r\n const retryErr = new RetryLimitError(\r\n typeof err === 'object' &&\r\n err &&\r\n 'message' in err &&\r\n typeof (err as { message?: unknown }).message === 'string'\r\n ? (err as { message: string }).message\r\n : 'Retry limit reached',\r\n err\r\n )\r\n await effectiveHooks.onError?.(request, retryErr)\r\n await effectiveHooks.onComplete?.(request, undefined, retryErr)\r\n throw retryErr\r\n }\r\n }\r\n\r\n const baseDispatch: PluginDispatch = async () => retryWithHooks()\r\n\r\n let dispatch = baseDispatch\r\n for (let i = plugins.length - 1; i >= 0; i--) {\r\n const plugin = plugins[i]\r\n if (plugin.wrapDispatch) {\r\n dispatch = plugin.wrapDispatch(dispatch)\r\n }\r\n }\r\n\r\n const actualPromise = dispatch(pluginContext)\r\n .then(async (response) => {\r\n for (const plugin of plugins) {\r\n await plugin.onSuccess?.(pluginContext, response)\r\n }\r\n return response\r\n })\r\n .catch(async (err: unknown) => {\r\n for (const plugin of plugins) {\r\n await plugin.onError?.(pluginContext, err)\r\n }\r\n throw err\r\n })\r\n\r\n const pendingEntry: PendingRequest = {\r\n promise: actualPromise,\r\n request,\r\n controller,\r\n }\r\n pendingRequests.push(pendingEntry)\r\n\r\n return actualPromise.finally(async () => {\r\n for (const plugin of plugins) {\r\n await plugin.onFinally?.(pluginContext)\r\n }\r\n\r\n const index = pendingRequests.indexOf(pendingEntry)\r\n if (index > -1) {\r\n pendingRequests.splice(index, 1)\r\n }\r\n })\r\n }\r\n\r\n let promise = execute() as Promise<Response>\r\n for (const plugin of plugins) {\r\n if (plugin.decoratePromise) {\r\n promise = plugin.decoratePromise(promise)\r\n }\r\n }\r\n return promise as Promise<Response> &\r\n PluginRequestPromiseExtensions<TPlugins>\r\n }\r\n\r\n Object.defineProperty(client, 'pendingRequests', {\r\n get() {\r\n return pendingRequests\r\n },\r\n enumerable: false,\r\n configurable: false,\r\n })\r\n\r\n Object.defineProperty(client, 'abortAll', {\r\n value: abortAll,\r\n writable: false,\r\n enumerable: false,\r\n configurable: false,\r\n })\r\n\r\n Object.defineProperties(client, extensionDescriptors)\r\n\r\n return client as FFetch<\r\n PluginExtensions<TPlugins>,\r\n PluginRequestPromiseExtensions<TPlugins>\r\n >\r\n}\r\n"],"mappings":"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","names":["defaultDelay","ctx","retryAfter","seconds","date","waitForRetryDelay","ms","signal","resolve","onAbort","timer","retry","fn","retries","delay","shouldRetry","request","lastErr","lastRes","i","wait","err","shouldRetry","ctx","error","response","AbortError","CircuitOpenError","TimeoutError","createClient","opts","clientDefaultTimeout","clientDefaultRetries","clientDefaultRetryDelay","defaultDelay","clientDefaultShouldRetry","shouldRetry","clientDefaultHooks","fetchHandler","inputPlugins","extensionDescriptors","plugins","plugin","index","a","b","aOrder","bOrder","entry","key","descriptor","propertyKey","pendingRequests","abortAll","client","input","init","promise","request","effectiveHooks","effectiveRetries","effectiveRetryDelay","effectiveShouldRetry","effectiveTimeout","userSignal","transformedSignal","pluginContext","effectiveThrowOnHttpError","createTimeoutSignal","timeout","controller","timeoutId","timeoutSignal","combinedSignal","signals","retryWithHooks","attempt","shouldRetryWithHook","ctx","retrying","lastResponse","res","retry","AbortError","TimeoutError","reqWithSignal","response","err","NetworkError","HttpError","resp","retryErr","RetryLimitError","dispatch","i","actualPromise","pendingEntry"]}
1
+ {"version":3,"sources":["../src/retry.ts","../src/should-retry.ts","../src/client.ts"],"sourcesContent":["import type { RetryContext } from './types.js'\n\nexport type RetryDelay = number | ((ctx: RetryContext) => number)\n\nexport const defaultDelay: RetryDelay = (ctx) => {\n const retryAfter = ctx.response?.headers.get('Retry-After')\n if (retryAfter) {\n const seconds = parseInt(retryAfter, 10)\n if (!isNaN(seconds)) return seconds * 1000\n const date = Date.parse(retryAfter)\n if (!isNaN(date)) return Math.max(0, date - Date.now())\n }\n return 2 ** ctx.attempt * 200 + Math.random() * 100\n}\n\nfunction waitForRetryDelay(ms: number, signal?: AbortSignal): Promise<void> {\n if (ms <= 0) return Promise.resolve()\n return new Promise((resolve) => {\n if (!signal) {\n setTimeout(resolve, ms)\n return\n }\n\n if (signal.aborted) {\n resolve()\n return\n }\n\n const onAbort = () => {\n clearTimeout(timer)\n resolve()\n }\n\n const timer = setTimeout(() => {\n signal.removeEventListener('abort', onAbort)\n resolve()\n }, ms)\n\n signal.addEventListener('abort', onAbort, { once: true })\n })\n}\n\nexport async function retry(\n fn: () => Promise<Response>,\n retries: number,\n delay: RetryDelay,\n shouldRetry: (ctx: RetryContext) => boolean = () => true,\n request: Request,\n signal?: AbortSignal\n): Promise<Response> {\n let lastErr: unknown\n let lastRes: Response | undefined\n\n for (let i = 0; i <= retries; i++) {\n const ctx: RetryContext = {\n attempt: i + 1,\n request,\n response: lastRes,\n error: lastErr,\n }\n try {\n lastRes = await fn()\n ctx.response = lastRes\n ctx.error = undefined\n if (i < retries && shouldRetry(ctx)) {\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n continue\n }\n return lastRes\n } catch (err) {\n lastErr = err\n ctx.error = err\n if (i === retries || !shouldRetry(ctx)) throw err\n const wait = typeof delay === 'function' ? delay(ctx) : delay\n await waitForRetryDelay(wait, signal)\n }\n }\n throw lastErr\n}\n","import { AbortError, CircuitOpenError, TimeoutError } from './error.js'\nimport type { RetryContext } from './types.js'\n\nexport function shouldRetry(ctx: RetryContext): boolean {\n const { error, response } = ctx\n if (\n error instanceof AbortError ||\n error instanceof CircuitOpenError ||\n error instanceof TimeoutError\n )\n return false\n if (!response) return true // network error\n return response.status >= 500 || response.status === 429\n}\n","import type {\n FFetchOptions,\n FFetch,\n FFetchRequestInit,\n PendingRequest,\n} from './types.js'\nimport { retry, defaultDelay } from './retry.js'\nimport { shouldRetry as defaultShouldRetry } from './should-retry.js'\nimport {\n type PluginDispatch,\n type PluginRequestContext,\n type PluginExtensions,\n type PluginRequestPromiseExtensions,\n type ClientPlugin,\n type PluginExtensionBase,\n type PluginRequestPromiseExtensionBase,\n} from './plugins.js'\nimport {\n TimeoutError,\n AbortError,\n RetryLimitError,\n NetworkError,\n} from './error.js'\n\nexport function createClient<\n TPlugins extends readonly ClientPlugin<\n PluginExtensionBase,\n PluginRequestPromiseExtensionBase\n >[] = readonly ClientPlugin<\n PluginExtensionBase,\n PluginRequestPromiseExtensionBase\n >[],\n>(\n opts: FFetchOptions<TPlugins> = {} as FFetchOptions<TPlugins>\n): FFetch<\n PluginExtensions<TPlugins>,\n PluginRequestPromiseExtensions<TPlugins>\n> {\n const {\n timeout: clientDefaultTimeout = 5_000,\n retries: clientDefaultRetries = 0,\n retryDelay: clientDefaultRetryDelay = defaultDelay,\n shouldRetry: clientDefaultShouldRetry = defaultShouldRetry,\n hooks: clientDefaultHooks = {},\n fetchHandler,\n plugins: inputPlugins = [] as unknown as TPlugins,\n } = opts\n\n const extensionDescriptors: PropertyDescriptorMap = Object.create(null)\n\n const plugins = inputPlugins\n .map((plugin, index) => ({ plugin, index }))\n .sort((a, b) => {\n const aOrder = a.plugin.order ?? 0\n const bOrder = b.plugin.order ?? 0\n if (aOrder !== bOrder) return aOrder - bOrder\n return a.index - b.index\n })\n .map((entry) => entry.plugin)\n\n for (const plugin of plugins) {\n plugin.setup?.({\n defineExtension: (key, descriptor) => {\n const propertyKey = key as PropertyKey\n if (propertyKey in extensionDescriptors) {\n throw new Error(\n `Plugin extension collision for property \"${String(propertyKey)}\"`\n )\n }\n if ('get' in descriptor) {\n extensionDescriptors[propertyKey] = {\n get: descriptor.get,\n enumerable: descriptor.enumerable ?? true,\n configurable: false,\n }\n return\n }\n extensionDescriptors[propertyKey] = {\n value: descriptor.value,\n writable: false,\n enumerable: descriptor.enumerable ?? true,\n configurable: false,\n }\n },\n })\n }\n\n const pendingRequests: PendingRequest[] = []\n\n // Helper to abort all pending requests\n function abortAll() {\n for (const entry of pendingRequests) {\n entry.controller?.abort()\n }\n }\n\n const client = (input: RequestInfo | URL, init: FFetchRequestInit = {}) => {\n const execute = async () => {\n let request = new Request(input, init)\n\n // Merge hooks: per-request hooks override client hooks, but fallback to client hooks\n const effectiveHooks = { ...clientDefaultHooks, ...(init.hooks || {}) }\n if (effectiveHooks.transformRequest) {\n request = await effectiveHooks.transformRequest(request)\n }\n await effectiveHooks.before?.(request)\n\n // Determine retry config (per-request overrides client default)\n const effectiveRetries = init.retries ?? clientDefaultRetries\n const effectiveRetryDelay =\n typeof init.retryDelay !== 'undefined'\n ? init.retryDelay\n : clientDefaultRetryDelay\n const effectiveShouldRetry = init.shouldRetry ?? clientDefaultShouldRetry\n\n // AbortSignal.timeout/any logic\n const effectiveTimeout = init.timeout ?? clientDefaultTimeout\n const userSignal = init.signal\n const transformedSignal = request.signal\n\n const pluginContext: PluginRequestContext = {\n request,\n init,\n state: Object.create(null),\n metadata: {\n startedAt: Date.now(),\n timeoutMs: effectiveTimeout,\n signals: {\n user:\n userSignal === undefined || userSignal === null\n ? undefined\n : userSignal,\n transformed: transformedSignal,\n },\n retry: {\n configuredRetries: effectiveRetries,\n configuredDelay: effectiveRetryDelay,\n attempt: 0,\n },\n },\n }\n\n for (const plugin of plugins) {\n await plugin.preRequest?.(pluginContext)\n }\n\n // Determine throwOnHttpError (per-request overrides client default)\n const effectiveThrowOnHttpError =\n typeof init.throwOnHttpError !== 'undefined'\n ? init.throwOnHttpError\n : (opts.throwOnHttpError ?? false)\n\n // Create timeout signal (manual implementation if AbortSignal.timeout not available)\n function createTimeoutSignal(timeout: number): AbortSignal {\n if (typeof AbortSignal?.timeout === 'function') {\n return AbortSignal.timeout(timeout)\n }\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n controller.signal.addEventListener(\n 'abort',\n () => clearTimeout(timeoutId),\n { once: true }\n )\n return controller.signal\n }\n\n let timeoutSignal: AbortSignal | undefined = undefined\n let combinedSignal: AbortSignal | undefined = undefined\n let controller: AbortController | undefined = undefined\n\n if (effectiveTimeout > 0) {\n timeoutSignal = createTimeoutSignal(effectiveTimeout)\n pluginContext.metadata.signals.timeout = timeoutSignal\n }\n\n const signals: AbortSignal[] = []\n if (userSignal) signals.push(userSignal)\n if (transformedSignal && transformedSignal !== userSignal) {\n signals.push(transformedSignal)\n }\n if (timeoutSignal) signals.push(timeoutSignal)\n\n if (signals.length === 1) {\n combinedSignal = signals[0]\n controller = new AbortController()\n } else {\n if (typeof AbortSignal.any !== 'function') {\n throw new Error(\n 'AbortSignal.any is required for combining multiple signals. Please install a polyfill for environments that do not support it.'\n )\n }\n combinedSignal = AbortSignal.any(signals)\n controller = new AbortController()\n }\n pluginContext.metadata.signals.combined = combinedSignal\n\n const retryWithHooks = async (\n dispatchCtx: PluginRequestContext,\n dispatchSignal: AbortSignal | undefined\n ) => {\n const requestForAttempt = dispatchCtx.request\n let attempt = 0\n const shouldRetryWithHook = (ctx: import('./types').RetryContext) => {\n attempt = ctx.attempt\n dispatchCtx.metadata.retry.attempt = attempt\n dispatchCtx.metadata.retry.lastError = ctx.error\n dispatchCtx.metadata.retry.lastResponse = ctx.response\n const retrying = effectiveShouldRetry(ctx)\n dispatchCtx.metadata.retry.shouldRetryResult = retrying\n if (retrying && attempt <= effectiveRetries) {\n effectiveHooks.onRetry?.(\n requestForAttempt,\n attempt - 1,\n ctx.error,\n ctx.response\n )\n }\n return retrying\n }\n\n let lastResponse: Response | undefined = undefined\n try {\n let res = await retry(\n async () => {\n if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n }\n if (timeoutSignal?.aborted) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out')\n }\n if (typeof dispatchSignal?.throwIfAborted === 'function') {\n dispatchSignal.throwIfAborted()\n } else if (dispatchSignal?.aborted) {\n if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n } else if (timeoutSignal?.aborted) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out')\n } else {\n throw new AbortError(\n 'Request was aborted',\n new DOMException('Aborted', 'AbortError')\n )\n }\n }\n const reqWithSignal = new Request(requestForAttempt, {\n signal: dispatchSignal,\n })\n try {\n const handler = init.fetchHandler ?? fetchHandler ?? fetch\n const response = await handler(reqWithSignal)\n lastResponse = response\n dispatchCtx.metadata.retry.lastResponse = response\n return response\n } catch (err) {\n dispatchCtx.metadata.retry.lastError = err\n if (err instanceof DOMException && err.name === 'AbortError') {\n if (\n timeoutSignal?.aborted &&\n (!userSignal || !userSignal.aborted)\n ) {\n effectiveHooks.onTimeout?.(requestForAttempt)\n throw new TimeoutError('signal timed out', err)\n } else if (userSignal?.aborted) {\n effectiveHooks.onAbort?.(requestForAttempt)\n throw new AbortError('Request was aborted by user')\n } else {\n throw new AbortError(\n 'Request was aborted',\n new DOMException('Aborted', 'AbortError')\n )\n }\n } else if (\n err instanceof TypeError &&\n /NetworkError|network error|failed to fetch|lost connection|NetworkError when attempting to fetch resource/i.test(\n err.message\n )\n ) {\n throw new NetworkError(err.message, err)\n }\n throw err\n }\n },\n effectiveRetries,\n effectiveRetryDelay,\n shouldRetryWithHook,\n requestForAttempt,\n dispatchSignal\n )\n if (effectiveHooks.transformResponse) {\n res = await effectiveHooks.transformResponse(res, requestForAttempt)\n }\n await effectiveHooks.after?.(requestForAttempt, res)\n await effectiveHooks.onComplete?.(requestForAttempt, res, undefined)\n if (\n effectiveThrowOnHttpError &&\n ((res.status >= 400 && res.status < 500 && res.status !== 429) ||\n res.status >= 500 ||\n res.status === 429)\n ) {\n const { HttpError } = await import('./error.js')\n throw new HttpError(\n `HTTP error: ${res.status} ${res.statusText}`,\n res\n )\n }\n return res\n } catch (err: unknown) {\n dispatchCtx.metadata.retry.lastError = err\n if (lastResponse) {\n const resp = lastResponse as Response\n if (\n effectiveThrowOnHttpError &&\n ((resp.status >= 400 &&\n resp.status < 500 &&\n resp.status !== 429) ||\n resp.status >= 500 ||\n resp.status === 429)\n ) {\n const { HttpError } = await import('./error.js')\n throw new HttpError(\n `HTTP error: ${resp.status} ${resp.statusText}`,\n resp\n )\n }\n return resp\n }\n if (err instanceof TimeoutError) {\n await effectiveHooks.onTimeout?.(requestForAttempt)\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n if (err instanceof AbortError) {\n await effectiveHooks.onAbort?.(requestForAttempt)\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n if (err instanceof NetworkError) {\n await effectiveHooks.onError?.(requestForAttempt, err)\n await effectiveHooks.onComplete?.(requestForAttempt, undefined, err)\n throw err\n }\n const retryErr = new RetryLimitError(\n typeof err === 'object' &&\n err &&\n 'message' in err &&\n typeof (err as { message?: unknown }).message === 'string'\n ? (err as { message: string }).message\n : 'Retry limit reached',\n err\n )\n await effectiveHooks.onError?.(requestForAttempt, retryErr)\n await effectiveHooks.onComplete?.(\n requestForAttempt,\n undefined,\n retryErr\n )\n throw retryErr\n }\n }\n\n const baseDispatch: PluginDispatch = async (ctx) => {\n const dispatchSignal =\n ctx === pluginContext ? combinedSignal : ctx.request.signal\n return retryWithHooks(ctx, dispatchSignal)\n }\n\n let dispatch = baseDispatch\n for (let i = plugins.length - 1; i >= 0; i--) {\n const plugin = plugins[i]\n if (plugin.wrapDispatch) {\n dispatch = plugin.wrapDispatch(dispatch)\n }\n }\n\n const actualPromise = dispatch(pluginContext)\n .then(async (response) => {\n for (const plugin of plugins) {\n await plugin.onSuccess?.(pluginContext, response)\n }\n return response\n })\n .catch(async (err: unknown) => {\n for (const plugin of plugins) {\n await plugin.onError?.(pluginContext, err)\n }\n throw err\n })\n\n const pendingEntry: PendingRequest = {\n promise: actualPromise,\n request,\n controller,\n }\n pendingRequests.push(pendingEntry)\n\n return actualPromise.finally(async () => {\n for (const plugin of plugins) {\n await plugin.onFinally?.(pluginContext)\n }\n\n const index = pendingRequests.indexOf(pendingEntry)\n if (index > -1) {\n pendingRequests.splice(index, 1)\n }\n })\n }\n\n let promise = execute() as Promise<Response>\n for (const plugin of plugins) {\n if (plugin.decoratePromise) {\n promise = plugin.decoratePromise(promise)\n }\n }\n return promise as Promise<Response> &\n PluginRequestPromiseExtensions<TPlugins>\n }\n\n Object.defineProperty(client, 'pendingRequests', {\n get() {\n return pendingRequests\n },\n enumerable: false,\n configurable: false,\n })\n\n Object.defineProperty(client, 'abortAll', {\n value: abortAll,\n writable: false,\n enumerable: false,\n configurable: false,\n })\n\n Object.defineProperties(client, extensionDescriptors)\n\n return client as FFetch<\n PluginExtensions<TPlugins>,\n PluginRequestPromiseExtensions<TPlugins>\n >\n}\n"],"mappings":"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","names":["defaultDelay","ctx","retryAfter","seconds","date","waitForRetryDelay","ms","signal","resolve","onAbort","timer","retry","fn","retries","delay","shouldRetry","request","lastErr","lastRes","i","wait","err","shouldRetry","ctx","error","response","AbortError","CircuitOpenError","TimeoutError","createClient","opts","clientDefaultTimeout","clientDefaultRetries","clientDefaultRetryDelay","defaultDelay","clientDefaultShouldRetry","shouldRetry","clientDefaultHooks","fetchHandler","inputPlugins","extensionDescriptors","plugins","plugin","index","a","b","aOrder","bOrder","entry","key","descriptor","propertyKey","pendingRequests","abortAll","client","input","init","promise","request","effectiveHooks","effectiveRetries","effectiveRetryDelay","effectiveShouldRetry","effectiveTimeout","userSignal","transformedSignal","pluginContext","effectiveThrowOnHttpError","createTimeoutSignal","timeout","controller","timeoutId","timeoutSignal","combinedSignal","signals","retryWithHooks","dispatchCtx","dispatchSignal","requestForAttempt","attempt","shouldRetryWithHook","ctx","retrying","lastResponse","res","retry","AbortError","TimeoutError","reqWithSignal","response","err","NetworkError","HttpError","resp","retryErr","RetryLimitError","dispatch","i","actualPromise","pendingEntry"]}