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,2133 @@
1
+ // src/lib/strings.ts
2
+ function isString(value) {
3
+ return typeof value === "string";
4
+ }
5
+ function splitGraphemes(text) {
6
+ const graphemes = [];
7
+ let grapheme = "";
8
+ let zwjSequence = "";
9
+ for (let i = 0; i < text.length; i++) {
10
+ const char = text[i];
11
+ const nextChar = text[i + 1] || "";
12
+ const code = char.charCodeAt(0);
13
+ if (code >= 768 && code <= 879 || // Combining Diacritical Marks
14
+ code >= 6832 && code <= 6911 || // Combining Diacritical Marks Extended
15
+ code >= 7616 && code <= 7679 || // Combining Diacritical Marks Supplement
16
+ code >= 65056 && code <= 65071 || // Combining Half Marks
17
+ code >= 3633 && code <= 3642 || // Thai combining marks
18
+ code >= 3655 && code <= 3662) {
19
+ grapheme += char;
20
+ } else if (char === "\u200D") {
21
+ zwjSequence += grapheme + char;
22
+ grapheme = "";
23
+ } else {
24
+ if (grapheme) {
25
+ if (zwjSequence) {
26
+ graphemes.push(zwjSequence + grapheme);
27
+ zwjSequence = "";
28
+ } else {
29
+ graphemes.push(grapheme);
30
+ }
31
+ }
32
+ grapheme = char;
33
+ if (char >= "\uD800" && char <= "\uDBFF" && nextChar >= "\uDC00" && nextChar <= "\uDFFF") {
34
+ grapheme += nextChar;
35
+ i++;
36
+ }
37
+ }
38
+ }
39
+ if (grapheme) {
40
+ if (zwjSequence) {
41
+ graphemes.push(zwjSequence + grapheme);
42
+ } else {
43
+ graphemes.push(grapheme);
44
+ }
45
+ }
46
+ return graphemes;
47
+ }
48
+
49
+ // src/lib/retry-utils/lib/retry-utils-errors.ts
50
+ var RetryUtilsErrPolicyConfigInvalidStrategy = class extends Error {
51
+ constructor(strategyProvided, validStrategies) {
52
+ super("Invalid strategy provided.");
53
+ this.strategyProvided = strategyProvided;
54
+ this.validStrategies = validStrategies;
55
+ this.name = "RetryUtilsErrPolicyConfigInvalidStrategy";
56
+ }
57
+ };
58
+ var RetryUtilsErrRunnerAlreadyCompleted = class extends Error {
59
+ constructor(invokedMethod) {
60
+ super(
61
+ "The runner has already completed running the operation. Use the .reset() method, and .run() to run the operation again."
62
+ );
63
+ this.invokedMethod = invokedMethod;
64
+ this.name = "RetryUtilsErrRunnerAlreadyCompleted";
65
+ }
66
+ };
67
+ var RetryUtilsErrRunnerAlreadyRunning = class extends Error {
68
+ constructor(invokedMethod) {
69
+ super("The operation is already running and cannot be started again.");
70
+ this.invokedMethod = invokedMethod;
71
+ this.name = "RetryUtilsErrRunnerAlreadyRunning";
72
+ }
73
+ };
74
+ var RetryUtilsErrRunnerForceTryRetryInProgress = class extends Error {
75
+ constructor(invokedMethod) {
76
+ super("Force try retry is already in progress.");
77
+ this.invokedMethod = invokedMethod;
78
+ this.name = "RetryUtilsErrRunnerForceTryRetryInProgress";
79
+ }
80
+ };
81
+ var RetryUtilsErrRunnerNotPaused = class extends Error {
82
+ constructor(invokedMethod) {
83
+ super(
84
+ "The runner is not in a paused state. resume() can only be called when the runner state is stopped."
85
+ );
86
+ this.invokedMethod = invokedMethod;
87
+ this.name = "RetryUtilsErrRunnerNotPaused";
88
+ }
89
+ };
90
+ var RetryUtilsErrRunnerCancelPending = class extends Error {
91
+ constructor(invokedMethod) {
92
+ super(
93
+ "A cancel operation is pending. The operation cannot be started again."
94
+ );
95
+ this.invokedMethod = invokedMethod;
96
+ this.name = "RetryUtilsErrRunnerCancelPending";
97
+ }
98
+ };
99
+ var RetryUtilsErrRunnerRetryCanceled = class extends Error {
100
+ constructor(invokedMethod) {
101
+ super(
102
+ "The operation was already canceled. Use either .resume(), .forceTry() or .reset() and .run() to run the operation again."
103
+ );
104
+ this.invokedMethod = invokedMethod;
105
+ this.name = "RetryUtilsErrRunnerRetryCanceled";
106
+ }
107
+ };
108
+ var RetryUtilsErrRunnerLastRetryFatallyFailed = class extends Error {
109
+ constructor(invokedMethod) {
110
+ super(
111
+ "The last retry attempt failed fatally. The operation cannot be retried. Use either .reset() then .run() or .forceTry() to run the operation again."
112
+ );
113
+ this.invokedMethod = invokedMethod;
114
+ this.name = "RetryUtilsErrRunnerLastRetryFatallyFailed";
115
+ }
116
+ };
117
+ var RetryUtilsErrRunnerAttemptsExhausted = class extends Error {
118
+ constructor(invokedMethod) {
119
+ super(
120
+ "All attempts were exhausted. The operation cannot be retried. Use either .reset() then .run() or .forceTry() to run the operation again."
121
+ );
122
+ this.invokedMethod = invokedMethod;
123
+ this.name = "RetryUtilsErrRunnerAttemptsExhausted";
124
+ }
125
+ };
126
+ var RetryUtilsErrRunnerLockAcquisitionError = class extends Error {
127
+ constructor(invokedMethod) {
128
+ super(
129
+ "Failed to acquire operation lock. Cannot attempt to run the operation."
130
+ );
131
+ this.invokedMethod = invokedMethod;
132
+ this.name = "RetryUtilsErrRunnerLockAcquisitionError";
133
+ }
134
+ };
135
+ var RetryUtilsErrRunnerUnexpectedError = class extends Error {
136
+ constructor(invokedMethod, originalError) {
137
+ super("An unexpected error occurred.");
138
+ this.invokedMethod = invokedMethod;
139
+ this.originalError = originalError;
140
+ this.name = "RetryUtilsErrRunnerUnexpectedError";
141
+ }
142
+ };
143
+ var RetryUtilsErrRunnerUnknownState = class extends Error {
144
+ constructor(invokedMethod, runnerState) {
145
+ super("An unknown runner state was encountered.");
146
+ this.invokedMethod = invokedMethod;
147
+ this.runnerState = runnerState;
148
+ this.name = "RetryUtilsErrRunnerUnknownState";
149
+ }
150
+ };
151
+ var RetryUtilsErrRunnerNotRunning = class extends Error {
152
+ constructor(invokedMethod) {
153
+ super("The operation is not currently running.");
154
+ this.invokedMethod = invokedMethod;
155
+ this.name = "RetryUtilsErrRunnerNotRunning";
156
+ }
157
+ };
158
+
159
+ // src/lib/clamp.ts
160
+ function clamp(value, min, max) {
161
+ return Math.max(min, Math.min(value, max));
162
+ }
163
+
164
+ // src/lib/retry-utils/lib/utils.ts
165
+ function calculateExponentialDelay({
166
+ retryCount,
167
+ minTimeoutMS,
168
+ maxTimeoutMS,
169
+ factor,
170
+ dispersion,
171
+ randomFn
172
+ }) {
173
+ let delay = minTimeoutMS * Math.pow(factor, retryCount);
174
+ if (dispersion > 0) {
175
+ const dispersionAmount = delay * dispersion;
176
+ delay += randomFn() * (dispersionAmount * 2) - dispersionAmount;
177
+ }
178
+ return clamp(delay, minTimeoutMS, maxTimeoutMS);
179
+ }
180
+ function extractErrorMessage(error) {
181
+ if (error instanceof Error) {
182
+ return error.message;
183
+ }
184
+ if (error !== null && error !== void 0 && typeof error === "object" && "message" in error && typeof error.message === "string") {
185
+ return error.message;
186
+ }
187
+ if (error !== null && error !== void 0 && typeof error === "object" && "error" in error) {
188
+ const nested = error.error;
189
+ if (nested instanceof Error) {
190
+ return nested.message;
191
+ } else if (nested !== null && nested !== void 0 && typeof nested === "object" && "message" in nested && typeof nested.message === "string") {
192
+ return nested.message;
193
+ } else {
194
+ return String(nested);
195
+ }
196
+ }
197
+ return String(error);
198
+ }
199
+ function getMostCommonError(errors) {
200
+ if (errors.length === 0) {
201
+ return null;
202
+ }
203
+ const refCounts = /* @__PURE__ */ new Map();
204
+ for (const error of errors) {
205
+ refCounts.set(error, (refCounts.get(error) ?? 0) + 1);
206
+ }
207
+ const messageCounts = /* @__PURE__ */ new Map();
208
+ for (const error of errors) {
209
+ const message = extractErrorMessage(error);
210
+ const existing = messageCounts.get(message);
211
+ if (existing) {
212
+ existing.count += 1;
213
+ } else {
214
+ messageCounts.set(message, { count: 1, error });
215
+ }
216
+ }
217
+ let mostCommon = null;
218
+ let maxCount = 0;
219
+ for (const [error, count] of refCounts) {
220
+ if (count > maxCount) {
221
+ maxCount = count;
222
+ mostCommon = error;
223
+ }
224
+ }
225
+ for (const { count, error } of messageCounts.values()) {
226
+ if (count > maxCount) {
227
+ maxCount = count;
228
+ mostCommon = error;
229
+ }
230
+ }
231
+ return mostCommon;
232
+ }
233
+
234
+ // src/lib/retry-utils/lib/retry-policy.ts
235
+ var RetryPolicy = class {
236
+ policy;
237
+ currentState = this.getEmptyCurrentState();
238
+ /**
239
+ * Gets the validated policy information for this retry policy instance.
240
+ * @returns {RetryPolicyValidated} The current retry policy settings.
241
+ */
242
+ get policyInfo() {
243
+ return this.policy;
244
+ }
245
+ /**
246
+ * Gets the total number of attempts made, including the initial attempt and any retries.
247
+ * @returns {number} The total number of attempts.
248
+ */
249
+ get attempts() {
250
+ if (this.currentState.wasSuccessful) {
251
+ return this.currentState.errors.length + 1;
252
+ } else {
253
+ return clamp(
254
+ this.currentState.errors.length,
255
+ this.wasInitialAttemptTaken ? 1 : 0,
256
+ Infinity
257
+ );
258
+ }
259
+ }
260
+ /**
261
+ * Checks if the initial attempt has been taken.
262
+ */
263
+ get wasInitialAttemptTaken() {
264
+ return this.currentState.wasInitialAttemptTaken;
265
+ }
266
+ /**
267
+ * Checks if the last operation attempt was successful. (used to calculate the number of attempts made)
268
+ */
269
+ get wasSuccessful() {
270
+ return this.currentState.wasSuccessful;
271
+ }
272
+ /**
273
+ * Gets the maximum number of retry attempts allowed by the current policy.
274
+ * @returns {number} The maximum number of retry attempts.
275
+ */
276
+ get maxRetryAttempts() {
277
+ return this.policy.maxRetryAttempts;
278
+ }
279
+ /**
280
+ * Gets the number of retry attempts made, excluding the initial attempt.
281
+ * @returns {number} The number of retries.
282
+ */
283
+ get retryCount() {
284
+ if (!this.wasInitialAttemptTaken) {
285
+ return 0;
286
+ }
287
+ return Math.max(this.attempts - 1, 0);
288
+ }
289
+ /**
290
+ * Checks if the retry attempts have been exhausted.
291
+ * @returns {boolean} True if the number of retries has reached the maximum allowed attempts; otherwise, false.
292
+ */
293
+ get areAttemptsExhausted() {
294
+ return this.retryCount >= this.maxRetryAttempts;
295
+ }
296
+ /**
297
+ * Gets a list of errors recorded from each retry attempt.
298
+ * @returns {unknown[]} An array of errors encountered during retry attempts.
299
+ */
300
+ get errors() {
301
+ return [...this.currentState.errors];
302
+ }
303
+ /**
304
+ * Gets the most common error encountered across all retry attempts.
305
+ *
306
+ * This method caches the most common error for performance. If the cache is invalidated due to a new error,
307
+ * it recalculates the most common error.
308
+ *
309
+ * @returns {unknown} The most common error, or null if no errors have been encountered.
310
+ */
311
+ get mostCommonError() {
312
+ if (this.currentState.mostCommonErrorCached.has) {
313
+ return this.currentState.mostCommonErrorCached.value;
314
+ } else {
315
+ const mostCommon = getMostCommonError(this.currentState.errors);
316
+ this.currentState.mostCommonErrorCached.has = true;
317
+ this.currentState.mostCommonErrorCached.value = mostCommon;
318
+ return mostCommon;
319
+ }
320
+ }
321
+ /**
322
+ * Gets the last error encountered during the retry attempts.
323
+ * @returns {unknown} The last error encountered, or null if no errors have been recorded.
324
+ */
325
+ get lastError() {
326
+ if (this.currentState.errors.length === 0) {
327
+ return null;
328
+ } else {
329
+ return this.currentState.errors[this.currentState.errors.length - 1];
330
+ }
331
+ }
332
+ /**
333
+ * Constructs a RetryPolicy instance with specified options.
334
+ *
335
+ * @param {RetryPolicyOptions} policy The retry policy options, including strategy, maximum retry attempts,
336
+ * and other parameters specific to the fixed or exponential strategy.
337
+ *
338
+ * Throws an error if an invalid retry strategy is provided.
339
+ */
340
+ constructor(policy) {
341
+ const DEFAULT_MAX_RETRY_ATTEMPTS = 10;
342
+ const DEFAULT_FACTOR = 1.5;
343
+ const DEFAULT_MIN_TIMEOUT_MS = 1e3;
344
+ const DEFAULT_MAX_TIMEOUT_MS = 3e4;
345
+ const DEFAULT_DISPERSION = 0.1;
346
+ if (policy.strategy === "fixed") {
347
+ this.policy = {
348
+ strategy: "fixed",
349
+ maxRetryAttempts: Math.floor(
350
+ clamp(
351
+ policy.maxRetryAttempts ?? DEFAULT_MAX_RETRY_ATTEMPTS,
352
+ 1,
353
+ Infinity
354
+ )
355
+ ),
356
+ delayMS: clamp(policy.delayMS ?? DEFAULT_MIN_TIMEOUT_MS, 1, Infinity)
357
+ };
358
+ } else if (policy.strategy === "exponential") {
359
+ const minTimeoutMS = clamp(
360
+ policy.minTimeoutMS ?? DEFAULT_MIN_TIMEOUT_MS,
361
+ 1,
362
+ Infinity
363
+ );
364
+ const maxTimeoutMS = clamp(
365
+ policy.maxTimeoutMS ?? DEFAULT_MAX_TIMEOUT_MS,
366
+ 1,
367
+ Infinity
368
+ );
369
+ const finalMin = Math.min(minTimeoutMS, maxTimeoutMS);
370
+ const finalMax = Math.max(minTimeoutMS, maxTimeoutMS);
371
+ this.policy = {
372
+ strategy: "exponential",
373
+ maxRetryAttempts: Math.floor(
374
+ clamp(
375
+ policy.maxRetryAttempts ?? DEFAULT_MAX_RETRY_ATTEMPTS,
376
+ 1,
377
+ Infinity
378
+ )
379
+ ),
380
+ factor: clamp(policy.factor ?? DEFAULT_FACTOR, 1, Infinity),
381
+ minTimeoutMS: finalMin,
382
+ maxTimeoutMS: finalMax,
383
+ dispersion: clamp(policy.dispersion ?? DEFAULT_DISPERSION, 0, 1)
384
+ };
385
+ } else {
386
+ throw new RetryUtilsErrPolicyConfigInvalidStrategy(
387
+ isString(policy["strategy"]) ? policy["strategy"] : "unknown",
388
+ ["fixed", "exponential"]
389
+ );
390
+ }
391
+ }
392
+ /**
393
+ * Resets the retry policy to its initial state.
394
+ *
395
+ * This method clears all recorded errors and marks the initial attempt as not taken,
396
+ * effectively resetting the state of the retry policy for a new operation.
397
+ */
398
+ reset() {
399
+ this.currentState = this.getEmptyCurrentState();
400
+ }
401
+ /**
402
+ * Determines if the initial operation attempt should proceed.
403
+ *
404
+ * This method checks if the initial attempt has already been taken and updates the state to reflect that
405
+ * the initial attempt is now being made. This method is used to ensure that the retry logic only kicks in after
406
+ * the first attempt has failed.
407
+ *
408
+ * Note that even upon success, you should call the reset method to clear the state for the next operation.
409
+ *
410
+ * @returns {boolean} True if the initial attempt has not been made yet; otherwise, false.
411
+ */
412
+ shouldDoFirstTry() {
413
+ if (this.currentState.wasInitialAttemptTaken) {
414
+ return false;
415
+ } else {
416
+ this.currentState.wasInitialAttemptTaken = true;
417
+ return true;
418
+ }
419
+ }
420
+ /**
421
+ * Marks the last operation attempt as successful.
422
+ */
423
+ markAsSuccessful() {
424
+ this.currentState.wasSuccessful = true;
425
+ }
426
+ /**
427
+ * Records an error that occurred during the last operation attempt.
428
+ *
429
+ * Does not check if was successful or not, nor checks if should retry or not.
430
+ */
431
+ reportError(error) {
432
+ this.currentState.errors.push(error);
433
+ this.currentState.mostCommonErrorCached.has = false;
434
+ }
435
+ /**
436
+ * Determines if a retry should be made based on the current state and the provided error.
437
+ *
438
+ * When called, this method stores the provided error, checks if further retries are allowed based on the
439
+ * maximum retry attempts, and calculates the delay for the next retry if applicable.
440
+ *
441
+ * It also invalidates the cached most common error since the error state has changed.
442
+ *
443
+ * @param {unknown} error The error that resulted from the last operation attempt. Can be omitted when `isQueryOnly` is `true`.
444
+ * @param {boolean} isQueryOnly If true, the method only queries if a retry should be made without storing the error.
445
+ * @returns {RetryQueryResult} An object indicating whether a retry should be attempted and the delay before the next attempt.
446
+ */
447
+ shouldRetry(error, isQueryOnly = false) {
448
+ if (this.currentState.wasSuccessful) {
449
+ if (!isQueryOnly) {
450
+ this.reportError(error);
451
+ }
452
+ return { shouldRetry: false, delayMS: 0 };
453
+ }
454
+ if (!isQueryOnly) {
455
+ this.reportError(error);
456
+ }
457
+ if (this.areAttemptsExhausted) {
458
+ return { shouldRetry: false, delayMS: 0 };
459
+ } else {
460
+ const delayMS = this.calculateNextDelay();
461
+ return { shouldRetry: true, delayMS };
462
+ }
463
+ }
464
+ /**
465
+ * Returning a fresh copy of the current state
466
+ * to be immutable and not changed by the caller
467
+ */
468
+ getEmptyCurrentState() {
469
+ return {
470
+ wasInitialAttemptTaken: false,
471
+ wasSuccessful: false,
472
+ errors: [],
473
+ mostCommonErrorCached: {
474
+ has: false,
475
+ value: null
476
+ }
477
+ };
478
+ }
479
+ /**
480
+ * Calculates the delay before the next retry attempt based on the current retry policy.
481
+ *
482
+ * For a fixed strategy, it returns the specified delay. For an exponential strategy, it calculates the delay
483
+ * based on the exponential backoff formula, considering the number of retry attempts, the base delay,
484
+ * the exponential factor, and any specified dispersion to introduce randomness.
485
+ *
486
+ * @returns {number} The calculated delay in milliseconds before the next retry attempt.
487
+ */
488
+ calculateNextDelay() {
489
+ if (this.policy.strategy === "fixed") {
490
+ return this.policy.delayMS;
491
+ } else if (this.policy.strategy === "exponential") {
492
+ return calculateExponentialDelay({
493
+ retryCount: this.retryCount,
494
+ minTimeoutMS: this.policy.minTimeoutMS,
495
+ maxTimeoutMS: this.policy.maxTimeoutMS,
496
+ factor: this.policy.factor,
497
+ dispersion: this.policy.dispersion,
498
+ randomFn: Math.random
499
+ });
500
+ }
501
+ return 1;
502
+ }
503
+ };
504
+
505
+ // src/lib/constants.ts
506
+ var BLANK_SPACE = " ";
507
+ var EOL = "\n";
508
+ var DOUBLE_EOL = EOL + EOL;
509
+ var INDENT = " ".repeat(4);
510
+ var DOUBLE_INDENT = INDENT + INDENT;
511
+ var ASCII_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
512
+ var ASCII_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
513
+ var ASCII_LETTERS = ASCII_LOWERCASE + ASCII_UPPERCASE;
514
+ var DIGITS = "0123456789";
515
+ var HEX_DIGITS = DIGITS + "abcdefABCDEF";
516
+ var PUNCTUATION = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
517
+ var WHITESPACE = " \n\r\v\f";
518
+ var PRINTABLE = DIGITS + ASCII_LETTERS + PUNCTUATION + WHITESPACE;
519
+
520
+ // src/lib/padding-utils.ts
521
+ function padLeft(str, length, padStr = BLANK_SPACE) {
522
+ return str.padStart(length, padStr);
523
+ }
524
+ function padRight(str, length, padStr = BLANK_SPACE) {
525
+ return str.padEnd(length, padStr);
526
+ }
527
+ function padCenter(str, length, prefer = "left", padStr = BLANK_SPACE) {
528
+ const midStrLength = length - str.length;
529
+ if (midStrLength > 0) {
530
+ const padLeftAmount = prefer === "left" ? Math.ceil(midStrLength / 2) : Math.floor(midStrLength / 2);
531
+ const padRightAmount = prefer === "left" ? Math.floor(midStrLength / 2) : Math.ceil(midStrLength / 2);
532
+ return padLeft("", padLeftAmount, padStr) + str + padRight("", padRightAmount, padStr);
533
+ } else {
534
+ return str;
535
+ }
536
+ }
537
+ function padCenterPreferRight(str, length, padStr = BLANK_SPACE) {
538
+ return padCenter(str, length, "right", padStr);
539
+ }
540
+
541
+ // src/lib/ascii-tables/ascii-table-utils.ts
542
+ import stringWidth from "string-width";
543
+ var ASCIITableUtils = class _ASCIITableUtils {
544
+ static centerText(text, width) {
545
+ return padCenterPreferRight(text, width, " ");
546
+ }
547
+ static createSeparator(columnWidths, character = "=") {
548
+ const totalWidth = columnWidths.reduce((sum, width) => sum + width + 3, 0) - 1;
549
+ return `+${padRight("", totalWidth, character)}+`;
550
+ }
551
+ static wrapText(text, maxLength) {
552
+ const words = text.split(" ");
553
+ const lines = [];
554
+ let currentLine = "";
555
+ for (const word of words) {
556
+ if (stringWidth(currentLine) + stringWidth(word) + 1 <= maxLength) {
557
+ currentLine += (currentLine ? " " : "") + word;
558
+ } else {
559
+ if (currentLine) {
560
+ lines.push(currentLine);
561
+ }
562
+ if (stringWidth(word) <= maxLength) {
563
+ currentLine = word;
564
+ } else {
565
+ const subWords = _ASCIITableUtils.splitWord(word, maxLength);
566
+ lines.push(...subWords.slice(0, -1));
567
+ currentLine = subWords[subWords.length - 1];
568
+ }
569
+ }
570
+ }
571
+ if (currentLine) {
572
+ lines.push(currentLine);
573
+ }
574
+ return lines;
575
+ }
576
+ static splitWord(word, maxLength) {
577
+ const graphemes = splitGraphemes(word);
578
+ const subWords = [];
579
+ let currentSubWord = "";
580
+ for (const grapheme of graphemes) {
581
+ if (stringWidth(currentSubWord + grapheme) <= maxLength) {
582
+ currentSubWord += grapheme;
583
+ } else {
584
+ subWords.push(currentSubWord);
585
+ currentSubWord = grapheme;
586
+ }
587
+ }
588
+ if (currentSubWord) {
589
+ subWords.push(currentSubWord);
590
+ }
591
+ return subWords;
592
+ }
593
+ };
594
+
595
+ // src/lib/ascii-tables/multi-column-ascii-table.ts
596
+ import stringWidth2 from "string-width";
597
+ var MultiColumnASCIITable = class {
598
+ headers;
599
+ rows;
600
+ tableWidth;
601
+ emptyMessage;
602
+ widthMode;
603
+ constructor(headers, options = {}) {
604
+ this.headers = headers;
605
+ this.rows = [];
606
+ this.tableWidth = options.tableWidth || 80;
607
+ this.emptyMessage = options.emptyMessage || "";
608
+ this.widthMode = options.widthMode || "flex";
609
+ const minTableWidth = this.getMinimumWidth();
610
+ if (this.tableWidth < minTableWidth) {
611
+ throw new Error(
612
+ `Table width must be at least ${minTableWidth} to accommodate the headers.`
613
+ );
614
+ }
615
+ }
616
+ getMinimumWidth() {
617
+ return this.headers.length * 4 + 1;
618
+ }
619
+ addRow(row) {
620
+ if (row.length !== this.headers.length) {
621
+ throw new Error(
622
+ `Number of values in the row (${row.length}) must match the number of headers (${this.headers.length}).`
623
+ );
624
+ }
625
+ this.rows.push(row);
626
+ }
627
+ toString(options = {}) {
628
+ const tableWidth = options.tableWidth || this.tableWidth;
629
+ const emptyMessage = options.emptyMessage || this.emptyMessage;
630
+ if (this.rows.length === 0) {
631
+ const emptyTableWidth = Math.min(tableWidth, 40);
632
+ const separator = "+" + "-".repeat(emptyTableWidth - 2) + "+";
633
+ const emptyMessageLines = ASCIITableUtils.wrapText(
634
+ emptyMessage,
635
+ emptyTableWidth - 4
636
+ );
637
+ const emptyRows = emptyMessageLines.map((line) => {
638
+ const paddingLeft = " ".repeat(
639
+ Math.floor((emptyTableWidth - stringWidth2(line) - 4) / 2)
640
+ );
641
+ const paddingRight = " ".repeat(
642
+ Math.ceil((emptyTableWidth - stringWidth2(line) - 4) / 2)
643
+ );
644
+ return `| ${paddingLeft}${line}${paddingRight} |`;
645
+ });
646
+ if (emptyRows.length === 0) {
647
+ emptyRows.push(`| ${" ".repeat(emptyTableWidth - 4)} |`);
648
+ }
649
+ return [separator, ...emptyRows, separator].join("\n");
650
+ }
651
+ const columnWidths = this.calculateColumnWidths(options);
652
+ const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);
653
+ const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, "-");
654
+ let tableString = headerSeparator + "\n";
655
+ const header = this.renderRow(this.headers, columnWidths);
656
+ tableString += header + "\n" + rowSeparator + "\n";
657
+ const rows = this.rows.map((row) => {
658
+ return this.renderRow(row, columnWidths);
659
+ });
660
+ tableString += rows.join("\n" + rowSeparator + "\n");
661
+ tableString += "\n" + headerSeparator;
662
+ return tableString;
663
+ }
664
+ calculateColumnWidths(options = {}) {
665
+ const tableWidth = options.tableWidth || this.tableWidth;
666
+ const widthMode = options.widthMode || this.widthMode;
667
+ const numColumns = this.headers.length;
668
+ if (widthMode === "fixed") {
669
+ const availableWidth2 = tableWidth - (numColumns + 1) * 3 + 1;
670
+ const columnWidth = Math.floor(availableWidth2 / numColumns);
671
+ const extraWidth = availableWidth2 % numColumns;
672
+ const columnWidths = new Array(numColumns).fill(columnWidth);
673
+ for (let i = 0; i < extraWidth; i++) {
674
+ columnWidths[i] += 1;
675
+ }
676
+ return columnWidths;
677
+ }
678
+ const availableWidth = tableWidth - (numColumns + 1) * 3 + 1;
679
+ const maxColumnWidth = Math.floor(availableWidth / numColumns);
680
+ const totalContentWidth = this.headers.reduce(
681
+ (sum, header) => sum + stringWidth2(header),
682
+ 0
683
+ );
684
+ if (availableWidth >= totalContentWidth) {
685
+ const remainingWidth = availableWidth - totalContentWidth;
686
+ const extraCharWidth = Math.floor(remainingWidth / numColumns);
687
+ const extraCharRemainder = remainingWidth % numColumns;
688
+ const columnWidths = this.headers.map((header, index) => {
689
+ const extraWidth = index < extraCharRemainder ? 1 : 0;
690
+ return stringWidth2(header) + extraCharWidth + extraWidth;
691
+ });
692
+ return columnWidths;
693
+ } else {
694
+ const columnWidths = this.headers.map(() => maxColumnWidth);
695
+ return columnWidths;
696
+ }
697
+ }
698
+ renderRow(row, columnWidths) {
699
+ const wrappedCells = row.map((value, index) => {
700
+ const wrappedLines = ASCIITableUtils.wrapText(value, columnWidths[index]);
701
+ return wrappedLines.map((line) => line.padEnd(columnWidths[index])).join("\n");
702
+ });
703
+ const maxLines = Math.max(
704
+ ...wrappedCells.map((cell) => cell.split("\n").length)
705
+ );
706
+ const paddedRows = [];
707
+ for (let i = 0; i < maxLines; i++) {
708
+ const rowLine = wrappedCells.map((cell, index) => {
709
+ const cellLines = cell.split("\n");
710
+ const cellLine = cellLines[i] || "";
711
+ const padding = " ".repeat(columnWidths[index] - stringWidth2(cellLine));
712
+ return " " + cellLine + padding + " ";
713
+ });
714
+ paddedRows.push("|" + rowLine.join("|") + "|");
715
+ }
716
+ return paddedRows.join("\n");
717
+ }
718
+ };
719
+
720
+ // src/lib/ascii-tables/key-value-ascii-table.ts
721
+ import stringWidth3 from "string-width";
722
+ var KeyValueASCIITable = class _KeyValueASCIITable {
723
+ tableWidth;
724
+ emptyMessage;
725
+ autoAdjustWidthWhenPossible = true;
726
+ rows = [];
727
+ constructor(options = {}) {
728
+ const minTableWidth = this.getMinimumWidth();
729
+ if (options.tableWidth && options.tableWidth < minTableWidth) {
730
+ throw new Error(
731
+ `Table width must be at least ${minTableWidth} to accommodate the table structure.`
732
+ );
733
+ }
734
+ this.tableWidth = options.tableWidth || 80;
735
+ this.autoAdjustWidthWhenPossible = options.autoAdjustWidthWhenPossible ?? true;
736
+ this.emptyMessage = options.emptyMessage || "";
737
+ }
738
+ getMinimumWidth() {
739
+ return 9;
740
+ }
741
+ /**
742
+ * Adds key and value to the table but placing the value on its own row.
743
+ *
744
+ * @param key
745
+ * @param value
746
+ */
747
+ addValueOnSeparateRow(key, value) {
748
+ const row = { kind: "own", key, value };
749
+ this.rows.push(row);
750
+ }
751
+ /**
752
+ * Adds key and value to the table.
753
+ *
754
+ * If provided value is an instance of ASCIITable or MultiColumnASCIITable, it will be rendered as a nested table on its own row for readability.
755
+ *
756
+ * @param key
757
+ * @param value
758
+ */
759
+ addRow(key, value) {
760
+ const row = { kind: "regular", key, value };
761
+ this.rows.push(row);
762
+ }
763
+ toString(options = {}) {
764
+ const tableWidth = options.tableWidth || this.tableWidth;
765
+ const canAutoAdjustWidthWhenPossible = options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;
766
+ const emptyMessage = options.emptyMessage || this.emptyMessage;
767
+ if (this.rows.length === 0) {
768
+ const emptyTableWidth = Math.min(tableWidth, 40);
769
+ const separator = "+" + "-".repeat(emptyTableWidth - 2) + "+";
770
+ const emptyMessageLines = ASCIITableUtils.wrapText(
771
+ emptyMessage,
772
+ emptyTableWidth - 4
773
+ );
774
+ const emptyRows = emptyMessageLines.map((line) => {
775
+ const paddingLeft = padRight(
776
+ "",
777
+ Math.floor((emptyTableWidth - stringWidth3(line) - 4) / 2),
778
+ " "
779
+ );
780
+ const paddingRight = padRight(
781
+ "",
782
+ Math.ceil((emptyTableWidth - stringWidth3(line) - 4) / 2),
783
+ " "
784
+ );
785
+ return `| ${paddingLeft}${line}${paddingRight} |`;
786
+ });
787
+ if (emptyRows.length === 0) {
788
+ emptyRows.push(`| ${" ".repeat(emptyTableWidth - 4)} |`);
789
+ }
790
+ return [separator, ...emptyRows, separator].join("\n");
791
+ }
792
+ const columnWidths = this.calculateColumnWidths(options);
793
+ const headerSeparator = ASCIITableUtils.createSeparator(columnWidths);
794
+ const rowSeparator = ASCIITableUtils.createSeparator(columnWidths, "-");
795
+ let tableString = headerSeparator + "\n";
796
+ for (const [rowIndex, row] of this.rows.entries()) {
797
+ const { kind, key, value } = row;
798
+ if (kind === "own" || value instanceof _KeyValueASCIITable || value instanceof MultiColumnASCIITable || Array.isArray(value)) {
799
+ const keyString = ASCIITableUtils.centerText(
800
+ key,
801
+ columnWidths[0] + columnWidths[1] + 3
802
+ );
803
+ tableString += `| ${keyString} |
804
+ `;
805
+ tableString += rowSeparator + "\n";
806
+ let valueString = "";
807
+ if (value instanceof _KeyValueASCIITable) {
808
+ valueString = this.formatValue(
809
+ value,
810
+ tableWidth - 4,
811
+ canAutoAdjustWidthWhenPossible,
812
+ ""
813
+ );
814
+ } else if (value instanceof MultiColumnASCIITable) {
815
+ valueString = this.formatValue(
816
+ value,
817
+ tableWidth - 4,
818
+ canAutoAdjustWidthWhenPossible,
819
+ ""
820
+ );
821
+ } else if (Array.isArray(value)) {
822
+ valueString = this.formatValue(
823
+ value,
824
+ tableWidth - 4,
825
+ canAutoAdjustWidthWhenPossible,
826
+ ""
827
+ );
828
+ } else if (row.kind === "own") {
829
+ valueString = this.formatTableRowOnOwnRow(
830
+ value,
831
+ tableWidth - 4,
832
+ tableWidth
833
+ );
834
+ }
835
+ const valueLines = valueString.split("\n");
836
+ const paddedValueLines = valueLines.map((line) => {
837
+ const padding = padRight("", tableWidth - stringWidth3(line) - 4, " ");
838
+ return `| ${line}${padding} |`;
839
+ });
840
+ tableString += paddedValueLines.join("\n") + "\n";
841
+ tableString += headerSeparator + "\n";
842
+ } else {
843
+ const keyLines = ASCIITableUtils.wrapText(key, columnWidths[0]);
844
+ const valueLines = ASCIITableUtils.wrapText(
845
+ this.formatValue(
846
+ value,
847
+ columnWidths[1],
848
+ canAutoAdjustWidthWhenPossible,
849
+ ""
850
+ ),
851
+ columnWidths[1]
852
+ );
853
+ const maxLines = Math.max(keyLines.length, valueLines.length);
854
+ for (let i = 0; i < maxLines; i++) {
855
+ const keyLine = keyLines[i] || "";
856
+ const valueLine = valueLines[i] || "";
857
+ const keyPadding = " ".repeat(columnWidths[0] - stringWidth3(keyLine));
858
+ const valuePadding = " ".repeat(
859
+ columnWidths[1] - stringWidth3(valueLine)
860
+ );
861
+ tableString += `| ${keyLine}${keyPadding} | ${valueLine}${valuePadding} |
862
+ `;
863
+ if (i === maxLines - 1) {
864
+ if (rowIndex === this.rows.length - 1) {
865
+ tableString += headerSeparator + "\n";
866
+ } else {
867
+ tableString += rowSeparator + "\n";
868
+ }
869
+ }
870
+ }
871
+ }
872
+ }
873
+ return tableString.trim();
874
+ }
875
+ calculateColumnWidths(options = {}) {
876
+ const tableWidth = options.tableWidth || this.tableWidth;
877
+ const canAutoAdjustWidthWhenPossible = options.autoAdjustWidthWhenPossible ?? this.autoAdjustWidthWhenPossible;
878
+ const columnWidths = [0, 0];
879
+ for (const row of this.rows) {
880
+ const { key, value } = row;
881
+ const keyWidth = stringWidth3(key);
882
+ const maxKeyWidth = Math.floor((tableWidth - 7) / 2);
883
+ if (keyWidth > columnWidths[0]) {
884
+ columnWidths[0] = Math.min(keyWidth, maxKeyWidth);
885
+ columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);
886
+ }
887
+ if (typeof value === "string") {
888
+ const valueWidth = Math.max(
889
+ ...value.split("\n").map((line) => stringWidth3(line))
890
+ );
891
+ if (valueWidth > columnWidths[1]) {
892
+ columnWidths[1] = Math.min(
893
+ valueWidth,
894
+ tableWidth - columnWidths[0] - 7
895
+ );
896
+ columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);
897
+ }
898
+ } else if (row.kind === "own") {
899
+ let valueWidth = 0;
900
+ if (isString(value)) {
901
+ valueWidth = Math.max(
902
+ ...value.split("\n").map((line) => stringWidth3(line))
903
+ );
904
+ }
905
+ if (valueWidth > columnWidths[1]) {
906
+ columnWidths[1] = Math.min(
907
+ valueWidth,
908
+ tableWidth - columnWidths[0] - 7
909
+ );
910
+ columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);
911
+ }
912
+ } else if (value instanceof _KeyValueASCIITable) {
913
+ let nestedTableColumnWidths = [];
914
+ if (canAutoAdjustWidthWhenPossible) {
915
+ const minWidth = value.getMinimumWidth();
916
+ const availableWidth2 = tableWidth - columnWidths[0] - 7;
917
+ const adjustedWidth = clamp(availableWidth2, minWidth, availableWidth2);
918
+ nestedTableColumnWidths = value.calculateColumnWidths({
919
+ tableWidth: adjustedWidth
920
+ });
921
+ } else {
922
+ nestedTableColumnWidths = value.calculateColumnWidths();
923
+ }
924
+ const nestedTableWidth = nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) + nestedTableColumnWidths.length * 3 - 1;
925
+ const availableWidth = tableWidth - columnWidths[0] - 7;
926
+ if (nestedTableWidth > availableWidth) {
927
+ columnWidths[1] = availableWidth;
928
+ } else {
929
+ columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);
930
+ }
931
+ } else if (value instanceof MultiColumnASCIITable) {
932
+ let nestedTableColumnWidths = [];
933
+ if (canAutoAdjustWidthWhenPossible) {
934
+ const minWidth = value.getMinimumWidth();
935
+ const availableWidth2 = tableWidth - columnWidths[0] - 7;
936
+ const adjustedWidth = clamp(availableWidth2, minWidth, availableWidth2);
937
+ nestedTableColumnWidths = value.calculateColumnWidths({
938
+ tableWidth: adjustedWidth
939
+ });
940
+ } else {
941
+ nestedTableColumnWidths = value.calculateColumnWidths();
942
+ }
943
+ const nestedTableWidth = nestedTableColumnWidths.reduce((sum, width) => sum + width, 0) + nestedTableColumnWidths.length * 3 - 1;
944
+ const availableWidth = tableWidth - columnWidths[0] - 7;
945
+ if (nestedTableWidth > availableWidth) {
946
+ columnWidths[1] = availableWidth;
947
+ } else {
948
+ columnWidths[1] = Math.max(columnWidths[1], nestedTableWidth);
949
+ }
950
+ } else if (Array.isArray(value)) {
951
+ for (const nestedCell of value) {
952
+ const nestedKeyWidth = stringWidth3(nestedCell.key);
953
+ const maxNestedKeyWidth = Math.floor((tableWidth - 7) / 2);
954
+ if (nestedKeyWidth > columnWidths[0]) {
955
+ columnWidths[0] = Math.min(nestedKeyWidth, maxNestedKeyWidth);
956
+ columnWidths[1] = Math.max(0, tableWidth - columnWidths[0] - 7);
957
+ }
958
+ if (typeof nestedCell.value === "string") {
959
+ const nestedValueWidth = Math.max(
960
+ ...nestedCell.value.split("\n").map((line) => stringWidth3(line))
961
+ );
962
+ if (nestedValueWidth > columnWidths[1]) {
963
+ columnWidths[1] = Math.min(
964
+ nestedValueWidth,
965
+ tableWidth - columnWidths[0] - 7
966
+ );
967
+ columnWidths[0] = Math.max(0, tableWidth - columnWidths[1] - 7);
968
+ }
969
+ }
970
+ }
971
+ }
972
+ }
973
+ return columnWidths;
974
+ }
975
+ formatValue(value, cellWidth, canAutoAdjustWidthWhenPossible, indent = "") {
976
+ if (typeof value === "string") {
977
+ return value;
978
+ } else if (typeof value === "number") {
979
+ return String(value);
980
+ } else if (typeof value === "boolean") {
981
+ return String(value);
982
+ } else if (value === null) {
983
+ return "null";
984
+ } else if (value === void 0) {
985
+ return "undefined";
986
+ } else if (value instanceof _KeyValueASCIITable) {
987
+ let nestedTableLines;
988
+ if (canAutoAdjustWidthWhenPossible) {
989
+ const minWidth = value.getMinimumWidth();
990
+ const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);
991
+ nestedTableLines = value.toString({ tableWidth: adjustedWidth }).split("\n");
992
+ } else {
993
+ nestedTableLines = value.toString().split("\n");
994
+ }
995
+ const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);
996
+ return indentedLines.join("\n");
997
+ } else if (value instanceof MultiColumnASCIITable) {
998
+ let nestedTableLines;
999
+ if (canAutoAdjustWidthWhenPossible) {
1000
+ const minWidth = value.getMinimumWidth();
1001
+ const adjustedWidth = clamp(cellWidth, minWidth, cellWidth);
1002
+ nestedTableLines = value.toString({ tableWidth: adjustedWidth }).split("\n");
1003
+ } else {
1004
+ nestedTableLines = value.toString().split("\n");
1005
+ }
1006
+ const indentedLines = nestedTableLines.map((line) => `${indent}${line}`);
1007
+ return indentedLines.join("\n");
1008
+ } else if (Array.isArray(value)) {
1009
+ const nestedValueLines = [];
1010
+ for (const { key, value: nestedValue } of value) {
1011
+ const formattedKey = `${indent}${key}:`;
1012
+ const formattedValue = this.formatValue(
1013
+ nestedValue,
1014
+ cellWidth - indent.length - stringWidth3(key) - 2,
1015
+ canAutoAdjustWidthWhenPossible,
1016
+ `${indent}`
1017
+ );
1018
+ const wrappedSpacer = padRight("", 4, " ");
1019
+ const wrappedValue = formattedValue.split("\n").map((line) => `${indent}${wrappedSpacer}${line}`);
1020
+ nestedValueLines.push(formattedKey);
1021
+ nestedValueLines.push(...wrappedValue);
1022
+ nestedValueLines.push("");
1023
+ }
1024
+ return nestedValueLines.slice(0, -1).join("\n");
1025
+ } else {
1026
+ throw new TypeError("Invalid value type provided");
1027
+ }
1028
+ }
1029
+ formatTableRowOnOwnRow(value, width, maxRowLength) {
1030
+ const lines = value.split("\n");
1031
+ const paddedLines = lines.map((line) => {
1032
+ const wrappedLines = ASCIITableUtils.wrapText(line, maxRowLength - 4);
1033
+ return wrappedLines.map((wrappedLine) => {
1034
+ const padding = padRight(
1035
+ "",
1036
+ width - stringWidth3(wrappedLine) - 2,
1037
+ " "
1038
+ );
1039
+ return `${wrappedLine}${padding}`;
1040
+ }).join("\n");
1041
+ });
1042
+ return paddedLines.join("\n");
1043
+ }
1044
+ };
1045
+
1046
+ // src/lib/error-to-string.ts
1047
+ function safeStringify(value) {
1048
+ if (value === null || value === void 0) {
1049
+ return String(value);
1050
+ }
1051
+ switch (typeof value) {
1052
+ case "string":
1053
+ return value;
1054
+ case "number":
1055
+ case "boolean":
1056
+ case "bigint":
1057
+ return String(value);
1058
+ case "object":
1059
+ return JSON.stringify(value);
1060
+ case "function":
1061
+ return "[Function]";
1062
+ case "symbol":
1063
+ return value.toString();
1064
+ default:
1065
+ return String(value);
1066
+ }
1067
+ }
1068
+ function errorToString(error, maxRowLength = 80) {
1069
+ const table = errorToASCIITable(error, maxRowLength);
1070
+ return table.toString();
1071
+ }
1072
+ function errorToASCIITable(error, maxRowLength) {
1073
+ const table = new KeyValueASCIITable({
1074
+ tableWidth: maxRowLength,
1075
+ autoAdjustWidthWhenPossible: true
1076
+ });
1077
+ if (error && typeof error === "object") {
1078
+ const err = error;
1079
+ table.addRow("Key", "Value");
1080
+ if (err["message"]) {
1081
+ table.addRow("Message", safeStringify(err["message"]));
1082
+ }
1083
+ if (err["name"]) {
1084
+ table.addRow("Name", safeStringify(err["name"]));
1085
+ }
1086
+ if (err["code"]) {
1087
+ table.addRow("Code", safeStringify(err["code"]));
1088
+ }
1089
+ if (err["errno"]) {
1090
+ table.addRow("Errno", safeStringify(err["errno"]));
1091
+ }
1092
+ if (err["errPrefix"]) {
1093
+ table.addRow("Prefix", safeStringify(err["errPrefix"]));
1094
+ }
1095
+ if (err["errType"]) {
1096
+ table.addRow("errType", safeStringify(err["errType"]));
1097
+ }
1098
+ if (err["errCode"]) {
1099
+ table.addRow("errCode", safeStringify(err["errCode"]));
1100
+ }
1101
+ if (err["additionalInfo"]) {
1102
+ const additionalInfo = err["additionalInfo"];
1103
+ const sensitiveFieldNames = err["sensitiveFieldNames"] || [];
1104
+ for (const key in additionalInfo) {
1105
+ if (sensitiveFieldNames.includes(key)) {
1106
+ table.addRow(`AdditionalInfo.${key}`, "***");
1107
+ } else {
1108
+ const value = additionalInfo[key];
1109
+ table.addRow(
1110
+ `AdditionalInfo.${key}`,
1111
+ stringifyValue(value, table, maxRowLength)
1112
+ );
1113
+ }
1114
+ }
1115
+ }
1116
+ if (err["stack"]) {
1117
+ table.addValueOnSeparateRow("Stack", safeStringify(err["stack"]));
1118
+ }
1119
+ }
1120
+ return table;
1121
+ }
1122
+ function stringifyValue(value, table, maxRowLength) {
1123
+ if (typeof value === "string") {
1124
+ return value;
1125
+ } else if (Array.isArray(value)) {
1126
+ return value.map((item) => {
1127
+ const result = stringifyValue(item, table, maxRowLength);
1128
+ if (typeof result === "string") {
1129
+ return result;
1130
+ } else if (result instanceof KeyValueASCIITable) {
1131
+ return result.toString();
1132
+ } else {
1133
+ return JSON.stringify(result);
1134
+ }
1135
+ }).join(", ");
1136
+ } else if (typeof value === "object" && value !== null) {
1137
+ if (value instanceof Error) {
1138
+ return errorToASCIITable(value, maxRowLength - 4);
1139
+ } else {
1140
+ const entries = Object.entries(value).map(
1141
+ ([key, val]) => ({
1142
+ key,
1143
+ value: stringifyValue(val, table, maxRowLength - 4)
1144
+ })
1145
+ );
1146
+ return entries;
1147
+ }
1148
+ } else {
1149
+ return String(value);
1150
+ }
1151
+ }
1152
+
1153
+ // src/lib/is-promise.ts
1154
+ function isPromise(obj) {
1155
+ return !!obj && (typeof obj === "object" || typeof obj === "function") && // @ts-expect-error - obj is checked to be object/function, then property access works at runtime
1156
+ typeof obj["then"] === "function";
1157
+ }
1158
+
1159
+ // src/lib/is-function.ts
1160
+ function isFunction(value) {
1161
+ return typeof value === "function" || value instanceof Function;
1162
+ }
1163
+
1164
+ // src/lib/safe-handle-callback.ts
1165
+ function safeHandleCallback(callbackName, callback, ...args) {
1166
+ const handleError = (error) => {
1167
+ if (typeof globalThis.dispatchEvent === "function") {
1168
+ globalThis.dispatchEvent(
1169
+ new ErrorEvent("reportError", {
1170
+ error: new Error(
1171
+ `Error in a callback ${callbackName}: ${DOUBLE_EOL}${errorToString(error)}`
1172
+ )
1173
+ })
1174
+ );
1175
+ }
1176
+ };
1177
+ if (isFunction(callback)) {
1178
+ try {
1179
+ const result = callback(...args);
1180
+ if (isPromise(result)) {
1181
+ result.catch((error) => {
1182
+ handleError(error);
1183
+ });
1184
+ }
1185
+ } catch (error) {
1186
+ handleError(error);
1187
+ }
1188
+ } else {
1189
+ handleError(
1190
+ new Error(`Callback provided for ${callbackName} is not a function`)
1191
+ );
1192
+ }
1193
+ }
1194
+
1195
+ // src/lib/promise-protected-resolver.ts
1196
+ var PromiseProtectedResolver = class {
1197
+ promise;
1198
+ get hasResolved() {
1199
+ return this._hasResolved;
1200
+ }
1201
+ _hasResolved = false;
1202
+ resolveHandler;
1203
+ rejectHandler;
1204
+ options;
1205
+ constructor(options = {}) {
1206
+ this.options = options;
1207
+ this.promise = new Promise((resolve, reject) => {
1208
+ this.resolveHandler = resolve;
1209
+ this.rejectHandler = reject;
1210
+ });
1211
+ }
1212
+ resolveOnce(value) {
1213
+ if (!this._hasResolved && this.resolveHandler) {
1214
+ this.executeBeforeCallback("resolve", value);
1215
+ this._hasResolved = true;
1216
+ this.resolveHandler(value);
1217
+ }
1218
+ }
1219
+ rejectOnce(reason) {
1220
+ if (!this._hasResolved && this.rejectHandler) {
1221
+ this.executeBeforeCallback("reject", reason);
1222
+ this._hasResolved = true;
1223
+ this.rejectHandler(reason);
1224
+ }
1225
+ }
1226
+ executeBeforeCallback(action, valueOrReason) {
1227
+ if (this.options.beforeResolveOrReject) {
1228
+ safeHandleCallback(
1229
+ "beforeResolveOrReject",
1230
+ this.options.beforeResolveOrReject,
1231
+ action,
1232
+ valueOrReason
1233
+ );
1234
+ }
1235
+ }
1236
+ };
1237
+
1238
+ // src/lib/id-helpers.ts
1239
+ import ObjectID from "bson-objectid";
1240
+ import {
1241
+ v4 as UUIDv4,
1242
+ v7 as UUIDv7,
1243
+ validate as uuidValidate,
1244
+ version as uuidVersion
1245
+ } from "uuid";
1246
+ import { ulid } from "ulid";
1247
+
1248
+ // src/lib/unix-time-helpers.ts
1249
+ function convertMSToUnix(value) {
1250
+ return Math.floor(value / 1e3);
1251
+ }
1252
+
1253
+ // src/lib/id-helpers.ts
1254
+ var IDENTIFIER_TYPES = ["objectID", "uuid4", "uuid7", "ulid"];
1255
+ function assertIdentifierType(type) {
1256
+ if (!IDENTIFIER_TYPES.includes(type)) {
1257
+ throw new TypeError(
1258
+ `Invalid ID type given: "${type}". Expected one of: ${IDENTIFIER_TYPES.join(", ")}`
1259
+ );
1260
+ }
1261
+ }
1262
+ function generateID(type, seedTime) {
1263
+ assertIdentifierType(type);
1264
+ if (seedTime !== void 0 && (!Number.isFinite(seedTime) || seedTime < 0)) {
1265
+ throw new TypeError(
1266
+ `seedTime must be a non-negative finite number (milliseconds), got: ${seedTime}`
1267
+ );
1268
+ }
1269
+ if (type === "objectID") {
1270
+ if (seedTime !== void 0) {
1271
+ const unixTime = convertMSToUnix(seedTime);
1272
+ return new ObjectID(unixTime).toHexString();
1273
+ } else {
1274
+ return new ObjectID().toHexString();
1275
+ }
1276
+ } else if (type === "uuid4") {
1277
+ return UUIDv4();
1278
+ } else if (type === "uuid7") {
1279
+ if (seedTime !== void 0) {
1280
+ return UUIDv7({ msecs: seedTime });
1281
+ } else {
1282
+ return UUIDv7();
1283
+ }
1284
+ } else if (type === "ulid") {
1285
+ if (seedTime !== void 0) {
1286
+ return ulid(seedTime);
1287
+ } else {
1288
+ return ulid();
1289
+ }
1290
+ } else {
1291
+ throw new TypeError(`Unhandled identifier type: "${type}"`);
1292
+ }
1293
+ }
1294
+
1295
+ // src/lib/is-plain-object.ts
1296
+ function isPlainObject(value) {
1297
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1298
+ }
1299
+
1300
+ // src/lib/event-emitter.ts
1301
+ var EventEmitterProtected = class {
1302
+ events;
1303
+ constructor() {
1304
+ this.events = /* @__PURE__ */ new Map();
1305
+ }
1306
+ /**
1307
+ * Subscribe to an event
1308
+ * @param event The event name to subscribe to
1309
+ * @param callback The callback function to be called when the event is emitted
1310
+ * @returns A function to unsubscribe from the event
1311
+ */
1312
+ on(event, callback) {
1313
+ if (!this.events.has(event)) {
1314
+ this.events.set(event, /* @__PURE__ */ new Set());
1315
+ }
1316
+ const callbacks = this.events.get(event);
1317
+ if (callbacks) {
1318
+ callbacks.add(callback);
1319
+ }
1320
+ return () => {
1321
+ const callbacks2 = this.events.get(event);
1322
+ if (callbacks2) {
1323
+ callbacks2.delete(callback);
1324
+ if (callbacks2.size === 0) {
1325
+ this.events.delete(event);
1326
+ }
1327
+ }
1328
+ };
1329
+ }
1330
+ /**
1331
+ * Subscribe to an event once - automatically unsubscribes after first emission
1332
+ * @param event The event name to subscribe to
1333
+ * @param callback The callback function to be called when the event is emitted
1334
+ * @returns A function to unsubscribe from the event before it's called
1335
+ */
1336
+ once(event, callback) {
1337
+ const unsubscribe = this.on(event, (data) => {
1338
+ unsubscribe();
1339
+ return callback(data);
1340
+ });
1341
+ return unsubscribe;
1342
+ }
1343
+ /**
1344
+ * Check if a specific callback is registered for an event.
1345
+ * Note: For 'once' handlers, this will return true for the wrapper function, not the original callback.
1346
+ * This means hasListener will return false when checking for the original callback of a 'once' subscription.
1347
+ *
1348
+ * @param event The event name to check
1349
+ * @param callback The callback function to look for
1350
+ * @returns true if the exact callback is registered, false otherwise
1351
+ */
1352
+ hasListener(event, callback) {
1353
+ const callbacks = this.events.get(event);
1354
+ return callbacks?.has(callback) ?? false;
1355
+ }
1356
+ /**
1357
+ * Check if an event has any subscribers
1358
+ * @param event The event name to check
1359
+ * @returns true if the event has subscribers, false otherwise
1360
+ */
1361
+ hasListeners(event) {
1362
+ const callbacks = this.events.get(event);
1363
+ return callbacks !== void 0 && callbacks.size > 0;
1364
+ }
1365
+ /**
1366
+ * Get the number of subscribers for an event
1367
+ * @param event The event name to check
1368
+ * @returns The number of subscribers
1369
+ */
1370
+ listenerCount(event) {
1371
+ const callbacks = this.events.get(event);
1372
+ return callbacks ? callbacks.size : 0;
1373
+ }
1374
+ /**
1375
+ * Remove all event listeners
1376
+ * @param event Optional event name. If not provided, removes all listeners for all events
1377
+ */
1378
+ clear(event) {
1379
+ if (event) {
1380
+ this.events.delete(event);
1381
+ } else {
1382
+ this.events.clear();
1383
+ }
1384
+ }
1385
+ /**
1386
+ * Emit an event with optional data
1387
+ * This method is protected to allow only derived classes to trigger events.
1388
+ * @param event The event name to emit
1389
+ * @param data Optional data to pass to the event handlers
1390
+ */
1391
+ emit(event, data) {
1392
+ const callbacks = this.events.get(event);
1393
+ if (callbacks) {
1394
+ for (const callback of callbacks) {
1395
+ safeHandleCallback(`event handler for ${event}`, callback, data);
1396
+ }
1397
+ }
1398
+ }
1399
+ };
1400
+
1401
+ // src/lib/retry-utils/lib/retry-runner.ts
1402
+ var AttemptContext = class {
1403
+ handled = false;
1404
+ id;
1405
+ abortController;
1406
+ startTime;
1407
+ constructor() {
1408
+ this.id = generateID("ulid");
1409
+ this.abortController = new AbortController();
1410
+ this.startTime = Date.now();
1411
+ }
1412
+ };
1413
+ var OPERATION_STARTED = "operation-started";
1414
+ var OPERATION_ENDED = "operation-ended";
1415
+ var ATTEMPT_STARTED = "attempt-started";
1416
+ var ATTEMPT_HANDLED = "attempt-handled";
1417
+ var RetryRunner = class extends EventEmitterProtected {
1418
+ // Human-readable label for debugging/logging purposes.
1419
+ _operationLabel = "Unnamed Operation";
1420
+ // Retry policy that determines retry behavior and tracks state.
1421
+ policy;
1422
+ // Prevents concurrent run/resume/forceTry calls.
1423
+ _isOperationLocked = false;
1424
+ // Mutable runtime state for the current operation.
1425
+ currentState = this.getEmptyCurrentState();
1426
+ // Grace period for cancellation before we force-complete.
1427
+ _gracePeriodMS = 1e3;
1428
+ // User-provided operation to retry on failure.
1429
+ operation;
1430
+ // Resolver for the current run/resume/forceTry operation.
1431
+ currentOperationResolver;
1432
+ // Resolvers for pending cancel() calls.
1433
+ cancelResolvers = /* @__PURE__ */ new Set();
1434
+ get operationLabel() {
1435
+ return this._operationLabel;
1436
+ }
1437
+ get runnerState() {
1438
+ return this.currentState.runnerState;
1439
+ }
1440
+ get timeTakenMS() {
1441
+ if (this.currentState.finalTimeTakenMS !== null) {
1442
+ return this.currentState.finalTimeTakenMS;
1443
+ } else if (this.currentState.operationStartTime !== null) {
1444
+ return Date.now() - this.currentState.operationStartTime;
1445
+ }
1446
+ return -1;
1447
+ }
1448
+ get attemptTimeTakenMS() {
1449
+ if (this.currentState.currentAttemptContext instanceof AttemptContext && !this.currentState.currentAttemptContext.handled) {
1450
+ return Date.now() - this.currentState.currentAttemptContext.startTime;
1451
+ }
1452
+ return this.currentState.lastAttemptTimeTakenMS;
1453
+ }
1454
+ get retryTimeRemaining() {
1455
+ if (this.currentState.retryTimeoutHandle !== null && this.currentState.retryTimeoutStartTime !== null && this.currentState.retryTimeoutDelayMS !== null) {
1456
+ const elapsed = Date.now() - this.currentState.retryTimeoutStartTime;
1457
+ const remaining = this.currentState.retryTimeoutDelayMS - elapsed;
1458
+ return Math.max(0, remaining);
1459
+ } else {
1460
+ return -1;
1461
+ }
1462
+ }
1463
+ get canForceTry() {
1464
+ return this.currentState.runnerState === "running" || this.currentState.runnerState === "exhausted" || this.currentState.runnerState === "fatal-error" || this.currentState.runnerState === "not-started" || this.currentState.runnerState === "stopping" || this.currentState.runnerState === "stopped";
1465
+ }
1466
+ get wasLastAttemptForced() {
1467
+ return this.currentState.lastAttemptWasForceTry;
1468
+ }
1469
+ get errors() {
1470
+ return this.policy.errors;
1471
+ }
1472
+ get wasInitialAttemptTaken() {
1473
+ return this.policy.wasInitialAttemptTaken;
1474
+ }
1475
+ get areAttemptsExhausted() {
1476
+ return this.policy.areAttemptsExhausted;
1477
+ }
1478
+ get attempts() {
1479
+ return this.policy.attempts;
1480
+ }
1481
+ get mostCommonError() {
1482
+ return this.policy.mostCommonError;
1483
+ }
1484
+ get lastError() {
1485
+ return this.policy.lastError;
1486
+ }
1487
+ get maxRetryAttempts() {
1488
+ return this.policy.maxRetryAttempts;
1489
+ }
1490
+ get policyInfo() {
1491
+ return this.policy.policyInfo;
1492
+ }
1493
+ get retryCount() {
1494
+ return this.policy.retryCount;
1495
+ }
1496
+ get wasSuccessful() {
1497
+ return this.policy.wasSuccessful;
1498
+ }
1499
+ get isRetryPending() {
1500
+ return this.currentState.retryTimeoutHandle !== null;
1501
+ }
1502
+ get isOperationRunning() {
1503
+ return this.currentState.runnerState === "running" || this.currentState.runnerState === "stopping";
1504
+ }
1505
+ get isAttemptRunning() {
1506
+ if (this.currentState.currentAttemptContext instanceof AttemptContext) {
1507
+ return !this.currentState.currentAttemptContext.handled;
1508
+ } else {
1509
+ return false;
1510
+ }
1511
+ }
1512
+ get graceCancelPeriodMS() {
1513
+ return this._gracePeriodMS;
1514
+ }
1515
+ constructor(policy, operation, options) {
1516
+ super();
1517
+ this.policy = new RetryPolicy(policy);
1518
+ this.operation = operation;
1519
+ if (isPlainObject(options)) {
1520
+ if (isString(options.operationLabel)) {
1521
+ this._operationLabel = options.operationLabel;
1522
+ }
1523
+ if (isFunction(options.onOperationStarted)) {
1524
+ this.on(
1525
+ OPERATION_STARTED,
1526
+ options.onOperationStarted
1527
+ );
1528
+ }
1529
+ if (isFunction(options.onOperationEnded)) {
1530
+ this.on(
1531
+ OPERATION_ENDED,
1532
+ options.onOperationEnded
1533
+ );
1534
+ }
1535
+ if (isFunction(options.onAttemptStarted)) {
1536
+ this.on(
1537
+ ATTEMPT_STARTED,
1538
+ options.onAttemptStarted
1539
+ );
1540
+ }
1541
+ if (isFunction(options.onAttemptHandled)) {
1542
+ this.on(
1543
+ ATTEMPT_HANDLED,
1544
+ options.onAttemptHandled
1545
+ );
1546
+ }
1547
+ }
1548
+ }
1549
+ /**
1550
+ * Set the grace period for cancellation in milliseconds
1551
+ *
1552
+ * Overrides the default grace period of 1000ms
1553
+ * Non-finite or negative values default to 1000ms. Use 0 for immediate force-cancel.
1554
+ */
1555
+ overrideGraceCancelPeriodMS(value) {
1556
+ if (!isFinite(value) || value < 0) {
1557
+ this._gracePeriodMS = 1e3;
1558
+ } else {
1559
+ this._gracePeriodMS = value;
1560
+ }
1561
+ }
1562
+ async waitForCompletion() {
1563
+ switch (this.currentState.runnerState) {
1564
+ case "completed":
1565
+ case "exhausted":
1566
+ case "fatal-error":
1567
+ case "stopped":
1568
+ return this.currentOperationResolver.promise;
1569
+ case "running":
1570
+ case "stopping":
1571
+ return this.currentOperationResolver.promise;
1572
+ case "not-started":
1573
+ return {
1574
+ status: "not_started",
1575
+ code: "not_running",
1576
+ error: new RetryUtilsErrRunnerNotRunning("waitForCompletion")
1577
+ };
1578
+ default:
1579
+ throw new RetryUtilsErrRunnerUnknownState(
1580
+ "waitForCompletion",
1581
+ this.currentState.runnerState
1582
+ );
1583
+ }
1584
+ }
1585
+ async run(shouldWaitForCompletion = false) {
1586
+ if (this._isOperationLocked) {
1587
+ return {
1588
+ status: "pre_operation_error",
1589
+ code: "lock_error",
1590
+ error: new RetryUtilsErrRunnerLockAcquisitionError("run")
1591
+ };
1592
+ }
1593
+ this._isOperationLocked = true;
1594
+ try {
1595
+ const checkDisallowedStates = this.checkForDisallowedPerOperationStates(
1596
+ "run",
1597
+ [
1598
+ "completed",
1599
+ "running",
1600
+ "stopping",
1601
+ "stopped",
1602
+ "fatal-error",
1603
+ "exhausted"
1604
+ ]
1605
+ );
1606
+ if (checkDisallowedStates.wasDisallowed && checkDisallowedStates.runResult) {
1607
+ return checkDisallowedStates.runResult;
1608
+ } else if (this.policy.shouldDoFirstTry()) {
1609
+ this.currentState.runnerState = "running";
1610
+ this.currentState.operationStartTime = Date.now();
1611
+ this.currentState.finalTimeTakenMS = null;
1612
+ this.emit(OPERATION_STARTED, { operationType: "initial" });
1613
+ this.currentOperationResolver = new PromiseProtectedResolver();
1614
+ void this.attemptOperation(false);
1615
+ if (shouldWaitForCompletion) {
1616
+ return this.currentOperationResolver.promise;
1617
+ } else {
1618
+ return { status: "running" };
1619
+ }
1620
+ } else {
1621
+ return {
1622
+ status: "pre_operation_error",
1623
+ code: "unexpected_error",
1624
+ error: new RetryUtilsErrRunnerUnexpectedError(
1625
+ "run",
1626
+ new Error(
1627
+ "Not first try, but this should had been caught before this point"
1628
+ )
1629
+ )
1630
+ };
1631
+ }
1632
+ } catch (error) {
1633
+ return {
1634
+ status: "pre_operation_error",
1635
+ code: "unexpected_error",
1636
+ error: new RetryUtilsErrRunnerUnexpectedError("run", error)
1637
+ };
1638
+ } finally {
1639
+ this._isOperationLocked = false;
1640
+ }
1641
+ }
1642
+ async cancel() {
1643
+ if (this.currentState.runnerState === "running" || this.currentState.runnerState === "stopping") {
1644
+ const cancellationPromiseProtectedResolver = new PromiseProtectedResolver();
1645
+ this.cancelResolvers.add(cancellationPromiseProtectedResolver);
1646
+ if (this.currentState.runnerState !== "stopping") {
1647
+ this.currentState.runnerState = "stopping";
1648
+ this.cleanupTimers();
1649
+ if (!this.currentState.currentAttemptContext || this.currentState.currentAttemptContext.handled) {
1650
+ this.confirmCancellation("stopped", {
1651
+ status: "canceled"
1652
+ });
1653
+ } else {
1654
+ this.currentState.currentAttemptContext.abortController.abort();
1655
+ this.currentState.cancellationTimeoutHandle = setTimeout(() => {
1656
+ if (this.currentState.currentAttemptContext instanceof AttemptContext && !this.currentState.currentAttemptContext.handled) {
1657
+ if (this.currentState.runnerState === "stopping") {
1658
+ const context = this.currentState.currentAttemptContext;
1659
+ context.handled = true;
1660
+ this.currentState.currentAttemptContext = null;
1661
+ this.cleanupTimers();
1662
+ const attemptTimeElapsedMS = Date.now() - context.startTime;
1663
+ this.currentState.lastAttemptTimeTakenMS = attemptTimeElapsedMS;
1664
+ this.emit(ATTEMPT_HANDLED, {
1665
+ attemptID: context.id,
1666
+ status: "skip",
1667
+ data: void 0,
1668
+ error: void 0,
1669
+ operationTimeElapsedMS: this.timeTakenMS,
1670
+ attemptTimeElapsedMS,
1671
+ wasCanceled: true
1672
+ });
1673
+ this.confirmCancellation(
1674
+ "stopped",
1675
+ {
1676
+ status: "canceled"
1677
+ },
1678
+ true
1679
+ );
1680
+ }
1681
+ }
1682
+ }, this._gracePeriodMS);
1683
+ }
1684
+ }
1685
+ return cancellationPromiseProtectedResolver.promise;
1686
+ } else {
1687
+ return "not-running";
1688
+ }
1689
+ }
1690
+ async reset() {
1691
+ if (this.currentState.runnerState === "running" || this.currentState.runnerState === "stopping") {
1692
+ await this.cancel();
1693
+ }
1694
+ this.currentState = this.getEmptyCurrentState();
1695
+ this.policy.reset();
1696
+ }
1697
+ async resume(shouldWaitForCompletion = false) {
1698
+ if (this._isOperationLocked) {
1699
+ return {
1700
+ status: "pre_operation_error",
1701
+ code: "lock_error",
1702
+ error: new RetryUtilsErrRunnerLockAcquisitionError("resume")
1703
+ };
1704
+ }
1705
+ this._isOperationLocked = true;
1706
+ try {
1707
+ const checkDisallowedStates = this.checkForDisallowedPerOperationStates(
1708
+ "resume",
1709
+ ["completed", "running", "stopping", "fatal-error", "exhausted"]
1710
+ );
1711
+ if (checkDisallowedStates.wasDisallowed && checkDisallowedStates.runResult) {
1712
+ return checkDisallowedStates.runResult;
1713
+ } else {
1714
+ if (this.currentState.runnerState !== "stopped") {
1715
+ return {
1716
+ status: "pre_operation_error",
1717
+ code: "not_paused",
1718
+ error: new RetryUtilsErrRunnerNotPaused("resume")
1719
+ };
1720
+ }
1721
+ this.currentState.runnerState = "running";
1722
+ this.currentState.operationStartTime = Date.now();
1723
+ this.currentState.finalTimeTakenMS = null;
1724
+ this.emit(OPERATION_STARTED, { operationType: "resume" });
1725
+ this.currentOperationResolver = new PromiseProtectedResolver();
1726
+ void this.attemptOperation(false);
1727
+ if (shouldWaitForCompletion) {
1728
+ return this.currentOperationResolver.promise;
1729
+ } else {
1730
+ return { status: "running" };
1731
+ }
1732
+ }
1733
+ } catch (error) {
1734
+ return {
1735
+ status: "pre_operation_error",
1736
+ code: "unexpected_error",
1737
+ error: new RetryUtilsErrRunnerUnexpectedError("resume", error)
1738
+ };
1739
+ } finally {
1740
+ this._isOperationLocked = false;
1741
+ }
1742
+ }
1743
+ async forceTry(options) {
1744
+ const shouldWaitForCompletion = options?.shouldWaitForCompletion ?? false;
1745
+ const shouldAbortRunning = options?.shouldAbortRunning ?? false;
1746
+ if (this._isOperationLocked) {
1747
+ return {
1748
+ status: "pre_operation_error",
1749
+ code: "lock_error",
1750
+ error: new RetryUtilsErrRunnerLockAcquisitionError("forceTry")
1751
+ };
1752
+ }
1753
+ this._isOperationLocked = true;
1754
+ try {
1755
+ const checkDisallowedStates = this.checkForDisallowedPerOperationStates(
1756
+ "forceTry",
1757
+ ["completed"]
1758
+ );
1759
+ if (checkDisallowedStates.wasDisallowed && checkDisallowedStates.runResult) {
1760
+ return checkDisallowedStates.runResult;
1761
+ }
1762
+ if (this.isAttemptRunning && !shouldAbortRunning) {
1763
+ if (shouldWaitForCompletion) {
1764
+ return this.currentOperationResolver.promise;
1765
+ } else {
1766
+ return { status: "running", reattached: true };
1767
+ }
1768
+ }
1769
+ if (this.isAttemptRunning && this.currentState.lastAttemptWasForceTry) {
1770
+ return {
1771
+ status: "pre_operation_error",
1772
+ code: "force_try_in_progress",
1773
+ error: new RetryUtilsErrRunnerForceTryRetryInProgress("forceTry")
1774
+ };
1775
+ }
1776
+ if (this.isAttemptRunning && this.currentState.currentAttemptContext) {
1777
+ this.currentState.currentAttemptContext.abortController.abort();
1778
+ }
1779
+ if (this.currentState.retryTimeoutHandle !== null) {
1780
+ clearTimeout(this.currentState.retryTimeoutHandle);
1781
+ this.currentState.retryTimeoutHandle = null;
1782
+ this.currentState.retryTimeoutStartTime = null;
1783
+ this.currentState.retryTimeoutDelayMS = null;
1784
+ this.currentState.lastAttemptWasForceTry = true;
1785
+ void this.attemptOperation(true);
1786
+ if (shouldWaitForCompletion) {
1787
+ return this.currentOperationResolver.promise;
1788
+ } else {
1789
+ return { status: "running", reattached: false };
1790
+ }
1791
+ } else {
1792
+ if (this.currentState.runnerState === "not-started") {
1793
+ this.policy.shouldDoFirstTry();
1794
+ } else if (this.currentState.runnerState === "stopping" || this.currentState.runnerState === "stopped") {
1795
+ this.cleanupTimers();
1796
+ this.confirmCancellation("running", {
1797
+ status: null
1798
+ });
1799
+ }
1800
+ this.currentState.runnerState = "running";
1801
+ this.currentState.operationStartTime = Date.now();
1802
+ this.currentState.finalTimeTakenMS = null;
1803
+ this.emit(OPERATION_STARTED, { operationType: "force" });
1804
+ if (!this.currentOperationResolver || this.currentOperationResolver.hasResolved) {
1805
+ this.currentOperationResolver = new PromiseProtectedResolver();
1806
+ }
1807
+ void this.attemptOperation(true);
1808
+ if (shouldWaitForCompletion) {
1809
+ return this.currentOperationResolver.promise;
1810
+ } else {
1811
+ return { status: "running", reattached: false };
1812
+ }
1813
+ }
1814
+ } catch (error) {
1815
+ return {
1816
+ status: "pre_operation_error",
1817
+ code: "unexpected_error",
1818
+ error: new RetryUtilsErrRunnerUnexpectedError(
1819
+ "forceTry",
1820
+ error
1821
+ )
1822
+ };
1823
+ } finally {
1824
+ this._isOperationLocked = false;
1825
+ }
1826
+ }
1827
+ /**
1828
+ * Returning a fresh copy of the current state
1829
+ * to be immutable and not changed by the caller
1830
+ */
1831
+ getEmptyCurrentState() {
1832
+ return {
1833
+ runnerState: "not-started",
1834
+ lastAttemptWasForceTry: false,
1835
+ currentAttemptContext: null,
1836
+ retryTimeoutHandle: null,
1837
+ retryTimeoutStartTime: null,
1838
+ retryTimeoutDelayMS: null,
1839
+ cancellationTimeoutHandle: null,
1840
+ operationStartTime: null,
1841
+ finalTimeTakenMS: null,
1842
+ lastAttemptTimeTakenMS: -1
1843
+ };
1844
+ }
1845
+ checkForDisallowedPerOperationStates(methodName, disallowedStates) {
1846
+ for (const checkForState of disallowedStates) {
1847
+ if (checkForState === "completed" && this.currentState.runnerState === "completed") {
1848
+ return {
1849
+ wasDisallowed: true,
1850
+ runResult: {
1851
+ status: "pre_operation_error",
1852
+ code: "already_completed",
1853
+ error: new RetryUtilsErrRunnerAlreadyCompleted(methodName)
1854
+ }
1855
+ };
1856
+ } else if (checkForState === "running" && this.currentState.runnerState === "running") {
1857
+ return {
1858
+ wasDisallowed: true,
1859
+ runResult: {
1860
+ status: "pre_operation_error",
1861
+ code: "already_running",
1862
+ error: new RetryUtilsErrRunnerAlreadyRunning(
1863
+ methodName
1864
+ )
1865
+ }
1866
+ };
1867
+ } else if (checkForState === "stopping" && this.currentState.runnerState === "stopping") {
1868
+ return {
1869
+ wasDisallowed: true,
1870
+ runResult: {
1871
+ status: "pre_operation_error",
1872
+ code: "cancel_pending",
1873
+ error: new RetryUtilsErrRunnerCancelPending(
1874
+ methodName
1875
+ )
1876
+ }
1877
+ };
1878
+ } else if (checkForState === "stopped" && this.currentState.runnerState === "stopped") {
1879
+ return {
1880
+ wasDisallowed: true,
1881
+ runResult: {
1882
+ status: "pre_operation_error",
1883
+ code: "retry_canceled",
1884
+ error: new RetryUtilsErrRunnerRetryCanceled("run")
1885
+ }
1886
+ };
1887
+ } else if (checkForState === "fatal-error" && this.currentState.runnerState === "fatal-error") {
1888
+ return {
1889
+ wasDisallowed: true,
1890
+ runResult: {
1891
+ status: "pre_operation_error",
1892
+ code: "fatally_failed",
1893
+ error: new RetryUtilsErrRunnerLastRetryFatallyFailed(
1894
+ methodName
1895
+ )
1896
+ }
1897
+ };
1898
+ } else if (checkForState === "exhausted" && (this.currentState.runnerState === "exhausted" || this.policy.areAttemptsExhausted)) {
1899
+ return {
1900
+ wasDisallowed: true,
1901
+ runResult: {
1902
+ status: "pre_operation_error",
1903
+ code: "attempts_exhausted",
1904
+ error: new RetryUtilsErrRunnerAttemptsExhausted(
1905
+ methodName
1906
+ )
1907
+ }
1908
+ };
1909
+ }
1910
+ }
1911
+ return { wasDisallowed: false };
1912
+ }
1913
+ cleanupTimers() {
1914
+ if (this.currentState.retryTimeoutHandle) {
1915
+ clearTimeout(this.currentState.retryTimeoutHandle);
1916
+ this.currentState.retryTimeoutHandle = null;
1917
+ this.currentState.retryTimeoutStartTime = null;
1918
+ this.currentState.retryTimeoutDelayMS = null;
1919
+ }
1920
+ if (this.currentState.cancellationTimeoutHandle) {
1921
+ clearTimeout(this.currentState.cancellationTimeoutHandle);
1922
+ this.currentState.cancellationTimeoutHandle = null;
1923
+ }
1924
+ }
1925
+ confirmCancellation(runnerState, resolveInfo, wasForced = false) {
1926
+ if (this.currentState.runnerState === "stopping") {
1927
+ this.cleanupTimers();
1928
+ this.currentState.runnerState = runnerState;
1929
+ for (const resolver of this.cancelResolvers) {
1930
+ resolver.resolveOnce(wasForced ? "forced" : "canceled");
1931
+ this.cancelResolvers.delete(resolver);
1932
+ }
1933
+ } else {
1934
+ this.currentState.runnerState = runnerState;
1935
+ }
1936
+ if (runnerState !== "running") {
1937
+ this.currentState.finalTimeTakenMS = this.currentState.operationStartTime !== null ? Date.now() - this.currentState.operationStartTime : -1;
1938
+ this.emit(OPERATION_ENDED, {
1939
+ runnerState,
1940
+ timeTakenMS: this.timeTakenMS
1941
+ });
1942
+ if (resolveInfo.status !== null) {
1943
+ if (resolveInfo.status === "attempt_success") {
1944
+ this.currentOperationResolver.resolveOnce({
1945
+ status: "attempt_success",
1946
+ ...resolveInfo.data !== void 0 ? { data: resolveInfo.data } : {}
1947
+ });
1948
+ } else {
1949
+ const nonSuccessResult = {
1950
+ status: resolveInfo.status
1951
+ };
1952
+ if (resolveInfo.code !== void 0) {
1953
+ nonSuccessResult.code = resolveInfo.code;
1954
+ }
1955
+ if (resolveInfo.error !== void 0) {
1956
+ nonSuccessResult.error = resolveInfo.error;
1957
+ }
1958
+ this.currentOperationResolver.resolveOnce(nonSuccessResult);
1959
+ }
1960
+ }
1961
+ }
1962
+ }
1963
+ handleReportResult(context, status, valueInfo) {
1964
+ if (
1965
+ // Ensure the context matches the current context
1966
+ this.currentState.currentAttemptContext && context.id !== this.currentState.currentAttemptContext.id || // Ensure the result hasn't already been handled
1967
+ context.handled
1968
+ ) {
1969
+ return;
1970
+ }
1971
+ this.currentState.currentAttemptContext = null;
1972
+ this.cleanupTimers();
1973
+ context.handled = true;
1974
+ let isSkip = false;
1975
+ let shouldQueryForRetry = false;
1976
+ let confirmCancellationInfo = {
1977
+ run: false,
1978
+ runnerState: null,
1979
+ resolveInfo: null
1980
+ };
1981
+ if (status === "success") {
1982
+ this.policy.markAsSuccessful();
1983
+ confirmCancellationInfo = {
1984
+ run: true,
1985
+ runnerState: "completed",
1986
+ resolveInfo: {
1987
+ status: "attempt_success",
1988
+ data: valueInfo.data
1989
+ }
1990
+ };
1991
+ } else if (status === "error") {
1992
+ shouldQueryForRetry = true;
1993
+ } else if (status === "fatal") {
1994
+ this.policy.shouldRetry(valueInfo.error ?? valueInfo.data, false);
1995
+ confirmCancellationInfo = {
1996
+ run: true,
1997
+ runnerState: "fatal-error",
1998
+ resolveInfo: {
1999
+ status: "attempt_fatal",
2000
+ error: valueInfo.error
2001
+ }
2002
+ };
2003
+ } else {
2004
+ isSkip = true;
2005
+ shouldQueryForRetry = true;
2006
+ }
2007
+ if (shouldQueryForRetry) {
2008
+ const shouldRetryQuery = this.policy.shouldRetry(
2009
+ valueInfo.error ?? valueInfo.data,
2010
+ isSkip
2011
+ );
2012
+ const isCanceledOrPendingCancel = this.currentState.runnerState === "stopping" || this.currentState.runnerState === "stopped";
2013
+ if (isCanceledOrPendingCancel) {
2014
+ confirmCancellationInfo = {
2015
+ run: true,
2016
+ runnerState: "stopped",
2017
+ resolveInfo: {
2018
+ status: "canceled"
2019
+ }
2020
+ };
2021
+ } else {
2022
+ if (shouldRetryQuery.shouldRetry) {
2023
+ if (shouldRetryQuery.delayMS > 0) {
2024
+ this.currentState.retryTimeoutStartTime = Date.now();
2025
+ this.currentState.retryTimeoutDelayMS = shouldRetryQuery.delayMS;
2026
+ this.currentState.retryTimeoutHandle = setTimeout(() => {
2027
+ this.currentState.retryTimeoutHandle = null;
2028
+ this.currentState.retryTimeoutStartTime = null;
2029
+ this.currentState.retryTimeoutDelayMS = null;
2030
+ void this.attemptOperation(false);
2031
+ }, shouldRetryQuery.delayMS);
2032
+ } else {
2033
+ void this.attemptOperation(false);
2034
+ }
2035
+ } else {
2036
+ confirmCancellationInfo = {
2037
+ run: true,
2038
+ runnerState: "exhausted",
2039
+ resolveInfo: {
2040
+ status: "attempts_exhausted",
2041
+ error: valueInfo.error
2042
+ }
2043
+ };
2044
+ }
2045
+ }
2046
+ }
2047
+ const attemptTimeElapsedMS = Date.now() - context.startTime;
2048
+ this.currentState.lastAttemptTimeTakenMS = attemptTimeElapsedMS;
2049
+ this.emit(ATTEMPT_HANDLED, {
2050
+ attemptID: context.id,
2051
+ status,
2052
+ data: valueInfo.data,
2053
+ error: valueInfo.error,
2054
+ operationTimeElapsedMS: this.timeTakenMS,
2055
+ attemptTimeElapsedMS,
2056
+ wasCanceled: this.currentState.runnerState === "stopping" || this.currentState.runnerState === "stopped"
2057
+ });
2058
+ if (confirmCancellationInfo.run && confirmCancellationInfo.runnerState !== null && confirmCancellationInfo.resolveInfo !== null) {
2059
+ this.confirmCancellation(
2060
+ confirmCancellationInfo.runnerState,
2061
+ confirmCancellationInfo.resolveInfo
2062
+ );
2063
+ }
2064
+ if (this.currentState.runnerState === "stopping") {
2065
+ this.confirmCancellation("stopped", {
2066
+ status: null
2067
+ });
2068
+ }
2069
+ }
2070
+ async attemptOperation(wasForced) {
2071
+ if (this.currentState.currentAttemptContext instanceof AttemptContext) {
2072
+ if (this.currentState.currentAttemptContext.handled) {
2073
+ return;
2074
+ }
2075
+ }
2076
+ if (this.currentState.runnerState === "running") {
2077
+ this.currentState.lastAttemptWasForceTry = wasForced;
2078
+ const context = new AttemptContext();
2079
+ this.currentState.currentAttemptContext = context;
2080
+ this.emit(ATTEMPT_STARTED, {
2081
+ attemptID: context.id,
2082
+ operationTimeElapsedMS: this.timeTakenMS,
2083
+ attemptTimeElapsedMS: 0
2084
+ });
2085
+ const reportResult = (status, value) => {
2086
+ if (status === "success" || status === "skip") {
2087
+ this.handleReportResult(context, status, {
2088
+ data: value
2089
+ });
2090
+ } else {
2091
+ this.handleReportResult(context, status, {
2092
+ error: value
2093
+ });
2094
+ }
2095
+ };
2096
+ try {
2097
+ const result = this.operation(
2098
+ reportResult,
2099
+ context.abortController.signal
2100
+ );
2101
+ if (isPromise(result)) {
2102
+ await result;
2103
+ }
2104
+ } catch (error) {
2105
+ this.handleReportResult(context, "error", {
2106
+ error
2107
+ });
2108
+ }
2109
+ }
2110
+ }
2111
+ };
2112
+ export {
2113
+ ATTEMPT_HANDLED,
2114
+ ATTEMPT_STARTED,
2115
+ OPERATION_ENDED,
2116
+ OPERATION_STARTED,
2117
+ RetryPolicy,
2118
+ RetryRunner,
2119
+ RetryUtilsErrPolicyConfigInvalidStrategy,
2120
+ RetryUtilsErrRunnerAlreadyCompleted,
2121
+ RetryUtilsErrRunnerAlreadyRunning,
2122
+ RetryUtilsErrRunnerAttemptsExhausted,
2123
+ RetryUtilsErrRunnerCancelPending,
2124
+ RetryUtilsErrRunnerForceTryRetryInProgress,
2125
+ RetryUtilsErrRunnerLastRetryFatallyFailed,
2126
+ RetryUtilsErrRunnerLockAcquisitionError,
2127
+ RetryUtilsErrRunnerNotPaused,
2128
+ RetryUtilsErrRunnerNotRunning,
2129
+ RetryUtilsErrRunnerRetryCanceled,
2130
+ RetryUtilsErrRunnerUnexpectedError,
2131
+ RetryUtilsErrRunnerUnknownState
2132
+ };
2133
+ //# sourceMappingURL=index.js.map