@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.
- package/dist/constants/index.d.ts +7 -8
- package/dist/constants/index.js +1 -1
- package/dist/{defaults-IsBgvt90.js → constants-Cj_bGg18.js} +27 -26
- package/dist/constants-Cj_bGg18.js.map +1 -0
- package/dist/{default-types-CyPF_5eh.d.ts → default-types-Cn2QRN13.d.ts} +292 -222
- package/dist/{index-CQfVY7gI.d.ts → index-WSyoCGJi.d.ts} +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +115 -124
- package/dist/index.js.map +1 -1
- package/dist/utils/external/index.d.ts +2 -74
- package/dist/utils/external/index.js +1 -1
- package/package.json +6 -6
- package/dist/defaults-IsBgvt90.js.map +0 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { A as CallApiConfig,
|
|
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-
|
|
91
|
+
//# sourceMappingURL=index-WSyoCGJi.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { n as createFetchClient, r as createFetchClientWithContext, t as callApi } from "./index-
|
|
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,
|
|
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,
|
|
55
|
-
const { cloneResponse, message: customErrorMessage, resultMode } =
|
|
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 {
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
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,
|
|
549
|
+
const { callApi, callApiArgs, error, errorContext, hookInfo, removeDedupeCacheEntry } = ctx;
|
|
574
550
|
const { options, request } = errorContext;
|
|
575
|
-
const
|
|
576
|
-
const
|
|
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":
|
|
580
|
-
|
|
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
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
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
|
|
595
|
+
return null;
|
|
614
596
|
};
|
|
615
|
-
return {
|
|
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
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
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,
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
798
|
+
errorInfoOptions: options,
|
|
812
799
|
shouldThrowOnError
|
|
813
800
|
};
|
|
814
|
-
const {
|
|
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
|
-
|
|
823
|
-
|
|
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
|
|
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
|
|
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) ??
|
|
843
|
+
], hookInfo) : null) ?? await handleRefetchThenRetryOrGetResult();
|
|
853
844
|
} finally {
|
|
854
|
-
|
|
845
|
+
removeDedupeCacheEntry();
|
|
855
846
|
}
|
|
856
847
|
};
|
|
857
848
|
return callApi;
|