@sebspark/retry 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,94 @@
1
+
2
+ //#region src/retry.ts
3
+ const defaultSettings = { retryCondition: () => true };
4
+ const mergeSettings = (...settings) => {
5
+ const s = settings.filter((s$1) => s$1);
6
+ if (!s.length) return void 0;
7
+ return Object.assign(defaultSettings, ...s);
8
+ };
9
+ const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
10
+ const retry = async (func, ...settings) => {
11
+ const mergedSettings = mergeSettings(...settings);
12
+ const makeCall = async (retries = 0) => {
13
+ try {
14
+ return await func();
15
+ } catch (error) {
16
+ if (mergedSettings && mergedSettings.retryCondition(error) && retries < mergedSettings.maxRetries) {
17
+ await wait(mergedSettings.interval(retries + 1));
18
+ return makeCall(retries + 1);
19
+ }
20
+ throw error;
21
+ }
22
+ };
23
+ return makeCall(0);
24
+ };
25
+ const interval = {
26
+ fixed: (delay) => (_retries) => delay,
27
+ linear: (delay) => (retries) => retries * delay,
28
+ exponential: (delay, base = 2) => (retries) => base ** (retries - 1) * delay
29
+ };
30
+ const clientErrorCodes = [
31
+ 400,
32
+ 401,
33
+ 402,
34
+ 403,
35
+ 404,
36
+ 405,
37
+ 406,
38
+ 407,
39
+ 408,
40
+ 409,
41
+ 410,
42
+ 411,
43
+ 412,
44
+ 413,
45
+ 414,
46
+ 415,
47
+ 416,
48
+ 417,
49
+ 418,
50
+ 421,
51
+ 422,
52
+ 423,
53
+ 424,
54
+ 425,
55
+ 426,
56
+ 428,
57
+ 429,
58
+ 431,
59
+ 451
60
+ ];
61
+ const serverErrorCodes = [
62
+ 500,
63
+ 501,
64
+ 502,
65
+ 503,
66
+ 504,
67
+ 505,
68
+ 506,
69
+ 507,
70
+ 508,
71
+ 510,
72
+ 511
73
+ ];
74
+ const retryCondition = {
75
+ always: (_error) => true,
76
+ httpErrors: (...codes) => (error) => {
77
+ const captureCodes = codes.flatMap((code) => {
78
+ if (typeof code === "number") return code;
79
+ if (code === "client") return clientErrorCodes;
80
+ if (code === "server") return serverErrorCodes;
81
+ return 500;
82
+ }).filter((code) => !!code);
83
+ const status = error.status || error.statusCode || error.response?.status || error.response?.statusCode || 0;
84
+ return captureCodes.includes(status);
85
+ },
86
+ serverErrors: (error) => retryCondition.httpErrors("server")(error),
87
+ custom: (func) => func
88
+ };
89
+
90
+ //#endregion
91
+ exports.interval = interval;
92
+ exports.retry = retry;
93
+ exports.retryCondition = retryCondition;
94
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["defaultSettings: Partial<RetrySettings>","s"],"sources":["../src/retry.ts"],"sourcesContent":["// biome-ignore lint/suspicious/noExplicitAny: Errors can be anything\nexport type RetryConditionFunction = (error: any) => boolean\n\nexport interface RetrySettings {\n maxRetries: number\n interval: (retryCount: number) => number\n retryCondition?: RetryConditionFunction\n maxDelay?: number\n}\n\nconst defaultSettings: Partial<RetrySettings> = {\n retryCondition: () => true,\n}\nconst mergeSettings = (\n ...settings: Array<RetrySettings | undefined>\n): RetrySettings | undefined => {\n // remove undefineds, return if no settings passed\n const s = settings.filter((s) => s) as RetrySettings[]\n if (!s.length) return undefined\n\n // merge settings with priority to the latest\n const merged: RetrySettings = Object.assign(defaultSettings, ...s)\n\n return merged\n}\n\nconst wait = (ms: number) =>\n new Promise<void>((resolve) => setTimeout(() => resolve(), ms))\n\nexport const retry = async <T>(\n func: () => Promise<T>,\n ...settings: Array<RetrySettings | undefined>\n): Promise<T> => {\n const mergedSettings = mergeSettings(...settings)\n\n const makeCall = async <T>(retries = 0): Promise<T> => {\n try {\n const response = await func()\n return response as T\n } catch (error) {\n if (\n mergedSettings &&\n // biome-ignore lint/style/noNonNullAssertion: Will be set by defaultSettings\n mergedSettings.retryCondition!(error) &&\n retries < mergedSettings.maxRetries\n ) {\n await wait(mergedSettings.interval(retries + 1))\n return makeCall(retries + 1)\n }\n\n throw error\n }\n }\n return makeCall(0)\n}\n\nexport const interval = {\n fixed: (delay: number) => (_retries: number) => delay,\n linear: (delay: number) => (retries: number) => retries * delay,\n exponential:\n (delay: number, base = 2) =>\n (retries: number) =>\n base ** (retries - 1) * delay,\n}\n\nconst clientErrorCodes = [\n 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,\n 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,\n] as const\ntype ClientErrorCode = (typeof clientErrorCodes)[number]\n\nconst serverErrorCodes = [\n 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511,\n] as const\ntype ServerErrorCode = (typeof serverErrorCodes)[number]\n\ntype ErrorType = 'server' | 'client' | ServerErrorCode | ClientErrorCode\n\ntype HttpError = {\n status?: number\n statusCode?: number\n response?: {\n status?: number\n statusCode?: number\n }\n}\n\nexport const retryCondition = {\n always: (_error: unknown) => true,\n httpErrors:\n (...codes: ErrorType[]) =>\n (error: HttpError) => {\n const captureCodes = codes\n .flatMap((code) => {\n if (typeof code === 'number') return code\n if (code === 'client') return clientErrorCodes\n if (code === 'server') return serverErrorCodes\n return 500\n })\n .filter((code) => !!code) as number[]\n const status =\n error.status ||\n error.statusCode ||\n error.response?.status ||\n error.response?.statusCode ||\n 0\n return captureCodes.includes(status)\n },\n serverErrors: (error: HttpError) =>\n retryCondition.httpErrors('server')(error),\n // biome-ignore lint/suspicious/noExplicitAny: Errors can be anything\n custom: (func: (error: any) => boolean) => func,\n}\n"],"mappings":";;AAUA,MAAMA,kBAA0C,EAC9C,sBAAsB,MACvB;AACD,MAAM,iBACJ,GAAG,aAC2B;CAE9B,MAAM,IAAI,SAAS,QAAQ,QAAMC,IAAE;AACnC,KAAI,CAAC,EAAE,OAAQ,QAAO;AAKtB,QAF8B,OAAO,OAAO,iBAAiB,GAAG,EAAE;;AAKpE,MAAM,QAAQ,OACZ,IAAI,SAAe,YAAY,iBAAiB,SAAS,EAAE,GAAG,CAAC;AAEjE,MAAa,QAAQ,OACnB,MACA,GAAG,aACY;CACf,MAAM,iBAAiB,cAAc,GAAG,SAAS;CAEjD,MAAM,WAAW,OAAU,UAAU,MAAkB;AACrD,MAAI;AAEF,UADiB,MAAM,MAAM;WAEtB,OAAO;AACd,OACE,kBAEA,eAAe,eAAgB,MAAM,IACrC,UAAU,eAAe,YACzB;AACA,UAAM,KAAK,eAAe,SAAS,UAAU,EAAE,CAAC;AAChD,WAAO,SAAS,UAAU,EAAE;;AAG9B,SAAM;;;AAGV,QAAO,SAAS,EAAE;;AAGpB,MAAa,WAAW;CACtB,QAAQ,WAAmB,aAAqB;CAChD,SAAS,WAAmB,YAAoB,UAAU;CAC1D,cACG,OAAe,OAAO,OACtB,YACC,SAAS,UAAU,KAAK;CAC7B;AAED,MAAM,mBAAmB;CACvB;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CACtE;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAClE;AAGD,MAAM,mBAAmB;CACvB;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CACnD;AAcD,MAAa,iBAAiB;CAC5B,SAAS,WAAoB;CAC7B,aACG,GAAG,WACH,UAAqB;EACpB,MAAM,eAAe,MAClB,SAAS,SAAS;AACjB,OAAI,OAAO,SAAS,SAAU,QAAO;AACrC,OAAI,SAAS,SAAU,QAAO;AAC9B,OAAI,SAAS,SAAU,QAAO;AAC9B,UAAO;IACP,CACD,QAAQ,SAAS,CAAC,CAAC,KAAK;EAC3B,MAAM,SACJ,MAAM,UACN,MAAM,cACN,MAAM,UAAU,UAChB,MAAM,UAAU,cAChB;AACF,SAAO,aAAa,SAAS,OAAO;;CAExC,eAAe,UACb,eAAe,WAAW,SAAS,CAAC,MAAM;CAE5C,SAAS,SAAkC;CAC5C"}
@@ -1,15 +1,16 @@
1
+ //#region src/retry.d.ts
1
2
  type RetryConditionFunction = (error: any) => boolean;
