@zayne-labs/callapi 1.12.6 → 1.13.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.
@@ -1,11 +1,11 @@
1
- import { A as CallApiConfig, Ct as DistributiveOmit, D as ThrowOnErrorBoolean, Et as Writeable, F as CallApiResult, L as GetBaseSchemaConfig, O as BaseCallApiConfig, R as GetBaseSchemaRoutes, S as GetCurrentRouteSchemaKey, St as AnyString, T as InferInitURL, V as GlobalMeta, _ as ResponseTypeType, _t as InferSchemaOutput, b as ApplyURLBasedConfig, d as GetResponseType, dt as BaseCallApiSchemaRoutes, f as InferCallApiResult, g as ResponseTypeMap, i as CallApiPlugin, j as CallApiContext, l as CallApiResultSuccessOrErrorVariant, mt as CallApiSchemaConfig, n as DefaultDataType, pt as CallApiSchema, r as DefaultPluginArray, t as DefaultCallApiContext, u as CallApiResultSuccessVariant, ut as BaseCallApiSchemaAndConfig, v as ResultModeType, vt as InferSchemaResult, wt as NoInferUnMasked, x as GetCurrentRouteSchema, y as ApplyStrictConfig } from "./default-types-CyPF_5eh.js";
1
+ import { A as CallApiConfig, D as ThrowOnErrorBoolean, Et as BaseCallApiSchemaRoutes, F as CallApiResult, Ft as DistributiveOmit, It as NoInferUnMasked, L as GetBaseSchemaConfig, Lt as Writeable, Mt as InferSchemaResult, O as BaseCallApiConfig, Ot as CallApiSchema, Pt as AnyString, R as GetBaseSchemaRoutes, S as GetCurrentRouteSchemaKey, T as InferInitURL, Tt as BaseCallApiSchemaAndConfig, V as GlobalMeta, _ as ResponseTypeType, b as ApplyURLBasedConfig, d as GetResponseType, f as InferCallApiResult, g as ResponseTypeMap, i as CallApiPlugin, j as CallApiContext, jt as InferSchemaOutput, kt as CallApiSchemaConfig, l as CallApiResultSuccessOrErrorVariant, n as DefaultDataType, r as DefaultPluginArray, t as DefaultCallApiContext, u as CallApiResultSuccessVariant, v as ResultModeType, x as GetCurrentRouteSchema, y as ApplyStrictConfig } from "./default-types-Cn2QRN13.js";
2
2
 
3
3
  //#region src/createFetchClient.d.ts
4
4
  declare const createFetchClientWithContext: <TOuterCallApiContext extends CallApiContext = DefaultCallApiContext>() => <TBaseCallApiContext extends CallApiContext = TOuterCallApiContext, TBaseData = TBaseCallApiContext["Data"], TBaseErrorData = TBaseCallApiContext["ErrorData"], TBaseResultMode extends ResultModeType = (TBaseCallApiContext["ResultMode"] extends ResultModeType ? TBaseCallApiContext["ResultMode"] : ResultModeType), TBaseThrowOnError extends ThrowOnErrorBoolean = boolean, TBaseResponseType extends ResponseTypeType = ResponseTypeType, const TBaseSchemaAndConfig extends BaseCallApiSchemaAndConfig = BaseCallApiSchemaAndConfig, const TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray, TComputedBaseSchemaConfig extends CallApiSchemaConfig = GetBaseSchemaConfig<TBaseSchemaAndConfig>, TComputedBaseSchemaRoutes extends BaseCallApiSchemaRoutes = GetBaseSchemaRoutes<TBaseSchemaAndConfig>>(initBaseConfig?: BaseCallApiConfig<TBaseCallApiContext, TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBaseSchemaAndConfig, TBasePluginArray>) => <TData = TBaseData, TErrorData = TBaseErrorData, TResultMode extends ResultModeType = TBaseResultMode, TCallApiContext extends CallApiContext = TBaseCallApiContext, TThrowOnError extends ThrowOnErrorBoolean = TBaseThrowOnError, TResponseType extends ResponseTypeType = TBaseResponseType, const TSchemaConfig extends CallApiSchemaConfig = TComputedBaseSchemaConfig, TInitURL extends InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig> = InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<TComputedBaseSchemaRoutes, TCurrentRouteSchemaKey>, const TPluginArray extends CallApiPlugin[] = TBasePluginArray, TComputedData = InferSchemaOutput<TSchema["data"], GetResponseType<TData, TResponseType>>, TComputedErrorData = InferSchemaOutput<TSchema["errorData"], GetResponseType<TErrorData, TResponseType>>, TComputedResult = CallApiResult<TComputedData, TComputedErrorData, TResultMode, TThrowOnError>>(initURL: TInitURL, initConfig?: CallApiConfig<TCallApiContext, TComputedData, TComputedErrorData, TResultMode, TThrowOnError, TResponseType, TComputedBaseSchemaRoutes, TSchema, TComputedBaseSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, TBasePluginArray, TPluginArray>) => Promise<TComputedResult>;
