lifecycleion 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +125 -0
  3. package/dist/index.cjs +7 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +5 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/arrays.cjs +95 -0
  10. package/dist/lib/arrays.cjs.map +1 -0
  11. package/dist/lib/arrays.d.cts +15 -0
  12. package/dist/lib/arrays.d.ts +15 -0
  13. package/dist/lib/arrays.js +63 -0
  14. package/dist/lib/arrays.js.map +1 -0
  15. package/dist/lib/ascii-tables/index.cjs +642 -0
  16. package/dist/lib/ascii-tables/index.cjs.map +1 -0
  17. package/dist/lib/ascii-tables/index.d.cts +66 -0
  18. package/dist/lib/ascii-tables/index.d.ts +66 -0
  19. package/dist/lib/ascii-tables/index.js +603 -0
  20. package/dist/lib/ascii-tables/index.js.map +1 -0
  21. package/dist/lib/clamp.cjs +41 -0
  22. package/dist/lib/clamp.cjs.map +1 -0
  23. package/dist/lib/clamp.d.cts +26 -0
  24. package/dist/lib/clamp.d.ts +26 -0
  25. package/dist/lib/clamp.js +15 -0
  26. package/dist/lib/clamp.js.map +1 -0
  27. package/dist/lib/constants.cjs +73 -0
  28. package/dist/lib/constants.cjs.map +1 -0
  29. package/dist/lib/constants.d.cts +17 -0
  30. package/dist/lib/constants.d.ts +17 -0
  31. package/dist/lib/constants.js +34 -0
  32. package/dist/lib/constants.js.map +1 -0
  33. package/dist/lib/curly-brackets.cjs +77 -0
  34. package/dist/lib/curly-brackets.cjs.map +1 -0
  35. package/dist/lib/curly-brackets.d.cts +17 -0
  36. package/dist/lib/curly-brackets.d.ts +17 -0
  37. package/dist/lib/curly-brackets.js +52 -0
  38. package/dist/lib/curly-brackets.js.map +1 -0
  39. package/dist/lib/deep-clone.cjs +87 -0
  40. package/dist/lib/deep-clone.cjs.map +1 -0
  41. package/dist/lib/deep-clone.d.cts +19 -0
  42. package/dist/lib/deep-clone.d.ts +19 -0
  43. package/dist/lib/deep-clone.js +62 -0
  44. package/dist/lib/deep-clone.js.map +1 -0
  45. package/dist/lib/error-to-string.cjs +743 -0
  46. package/dist/lib/error-to-string.cjs.map +1 -0
  47. package/dist/lib/error-to-string.d.cts +3 -0
  48. package/dist/lib/error-to-string.d.ts +3 -0
  49. package/dist/lib/error-to-string.js +706 -0
  50. package/dist/lib/error-to-string.js.map +1 -0
  51. package/dist/lib/event-emitter.cjs +899 -0
  52. package/dist/lib/event-emitter.cjs.map +1 -0
  53. package/dist/lib/event-emitter.d.cts +78 -0
  54. package/dist/lib/event-emitter.d.ts +78 -0
  55. package/dist/lib/event-emitter.js +861 -0
  56. package/dist/lib/event-emitter.js.map +1 -0
  57. package/dist/lib/id-helpers.cjs +205 -0
  58. package/dist/lib/id-helpers.cjs.map +1 -0
  59. package/dist/lib/id-helpers.d.cts +198 -0
  60. package/dist/lib/id-helpers.d.ts +198 -0
  61. package/dist/lib/id-helpers.js +170 -0
  62. package/dist/lib/id-helpers.js.map +1 -0
  63. package/dist/lib/is-boolean.cjs +33 -0
  64. package/dist/lib/is-boolean.cjs.map +1 -0
  65. package/dist/lib/is-boolean.d.cts +19 -0
  66. package/dist/lib/is-boolean.d.ts +19 -0
  67. package/dist/lib/is-boolean.js +8 -0
  68. package/dist/lib/is-boolean.js.map +1 -0
  69. package/dist/lib/is-function.cjs +33 -0
  70. package/dist/lib/is-function.cjs.map +1 -0
  71. package/dist/lib/is-function.d.cts +3 -0
  72. package/dist/lib/is-function.d.ts +3 -0
  73. package/dist/lib/is-function.js +8 -0
  74. package/dist/lib/is-function.js.map +1 -0
  75. package/dist/lib/is-number.cjs +38 -0
  76. package/dist/lib/is-number.cjs.map +1 -0
  77. package/dist/lib/is-number.d.cts +38 -0
  78. package/dist/lib/is-number.d.ts +38 -0
  79. package/dist/lib/is-number.js +12 -0
  80. package/dist/lib/is-number.js.map +1 -0
  81. package/dist/lib/is-plain-object.cjs +33 -0
  82. package/dist/lib/is-plain-object.cjs.map +1 -0
  83. package/dist/lib/is-plain-object.d.cts +20 -0
  84. package/dist/lib/is-plain-object.d.ts +20 -0
  85. package/dist/lib/is-plain-object.js +8 -0
  86. package/dist/lib/is-plain-object.js.map +1 -0
  87. package/dist/lib/is-promise.cjs +34 -0
  88. package/dist/lib/is-promise.cjs.map +1 -0
  89. package/dist/lib/is-promise.d.cts +3 -0
  90. package/dist/lib/is-promise.d.ts +3 -0
  91. package/dist/lib/is-promise.js +9 -0
  92. package/dist/lib/is-promise.js.map +1 -0
  93. package/dist/lib/json-helpers.cjs +49 -0
  94. package/dist/lib/json-helpers.cjs.map +1 -0
  95. package/dist/lib/json-helpers.d.cts +10 -0
  96. package/dist/lib/json-helpers.d.ts +10 -0
  97. package/dist/lib/json-helpers.js +22 -0
  98. package/dist/lib/json-helpers.js.map +1 -0
  99. package/dist/lib/lifecycle-manager/index.cjs +5594 -0
  100. package/dist/lib/lifecycle-manager/index.cjs.map +1 -0
  101. package/dist/lib/lifecycle-manager/index.d.cts +2044 -0
  102. package/dist/lib/lifecycle-manager/index.d.ts +2044 -0
  103. package/dist/lib/lifecycle-manager/index.js +5543 -0
  104. package/dist/lib/lifecycle-manager/index.js.map +1 -0
  105. package/dist/lib/logger/index.cjs +2514 -0
  106. package/dist/lib/logger/index.cjs.map +1 -0
  107. package/dist/lib/logger/index.d.cts +630 -0
  108. package/dist/lib/logger/index.d.ts +630 -0
  109. package/dist/lib/logger/index.js +2470 -0
  110. package/dist/lib/logger/index.js.map +1 -0
  111. package/dist/lib/padding-utils.cjs +77 -0
  112. package/dist/lib/padding-utils.cjs.map +1 -0
  113. package/dist/lib/padding-utils.d.cts +44 -0
  114. package/dist/lib/padding-utils.d.ts +44 -0
  115. package/dist/lib/padding-utils.js +46 -0
  116. package/dist/lib/padding-utils.js.map +1 -0
  117. package/dist/lib/process-signal-manager.cjs +1306 -0
  118. package/dist/lib/process-signal-manager.cjs.map +1 -0
  119. package/dist/lib/process-signal-manager.d.cts +305 -0
  120. package/dist/lib/process-signal-manager.d.ts +305 -0
  121. package/dist/lib/process-signal-manager.js +1269 -0
  122. package/dist/lib/process-signal-manager.js.map +1 -0
  123. package/dist/lib/promise-protected-resolver.cjs +828 -0
  124. package/dist/lib/promise-protected-resolver.cjs.map +1 -0
  125. package/dist/lib/promise-protected-resolver.d.cts +17 -0
  126. package/dist/lib/promise-protected-resolver.d.ts +17 -0
  127. package/dist/lib/promise-protected-resolver.js +791 -0
  128. package/dist/lib/promise-protected-resolver.js.map +1 -0
  129. package/dist/lib/retry-utils/index.cjs +2183 -0
  130. package/dist/lib/retry-utils/index.cjs.map +1 -0
  131. package/dist/lib/retry-utils/index.d.cts +321 -0
  132. package/dist/lib/retry-utils/index.d.ts +321 -0
  133. package/dist/lib/retry-utils/index.js +2133 -0
  134. package/dist/lib/retry-utils/index.js.map +1 -0
  135. package/dist/lib/safe-handle-callback.cjs +818 -0
  136. package/dist/lib/safe-handle-callback.cjs.map +1 -0
  137. package/dist/lib/safe-handle-callback.d.cts +43 -0
  138. package/dist/lib/safe-handle-callback.d.ts +43 -0
  139. package/dist/lib/safe-handle-callback.js +780 -0
  140. package/dist/lib/safe-handle-callback.js.map +1 -0
  141. package/dist/lib/serialize-error/index.cjs +93 -0
  142. package/dist/lib/serialize-error/index.cjs.map +1 -0
  143. package/dist/lib/serialize-error/index.d.cts +26 -0
  144. package/dist/lib/serialize-error/index.d.ts +26 -0
  145. package/dist/lib/serialize-error/index.js +64 -0
  146. package/dist/lib/serialize-error/index.js.map +1 -0
  147. package/dist/lib/single-event-observer.cjs +841 -0
  148. package/dist/lib/single-event-observer.cjs.map +1 -0
  149. package/dist/lib/single-event-observer.d.cts +54 -0
  150. package/dist/lib/single-event-observer.d.ts +54 -0
  151. package/dist/lib/single-event-observer.js +803 -0
  152. package/dist/lib/single-event-observer.js.map +1 -0
  153. package/dist/lib/sleep.cjs +37 -0
  154. package/dist/lib/sleep.cjs.map +1 -0
  155. package/dist/lib/sleep.d.cts +11 -0
  156. package/dist/lib/sleep.d.ts +11 -0
  157. package/dist/lib/sleep.js +12 -0
  158. package/dist/lib/sleep.js.map +1 -0
  159. package/dist/lib/strings.cjs +186 -0
  160. package/dist/lib/strings.cjs.map +1 -0
  161. package/dist/lib/strings.d.cts +107 -0
  162. package/dist/lib/strings.d.ts +107 -0
  163. package/dist/lib/strings.js +149 -0
  164. package/dist/lib/strings.js.map +1 -0
  165. package/dist/lib/tmp-dir.cjs +254 -0
  166. package/dist/lib/tmp-dir.cjs.map +1 -0
  167. package/dist/lib/tmp-dir.d.cts +63 -0
  168. package/dist/lib/tmp-dir.d.ts +63 -0
  169. package/dist/lib/tmp-dir.js +211 -0
  170. package/dist/lib/tmp-dir.js.map +1 -0
  171. package/dist/lib/unix-time-helpers.cjs +53 -0
  172. package/dist/lib/unix-time-helpers.cjs.map +1 -0
  173. package/dist/lib/unix-time-helpers.d.cts +56 -0
  174. package/dist/lib/unix-time-helpers.d.ts +56 -0
  175. package/dist/lib/unix-time-helpers.js +24 -0
  176. package/dist/lib/unix-time-helpers.js.map +1 -0
  177. package/package.json +220 -0
