@ls-stack/utils 3.20.0 → 3.22.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.
@@ -32,7 +32,7 @@
32
32
  - [objUtils](objUtils.md)
33
33
  - [parallelAsyncCalls](parallelAsyncCalls/README.md)
34
34
  - [promiseUtils](promiseUtils/README.md)
35
- - [retryOnError](retryOnError.md)
35
+ - [retryOnError](retryOnError/README.md)
36
36
  - [runShellCmd](runShellCmd/README.md)
37
37
  - [safeJson](safeJson.md)
38
38
  - [saferTyping](saferTyping.md)
@@ -15,7 +15,7 @@
15
15
  ### concurrentCalls()
16
16
 
17
17
  ```ts
18
- function concurrentCalls<R, E>(): ConcurrentCalls<R, E>;
18
+ function concurrentCalls<R>(): ConcurrentCalls<R, Error>;
19
19
  ```
20
20
 
21
21
  Defined in: [packages/utils/src/concurrentCalls.ts:180](https://github.com/lucasols/utils/blob/main/packages/utils/src/concurrentCalls.ts#L180)
@@ -30,22 +30,16 @@ Executes multiple asynchronous calls concurrently and collects the results in a
30
30
 
31
31
  The type of the result value.
32
32
 
33
- ##### E
34
-
35
- `E` *extends* `Error` = `Error`
36
-
37
- The type of the error.
38
-
39
33
  #### Returns
40
34
 
41
- [`ConcurrentCalls`](-internal-.md#concurrentcalls)\<`R`, `E`\>
35
+ [`ConcurrentCalls`](-internal-.md#concurrentcalls)\<`R`, `Error`\>
42
36
 
43
37
  ***
44
38
 
45
39
  ### concurrentCallsWithMetadata()
46
40
 
47
41
  ```ts
48
- function concurrentCallsWithMetadata<M, R, E>(): ConcurrentCallsWithMetadata<M, R, E>;
42
+ function concurrentCallsWithMetadata<M, R>(): ConcurrentCallsWithMetadata<M, R, Error>;
49
43
  ```
50
44
 
51
45
  Defined in: [packages/utils/src/concurrentCalls.ts:373](https://github.com/lucasols/utils/blob/main/packages/utils/src/concurrentCalls.ts#L373)
@@ -66,12 +60,6 @@ The type of the call metadata.
66
60
 
67
61
  The type of the result value.
68
62
 
69
- ##### E
70
-
71
- `E` *extends* `Error` = `Error`
72
-
73
- The type of the error from individual Result objects.
74
-
75
63
  #### Returns
76
64
 
77
- [`ConcurrentCallsWithMetadata`](-internal-.md#concurrentcallswithmetadata)\<`M`, `R`, `E`\>
65
+ [`ConcurrentCallsWithMetadata`](-internal-.md#concurrentcallswithmetadata)\<`M`, `R`, `Error`\>
package/docs/modules.md CHANGED
@@ -32,7 +32,7 @@
32
32
  - [objUtils](objUtils.md)
33
33
  - [parallelAsyncCalls](parallelAsyncCalls/README.md)
34
34
  - [promiseUtils](promiseUtils/README.md)
35
- - [retryOnError](retryOnError.md)
35
+ - [retryOnError](retryOnError/README.md)
36
36
  - [runShellCmd](runShellCmd/README.md)
37
37
  - [safeJson](safeJson.md)
38
38
  - [saferTyping](saferTyping.md)
@@ -0,0 +1,71 @@
1
+ [**@ls-stack/utils**](../README.md)
2
+
3
+ ***
4
+
5
+ [@ls-stack/utils](../modules.md) / [retryOnError](README.md) / \<internal\>
6
+
7
+ # \<internal\>
8
+
9
+ ## Type Aliases
10
+
11
+ ### RetryOptions
12
+
13
+ ```ts
14
+ type RetryOptions = object;
15
+ ```
16
+
17
+ Defined in: [packages/utils/src/retryOnError.ts:6](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L6)
18
+
19
+ Configuration options for retryOnError function.
20
+
21
+ #### Properties
22
+
23
+ ##### debugId?
24
+
25
+ ```ts
26
+ optional debugId: string;
27
+ ```
28
+
29
+ Defined in: [packages/utils/src/retryOnError.ts:15](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L15)
30
+
31
+ Optional ID for debug logging
32
+
33
+ ##### delayBetweenRetriesMs?
34
+
35
+ ```ts
36
+ optional delayBetweenRetriesMs: number | (retry) => number;
37
+ ```
38
+
39
+ Defined in: [packages/utils/src/retryOnError.ts:8](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L8)
40
+
41
+ Delay between retries in milliseconds or function returning delay
42
+
43
+ ##### retryCondition()?
44
+
45
+ ```ts
46
+ optional retryCondition: (error, lastAttempt) => boolean;
47
+ ```
48
+
49
+ Defined in: [packages/utils/src/retryOnError.ts:10](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L10)
50
+
51
+ Function to determine if retry should happen, receives error and duration of last attempt
52
+
53
+ ###### Parameters
54
+
55
+ ###### error
56
+
57
+ `unknown`
58
+
59
+ ###### lastAttempt
60
+
61
+ ###### duration
62
+
63
+ `number`
64
+
65
+ ###### retry
66
+
67
+ `number`
68
+
69
+ ###### Returns
70
+
71
+ `boolean`
@@ -0,0 +1,81 @@
1
+ [**@ls-stack/utils**](../README.md)
2
+
3
+ ***
4
+
5
+ [@ls-stack/utils](../modules.md) / retryOnError
6
+
7
+ # retryOnError
8
+
9
+ ## Modules
10
+
11
+ - [\<internal\>](-internal-.md)
12
+
13
+ ## Functions
14
+
15
+ ### retryOnError()
16
+
17
+ ```ts
18
+ function retryOnError<T>(
19
+ fn,
20
+ maxRetries,
21
+ options,
22
+ retry,
23
+ originalMaxRetries): Promise<T>;
24
+ ```
25
+
26
+ Defined in: [packages/utils/src/retryOnError.ts:36](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L36)
27
+
28
+ Retries a function on error with configurable retry logic.
29
+
30
+ #### Type Parameters
31
+
32
+ ##### T
33
+
34
+ `T`
35
+
36
+ #### Parameters
37
+
38
+ ##### fn
39
+
40
+ (`ctx`) => `Promise`\<`T`\>
41
+
42
+ Function to retry that receives context with retry count
43
+
44
+ ##### maxRetries
45
+
46
+ `number`
47
+
48
+ Maximum number of retries
49
+
50
+ ##### options
51
+
52
+ [`RetryOptions`](-internal-.md#retryoptions) = `{}`
53
+
54
+ Configuration options
55
+
56
+ ##### retry
57
+
58
+ `number` = `0`
59
+
60
+ ##### originalMaxRetries
61
+
62
+ `number` = `maxRetries`
63
+
64
+ #### Returns
65
+
66
+ `Promise`\<`T`\>
67
+
68
+ Promise resolving to the function result or rejecting with the final error
69
+
70
+ #### Example
71
+
72
+ ```ts
73
+ await retryOnError(
74
+ async (ctx) => {
75
+ console.log(`Attempt ${ctx.retry + 1}`);
76
+ return await fetchData();
77
+ },
78
+ 3,
79
+ { delayBetweenRetriesMs: 1000 }
80
+ );
81
+ ```
@@ -42,7 +42,7 @@ declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
42
42
  * @template R - The type of the result value.
43
43
  * @template E - The type of the error.
44
44
  */
45
- declare function concurrentCalls<R = unknown, E extends Error = Error>(): ConcurrentCalls<R, E>;
45
+ declare function concurrentCalls<R = unknown>(): ConcurrentCalls<R, Error>;
46
46
  declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error> {
47
47
  #private;
48
48
  add(...calls: {
@@ -72,6 +72,6 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
72
72
  * @template R - The type of the result value.
73
73
  * @template E - The type of the error from individual Result objects.
74
74
  */
75
- declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error>(): ConcurrentCallsWithMetadata<M, R, E>;
75
+ declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown>(): ConcurrentCallsWithMetadata<M, R, Error>;
76
76
 
77
77
  export { concurrentCalls, concurrentCallsWithMetadata };
@@ -42,7 +42,7 @@ declare class ConcurrentCalls<R = unknown, E extends Error = Error> {
42
42
  * @template R - The type of the result value.
43
43
  * @template E - The type of the error.
44
44
  */
45
- declare function concurrentCalls<R = unknown, E extends Error = Error>(): ConcurrentCalls<R, E>;
45
+ declare function concurrentCalls<R = unknown>(): ConcurrentCalls<R, Error>;
46
46
  declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error> {
47
47
  #private;
48
48
  add(...calls: {
@@ -72,6 +72,6 @@ declare class ConcurrentCallsWithMetadata<M extends ValidMetadata, R = unknown,
72
72
  * @template R - The type of the result value.
73
73
  * @template E - The type of the error from individual Result objects.
74
74
  */
75
- declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown, E extends Error = Error>(): ConcurrentCallsWithMetadata<M, R, E>;
75
+ declare function concurrentCallsWithMetadata<M extends ValidMetadata, R = unknown>(): ConcurrentCallsWithMetadata<M, R, Error>;
76
76
 
77
77
  export { concurrentCalls, concurrentCallsWithMetadata };
@@ -30,33 +30,23 @@ function sleep(ms) {
30
30
  }
31
31
 
32
32
  // src/retryOnError.ts
33
- async function retryOnError(fn, maxRetries, options = {}, retry = 0) {
34
- const {
35
- delayBetweenRetriesMs,
36
- retryCondition,
37
- maxErrorDurationMs = 400
38
- } = options;
33
+ async function retryOnError(fn, maxRetries, options = {}, retry = 0, originalMaxRetries = maxRetries) {
34
+ const { delayBetweenRetriesMs, retryCondition } = options;
39
35
  if (options.debugId) {
40
36
  if (retry > 0) {
41
37
  console.info(
42
- `Retrying ${options.debugId} (retry ${retry}/${maxRetries}) after error`
38
+ `Retrying ${options.debugId} (retry ${retry}/${originalMaxRetries}) after error`
43
39
  );
44
40
  }
45
41
  }
46
42
  const startTime = Date.now();
47
43
  try {
48
- return await fn();
44
+ return await fn({ retry });
49
45
  } catch (error) {
50
46
  if (maxRetries > 0) {
51
47
  const errorDuration = Date.now() - startTime;
52
- const shouldRetry = retryCondition ? retryCondition(error) : true;
53
- let maxErrorDurationMsToUse = maxErrorDurationMs;
54
- if (typeof shouldRetry === "boolean") {
55
- if (!shouldRetry) throw error;
56
- } else {
57
- maxErrorDurationMsToUse = shouldRetry.maxErrorDurationMs;
58
- }
59
- if (errorDuration > maxErrorDurationMsToUse) {
48
+ const shouldRetry = retryCondition ? retryCondition(error, { duration: errorDuration, retry }) : true;
49
+ if (!shouldRetry) {
60
50
  throw error;
61
51
  }
62
52
  if (delayBetweenRetriesMs) {
@@ -64,7 +54,13 @@ async function retryOnError(fn, maxRetries, options = {}, retry = 0) {
64
54
  typeof delayBetweenRetriesMs === "function" ? delayBetweenRetriesMs(retry) : delayBetweenRetriesMs
65
55
  );
66
56
  }
67
- return retryOnError(fn, maxRetries - 1, options, retry + 1);
57
+ return retryOnError(
58
+ fn,
59
+ maxRetries - 1,
60
+ options,
61
+ retry + 1,
62
+ originalMaxRetries
63
+ );
68
64
  } else {
69
65
  throw error;
70
66
  }
@@ -1,10 +1,38 @@
1
- declare function retryOnError<T>(fn: () => Promise<T>, maxRetries: number, options?: {
1
+ /**
2
+ * Configuration options for retryOnError function.
3
+ */
4
+ type RetryOptions = {
5
+ /** Delay between retries in milliseconds or function returning delay */
2
6
  delayBetweenRetriesMs?: number | ((retry: number) => number);
3
- retryCondition?: (error: unknown) => boolean | {
4
- maxErrorDurationMs: number;
5
- };
6
- maxErrorDurationMs?: number;
7
+ /** Function to determine if retry should happen, receives error and duration of last attempt */
8
+ retryCondition?: (error: unknown, lastAttempt: {
9
+ duration: number;
10
+ retry: number;
11
+ }) => boolean;
12
+ /** Optional ID for debug logging */
7
13
  debugId?: string;
8
- }, retry?: number): Promise<T>;
14
+ };
15
+ /**
16
+ * Retries a function on error with configurable retry logic.
17
+ *
18
+ * @param fn - Function to retry that receives context with retry count
19
+ * @param maxRetries - Maximum number of retries
20
+ * @param options - Configuration options
21
+ * @returns Promise resolving to the function result or rejecting with the final error
22
+ *
23
+ * @example
24
+ * await retryOnError(
25
+ * async (ctx) => {
26
+ * console.log(`Attempt ${ctx.retry + 1}`);
27
+ * return await fetchData();
28
+ * },
29
+ * 3,
30
+ * { delayBetweenRetriesMs: 1000 }
31
+ * );
32
+ */
33
+ declare function retryOnError<T>(fn: (ctx: {
34
+ /** Current retry count, (0 for first attempt) */
35
+ retry: number;
36
+ }) => Promise<T>, maxRetries: number, options?: RetryOptions, retry?: number, originalMaxRetries?: number): Promise<T>;
9
37
 
10
38
  export { retryOnError };
@@ -1,10 +1,38 @@
1
- declare function retryOnError<T>(fn: () => Promise<T>, maxRetries: number, options?: {
1
+ /**
2
+ * Configuration options for retryOnError function.
3
+ */
4
+ type RetryOptions = {
5
+ /** Delay between retries in milliseconds or function returning delay */
2
6
  delayBetweenRetriesMs?: number | ((retry: number) => number);
3
- retryCondition?: (error: unknown) => boolean | {
4
- maxErrorDurationMs: number;
5
- };
6
- maxErrorDurationMs?: number;
7
+ /** Function to determine if retry should happen, receives error and duration of last attempt */
8
+ retryCondition?: (error: unknown, lastAttempt: {
9
+ duration: number;
10
+ retry: number;
11
+ }) => boolean;
12
+ /** Optional ID for debug logging */
7
13
  debugId?: string;
8
- }, retry?: number): Promise<T>;
14
+ };
15
+ /**
16
+ * Retries a function on error with configurable retry logic.
17
+ *
18
+ * @param fn - Function to retry that receives context with retry count
19
+ * @param maxRetries - Maximum number of retries
20
+ * @param options - Configuration options
21
+ * @returns Promise resolving to the function result or rejecting with the final error
22
+ *
23
+ * @example
24
+ * await retryOnError(
25
+ * async (ctx) => {
26
+ * console.log(`Attempt ${ctx.retry + 1}`);
27
+ * return await fetchData();
28
+ * },
29
+ * 3,
30
+ * { delayBetweenRetriesMs: 1000 }
31
+ * );
32
+ */
33
+ declare function retryOnError<T>(fn: (ctx: {
34
+ /** Current retry count, (0 for first attempt) */
35
+ retry: number;
36
+ }) => Promise<T>, maxRetries: number, options?: RetryOptions, retry?: number, originalMaxRetries?: number): Promise<T>;
9
37
 
10
38
  export { retryOnError };
@@ -3,33 +3,23 @@ import {
3
3
  } from "./chunk-5DZT3Z5Z.js";
4
4
 
5
5
  // src/retryOnError.ts
6
- async function retryOnError(fn, maxRetries, options = {}, retry = 0) {
7
- const {
8
- delayBetweenRetriesMs,
9
- retryCondition,
10
- maxErrorDurationMs = 400
11
- } = options;
6
+ async function retryOnError(fn, maxRetries, options = {}, retry = 0, originalMaxRetries = maxRetries) {
7
+ const { delayBetweenRetriesMs, retryCondition } = options;
12
8
  if (options.debugId) {
13
9
  if (retry > 0) {
14
10
  console.info(
15
- `Retrying ${options.debugId} (retry ${retry}/${maxRetries}) after error`
11
+ `Retrying ${options.debugId} (retry ${retry}/${originalMaxRetries}) after error`
16
12
  );
17
13
  }
18
14
  }
19
15
  const startTime = Date.now();
20
16
  try {
21
- return await fn();
17
+ return await fn({ retry });
22
18
  } catch (error) {
23
19
  if (maxRetries > 0) {
24
20
  const errorDuration = Date.now() - startTime;
25
- const shouldRetry = retryCondition ? retryCondition(error) : true;
26
- let maxErrorDurationMsToUse = maxErrorDurationMs;
27
- if (typeof shouldRetry === "boolean") {
28
- if (!shouldRetry) throw error;
29
- } else {
30
- maxErrorDurationMsToUse = shouldRetry.maxErrorDurationMs;
31
- }
32
- if (errorDuration > maxErrorDurationMsToUse) {
21
+ const shouldRetry = retryCondition ? retryCondition(error, { duration: errorDuration, retry }) : true;
22
+ if (!shouldRetry) {
33
23
  throw error;
34
24
  }
35
25
  if (delayBetweenRetriesMs) {
@@ -37,7 +27,13 @@ async function retryOnError(fn, maxRetries, options = {}, retry = 0) {
37
27
  typeof delayBetweenRetriesMs === "function" ? delayBetweenRetriesMs(retry) : delayBetweenRetriesMs
38
28
  );
39
29
  }
40
- return retryOnError(fn, maxRetries - 1, options, retry + 1);
30
+ return retryOnError(
31
+ fn,
32
+ maxRetries - 1,
33
+ options,
34
+ retry + 1,
35
+ originalMaxRetries
36
+ );
41
37
  } else {
42
38
  throw error;
43
39
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ls-stack/utils",
3
3
  "description": "Universal TypeScript utilities for browser and Node.js",
4
- "version": "3.20.0",
4
+ "version": "3.22.0",
5
5
  "license": "MIT",
6
6
  "files": [
7
7
  "lib",
@@ -1,67 +0,0 @@
1
- [**@ls-stack/utils**](README.md)
2
-
3
- ***
4
-
5
- [@ls-stack/utils](modules.md) / retryOnError
6
-
7
- # retryOnError
8
-
9
- ## Functions
10
-
11
- ### retryOnError()
12
-
13
- ```ts
14
- function retryOnError<T>(
15
- fn,
16
- maxRetries,
17
- options,
18
- retry): Promise<T>;
19
- ```
20
-
21
- Defined in: [packages/utils/src/retryOnError.ts:3](https://github.com/lucasols/utils/blob/main/packages/utils/src/retryOnError.ts#L3)
22
-
23
- #### Type Parameters
24
-
25
- ##### T
26
-
27
- `T`
28
-
29
- #### Parameters
30
-
31
- ##### fn
32
-
33
- () => `Promise`\<`T`\>
34
-
35
- ##### maxRetries
36
-
37
- `number`
38
-
39
- ##### options
40
-
41
- ###### debugId?
42
-
43
- `string`
44
-
45
- ###### delayBetweenRetriesMs?
46
-
47
- `number` \| (`retry`) => `number`
48
-
49
- ###### maxErrorDurationMs?
50
-
51
- `number`
52
-
53
- ###### retryCondition?
54
-
55
- (`error`) =>
56
- \| `boolean`
57
- \| \{
58
- `maxErrorDurationMs`: `number`;
59
- \}
60
-
61
- ##### retry
62
-
63
- `number` = `0`
64
-
65
- #### Returns
66
-
67
- `Promise`\<`T`\>