5
5
  declare const createFetchClient: <TBaseCallApiContext extends CallApiContext = {
6
+ InferredExtraOptions: unknown;
6
7
  Data: DefaultDataType;
7
8
  ErrorData: DefaultDataType;
8
- InferredExtraOptions: unknown;
9
9
  ResultMode: ResultModeType;
10
10
  Meta: GlobalMeta;
11
11
  }, TBaseData = TBaseCallApiContext["Data"], TBaseErrorData = TBaseCallApiContext["ErrorData"], TBaseResultMode extends ResultModeType = (TBaseCallApiContext["ResultMode"] extends ResultModeType ? TBaseCallApiContext["ResultMode"] : ResultModeType), TBaseThrowOnError extends ThrowOnErrorBoolean = boolean, TBaseResponseType extends ResponseTypeType = ResponseTypeType, const TBaseSchemaAndConfig extends BaseCallApiSchemaAndConfig = BaseCallApiSchemaAndConfig, const TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray, TComputedBaseSchemaConfig extends CallApiSchemaConfig = Writeable<NonNullable<TBaseSchemaAndConfig["config"]>, "deep">, TComputedBaseSchemaRoutes extends BaseCallApiSchemaRoutes = Writeable<TBaseSchemaAndConfig["routes"], "deep">>(initBaseConfig?: BaseCallApiConfig<TBaseCallApiContext, TBaseData, TBaseErrorData, TBaseResultMode, TBaseThrowOnError, TBaseResponseType, TBaseSchemaAndConfig, TBasePluginArray>) => <TData = TBaseData, TErrorData = TBaseErrorData, TResultMode extends ResultModeType = TBaseResultMode, TCallApiContext extends CallApiContext = TBaseCallApiContext, TThrowOnError extends ThrowOnErrorBoolean = TBaseThrowOnError, TResponseType extends ResponseTypeType = TBaseResponseType, const TSchemaConfig extends CallApiSchemaConfig = TComputedBaseSchemaConfig, TInitURL extends InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig> = InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<TComputedBaseSchemaRoutes, TCurrentRouteSchemaKey, TComputedBaseSchemaRoutes["@default"], TComputedBaseSchemaRoutes[TCurrentRouteSchemaKey], NonNullable<Omit<TComputedBaseSchemaRoutes["@default"], keyof TComputedBaseSchemaRoutes[TCurrentRouteSchemaKey]> & TComputedBaseSchemaRoutes[TCurrentRouteSchemaKey]>>, const TPluginArray extends CallApiPlugin[] = TBasePluginArray, TComputedData = InferSchemaResult<TSchema["data"], GetResponseType<TData, TResponseType, ResponseTypeMap<TData>>, "infer-output">, TComputedErrorData = InferSchemaResult<TSchema["errorData"], GetResponseType<TErrorData, TResponseType, ResponseTypeMap<TErrorData>>, "infer-output">, TComputedResult = InferCallApiResult<TComputedData, TComputedErrorData, TResultMode, TThrowOnError, {
@@ -25,9 +25,9 @@ declare const createFetchClient: <TBaseCallApiContext extends CallApiContext = {
25
25
  withoutResponse: DistributiveOmit<TThrowOnError extends true ? CallApiResultSuccessVariant<TComputedData> : CallApiResultSuccessOrErrorVariant<TComputedData, TComputedErrorData>, "response"> extends infer T ? { [Key in keyof T]: T[Key] } : never;
26
26
  }>>(initURL: TInitURL, initConfig?: CallApiConfig<TCallApiContext, TComputedData, TComputedErrorData, TResultMode, TThrowOnError, TResponseType, TComputedBaseSchemaRoutes, TSchema, TComputedBaseSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, TBasePluginArray, TPluginArray>) => Promise<TComputedResult>;
27
27
  declare const callApi: <TData = unknown, TErrorData = unknown, TResultMode extends ResultModeType = ResultModeType, TCallApiContext extends CallApiContext = {
28
+ InferredExtraOptions: unknown;
28
29
  Data: DefaultDataType;
29
30
  ErrorData: DefaultDataType;
30
- InferredExtraOptions: unknown;
31
31
  ResultMode: ResultModeType;
32
32
  Meta: GlobalMeta;
33
33
  }, TThrowOnError extends ThrowOnErrorBoolean = boolean, TResponseType extends ResponseTypeType = ResponseTypeType, const TSchemaConfig extends CallApiSchemaConfig = CallApiSchemaConfig, TInitURL extends ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "@delete/" | "@get/" | "@patch/" | "@post/" | "@put/">> = ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, AnyString | "@delete/" | "@get/" | "@patch/" | "@post/" | "@put/">>, TCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> = GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>, const TSchema extends CallApiSchema = GetCurrentRouteSchema<{
@@ -88,4 +88,4 @@ declare const callApi: <TData = unknown, TErrorData = unknown, TResultMode exten
88
88
  }, TSchema, CallApiSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, DefaultPluginArray, TPluginArray>) => Promise<TComputedResult>;