@@ -0,0 +1,321 @@
1
+ import { EventEmitterProtected } from '../event-emitter.cjs';
2
+
3
+ type RetryPolicyOptions = RetryPolicyOptionsStrategyFixed | RetryPolicyOptionsStrategyExponential;
4
+ type RetryPolicyValidated = Required<RetryPolicyOptions>;
5
+ interface RetryPolicyOptionsStrategyFixed {
6
+ strategy: 'fixed';
7
+ maxRetryAttempts?: number;
8
+ delayMS?: number;
9
+ }
10
+ interface RetryPolicyOptionsStrategyExponential {
11
+ strategy: 'exponential';
12
+ maxRetryAttempts?: number;
13
+ factor?: number;
14
+ minTimeoutMS?: number;
15
+ maxTimeoutMS?: number;
16
+ dispersion?: number;
17
+ }
18
+ interface RetryQueryResult {
19
+ shouldRetry: boolean;
20
+ delayMS: number;
21
+ }
22
+ type RunAttemptStatusCodes = 'not_started' | 'pre_operation_error' | 'canceled' | 'attempts_exhausted' | 'attempt_success' | 'attempt_fatal' | 'running';
23
+ type RunnerErrorCode = 'already_completed' | 'already_running' | 'attempts_exhausted' | 'cancel_pending' | 'force_try_in_progress' | 'fatally_failed' | 'lock_error' | 'not_paused' | 'not_running' | 'retry_canceled' | 'unexpected_error';
24
+
25
+ declare class RetryPolicy {
26
+ private policy;
27
+ private currentState;
28
+ /**
29
+ * Gets the validated policy information for this retry policy instance.
30
+ * @returns {RetryPolicyValidated} The current retry policy settings.
31
+ */
32
+ get policyInfo(): RetryPolicyValidated;
33
+ /**
34
+ * Gets the total number of attempts made, including the initial attempt and any retries.
35
+ * @returns {number} The total number of attempts.
36
+ */
37
+ get attempts(): number;
38
+ /**
39
+ * Checks if the initial attempt has been taken.
40
+ */
41
+ get wasInitialAttemptTaken(): boolean;
42
+ /**
43
+ * Checks if the last operation attempt was successful. (used to calculate the number of attempts made)
44
+ */
45
+ get wasSuccessful(): boolean;
46
+ /**
47
+ * Gets the maximum number of retry attempts allowed by the current policy.
48
+ * @returns {number} The maximum number of retry attempts.
49
+ */
50
+ get maxRetryAttempts(): number;
51
+ /**
52
+ * Gets the number of retry attempts made, excluding the initial attempt.
53
+ * @returns {number} The number of retries.
54
+ */
55
+ get retryCount(): number;
56
+ /**
57
+ * Checks if the retry attempts have been exhausted.
58
+ * @returns {boolean} True if the number of retries has reached the maximum allowed attempts; otherwise, false.
59
+ */
60
+ get areAttemptsExhausted(): boolean;
61
+ /**
62
+ * Gets a list of errors recorded from each retry attempt.
63
+ * @returns {unknown[]} An array of errors encountered during retry attempts.
64
+ */
65
+ get errors(): unknown[];
66
+ /**
67
+ * Gets the most common error encountered across all retry attempts.
68
+ *
69
+ * This method caches the most common error for performance. If the cache is invalidated due to a new error,
70
+ * it recalculates the most common error.
71
+ *
72
+ * @returns {unknown} The most common error, or null if no errors have been encountered.
73
+ */
74
+ get mostCommonError(): unknown;
75
+ /**
76
+ * Gets the last error encountered during the retry attempts.
77
+ * @returns {unknown} The last error encountered, or null if no errors have been recorded.
78
+ */
79
+ get lastError(): unknown;
80
+ /**
81
+ * Constructs a RetryPolicy instance with specified options.
82
+ *
83
+ * @param {RetryPolicyOptions} policy The retry policy options, including strategy, maximum retry attempts,
84
+ * and other parameters specific to the fixed or exponential strategy.
85
+ *
86
+ * Throws an error if an invalid retry strategy is provided.
87
+ */
88
+ constructor(policy: RetryPolicyOptions);
89
+ /**
90
+ * Resets the retry policy to its initial state.
91
+ *
92
+ * This method clears all recorded errors and marks the initial attempt as not taken,
93
+ * effectively resetting the state of the retry policy for a new operation.
94
+ */
95
+ reset(): void;
96
+ /**
97
+ * Determines if the initial operation attempt should proceed.
98
+ *
99
+ * This method checks if the initial attempt has already been taken and updates the state to reflect that
100
+ * the initial attempt is now being made. This method is used to ensure that the retry logic only kicks in after
101
+ * the first attempt has failed.
102
+ *
103
+ * Note that even upon success, you should call the reset method to clear the state for the next operation.
104
+ *
105
+ * @returns {boolean} True if the initial attempt has not been made yet; otherwise, false.
106
+ */
107
+ shouldDoFirstTry(): boolean;
108
+ /**
109
+ * Marks the last operation attempt as successful.
110
+ */
111
+ markAsSuccessful(): void;
112
+ /**
113
+ * Records an error that occurred during the last operation attempt.
114
+ *
115
+ * Does not check if was successful or not, nor checks if should retry or not.
116
+ */
117
+ reportError(error: unknown): void;
118
+ /**
119
+ * Determines if a retry should be made based on the current state and the provided error.
120
+ *
121
+ * When called, this method stores the provided error, checks if further retries are allowed based on the
122
+ * maximum retry attempts, and calculates the delay for the next retry if applicable.
123
+ *
124
+ * It also invalidates the cached most common error since the error state has changed.
125
+ *
126
+ * @param {unknown} error The error that resulted from the last operation attempt. Can be omitted when `isQueryOnly` is `true`.
127
+ * @param {boolean} isQueryOnly If true, the method only queries if a retry should be made without storing the error.
128
+ * @returns {RetryQueryResult} An object indicating whether a retry should be attempted and the delay before the next attempt.
129
+ */
130
+ shouldRetry(error?: unknown, isQueryOnly?: boolean): RetryQueryResult;
131
+ /**
132
+ * Returning a fresh copy of the current state
133
+ * to be immutable and not changed by the caller
134
+ */
135
+ private getEmptyCurrentState;
136
+ /**
137
+ * Calculates the delay before the next retry attempt based on the current retry policy.
138
+ *
139
+ * For a fixed strategy, it returns the specified delay. For an exponential strategy, it calculates the delay
140
+ * based on the exponential backoff formula, considering the number of retry attempts, the base delay,
141
+ * the exponential factor, and any specified dispersion to introduce randomness.
142
+ *
143
+ * @returns {number} The calculated delay in milliseconds before the next retry attempt.
144
+ */
145
+ private calculateNextDelay;
146
+ }
147
+
148
+ type ReportResultStatus = 'success' | 'error' | 'fatal' | 'skip';
149
+ type ReportResult<T = unknown> = {
150
+ (status: 'success', value?: T): void;
151
+ (status: 'skip', value?: T): void;
152
+ (status: 'error', value?: unknown): void;
153
+ (status: 'fatal', value?: unknown): void;
154
+ };
155
+ interface RunResultSuccess<T> {
156
+ status: 'attempt_success';
157
+ data?: T;
158
+ }
159
+ interface RunResultNonSuccess {
160
+ status: Exclude<RunAttemptStatusCodes, 'attempt_success'>;
161
+ code?: RunnerErrorCode;
162
+ error?: unknown;
163
+ reattached?: boolean;
164
+ }
165
+ type RunResult<T> = RunResultSuccess<T> | RunResultNonSuccess;
166
+ type CancelResult = 'canceled' | 'forced' | 'not-running';
167
+ type OperationStartedType = 'initial' | 'resume' | 'force';
168
+ interface OnOperationEndedInfo {
169
+ runnerState: RunnerState;
170
+ timeTakenMS: number;
171
+ }
172
+ interface OnOperationStartedInfo {
173
+ operationType: OperationStartedType;
174
+ }
175
+ interface OnAttemptStartedInfo {
176
+ attemptID: string;
177
+ operationTimeElapsedMS: number;
178
+ attemptTimeElapsedMS: number;
179
+ }
180
+ interface OnAttemptHandledInfo<T> {
181
+ attemptID: string;
182
+ status: ReportResultStatus;
183
+ operationTimeElapsedMS: number;
184
+ attemptTimeElapsedMS: number;
185
+ data?: T;
186
+ error?: unknown;
187
+ wasCanceled: boolean;
188
+ }
189
+ declare const OPERATION_STARTED = "operation-started";
190
+ declare const OPERATION_ENDED = "operation-ended";
191
+ declare const ATTEMPT_STARTED = "attempt-started";
192
+ declare const ATTEMPT_HANDLED = "attempt-handled";
193
+ interface RetryRunnerOptions<T = unknown> {
194
+ operationLabel?: string;
195
+ onOperationStarted?: (info: OnOperationStartedInfo) => void;
196
+ onOperationEnded?: (info: OnOperationEndedInfo) => void;
197
+ onAttemptStarted?: (info: OnAttemptStartedInfo) => void;
198
+ onAttemptHandled?: (info: OnAttemptHandledInfo<T>) => void;
199
+ }
200
+ interface ForceTryOptions {
201
+ shouldWaitForCompletion?: boolean;
202
+ shouldAbortRunning?: boolean;
203
+ }
204
+ type RunnerState = 'not-started' | 'running' | 'stopping' | 'stopped' | 'completed' | 'exhausted' | 'fatal-error';
205
+ declare class RetryRunner<T = unknown> extends EventEmitterProtected {
206
+ private _operationLabel;
207
+ private policy;
208
+ private _isOperationLocked;
209
+ private currentState;
210
+ private _gracePeriodMS;
211
+ private operation;
212
+ private currentOperationResolver;
213
+ private cancelResolvers;
214
+ get operationLabel(): string;
215
+ get runnerState(): RunnerState;
216
+ get timeTakenMS(): number;
217
+ get attemptTimeTakenMS(): number;
218
+ get retryTimeRemaining(): number;
219
+ get canForceTry(): boolean;
220
+ get wasLastAttemptForced(): boolean;
221
+ get errors(): unknown[];
222
+ get wasInitialAttemptTaken(): boolean;
223
+ get areAttemptsExhausted(): boolean;
224
+ get attempts(): number;
225
+ get mostCommonError(): unknown;
226
+ get lastError(): unknown;
227
+ get maxRetryAttempts(): number;
228
+ get policyInfo(): RetryPolicyValidated;
229
+ get retryCount(): number;
230
+ get wasSuccessful(): boolean;
231
+ get isRetryPending(): boolean;
232
+ get isOperationRunning(): boolean;
233
+ get isAttemptRunning(): boolean;
234
+ get graceCancelPeriodMS(): number;
235
+ constructor(policy: RetryPolicyOptions, operation: (reportResult: ReportResult<T>, signal: AbortSignal) => void | Promise<void>, options?: RetryRunnerOptions<T>);
236
+ /**
237
+ * Set the grace period for cancellation in milliseconds
238
+ *
239
+ * Overrides the default grace period of 1000ms
240
+ * Non-finite or negative values default to 1000ms. Use 0 for immediate force-cancel.
241
+ */
242
+ overrideGraceCancelPeriodMS(value: number): void;
243
+ waitForCompletion(): Promise<RunResult<T>>;
244
+ run(shouldWaitForCompletion?: boolean): Promise<RunResult<T>>;
245
+ cancel(): Promise<CancelResult>;
246
+ reset(): Promise<void>;
247
+ resume(shouldWaitForCompletion?: boolean): Promise<RunResult<T>>;
248
+ forceTry(options?: ForceTryOptions): Promise<RunResult<T>>;
249
+ /**
250
+ * Returning a fresh copy of the current state
251
+ * to be immutable and not changed by the caller
252
+ */
253
+ private getEmptyCurrentState;
254
+ private checkForDisallowedPerOperationStates;
255
+ private cleanupTimers;
256
+ private confirmCancellation;
257
+ private handleReportResult;
258
+ private attemptOperation;
259
+ }
260
+
261
+ /**
262
+ * Simple error classes for retry-utils
263
+ * Following the pattern from FileSinkError
264
+ */
265
+ declare class RetryUtilsErrPolicyConfigInvalidStrategy extends Error {
266
+ strategyProvided: string;
267
+ validStrategies: string[];
268
+ constructor(strategyProvided: string, validStrategies: string[]);
269
+ }
270
+ declare class RetryUtilsErrRunnerAlreadyCompleted extends Error {
271
+ invokedMethod: 'run' | 'resume' | 'forceTry';
272
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry');
273
+ }
274
+ declare class RetryUtilsErrRunnerAlreadyRunning extends Error {
275
+ invokedMethod: 'run' | 'resume';
276
+ constructor(invokedMethod: 'run' | 'resume');
277
+ }
278
+ declare class RetryUtilsErrRunnerForceTryRetryInProgress extends Error {
279
+ invokedMethod: 'forceTry';
280
+ constructor(invokedMethod: 'forceTry');
281
+ }
282
+ declare class RetryUtilsErrRunnerNotPaused extends Error {
283
+ invokedMethod: 'resume';
284
+ constructor(invokedMethod: 'resume');
285
+ }
286
+ declare class RetryUtilsErrRunnerCancelPending extends Error {
287
+ invokedMethod: 'run' | 'resume';
288
+ constructor(invokedMethod: 'run' | 'resume');
289
+ }
290
+ declare class RetryUtilsErrRunnerRetryCanceled extends Error {
291
+ invokedMethod: 'run';
292
+ constructor(invokedMethod: 'run');
293
+ }
294
+ declare class RetryUtilsErrRunnerLastRetryFatallyFailed extends Error {
295
+ invokedMethod: 'run' | 'resume';
296
+ constructor(invokedMethod: 'run' | 'resume');
297
+ }
298
+ declare class RetryUtilsErrRunnerAttemptsExhausted extends Error {
299
+ invokedMethod: 'run' | 'resume';
300
+ constructor(invokedMethod: 'run' | 'resume');
301
+ }
302
+ declare class RetryUtilsErrRunnerLockAcquisitionError extends Error {
303
+ invokedMethod: 'run' | 'resume' | 'forceTry';
304
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry');
305
+ }
306
+ declare class RetryUtilsErrRunnerUnexpectedError extends Error {
307
+ invokedMethod: 'run' | 'resume' | 'forceTry';
308
+ originalError: Error;
309
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry', originalError: Error);
310
+ }
311
+ declare class RetryUtilsErrRunnerUnknownState extends Error {
312
+ invokedMethod: 'waitForCompletion';
313
+ runnerState: string;
314
+ constructor(invokedMethod: 'waitForCompletion', runnerState: string);
315
+ }
316
+ declare class RetryUtilsErrRunnerNotRunning extends Error {
317
+ invokedMethod: 'waitForCompletion';
318
+ constructor(invokedMethod: 'waitForCompletion');
319
+ }
320
+
321
+ export { ATTEMPT_HANDLED, ATTEMPT_STARTED, type CancelResult, type ForceTryOptions, OPERATION_ENDED, OPERATION_STARTED, type OnAttemptHandledInfo, type OnAttemptStartedInfo, type OnOperationEndedInfo, type OnOperationStartedInfo, type OperationStartedType, type ReportResult, type ReportResultStatus, RetryPolicy, type RetryPolicyOptions, type RetryPolicyOptionsStrategyExponential, type RetryPolicyOptionsStrategyFixed, type RetryPolicyValidated, type RetryQueryResult, RetryRunner, type RetryRunnerOptions, RetryUtilsErrPolicyConfigInvalidStrategy, RetryUtilsErrRunnerAlreadyCompleted, RetryUtilsErrRunnerAlreadyRunning, RetryUtilsErrRunnerAttemptsExhausted, RetryUtilsErrRunnerCancelPending, RetryUtilsErrRunnerForceTryRetryInProgress, RetryUtilsErrRunnerLastRetryFatallyFailed, RetryUtilsErrRunnerLockAcquisitionError, RetryUtilsErrRunnerNotPaused, RetryUtilsErrRunnerNotRunning, RetryUtilsErrRunnerRetryCanceled, RetryUtilsErrRunnerUnexpectedError, RetryUtilsErrRunnerUnknownState, type RunAttemptStatusCodes, type RunResult, type RunResultNonSuccess, type RunResultSuccess, type RunnerErrorCode, type RunnerState };
@@ -0,0 +1,321 @@
1
+ import { EventEmitterProtected } from '../event-emitter.js';
2
+
3
+ type RetryPolicyOptions = RetryPolicyOptionsStrategyFixed | RetryPolicyOptionsStrategyExponential;
4
+ type RetryPolicyValidated = Required<RetryPolicyOptions>;
5
+ interface RetryPolicyOptionsStrategyFixed {
6
+ strategy: 'fixed';
7
+ maxRetryAttempts?: number;
8
+ delayMS?: number;
9
+ }
10
+ interface RetryPolicyOptionsStrategyExponential {
11
+ strategy: 'exponential';
12
+ maxRetryAttempts?: number;
13
+ factor?: number;
14
+ minTimeoutMS?: number;
15
+ maxTimeoutMS?: number;
16
+ dispersion?: number;
17
+ }
18
+ interface RetryQueryResult {
19
+ shouldRetry: boolean;
20
+ delayMS: number;
21
+ }
22
+ type RunAttemptStatusCodes = 'not_started' | 'pre_operation_error' | 'canceled' | 'attempts_exhausted' | 'attempt_success' | 'attempt_fatal' | 'running';
23
+ type RunnerErrorCode = 'already_completed' | 'already_running' | 'attempts_exhausted' | 'cancel_pending' | 'force_try_in_progress' | 'fatally_failed' | 'lock_error' | 'not_paused' | 'not_running' | 'retry_canceled' | 'unexpected_error';
24
+
25
+ declare class RetryPolicy {
26
+ private policy;
27
+ private currentState;
28
+ /**
29
+ * Gets the validated policy information for this retry policy instance.
30
+ * @returns {RetryPolicyValidated} The current retry policy settings.
31
+ */
32
+ get policyInfo(): RetryPolicyValidated;
33
+ /**
34
+ * Gets the total number of attempts made, including the initial attempt and any retries.
35
+ * @returns {number} The total number of attempts.
36
+ */
37
+ get attempts(): number;
38
+ /**
39
+ * Checks if the initial attempt has been taken.
40
+ */
41
+ get wasInitialAttemptTaken(): boolean;
42
+ /**
43
+ * Checks if the last operation attempt was successful. (used to calculate the number of attempts made)
44
+ */
45
+ get wasSuccessful(): boolean;
46
+ /**
47
+ * Gets the maximum number of retry attempts allowed by the current policy.
48
+ * @returns {number} The maximum number of retry attempts.
49
+ */
50
+ get maxRetryAttempts(): number;
51
+ /**
52
+ * Gets the number of retry attempts made, excluding the initial attempt.
53
+ * @returns {number} The number of retries.
54
+ */
55
+ get retryCount(): number;
56
+ /**
57
+ * Checks if the retry attempts have been exhausted.
58
+ * @returns {boolean} True if the number of retries has reached the maximum allowed attempts; otherwise, false.
59
+ */
60
+ get areAttemptsExhausted(): boolean;
61
+ /**
62
+ * Gets a list of errors recorded from each retry attempt.
63
+ * @returns {unknown[]} An array of errors encountered during retry attempts.
64
+ */
65
+ get errors(): unknown[];
66
+ /**
67
+ * Gets the most common error encountered across all retry attempts.
68
+ *
69
+ * This method caches the most common error for performance. If the cache is invalidated due to a new error,
70
+ * it recalculates the most common error.
71
+ *
72
+ * @returns {unknown} The most common error, or null if no errors have been encountered.
73
+ */
74
+ get mostCommonError(): unknown;
75
+ /**
76
+ * Gets the last error encountered during the retry attempts.
77
+ * @returns {unknown} The last error encountered, or null if no errors have been recorded.
78
+ */
79
+ get lastError(): unknown;
80
+ /**
81
+ * Constructs a RetryPolicy instance with specified options.
82
+ *
83
+ * @param {RetryPolicyOptions} policy The retry policy options, including strategy, maximum retry attempts,
84
+ * and other parameters specific to the fixed or exponential strategy.
85
+ *
86
+ * Throws an error if an invalid retry strategy is provided.
87
+ */
88
+ constructor(policy: RetryPolicyOptions);
89
+ /**
90
+ * Resets the retry policy to its initial state.
91
+ *
92
+ * This method clears all recorded errors and marks the initial attempt as not taken,
93
+ * effectively resetting the state of the retry policy for a new operation.
94
+ */
95
+ reset(): void;
96
+ /**
97
+ * Determines if the initial operation attempt should proceed.
98
+ *
99
+ * This method checks if the initial attempt has already been taken and updates the state to reflect that
100
+ * the initial attempt is now being made. This method is used to ensure that the retry logic only kicks in after
101
+ * the first attempt has failed.
102
+ *
103
+ * Note that even upon success, you should call the reset method to clear the state for the next operation.
104
+ *
105
+ * @returns {boolean} True if the initial attempt has not been made yet; otherwise, false.
106
+ */
107
+ shouldDoFirstTry(): boolean;
108
+ /**
109
+ * Marks the last operation attempt as successful.
110
+ */
111
+ markAsSuccessful(): void;
112
+ /**
113
+ * Records an error that occurred during the last operation attempt.
114
+ *
115
+ * Does not check if was successful or not, nor checks if should retry or not.
116
+ */
117
+ reportError(error: unknown): void;
118
+ /**
119
+ * Determines if a retry should be made based on the current state and the provided error.
120
+ *
121
+ * When called, this method stores the provided error, checks if further retries are allowed based on the
122
+ * maximum retry attempts, and calculates the delay for the next retry if applicable.
123
+ *
124
+ * It also invalidates the cached most common error since the error state has changed.
125
+ *
126
+ * @param {unknown} error The error that resulted from the last operation attempt. Can be omitted when `isQueryOnly` is `true`.
127
+ * @param {boolean} isQueryOnly If true, the method only queries if a retry should be made without storing the error.
128
+ * @returns {RetryQueryResult} An object indicating whether a retry should be attempted and the delay before the next attempt.
129
+ */
130
+ shouldRetry(error?: unknown, isQueryOnly?: boolean): RetryQueryResult;
131
+ /**
132
+ * Returning a fresh copy of the current state
133
+ * to be immutable and not changed by the caller
134
+ */
135
+ private getEmptyCurrentState;
136
+ /**
137
+ * Calculates the delay before the next retry attempt based on the current retry policy.
138
+ *
139
+ * For a fixed strategy, it returns the specified delay. For an exponential strategy, it calculates the delay
140
+ * based on the exponential backoff formula, considering the number of retry attempts, the base delay,
141
+ * the exponential factor, and any specified dispersion to introduce randomness.
142
+ *
143
+ * @returns {number} The calculated delay in milliseconds before the next retry attempt.
144
+ */
145
+ private calculateNextDelay;
146
+ }
147
+
148
+ type ReportResultStatus = 'success' | 'error' | 'fatal' | 'skip';
149
+ type ReportResult<T = unknown> = {
150
+ (status: 'success', value?: T): void;
151
+ (status: 'skip', value?: T): void;
152
+ (status: 'error', value?: unknown): void;
153
+ (status: 'fatal', value?: unknown): void;
154
+ };
155
+ interface RunResultSuccess<T> {
156
+ status: 'attempt_success';
157
+ data?: T;
158
+ }
159
+ interface RunResultNonSuccess {
160
+ status: Exclude<RunAttemptStatusCodes, 'attempt_success'>;
161
+ code?: RunnerErrorCode;
162
+ error?: unknown;
163
+ reattached?: boolean;
164
+ }
165
+ type RunResult<T> = RunResultSuccess<T> | RunResultNonSuccess;
166
+ type CancelResult = 'canceled' | 'forced' | 'not-running';
167
+ type OperationStartedType = 'initial' | 'resume' | 'force';
168
+ interface OnOperationEndedInfo {
169
+ runnerState: RunnerState;
170
+ timeTakenMS: number;
171
+ }
172
+ interface OnOperationStartedInfo {
173
+ operationType: OperationStartedType;
174
+ }
175
+ interface OnAttemptStartedInfo {
176
+ attemptID: string;
177
+ operationTimeElapsedMS: number;
178
+ attemptTimeElapsedMS: number;
179
+ }
180
+ interface OnAttemptHandledInfo<T> {
181
+ attemptID: string;
182
+ status: ReportResultStatus;
183
+ operationTimeElapsedMS: number;
184
+ attemptTimeElapsedMS: number;
185
+ data?: T;
186
+ error?: unknown;
187
+ wasCanceled: boolean;
188
+ }
189
+ declare const OPERATION_STARTED = "operation-started";
190
+ declare const OPERATION_ENDED = "operation-ended";
191
+ declare const ATTEMPT_STARTED = "attempt-started";
192
+ declare const ATTEMPT_HANDLED = "attempt-handled";
193
+ interface RetryRunnerOptions<T = unknown> {
194
+ operationLabel?: string;
195
+ onOperationStarted?: (info: OnOperationStartedInfo) => void;
196
+ onOperationEnded?: (info: OnOperationEndedInfo) => void;
197
+ onAttemptStarted?: (info: OnAttemptStartedInfo) => void;
198
+ onAttemptHandled?: (info: OnAttemptHandledInfo<T>) => void;
199
+ }
200
+ interface ForceTryOptions {
201
+ shouldWaitForCompletion?: boolean;
202
+ shouldAbortRunning?: boolean;
203
+ }
204
+ type RunnerState = 'not-started' | 'running' | 'stopping' | 'stopped' | 'completed' | 'exhausted' | 'fatal-error';
205
+ declare class RetryRunner<T = unknown> extends EventEmitterProtected {
206
+ private _operationLabel;
207
+ private policy;
208
+ private _isOperationLocked;
209
+ private currentState;
210
+ private _gracePeriodMS;
211
+ private operation;
212
+ private currentOperationResolver;
213
+ private cancelResolvers;
214
+ get operationLabel(): string;
215
+ get runnerState(): RunnerState;
216
+ get timeTakenMS(): number;
217
+ get attemptTimeTakenMS(): number;
218
+ get retryTimeRemaining(): number;
219
+ get canForceTry(): boolean;
220
+ get wasLastAttemptForced(): boolean;
221
+ get errors(): unknown[];
222
+ get wasInitialAttemptTaken(): boolean;
223
+ get areAttemptsExhausted(): boolean;
224
+ get attempts(): number;
225
+ get mostCommonError(): unknown;
226
+ get lastError(): unknown;
227
+ get maxRetryAttempts(): number;
228
+ get policyInfo(): RetryPolicyValidated;
229
+ get retryCount(): number;
230
+ get wasSuccessful(): boolean;
231
+ get isRetryPending(): boolean;
232
+ get isOperationRunning(): boolean;
233
+ get isAttemptRunning(): boolean;
234
+ get graceCancelPeriodMS(): number;
235
+ constructor(policy: RetryPolicyOptions, operation: (reportResult: ReportResult<T>, signal: AbortSignal) => void | Promise<void>, options?: RetryRunnerOptions<T>);
236
+ /**
237
+ * Set the grace period for cancellation in milliseconds
238
+ *
239
+ * Overrides the default grace period of 1000ms
240
+ * Non-finite or negative values default to 1000ms. Use 0 for immediate force-cancel.
241
+ */
242
+ overrideGraceCancelPeriodMS(value: number): void;
243
+ waitForCompletion(): Promise<RunResult<T>>;
244
+ run(shouldWaitForCompletion?: boolean): Promise<RunResult<T>>;
245
+ cancel(): Promise<CancelResult>;
246
+ reset(): Promise<void>;
247
+ resume(shouldWaitForCompletion?: boolean): Promise<RunResult<T>>;
248
+ forceTry(options?: ForceTryOptions): Promise<RunResult<T>>;
249
+ /**
250
+ * Returning a fresh copy of the current state
251
+ * to be immutable and not changed by the caller
252
+ */
253
+ private getEmptyCurrentState;
254
+ private checkForDisallowedPerOperationStates;
255
+ private cleanupTimers;
256
+ private confirmCancellation;
257
+ private handleReportResult;
258
+ private attemptOperation;
259
+ }
260
+
261
+ /**
262
+ * Simple error classes for retry-utils
263
+ * Following the pattern from FileSinkError
264
+ */
265
+ declare class RetryUtilsErrPolicyConfigInvalidStrategy extends Error {
266
+ strategyProvided: string;
267
+ validStrategies: string[];
268
+ constructor(strategyProvided: string, validStrategies: string[]);
269
+ }
270
+ declare class RetryUtilsErrRunnerAlreadyCompleted extends Error {
271
+ invokedMethod: 'run' | 'resume' | 'forceTry';
272
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry');
273
+ }
274
+ declare class RetryUtilsErrRunnerAlreadyRunning extends Error {
275
+ invokedMethod: 'run' | 'resume';
276
+ constructor(invokedMethod: 'run' | 'resume');
277
+ }
278
+ declare class RetryUtilsErrRunnerForceTryRetryInProgress extends Error {
279
+ invokedMethod: 'forceTry';
280
+ constructor(invokedMethod: 'forceTry');
281
+ }
282
+ declare class RetryUtilsErrRunnerNotPaused extends Error {
283
+ invokedMethod: 'resume';
284
+ constructor(invokedMethod: 'resume');
285
+ }
286
+ declare class RetryUtilsErrRunnerCancelPending extends Error {
287
+ invokedMethod: 'run' | 'resume';
288
+ constructor(invokedMethod: 'run' | 'resume');
289
+ }
290
+ declare class RetryUtilsErrRunnerRetryCanceled extends Error {
291
+ invokedMethod: 'run';
292
+ constructor(invokedMethod: 'run');
293
+ }
294
+ declare class RetryUtilsErrRunnerLastRetryFatallyFailed extends Error {
295
+ invokedMethod: 'run' | 'resume';
296
+ constructor(invokedMethod: 'run' | 'resume');
297
+ }
298
+ declare class RetryUtilsErrRunnerAttemptsExhausted extends Error {
299
+ invokedMethod: 'run' | 'resume';
300
+ constructor(invokedMethod: 'run' | 'resume');
301
+ }
302
+ declare class RetryUtilsErrRunnerLockAcquisitionError extends Error {
303
+ invokedMethod: 'run' | 'resume' | 'forceTry';
304
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry');
305
+ }
306
+ declare class RetryUtilsErrRunnerUnexpectedError extends Error {
307
+ invokedMethod: 'run' | 'resume' | 'forceTry';
308
+ originalError: Error;
309
+ constructor(invokedMethod: 'run' | 'resume' | 'forceTry', originalError: Error);
310
+ }
311
+ declare class RetryUtilsErrRunnerUnknownState extends Error {
312
+ invokedMethod: 'waitForCompletion';
313
+ runnerState: string;
314
+ constructor(invokedMethod: 'waitForCompletion', runnerState: string);
315
+ }
316
+ declare class RetryUtilsErrRunnerNotRunning extends Error {
317
+ invokedMethod: 'waitForCompletion';
318
+ constructor(invokedMethod: 'waitForCompletion');
319
+ }
320
+
321
+ export { ATTEMPT_HANDLED, ATTEMPT_STARTED, type CancelResult, type ForceTryOptions, OPERATION_ENDED, OPERATION_STARTED, type OnAttemptHandledInfo, type OnAttemptStartedInfo, type OnOperationEndedInfo, type OnOperationStartedInfo, type OperationStartedType, type ReportResult, type ReportResultStatus, RetryPolicy, type RetryPolicyOptions, type RetryPolicyOptionsStrategyExponential, type RetryPolicyOptionsStrategyFixed, type RetryPolicyValidated, type RetryQueryResult, RetryRunner, type RetryRunnerOptions, RetryUtilsErrPolicyConfigInvalidStrategy, RetryUtilsErrRunnerAlreadyCompleted, RetryUtilsErrRunnerAlreadyRunning, RetryUtilsErrRunnerAttemptsExhausted, RetryUtilsErrRunnerCancelPending, RetryUtilsErrRunnerForceTryRetryInProgress, RetryUtilsErrRunnerLastRetryFatallyFailed, RetryUtilsErrRunnerLockAcquisitionError, RetryUtilsErrRunnerNotPaused, RetryUtilsErrRunnerNotRunning, RetryUtilsErrRunnerRetryCanceled, RetryUtilsErrRunnerUnexpectedError, RetryUtilsErrRunnerUnknownState, type RunAttemptStatusCodes, type RunResult, type RunResultNonSuccess, type RunResultSuccess, type RunnerErrorCode, type RunnerState };