2
3
  interface RetrySettings {
3
- maxRetries: number;
4
- interval: (retryCount: number) => number;
5
- retryCondition?: RetryConditionFunction;
6
- maxDelay?: number;
4
+ maxRetries: number;
5
+ interval: (retryCount: number) => number;
6
+ retryCondition?: RetryConditionFunction;
7
+ maxDelay?: number;
7
8
  }
8
9
  declare const retry: <T>(func: () => Promise<T>, ...settings: Array<RetrySettings | undefined>) => Promise<T>;
9
10
  declare const interval: {
10
- fixed: (delay: number) => (_retries: number) => number;
11
- linear: (delay: number) => (retries: number) => number;
12
- exponential: (delay: number, base?: number) => (retries: number) => number;
11
+ fixed: (delay: number) => (_retries: number) => number;
12
+ linear: (delay: number) => (retries: number) => number;
13
+ exponential: (delay: number, base?: number) => (retries: number) => number;
13
14
  };
14
15
  declare const clientErrorCodes: readonly [400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451];
15
16
  type ClientErrorCode = (typeof clientErrorCodes)[number];
@@ -17,18 +18,19 @@ declare const serverErrorCodes: readonly [500, 501, 502, 503, 504, 505, 506, 507
17
18
  type ServerErrorCode = (typeof serverErrorCodes)[number];
18
19
  type ErrorType = 'server' | 'client' | ServerErrorCode | ClientErrorCode;
19
20
  type HttpError = {
21
+ status?: number;
22
+ statusCode?: number;
23
+ response?: {
20
24
  status?: number;
21
25
  statusCode?: number;
22
- response?: {
23
- status?: number;
24
- statusCode?: number;
25
- };
26
+ };
26
27
  };
27
28
  declare const retryCondition: {
28
- always: (_error: unknown) => boolean;
29
- httpErrors: (...codes: ErrorType[]) => (error: HttpError) => boolean;
30
- serverErrors: (error: HttpError) => boolean;
31
- custom: (func: (error: any) => boolean) => (error: any) => boolean;
29
+ always: (_error: unknown) => boolean;
30
+ httpErrors: (...codes: ErrorType[]) => (error: HttpError) => boolean;
31
+ serverErrors: (error: HttpError) => boolean;
32
+ custom: (func: (error: any) => boolean) => (error: any) => boolean;
32
33
  };
33
-
34
- export { type RetryConditionFunction, type RetrySettings, interval, retry, retryCondition };
34
+ //#endregion
35
+ export { RetryConditionFunction, RetrySettings, interval, retry, retryCondition };
36
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/retry.ts"],"sourcesContent":[],"mappings":";KACY,sBAAA;AAAA,UAEK,aAAA,CAFiB;EAEjB,UAAA,EAAA,MAAa;EA0BjB,QAyBZ,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAxBqB,cAAA,CAAA,EAxBH,sBAwBG;EAAR,QAAA,CAAA,EAAA,MAAA;;AACC,cAFF,KAEE,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAAA,GAAA,GADD,OACC,CADO,CACP,CAAA,EAAA,GAAA,QAAA,EAAA,KAAA,CAAM,aAAN,GAAA,SAAA,CAAA,EAAA,GACZ,OADY,CACJ,CADI,CAAA;AACJ,cAwBE,QAxBF,EAAA;EAAR,KAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAAO,MAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAwBG,WAOZ,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,MAAA,EAAA,GAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAAA,MAAA;AAAA,CAAA;AAKS,cAHJ,gBAIc,EAAA,SAAW,CAAA,GAAA,EAAA,GAAgB,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;AAAA,KAA1C,eAAA,GAIK,CAAA,OAJqB,gBAIrB,CAAA,CAAA,MAAA,CAAA;AAAA,cAFJ,gBAGc,EAAA,SAAW,CAAA,GAAA,EAAA,GAAgB,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;AAAA,KAA1C,eAAA,GAES,CAAA,OAFiB,gBAE0B,CAAA,CAAA,MAAA,CAAA;AAAe,KAAnE,SAAA,GAES,QAAA,GAAA,QAAA,GAFyB,eAEzB,GAF2C,eAE3C;AASd,KATK,SAAA,GASQ;EAGE,MAAA,CAAA,EAAA,MAAA;EACH,UAAA,CAAA,EAAA,MAAA;EAiBY,QAAA,CAAA,EAAA;IAAS,MAAA,CAAA,EAAA,MAAA;;;;cArBpB;;yBAGE,wBACH;wBAiBY"}
package/dist/index.d.mts CHANGED
@@ -1,15 +1,16 @@
1
+ //#region src/retry.d.ts
1
2
  type RetryConditionFunction = (error: any) => boolean;
2
3
  interface RetrySettings {
3
- maxRetries: number;
4
- interval: (retryCount: number) => number;
5
- retryCondition?: RetryConditionFunction;
6
- maxDelay?: number;
4
+ maxRetries: number;
5
+ interval: (retryCount: number) => number;
6
+ retryCondition?: RetryConditionFunction;
7
+ maxDelay?: number;
7
8
  }
8
9
  declare const retry: <T>(func: () => Promise<T>, ...settings: Array<RetrySettings | undefined>) => Promise<T>;
9
10
  declare const interval: {
10
- fixed: (delay: number) => (_retries: number) => number;
11
- linear: (delay: number) => (retries: number) => number;
12
- exponential: (delay: number, base?: number) => (retries: number) => number;
11
+ fixed: (delay: number) => (_retries: number) => number;
12
+ linear: (delay: number) => (retries: number) => number;
13
+ exponential: (delay: number, base?: number) => (retries: number) => number;
13
14
  };
14
15
  declare const clientErrorCodes: readonly [400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451];
15
16
  type ClientErrorCode = (typeof clientErrorCodes)[number];
@@ -17,18 +18,19 @@ declare const serverErrorCodes: readonly [500, 501, 502, 503, 504, 505, 506, 507
17
18
  type ServerErrorCode = (typeof serverErrorCodes)[number];
18
19
  type ErrorType = 'server' | 'client' | ServerErrorCode | ClientErrorCode;
19
20
  type HttpError = {
21
+ status?: number;
22
+ statusCode?: number;
23
+ response?: {
20
24
  status?: number;
21
25
  statusCode?: number;
22
- response?: {
23
- status?: number;
24
- statusCode?: number;
25
- };
26
+ };
26
27
  };
27
28
  declare const retryCondition: {
28
- always: (_error: unknown) => boolean;
29
- httpErrors: (...codes: ErrorType[]) => (error: HttpError) => boolean;
30
- serverErrors: (error: HttpError) => boolean;
31
- custom: (func: (error: any) => boolean) => (error: any) => boolean;
29
+ always: (_error: unknown) => boolean;
30
+ httpErrors: (...codes: ErrorType[]) => (error: HttpError) => boolean;
31
+ serverErrors: (error: HttpError) => boolean;
32
+ custom: (func: (error: any) => boolean) => (error: any) => boolean;
32
33
  };
33
-
34
- export { type RetryConditionFunction, type RetrySettings, interval, retry, retryCondition };
34
+ //#endregion
35
+ export { RetryConditionFunction, RetrySettings, interval, retry, retryCondition };
36
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/retry.ts"],"sourcesContent":[],"mappings":";KACY,sBAAA;AAAA,UAEK,aAAA,CAFiB;EAEjB,UAAA,EAAA,MAAa;EA0BjB,QAyBZ,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAxBqB,cAAA,CAAA,EAxBH,sBAwBG;EAAR,QAAA,CAAA,EAAA,MAAA;;AACC,cAFF,KAEE,EAAA,CAAA,CAAA,CAAA,CAAA,IAAA,EAAA,GAAA,GADD,OACC,CADO,CACP,CAAA,EAAA,GAAA,QAAA,EAAA,KAAA,CAAM,aAAN,GAAA,SAAA,CAAA,EAAA,GACZ,OADY,CACJ,CADI,CAAA;AACJ,cAwBE,QAxBF,EAAA;EAAR,KAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAAO,MAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,GAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAAA,MAAA;EAwBG,WAOZ,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,IAAA,CAAA,EAAA,MAAA,EAAA,GAAA,CAAA,OAAA,EAAA,MAAA,EAAA,GAAA,MAAA;AAAA,CAAA;AAKS,cAHJ,gBAIc,EAAA,SAAW,CAAA,GAAA,EAAA,GAAgB,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;AAAA,KAA1C,eAAA,GAIK,CAAA,OAJqB,gBAIrB,CAAA,CAAA,MAAA,CAAA;AAAA,cAFJ,gBAGc,EAAA,SAAW,CAAA,GAAA,EAAA,GAAgB,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,EAAA,GAAA,CAAA;AAAA,KAA1C,eAAA,GAES,CAAA,OAFiB,gBAE0B,CAAA,CAAA,MAAA,CAAA;AAAe,KAAnE,SAAA,GAES,QAAA,GAAA,QAAA,GAFyB,eAEzB,GAF2C,eAE3C;AASd,KATK,SAAA,GASQ;EAGE,MAAA,CAAA,EAAA,MAAA;EACH,UAAA,CAAA,EAAA,MAAA;EAiBY,QAAA,CAAA,EAAA;IAAS,MAAA,CAAA,EAAA,MAAA;;;;cArBpB;;yBAGE,wBACH;wBAiBY"}
package/dist/index.mjs CHANGED
@@ -1,98 +1,91 @@
1
- // src/retry.ts
2
- var defaultSettings = {
3
- retryCondition: () => true
1
+ //#region src/retry.ts
2
+ const defaultSettings = { retryCondition: () => true };
3
+ const mergeSettings = (...settings) => {
4
+ const s = settings.filter((s$1) => s$1);
5
+ if (!s.length) return void 0;
6
+ return Object.assign(defaultSettings, ...s);
4
7
  };
5
- var mergeSettings = (...settings) => {
6
- const s = settings.filter((s2) => s2);
7
- if (!s.length) return void 0;
8
- const merged = Object.assign(defaultSettings, ...s);
9
- return merged;
8
+ const wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
9
+ const retry = async (func, ...settings) => {
10
+ const mergedSettings = mergeSettings(...settings);
11
+ const makeCall = async (retries = 0) => {
12
+ try {
13
+ return await func();
14
+ } catch (error) {
15
+ if (mergedSettings && mergedSettings.retryCondition(error) && retries < mergedSettings.maxRetries) {
16
+ await wait(mergedSettings.interval(retries + 1));
17
+ return makeCall(retries + 1);
18
+ }
19
+ throw error;
20
+ }
21
+ };
22
+ return makeCall(0);
10
23
  };
11
- var wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
12
- var retry = async (func, ...settings) => {
13
- const mergedSettings = mergeSettings(...settings);
14
- const makeCall = async (retries = 0) => {
15
- try {
16
- const response = await func();
17
- return response;
18
- } catch (error) {
19
- if (mergedSettings && // biome-ignore lint/style/noNonNullAssertion: Will be set by defaultSettings
20
- mergedSettings.retryCondition(error) && retries < mergedSettings.maxRetries) {
21
- await wait(mergedSettings.interval(retries + 1));
22
- return makeCall(retries + 1);
23
- }
24
- throw error;
25
- }
26
- };
27
- return makeCall(0);
24
+ const interval = {
25
+ fixed: (delay) => (_retries) => delay,
26
+ linear: (delay) => (retries) => retries * delay,
27
+ exponential: (delay, base = 2) => (retries) => base ** (retries - 1) * delay
28
28
  };
29
- var interval = {
30
- fixed: (delay) => (_retries) => delay,
31
- linear: (delay) => (retries) => retries * delay,
32
- exponential: (delay, base = 2) => (retries) => base ** (retries - 1) * delay
33
- };
34
- var clientErrorCodes = [
35
- 400,
36
- 401,
37
- 402,
38
- 403,
39
- 404,
40
- 405,
41
- 406,
42
- 407,
43
- 408,
44
- 409,
45
- 410,
46
- 411,
47
- 412,
48
- 413,
49
- 414,
50
- 415,
51
- 416,
52
- 417,
53
- 418,
54
- 421,
55
- 422,
56
- 423,
57
- 424,
58
- 425,
59
- 426,
60
- 428,
61
- 429,
62
- 431,
63
- 451
29
+ const clientErrorCodes = [
30
+ 400,
31
+ 401,
32
+ 402,
33
+ 403,
34
+ 404,
35
+ 405,
36
+ 406,
37
+ 407,
38
+ 408,
39
+ 409,
40
+ 410,
41
+ 411,
42
+ 412,
43
+ 413,
44
+ 414,
45
+ 415,
46
+ 416,
47
+ 417,
48
+ 418,
49
+ 421,
50
+ 422,
51
+ 423,
52
+ 424,
53
+ 425,
54
+ 426,
55
+ 428,
56
+ 429,
57
+ 431,
58
+ 451
64
59
  ];
65
- var serverErrorCodes = [
66
- 500,
67
- 501,
68
- 502,
69
- 503,
70
- 504,
71
- 505,
72
- 506,
73
- 507,
74
- 508,
75
- 510,
76
- 511
60
+ const serverErrorCodes = [
61
+ 500,
62
+ 501,
63
+ 502,
64
+ 503,
65
+ 504,
66
+ 505,
67
+ 506,
68
+ 507,
69
+ 508,
70
+ 510,
71
+ 511
77
72
  ];
78
- var retryCondition = {
79
- always: (_error) => true,
80
- httpErrors: (...codes) => (error) => {
81
- const captureCodes = codes.flatMap((code) => {
82
- if (typeof code === "number") return code;
83
- if (code === "client") return clientErrorCodes;
84
- if (code === "server") return serverErrorCodes;
85
- return 500;
86
- }).filter((code) => !!code);
87
- const status = error.status || error.statusCode || error.response?.status || error.response?.statusCode || 0;
88
- return captureCodes.includes(status);
89
- },
90
- serverErrors: (error) => retryCondition.httpErrors("server")(error),
91
- // biome-ignore lint/suspicious/noExplicitAny: Errors can be anything
92
- custom: (func) => func
93
- };
94
- export {
95
- interval,
96
- retry,
97
- retryCondition
73
+ const retryCondition = {
74
+ always: (_error) => true,
75
+ httpErrors: (...codes) => (error) => {
76
+ const captureCodes = codes.flatMap((code) => {
77
+ if (typeof code === "number") return code;
78
+ if (code === "client") return clientErrorCodes;
79
+ if (code === "server") return serverErrorCodes;
80
+ return 500;
81
+ }).filter((code) => !!code);
82
+ const status = error.status || error.statusCode || error.response?.status || error.response?.statusCode || 0;
83
+ return captureCodes.includes(status);
84
+ },
85
+ serverErrors: (error) => retryCondition.httpErrors("server")(error),
86
+ custom: (func) => func
98
87
  };
88
+
89
+ //#endregion
90
+ export { interval, retry, retryCondition };
91
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["defaultSettings: Partial<RetrySettings>","s"],"sources":["../src/retry.ts"],"sourcesContent":["// biome-ignore lint/suspicious/noExplicitAny: Errors can be anything\nexport type RetryConditionFunction = (error: any) => boolean\n\nexport interface RetrySettings {\n maxRetries: number\n interval: (retryCount: number) => number\n retryCondition?: RetryConditionFunction\n maxDelay?: number\n}\n\nconst defaultSettings: Partial<RetrySettings> = {\n retryCondition: () => true,\n}\nconst mergeSettings = (\n ...settings: Array<RetrySettings | undefined>\n): RetrySettings | undefined => {\n // remove undefineds, return if no settings passed\n const s = settings.filter((s) => s) as RetrySettings[]\n if (!s.length) return undefined\n\n // merge settings with priority to the latest\n const merged: RetrySettings = Object.assign(defaultSettings, ...s)\n\n return merged\n}\n\nconst wait = (ms: number) =>\n new Promise<void>((resolve) => setTimeout(() => resolve(), ms))\n\nexport const retry = async <T>(\n func: () => Promise<T>,\n ...settings: Array<RetrySettings | undefined>\n): Promise<T> => {\n const mergedSettings = mergeSettings(...settings)\n\n const makeCall = async <T>(retries = 0): Promise<T> => {\n try {\n const response = await func()\n return response as T\n } catch (error) {\n if (\n mergedSettings &&\n // biome-ignore lint/style/noNonNullAssertion: Will be set by defaultSettings\n mergedSettings.retryCondition!(error) &&\n retries < mergedSettings.maxRetries\n ) {\n await wait(mergedSettings.interval(retries + 1))\n return makeCall(retries + 1)\n }\n\n throw error\n }\n }\n return makeCall(0)\n}\n\nexport const interval = {\n fixed: (delay: number) => (_retries: number) => delay,\n linear: (delay: number) => (retries: number) => retries * delay,\n exponential:\n (delay: number, base = 2) =>\n (retries: number) =>\n base ** (retries - 1) * delay,\n}\n\nconst clientErrorCodes = [\n 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414,\n 415, 416, 417, 418, 421, 422, 423, 424, 425, 426, 428, 429, 431, 451,\n] as const\ntype ClientErrorCode = (typeof clientErrorCodes)[number]\n\nconst serverErrorCodes = [\n 500, 501, 502, 503, 504, 505, 506, 507, 508, 510, 511,\n] as const\ntype ServerErrorCode = (typeof serverErrorCodes)[number]\n\ntype ErrorType = 'server' | 'client' | ServerErrorCode | ClientErrorCode\n\ntype HttpError = {\n status?: number\n statusCode?: number\n response?: {\n status?: number\n statusCode?: number\n }\n}\n\nexport const retryCondition = {\n always: (_error: unknown) => true,\n httpErrors:\n (...codes: ErrorType[]) =>\n (error: HttpError) => {\n const captureCodes = codes\n .flatMap((code) => {\n if (typeof code === 'number') return code\n if (code === 'client') return clientErrorCodes\n if (code === 'server') return serverErrorCodes\n return 500\n })\n .filter((code) => !!code) as number[]\n const status =\n error.status ||\n error.statusCode ||\n error.response?.status ||\n error.response?.statusCode ||\n 0\n return captureCodes.includes(status)\n },\n serverErrors: (error: HttpError) =>\n retryCondition.httpErrors('server')(error),\n // biome-ignore lint/suspicious/noExplicitAny: Errors can be anything\n custom: (func: (error: any) => boolean) => func,\n}\n"],"mappings":";AAUA,MAAMA,kBAA0C,EAC9C,sBAAsB,MACvB;AACD,MAAM,iBACJ,GAAG,aAC2B;CAE9B,MAAM,IAAI,SAAS,QAAQ,QAAMC,IAAE;AACnC,KAAI,CAAC,EAAE,OAAQ,QAAO;AAKtB,QAF8B,OAAO,OAAO,iBAAiB,GAAG,EAAE;;AAKpE,MAAM,QAAQ,OACZ,IAAI,SAAe,YAAY,iBAAiB,SAAS,EAAE,GAAG,CAAC;AAEjE,MAAa,QAAQ,OACnB,MACA,GAAG,aACY;CACf,MAAM,iBAAiB,cAAc,GAAG,SAAS;CAEjD,MAAM,WAAW,OAAU,UAAU,MAAkB;AACrD,MAAI;AAEF,UADiB,MAAM,MAAM;WAEtB,OAAO;AACd,OACE,kBAEA,eAAe,eAAgB,MAAM,IACrC,UAAU,eAAe,YACzB;AACA,UAAM,KAAK,eAAe,SAAS,UAAU,EAAE,CAAC;AAChD,WAAO,SAAS,UAAU,EAAE;;AAG9B,SAAM;;;AAGV,QAAO,SAAS,EAAE;;AAGpB,MAAa,WAAW;CACtB,QAAQ,WAAmB,aAAqB;CAChD,SAAS,WAAmB,YAAoB,UAAU;CAC1D,cACG,OAAe,OAAO,OACtB,YACC,SAAS,UAAU,KAAK;CAC7B;AAED,MAAM,mBAAmB;CACvB;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CACtE;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAClE;AAGD,MAAM,mBAAmB;CACvB;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CAAK;CACnD;AAcD,MAAa,iBAAiB;CAC5B,SAAS,WAAoB;CAC7B,aACG,GAAG,WACH,UAAqB;EACpB,MAAM,eAAe,MAClB,SAAS,SAAS;AACjB,OAAI,OAAO,SAAS,SAAU,QAAO;AACrC,OAAI,SAAS,SAAU,QAAO;AAC9B,OAAI,SAAS,SAAU,QAAO;AAC9B,UAAO;IACP,CACD,QAAQ,SAAS,CAAC,CAAC,KAAK;EAC3B,MAAM,SACJ,MAAM,UACN,MAAM,cACN,MAAM,UAAU,UAChB,MAAM,UAAU,cAChB;AACF,SAAO,aAAa,SAAS,OAAO;;CAExC,eAAe,UACb,eAAe,WAAW,SAAS,CAAC,MAAM;CAE5C,SAAS,SAAkC;CAC5C"}
package/package.json CHANGED
@@ -1,15 +1,27 @@
1
1
  {
2
2
  "name": "@sebspark/retry",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "license": "Apache-2.0",
5
- "main": "dist/index.js",
5
+ "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
7
- "types": "dist/index.d.ts",
7
+ "types": "dist/index.d.mts",
8
+ "exports": {
9
+ ".": {
10
+ "import": {
11
+ "types": "./dist/index.d.mts",
12
+ "default": "./dist/index.mjs"
13
+ },
14
+ "require": {
15
+ "types": "./dist/index.d.cts",
16
+ "default": "./dist/index.cjs"
17
+ }
18
+ }
19
+ },
8
20
  "files": [
9
21
  "dist"
10
22
  ],
11
23
  "scripts": {
12
- "build": "tsup-node src/index.ts --format esm,cjs --target node22 --dts",
24
+ "build": "spark-build src/index.ts --format=esm --format=cjs",
13
25
  "dev": "tsc --watch --noEmit",
14
26
  "lint": "biome lint .",
15
27
  "test": "vitest run --passWithNoTests --coverage",
package/dist/index.js DELETED
@@ -1,127 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- interval: () => interval,
24
- retry: () => retry,
25
- retryCondition: () => retryCondition
26
- });
27
- module.exports = __toCommonJS(index_exports);
28
-
29
- // src/retry.ts
30
- var defaultSettings = {
31
- retryCondition: () => true
32
- };
33
- var mergeSettings = (...settings) => {
34
- const s = settings.filter((s2) => s2);
35
- if (!s.length) return void 0;
36
- const merged = Object.assign(defaultSettings, ...s);
37
- return merged;
38
- };
39
- var wait = (ms) => new Promise((resolve) => setTimeout(() => resolve(), ms));
40
- var retry = async (func, ...settings) => {
41
- const mergedSettings = mergeSettings(...settings);
42
- const makeCall = async (retries = 0) => {
43
- try {
44
- const response = await func();
45
- return response;
46
- } catch (error) {
47
- if (mergedSettings && // biome-ignore lint/style/noNonNullAssertion: Will be set by defaultSettings
48
- mergedSettings.retryCondition(error) && retries < mergedSettings.maxRetries) {
49
- await wait(mergedSettings.interval(retries + 1));
50
- return makeCall(retries + 1);
51
- }
52
- throw error;
53
- }
54
- };
55
- return makeCall(0);
56
- };
57
- var interval = {
58
- fixed: (delay) => (_retries) => delay,
59
- linear: (delay) => (retries) => retries * delay,
60
- exponential: (delay, base = 2) => (retries) => base ** (retries - 1) * delay
61
- };
62
- var clientErrorCodes = [
63
- 400,
64
- 401,
65
- 402,
66
- 403,
67
- 404,
68
- 405,
69
- 406,
70
- 407,
71
- 408,
72
- 409,
73
- 410,
74
- 411,
75
- 412,
76
- 413,
77
- 414,
78
- 415,
79
- 416,
80
- 417,
81
- 418,
82
- 421,
83
- 422,
84
- 423,
85
- 424,
86
- 425,
87
- 426,
88
- 428,
89
- 429,
90
- 431,
91
- 451
92
- ];
93
- var serverErrorCodes = [
94
- 500,
95
- 501,
96
- 502,
97
- 503,
98
- 504,
99
- 505,
100
- 506,
101
- 507,
102
- 508,
103
- 510,
104
- 511
105
- ];
106
- var retryCondition = {
107
- always: (_error) => true,
108
- httpErrors: (...codes) => (error) => {
109
- const captureCodes = codes.flatMap((code) => {
110
- if (typeof code === "number") return code;
111
- if (code === "client") return clientErrorCodes;
112
- if (code === "server") return serverErrorCodes;
113
- return 500;
114
- }).filter((code) => !!code);
115
- const status = error.status || error.statusCode || error.response?.status || error.response?.statusCode || 0;
116
- return captureCodes.includes(status);
117
- },
118
- serverErrors: (error) => retryCondition.httpErrors("server")(error),
119
- // biome-ignore lint/suspicious/noExplicitAny: Errors can be anything
120
- custom: (func) => func
121
- };
122
- // Annotate the CommonJS export names for ESM import in node:
123
- 0 && (module.exports = {
124
- interval,
125
- retry,
126
- retryCondition
127
- });