89
89
  //#endregion
90
90
  export { createFetchClient as n, createFetchClientWithContext as r, callApi as t };
91
- //# sourceMappingURL=index-CQfVY7gI.d.ts.map
91
+ //# sourceMappingURL=index-WSyoCGJi.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- import { $ as Hooks, A as CallApiConfig, B as GetCallApiContextRequired, C as InferAllMainRouteKeys, E as InferParamsFromRoute, H as InstanceContext, I as CallApiResultLoose, J as Middlewares, K as FetchImpl, M as CallApiExtraOptions, N as CallApiParameters, O as BaseCallApiConfig, P as CallApiRequestOptions, Q as ErrorContext, S as GetCurrentRouteSchemaKey, T as InferInitURL, U as Register, X as CallApiExtraOptionsForHooks, Y as DedupeOptions, Z as CallApiRequestOptionsForHooks, _ as ResponseTypeType, _t as InferSchemaOutput, a as PluginHooks, at as ResponseStreamContext, c as CallApiResultErrorVariant, ct as RetryOptions, dt as BaseCallApiSchemaRoutes, et as HooksOrHooksArray, ft as BaseSchemaRouteKeyPrefixes, gt as InferSchemaInput, h as PossibleValidationError, i as CallApiPlugin, it as ResponseErrorContext, k as BaseCallApiExtraOptions, l as CallApiResultSuccessOrErrorVariant, lt as URLOptions, m as PossibleJavaScriptError, mt as CallApiSchemaConfig, nt as RequestStreamContext, o as PluginMiddlewares, ot as SuccessContext, p as PossibleHTTPError, pt as CallApiSchema, q as FetchMiddlewareContext, rt as ResponseContext, s as PluginSetupContext, st as RefetchOptions, t as DefaultCallApiContext, tt as RequestContext, u as CallApiResultSuccessVariant, v as ResultModeType, w as InferAllMainRoutes, z as GetCallApiContext } from "./default-types-CyPF_5eh.js";
2
- import { n as createFetchClient, r as createFetchClientWithContext, t as callApi } from "./index-CQfVY7gI.js";
1
+ import { $ as RequestContext, A as CallApiConfig, At as InferSchemaInput, B as GetCallApiContextRequired, C as InferAllMainRouteKeys, Dt as BaseSchemaRouteKeyPrefixes, E as InferParamsFromRoute, Et as BaseCallApiSchemaRoutes, G as FetchMiddlewareContext, H as InstanceContext, I as CallApiResultLoose, J as CallApiExtraOptionsForHooks, K as Middlewares, M as CallApiExtraOptions, N as CallApiParameters, Nt as URLOptions, O as BaseCallApiConfig, Ot as CallApiSchema, P as CallApiRequestOptions, Q as HooksOrHooksArray, S as GetCurrentRouteSchemaKey, T as InferInitURL, U as Register, W as FetchImpl, X as ErrorContext, Y as CallApiRequestOptionsForHooks, Z as Hooks, _ as ResponseTypeType, a as PluginHooks, at as RefetchOptions, c as CallApiResultErrorVariant, et as RequestStreamContext, h as PossibleValidationError, i as CallApiPlugin, it as SuccessContext, jt as InferSchemaOutput, k as BaseCallApiExtraOptions, kt as CallApiSchemaConfig, l as CallApiResultSuccessOrErrorVariant, m as PossibleJavaScriptError, nt as ResponseErrorContext, o as PluginMiddlewares, ot as RetryOptions, p as PossibleHTTPError, q as DedupeOptions, rt as ResponseStreamContext, s as PluginSetupContext, t as DefaultCallApiContext, tt as ResponseContext, u as CallApiResultSuccessVariant, v as ResultModeType, w as InferAllMainRoutes, z as GetCallApiContext } from "./default-types-Cn2QRN13.js";
2
+ import { n as createFetchClient, r as createFetchClientWithContext, t as callApi } from "./index-WSyoCGJi.js";
3
3
  export { BaseCallApiConfig, BaseCallApiExtraOptions, BaseCallApiSchemaRoutes, BaseSchemaRouteKeyPrefixes, CallApiConfig, CallApiExtraOptions, CallApiExtraOptionsForHooks, CallApiParameters, CallApiPlugin, CallApiRequestOptions, CallApiRequestOptionsForHooks, CallApiResultLoose as CallApiResult, CallApiResultErrorVariant, CallApiResultSuccessOrErrorVariant, CallApiResultSuccessVariant, CallApiSchema, CallApiSchemaConfig, DedupeOptions, DefaultCallApiContext, ErrorContext, FetchImpl, FetchMiddlewareContext, GetCallApiContext, GetCallApiContextRequired, GetCurrentRouteSchemaKey, Hooks, HooksOrHooksArray, InferAllMainRouteKeys, InferAllMainRoutes, InferInitURL, InferParamsFromRoute, InferSchemaInput, InferSchemaOutput, InstanceContext, Middlewares, PluginHooks, PluginMiddlewares, PluginSetupContext, PossibleHTTPError, PossibleJavaScriptError, PossibleValidationError, RefetchOptions, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeType, ResultModeType, RetryOptions, SuccessContext, URLOptions, callApi, createFetchClient, createFetchClientWithContext };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as getCurrentRouteSchemaKeyAndMainInitURL, B as isString, L as isArray, M as handleSchemaValidation, N as HTTPError, R as isBoolean, a as getBody, c as getMethod, d as splitConfig, f as waitFor, h as isHTTPErrorInstance, i as createTimeoutSignal, j as handleConfigValidation, k as getFullAndNormalizedURL, l as getResolvedHeaders, o as getFetchImpl, r as createCombinedSignal, s as getHeaders, t as extraOptionDefaults, u as omitKeys, v as isValidationErrorInstance, z as isFunction } from "./defaults-IsBgvt90.js";
1
+ import { A as getCurrentRouteSchemaKeyAndMainInitURL, I as isArray, L as isFunction, M as handleSchemaValidation, N as HTTPError, R as isString, a as getBody, c as getMethod, d as splitConfig, f as waitFor, h as isHTTPErrorInstance, i as createTimeoutSignal, j as handleConfigValidation, k as getFullAndNormalizedURL, l as getResolvedHeaders, o as getFetchImpl, r as createCombinedSignal, s as getHeaders, t as extraOptionDefaults, u as omitKeys, v as isValidationErrorInstance } from "./constants-Cj_bGg18.js";
2
2
  //#region src/result.ts
3
3
  const getResponseType = (response, responseParser) => ({
4
4
  arrayBuffer: () => response.arrayBuffer(),
@@ -51,8 +51,8 @@ const resolveSuccessResult = (data, info) => {
51
51
  response
52
52
  })[resultMode ?? "all"]();
53
53
  };
54
- const resolveErrorResult = (error, info) => {
55
- const { cloneResponse, message: customErrorMessage, resultMode } = info;
54
+ const resolveErrorResult = (error, infoOptions) => {
55
+ const { cloneResponse, message: customErrorMessage, resultMode } = infoOptions;
56
56
  let errorDetails = {
57
57
  data: null,
58
58
  error: {
@@ -96,17 +96,6 @@ const resolveErrorResult = (error, info) => {
96
96
  errorResult
97
97
  };
98
98
  };
99
- const getCustomizedErrorResult = (errorResult, customErrorInfo) => {
100
- if (!errorResult) return null;
101
- const { message = errorResult.error.message } = customErrorInfo;
102
- return {
103
- ...errorResult,
104
- error: {
105
- ...errorResult.error,
106
- message
107
- }
108
- };
109
- };
110
99
  //#endregion
111
100
  //#region src/hooks.ts
112
101
  const getHookRegistriesAndKeys = () => {
@@ -148,13 +137,13 @@ const executeHooks = async (...hookResultsOrPromise) => {
148
137
  await Promise.all(validHooks);
149
138
  };
150
139
  const executeHooksInCatchBlock = async (hookResultsOrPromise, hookInfo) => {
151
- const { errorInfo, shouldThrowOnError } = hookInfo;
140
+ const { errorInfoOptions, shouldThrowOnError } = hookInfo;
152
141
  try {
153
142
  await Promise.all(hookResultsOrPromise);
154
143
  return null;
155
144
  } catch (hookError) {
156
145
  if (shouldThrowOnError) throw hookError;
157
- const { errorResult } = resolveErrorResult(hookError, errorInfo);
146
+ const { errorResult } = resolveErrorResult(hookError, errorInfoOptions);
158
147
  return errorResult;
159
148
  }
160
149
  };
@@ -287,10 +276,8 @@ const toStreamableResponse = (context) => {
287
276
  };
288
277
  //#endregion
289
278
  //#region src/dedupe.ts
290
- const createDedupeStrategy = async (context) => {
291
- const { $GlobalRequestInfoCache, $LocalRequestInfoCache, baseConfig, config, newFetchController, options: globalOptions } = context;
292
- const dedupeStrategy = globalOptions.dedupeStrategy ?? extraOptionDefaults.dedupeStrategy;
293
- const resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy(context) : dedupeStrategy;
279
+ const createDedupeManager = async (context) => {
280
+ const { $GlobalRequestInfoCache, $LocalRequestInfoCache, baseConfig, config, newFetchController, options: globalOptions, resolvedDedupeStrategy } = context;
294
281
  const shouldDisableDedupe = resolvedDedupeStrategy === "none";
295
282
  const getDedupeKey = () => {
296
283
  const dedupeKey = globalOptions.dedupeKey ?? extraOptionDefaults.dedupeKey;
@@ -337,7 +324,6 @@ const createDedupeStrategy = async (context) => {
337
324
  if (!shouldDisableDedupe) await waitFor(.01);
338
325
  const prevRequestInfo = $RequestInfoCache?.get();
339
326
  const getAbortErrorMessage = () => {
340
- if (shouldDisableDedupe) return;
341
327
  return globalOptions.dedupeKey != null ? `Duplicate request detected - Aborted previous request with key '${dedupeKey}'` : `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}'`;
342
328
  };
343
329
  const handleRequestCancelStrategy = () => {
@@ -365,15 +351,11 @@ const createDedupeStrategy = async (context) => {
365
351
  response: await responsePromise
366
352
  });
367
353
  };
368
- const removeDedupeKeyFromCache = () => {
369
- $RequestInfoCache?.delete();
370
- };
371
354
  return {
372
355
  getAbortErrorMessage,
373
356
  handleRequestCancelStrategy,
374
357
  handleRequestDeferStrategy,
375
- removeDedupeKeyFromCache,
376
- resolvedDedupeStrategy
358
+ removeDedupeCacheEntry: () => $RequestInfoCache?.delete()
377
359
  };
378
360
  };
379
361
  //#endregion
@@ -537,82 +519,82 @@ const setupHooksAndMiddlewares = (context) => {
537
519
  };
538
520
  //#endregion
539
521
  //#region src/refetch.ts
522
+ const shouldAttemptRefetchSymbol = Symbol("shouldAttemptRefetch");
540
523
  const createRefetchManager = (ctx) => {
541
- const { callApi, callApiArgs, options } = ctx;
542
- const currentRefetchCount = options["~refetchCount"] ?? 1;
543
- const refetch = async (refetchOptionOverrides) => {
544
- const maxRefetchAttempts = refetchOptionOverrides?.refetchAttempts ?? options.refetchAttempts ?? extraOptionDefaults.refetchAttempts;
545
- if (!(currentRefetchCount <= maxRefetchAttempts)) {
546
- const message = `Maximum refetch attempts (${maxRefetchAttempts}) exceeded. This prevents infinite loops. Increase 'maxRefetchAttempts' if needed.`;
547
- console.error(message);
548
- return null;
524
+ const { callApi, callApiArgs, options, removeDedupeCacheEntry } = ctx;
525
+ const shouldAttemptRefetch = () => {
526
+ return options[shouldAttemptRefetchSymbol] ?? false;
527
+ };
528
+ const refetch = () => {
529
+ options[shouldAttemptRefetchSymbol] = true;
530
+ };
531
+ const handleRefetch = () => {
532
+ if (shouldAttemptRefetch()) {
533
+ removeDedupeCacheEntry();
534
+ return callApi(callApiArgs.initURL, {
535
+ ...callApiArgs.config,
536
+ [shouldAttemptRefetchSymbol]: false
537
+ });
549
538
  }
550
- const updatedConfig = {
551
- ...callApiArgs.config,
552
- ...refetchOptionOverrides,
553
- "~refetchCount": currentRefetchCount + 1
554
- };
555
- return callApi(callApiArgs.initURL, updatedConfig);
539
+ return null;
540
+ };
541
+ return {
542
+ handleRefetch,
543
+ refetch
556
544
  };
557
- return { refetch };
558
545
  };
559
546
  //#endregion
560
547
  //#region src/retry.ts
561
- const getLinearDelay = (currentAttemptCount, options) => {
562
- const retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;
563
- return isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;
564
- };
565
- const getExponentialDelay = (currentAttemptCount, options) => {
566
- const retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;
567
- const resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;
568
- const maxDelay = options.retryMaxDelay ?? extraOptionDefaults.retryMaxDelay;
569
- const exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;
570
- return Math.min(exponentialDelay, maxDelay);
571
- };
572
548
  const createRetryManager = (ctx) => {
573
- const { callApi, callApiArgs, error, errorContext, errorResult, hookInfo } = ctx;
549
+ const { callApi, callApiArgs, error, errorContext, hookInfo, removeDedupeCacheEntry } = ctx;
574
550
  const { options, request } = errorContext;
575
- const currentAttemptCount = options["~retryAttemptCount"] ?? 1;
576
- const retryStrategy = options.retryStrategy ?? extraOptionDefaults.retryStrategy;
551
+ const currentRetryAttemptCount = options["~retryAttemptCount"] ?? 1;
552
+ const shouldAttemptRetry = async () => {
553
+ if (request.signal?.aborted) return false;
554
+ const maxRetryAttempts = options.retryAttempts ?? extraOptionDefaults.retryAttempts;
555
+ const retryCondition = options.retryCondition ?? extraOptionDefaults.retryCondition;
556
+ if (!(currentRetryAttemptCount <= maxRetryAttempts && await retryCondition(errorContext))) return false;
557
+ const retryMethods = options.retryMethods ?? extraOptionDefaults.retryMethods;
558
+ const includesMethod = request.method != null && retryMethods.length > 0 ? retryMethods.includes(request.method) : true;
559
+ const retryStatusCodes = options.retryStatusCodes ?? extraOptionDefaults.retryStatusCodes;
560
+ const includesStatusCodes = errorContext.response != null && retryStatusCodes.length > 0 ? retryStatusCodes.includes(errorContext.response.status) : true;
561
+ return includesMethod && includesStatusCodes;
562
+ };
577
563
  const getDelay = () => {
564
+ const retryStrategy = options.retryStrategy ?? extraOptionDefaults.retryStrategy;
578
565
  switch (retryStrategy) {
579
- case "exponential": return getExponentialDelay(currentAttemptCount, options);
580
- case "linear": return getLinearDelay(currentAttemptCount, options);
566
+ case "exponential": {
567
+ const retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;
568
+ const resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentRetryAttemptCount) : retryDelay;
569
+ const maxDelay = options.retryMaxDelay ?? extraOptionDefaults.retryMaxDelay;
570
+ const exponentialDelay = resolvedRetryDelay * 2 ** (currentRetryAttemptCount - 1);
571
+ return Math.min(exponentialDelay, maxDelay);
572
+ }
573
+ case "linear": {
574
+ const retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;
575
+ return isFunction(retryDelay) ? retryDelay(currentRetryAttemptCount) : retryDelay;
576
+ }
581
577
  default: throw new Error(`Invalid retry strategy: ${String(retryStrategy)}`);
582
578
  }
583
579
  };
584
- const shouldAttemptRetry = async () => {
585
- if (isBoolean(request.signal) && request.signal.aborted) return false;
586
- const retryCondition = options.retryCondition ?? extraOptionDefaults.retryCondition;
587
- const maxRetryAttempts = options.retryAttempts ?? extraOptionDefaults.retryAttempts;
588
- const customRetryCondition = await retryCondition(errorContext);
589
- if (!(currentAttemptCount <= maxRetryAttempts && customRetryCondition)) return false;
590
- const retryMethods = new Set(options.retryMethods ?? extraOptionDefaults.retryMethods);
591
- const includesMethod = isString(request.method) && retryMethods.size > 0 ? retryMethods.has(request.method) : true;
592
- const retryStatusCodes = new Set(options.retryStatusCodes ?? extraOptionDefaults.retryStatusCodes);
593
- const includesStatusCodes = errorContext.response != null && retryStatusCodes.size > 0 ? retryStatusCodes.has(errorContext.response.status) : true;
594
- return includesMethod && includesStatusCodes;
595
- };
596
580
  const handleRetry = async () => {
597
- const retryContext = {
598
- ...errorContext,
599
- retryAttemptCount: currentAttemptCount
600
- };
601
- const hookError = await executeHooksInCatchBlock([options.onRetry?.(retryContext)], hookInfo);
602
- if (hookError) return hookError;
603
- await waitFor(getDelay());
604
- const updatedConfig = {
605
- ...callApiArgs.config,
606
- "~retryAttemptCount": currentAttemptCount + 1
607
- };
608
- return callApi(callApiArgs.initURL, updatedConfig);
609
- };
610
- const handleRetryOrGetErrorResult = async () => {
611
- if (await shouldAttemptRetry()) return handleRetry();
581
+ if (await shouldAttemptRetry()) {
582
+ const hookError = await executeHooksInCatchBlock([options.onRetry?.({
583
+ ...errorContext,
584
+ retryAttemptCount: currentRetryAttemptCount
585
+ })], hookInfo);
586
+ if (hookError) return hookError;
587
+ await waitFor(getDelay());
588
+ removeDedupeCacheEntry();
589
+ return callApi(callApiArgs.initURL, {
590
+ ...callApiArgs.config,
591
+ "~retryAttemptCount": currentRetryAttemptCount + 1
592
+ });
593
+ }
612
594
  if (hookInfo.shouldThrowOnError) throw error;
613
- return errorResult;
595
+ return null;
614
596
  };
615
- return { handleRetryOrGetErrorResult };
597
+ return { handleRetry };
616
598
  };
617
599
  //#endregion
618
600
  //#region src/createFetchClient.ts
@@ -679,33 +661,42 @@ const createFetchClientWithContext = () => {
679
661
  initURL: resolvedInitURL,
680
662
  initURLNormalized: normalizedInitURL
681
663
  };
682
- const refetchFnResult = createRefetchManager({
683
- callApi,
684
- callApiArgs: {
685
- config,
686
- initURL
687
- },
688
- options
689
- });
690
- Object.assign(options, refetchFnResult);
691
- const newFetchController = options.dedupeStrategy === "none" ? null : new AbortController();
664
+ const dedupeStrategy = options.dedupeStrategy ?? extraOptionDefaults.dedupeStrategy;
665
+ const resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy({
666
+ baseConfig,
667
+ config,
668
+ options,
669
+ request: resolvedRequest
670
+ }) : dedupeStrategy;
671
+ const newFetchController = resolvedDedupeStrategy === "none" ? null : new AbortController();
692
672
  const combinedSignal = createCombinedSignal(createTimeoutSignal(options.timeout), resolvedRequest.signal, newFetchController?.signal);
693
673
  const request = {
694
674
  ...resolvedRequest,
695
675
  signal: combinedSignal
696
676
  };
697
- const { getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeKeyFromCache, resolvedDedupeStrategy } = await createDedupeStrategy({
677
+ const { getAbortErrorMessage, handleRequestCancelStrategy, handleRequestDeferStrategy, removeDedupeCacheEntry } = await createDedupeManager({
698
678
  $GlobalRequestInfoCache,
699
679
  $LocalRequestInfoCache,
700
680
  baseConfig,
701
681
  config,
702
682
  newFetchController,
703
683
  options,
704
- request
684
+ request,
685
+ resolvedDedupeStrategy
705
686
  });
687
+ const { handleRefetch, refetch } = createRefetchManager({
688
+ callApi,
689
+ callApiArgs: {
690
+ config,
691
+ initURL
692
+ },
693
+ options,
694
+ removeDedupeCacheEntry
695
+ });
696
+ options.refetch = refetch;
706
697
  try {
707
698
  handleRequestCancelStrategy();
708
- await executeHooks(options.onRequest?.({
699
+ if (options.onRequest) await executeHooks(options.onRequest({
709
700
  baseConfig,
710
701
  config,
711
702
  options,
@@ -719,7 +710,7 @@ const createFetchClientWithContext = () => {
719
710
  request
720
711
  });
721
712
  Object.assign(options, extraOptionsValidationResult);
722
- const modifiedRequestOptionsValidationResult = {
713
+ Object.assign(request, {
723
714
  body: getBody({
724
715
  body: requestOptionsValidationResult.body,
725
716
  bodySerializer: options.bodySerializer,
@@ -734,15 +725,14 @@ const createFetchClientWithContext = () => {
734
725
  initURL: resolvedInitURL,
735
726
  method: requestOptionsValidationResult.method
736
727
  })
737
- };
738
- Object.assign(request, modifiedRequestOptionsValidationResult);
728
+ });
739
729
  const readyRequestContext = {
740
730
  baseConfig,
741
731
  config,
742
732
  options,
743
733
  request
744
734
  };
745
- await executeHooks(options.onRequestReady?.(readyRequestContext));
735
+ if (options.onRequestReady) await executeHooks(options.onRequestReady(readyRequestContext));
746
736
  const response = await handleRequestDeferStrategy({
747
737
  fetchApi: getFetchImpl({
748
738
  customFetchImpl: options.customFetchImpl,
@@ -784,20 +774,17 @@ const createFetchClientWithContext = () => {
784
774
  request,
785
775
  response
786
776
  };
787
- await executeHooks(options.onSuccess?.(successContext), options.onResponse?.({
777
+ if (options.onSuccess || options.onResponse) await executeHooks(options.onSuccess?.(successContext), options.onResponse?.({
788
778
  ...successContext,
789
779
  error: null
790
780
  }));
791
- return resolveSuccessResult(successContext.data, {
781
+ const successResult = resolveSuccessResult(successContext.data, {
792
782
  response: successContext.response,
793
783
  resultMode: options.resultMode
794
784
  });
785
+ return await handleRefetch() ?? successResult;
795
786
  } catch (error) {
796
- const errorInfo = {
797
- cloneResponse: options.cloneResponse,
798
- resultMode: options.resultMode
799
- };
800
- const { errorDetails, errorResult } = resolveErrorResult(error, errorInfo);
787
+ const { errorDetails, errorResult } = resolveErrorResult(error, options);
801
788
  const errorContext = {
802
789
  baseConfig,
803
790
  config,
@@ -808,10 +795,10 @@ const createFetchClientWithContext = () => {
808
795
  };
809
796
  const shouldThrowOnError = Boolean(isFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError);
810
797
  const hookInfo = {
811
- errorInfo,
798
+ errorInfoOptions: options,
812
799
  shouldThrowOnError
813
800
  };
814
- const { handleRetryOrGetErrorResult } = createRetryManager({
801
+ const { handleRetry } = createRetryManager({
815
802
  callApi,
816
803
  callApiArgs: {
817
804
  config,
@@ -819,39 +806,43 @@ const createFetchClientWithContext = () => {
819
806
  },
820
807
  error,
821
808
  errorContext,
822
- errorResult,
823
- hookInfo
809
+ hookInfo,
810
+ removeDedupeCacheEntry
824
811
  });
812
+ const handleRefetchThenRetryOrGetResult = async () => {
813
+ return await handleRefetch() ?? await handleRetry() ?? errorResult;
814
+ };
825
815
  const responseContext = errorContext.response ? {
826
816
  ...errorContext,
827
817
  data: null
828
818
  } : null;
829
- if (isValidationErrorInstance(error)) return await executeHooksInCatchBlock([
819
+ if (isValidationErrorInstance(error)) return (responseContext && options.onResponse || options.onValidationError || options.onError ? await executeHooksInCatchBlock([
830
820
  responseContext && options.onResponse?.(responseContext),
831
821
  options.onValidationError?.(errorContext),
832
822
  options.onError?.(errorContext)
833
- ], hookInfo) ?? await handleRetryOrGetErrorResult();
834
- if (isHTTPErrorInstance(error)) return await executeHooksInCatchBlock([
823
+ ], hookInfo) : null) ?? await handleRefetchThenRetryOrGetResult();
824
+ if (isHTTPErrorInstance(error)) return (responseContext && options.onResponse || options.onResponseError || options.onError ? await executeHooksInCatchBlock([
835
825
  responseContext && options.onResponse?.(responseContext),
836
826
  options.onResponseError?.(errorContext),
837
827
  options.onError?.(errorContext)
838
- ], hookInfo) ?? await handleRetryOrGetErrorResult();
839
- let message = error?.message;
828
+ ], hookInfo) : null) ?? await handleRefetchThenRetryOrGetResult();
840
829
  if (error instanceof DOMException && error.name === "AbortError") {
841
- message = getAbortErrorMessage();
830
+ const message = getAbortErrorMessage();
831
+ errorResult && (errorResult.error.message = message);
842
832
  !shouldThrowOnError && console.error(`${error.name}:`, message);
843
833
  }
844
834
  if (error instanceof DOMException && error.name === "TimeoutError") {
845
- message = `Request timed out after ${options.timeout}ms`;
835
+ const message = `Request timed out after ${options.timeout}ms`;
836
+ errorResult && (errorResult.error.message = message);
846
837
  !shouldThrowOnError && console.error(`${error.name}:`, message);
847
838
  }
848
- return await executeHooksInCatchBlock([
839
+ return (responseContext && options.onResponse || options.onRequestError || options.onError ? await executeHooksInCatchBlock([
849
840
  responseContext && options.onResponse?.(responseContext),
850
841
  options.onRequestError?.(errorContext),
851
842
  options.onError?.(errorContext)
852
- ], hookInfo) ?? getCustomizedErrorResult(await handleRetryOrGetErrorResult(), { message });
843
+ ], hookInfo) : null) ?? await handleRefetchThenRetryOrGetResult();
853
844
  } finally {
854
- removeDedupeKeyFromCache();
845
+ removeDedupeCacheEntry();
855
846
  }
856
847
  };
857
848
  return callApi;