awaitly 1.34.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
  2. package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
  3. package/dist/errors-DtXvrCiO.d.cts +708 -0
  4. package/dist/errors-DtXvrCiO.d.ts +708 -0
  5. package/dist/index.cjs +4594 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +1970 -141
  8. package/dist/index.d.ts +1970 -141
  9. package/dist/index.js +4398 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/result.cjs +641 -1
  12. package/dist/result.cjs.map +1 -1
  13. package/dist/result.d.cts +35 -5
  14. package/dist/result.d.ts +35 -5
  15. package/dist/result.js +561 -1
  16. package/dist/result.js.map +1 -1
  17. package/dist/testing.cjs +4202 -8
  18. package/dist/testing.cjs.map +1 -1
  19. package/dist/testing.d.cts +2 -6
  20. package/dist/testing.d.ts +2 -6
  21. package/dist/testing.js +4154 -8
  22. package/dist/testing.js.map +1 -1
  23. package/dist/{run-entry-D2MmJFj9.d.cts → types-B8NfNRGX.d.ts} +1152 -1499
  24. package/dist/{run-entry-Dduz-is2.d.ts → types-BZ2f4MRR.d.cts} +1152 -1499
  25. package/dist/workflow.cjs +7096 -6
  26. package/dist/workflow.cjs.map +1 -1
  27. package/dist/workflow.d.cts +3346 -22
  28. package/dist/workflow.d.ts +3346 -22
  29. package/dist/workflow.js +6929 -6
  30. package/dist/workflow.js.map +1 -1
  31. package/package.json +13 -178
  32. package/dist/adapters.cjs +0 -7
  33. package/dist/adapters.cjs.map +0 -1
  34. package/dist/adapters.d.cts +0 -179
  35. package/dist/adapters.d.ts +0 -179
  36. package/dist/adapters.js +0 -7
  37. package/dist/adapters.js.map +0 -1
  38. package/dist/batch.cjs +0 -7
  39. package/dist/batch.cjs.map +0 -1
  40. package/dist/batch.d.cts +0 -200
  41. package/dist/batch.d.ts +0 -200
  42. package/dist/batch.js +0 -7
  43. package/dist/batch.js.map +0 -1
  44. package/dist/bind-deps.cjs +0 -2
  45. package/dist/bind-deps.cjs.map +0 -1
  46. package/dist/bind-deps.d.cts +0 -28
  47. package/dist/bind-deps.d.ts +0 -28
  48. package/dist/bind-deps.js +0 -2
  49. package/dist/bind-deps.js.map +0 -1
  50. package/dist/cache.cjs +0 -2
  51. package/dist/cache.cjs.map +0 -1
  52. package/dist/cache.d.cts +0 -269
  53. package/dist/cache.d.ts +0 -269
  54. package/dist/cache.js +0 -2
  55. package/dist/cache.js.map +0 -1
  56. package/dist/circuit-breaker.cjs +0 -7
  57. package/dist/circuit-breaker.cjs.map +0 -1
  58. package/dist/circuit-breaker.d.cts +0 -211
  59. package/dist/circuit-breaker.d.ts +0 -211
  60. package/dist/circuit-breaker.js +0 -7
  61. package/dist/circuit-breaker.js.map +0 -1
  62. package/dist/conditional.cjs +0 -2
  63. package/dist/conditional.cjs.map +0 -1
  64. package/dist/conditional.d.cts +0 -252
  65. package/dist/conditional.d.ts +0 -252
  66. package/dist/conditional.js +0 -2
  67. package/dist/conditional.js.map +0 -1
  68. package/dist/core.cjs +0 -7
  69. package/dist/core.cjs.map +0 -1
  70. package/dist/core.d.cts +0 -5
  71. package/dist/core.d.ts +0 -5
  72. package/dist/core.js +0 -7
  73. package/dist/core.js.map +0 -1
  74. package/dist/di-COl5oFnR.d.cts +0 -15
  75. package/dist/di-CyDj_JyZ.d.ts +0 -15
  76. package/dist/diagnostics.cjs +0 -8
  77. package/dist/diagnostics.cjs.map +0 -1
  78. package/dist/diagnostics.d.cts +0 -68
  79. package/dist/diagnostics.d.ts +0 -68
  80. package/dist/diagnostics.js +0 -8
  81. package/dist/diagnostics.js.map +0 -1
  82. package/dist/durable.cjs +0 -11
  83. package/dist/durable.cjs.map +0 -1
  84. package/dist/durable.d.cts +0 -9
  85. package/dist/durable.d.ts +0 -9
  86. package/dist/durable.js +0 -11
  87. package/dist/durable.js.map +0 -1
  88. package/dist/duration.cjs +0 -2
  89. package/dist/duration.cjs.map +0 -1
  90. package/dist/duration.js +0 -2
  91. package/dist/duration.js.map +0 -1
  92. package/dist/engine.cjs +0 -11
  93. package/dist/engine.cjs.map +0 -1
  94. package/dist/engine.d.cts +0 -115
  95. package/dist/engine.d.ts +0 -115
  96. package/dist/engine.js +0 -11
  97. package/dist/engine.js.map +0 -1
  98. package/dist/errors.cjs +0 -2
  99. package/dist/errors.cjs.map +0 -1
  100. package/dist/errors.d.cts +0 -361
  101. package/dist/errors.d.ts +0 -361
  102. package/dist/errors.js +0 -2
  103. package/dist/errors.js.map +0 -1
  104. package/dist/fetch.cjs +0 -7
  105. package/dist/fetch.cjs.map +0 -1
  106. package/dist/fetch.d.cts +0 -86
  107. package/dist/fetch.d.ts +0 -86
  108. package/dist/fetch.js +0 -7
  109. package/dist/fetch.js.map +0 -1
  110. package/dist/flow.cjs +0 -7
  111. package/dist/flow.cjs.map +0 -1
  112. package/dist/flow.d.cts +0 -163
  113. package/dist/flow.d.ts +0 -163
  114. package/dist/flow.js +0 -7
  115. package/dist/flow.js.map +0 -1
  116. package/dist/functional.cjs +0 -2
  117. package/dist/functional.cjs.map +0 -1
  118. package/dist/functional.d.cts +0 -444
  119. package/dist/functional.d.ts +0 -444
  120. package/dist/functional.js +0 -2
  121. package/dist/functional.js.map +0 -1
  122. package/dist/guards-BodHXLzX.d.cts +0 -72
  123. package/dist/guards-CeWoQ8fn.d.ts +0 -72
  124. package/dist/hitl-BPE_1UiM.d.cts +0 -468
  125. package/dist/hitl-byp570uC.d.ts +0 -468
  126. package/dist/hitl.cjs +0 -7
  127. package/dist/hitl.cjs.map +0 -1
  128. package/dist/hitl.d.cts +0 -442
  129. package/dist/hitl.d.ts +0 -442
  130. package/dist/hitl.js +0 -7
  131. package/dist/hitl.js.map +0 -1
  132. package/dist/index-BYT3amEz.d.ts +0 -417
  133. package/dist/index-C_ak66jy.d.cts +0 -417
  134. package/dist/match-entry-DjI2bLpD.d.cts +0 -209
  135. package/dist/match-entry-DjI2bLpD.d.ts +0 -209
  136. package/dist/match.cjs +0 -2
  137. package/dist/match.cjs.map +0 -1
  138. package/dist/match.d.cts +0 -1
  139. package/dist/match.d.ts +0 -1
  140. package/dist/match.js +0 -2
  141. package/dist/match.js.map +0 -1
  142. package/dist/otel.cjs +0 -2
  143. package/dist/otel.cjs.map +0 -1
  144. package/dist/otel.d.cts +0 -188
  145. package/dist/otel.d.ts +0 -188
  146. package/dist/otel.js +0 -2
  147. package/dist/otel.js.map +0 -1
  148. package/dist/persistence-entry-DOMx3woy.d.ts +0 -822
  149. package/dist/persistence-entry-ymCA4iDu.d.cts +0 -822
  150. package/dist/persistence.cjs +0 -2
  151. package/dist/persistence.cjs.map +0 -1
  152. package/dist/persistence.d.cts +0 -7
  153. package/dist/persistence.d.ts +0 -7
  154. package/dist/persistence.js +0 -2
  155. package/dist/persistence.js.map +0 -1
  156. package/dist/policies.cjs +0 -2
  157. package/dist/policies.cjs.map +0 -1
  158. package/dist/policies.d.cts +0 -379
  159. package/dist/policies.d.ts +0 -379
  160. package/dist/policies.js +0 -2
  161. package/dist/policies.js.map +0 -1
  162. package/dist/ratelimit.cjs +0 -7
  163. package/dist/ratelimit.cjs.map +0 -1
  164. package/dist/ratelimit.d.cts +0 -458
  165. package/dist/ratelimit.d.ts +0 -458
  166. package/dist/ratelimit.js +0 -7
  167. package/dist/ratelimit.js.map +0 -1
  168. package/dist/reliability.cjs +0 -11
  169. package/dist/reliability.cjs.map +0 -1
  170. package/dist/reliability.d.cts +0 -11
  171. package/dist/reliability.d.ts +0 -11
  172. package/dist/reliability.js +0 -11
  173. package/dist/reliability.js.map +0 -1
  174. package/dist/resolver.cjs +0 -7
  175. package/dist/resolver.cjs.map +0 -1
  176. package/dist/resolver.d.cts +0 -68
  177. package/dist/resolver.d.ts +0 -68
  178. package/dist/resolver.js +0 -7
  179. package/dist/resolver.js.map +0 -1
  180. package/dist/resource.cjs +0 -7
  181. package/dist/resource.cjs.map +0 -1
  182. package/dist/resource.d.cts +0 -174
  183. package/dist/resource.d.ts +0 -174
  184. package/dist/resource.js +0 -7
  185. package/dist/resource.js.map +0 -1
  186. package/dist/result/retry.cjs +0 -2
  187. package/dist/result/retry.cjs.map +0 -1
  188. package/dist/result/retry.d.cts +0 -70
  189. package/dist/result/retry.d.ts +0 -70
  190. package/dist/result/retry.js +0 -2
  191. package/dist/result/retry.js.map +0 -1
  192. package/dist/retry.cjs +0 -2
  193. package/dist/retry.cjs.map +0 -1
  194. package/dist/retry.d.cts +0 -388
  195. package/dist/retry.d.ts +0 -388
  196. package/dist/retry.js +0 -2
  197. package/dist/retry.js.map +0 -1
  198. package/dist/run.cjs +0 -7
  199. package/dist/run.cjs.map +0 -1
  200. package/dist/run.d.cts +0 -4
  201. package/dist/run.d.ts +0 -4
  202. package/dist/run.js +0 -7
  203. package/dist/run.js.map +0 -1
  204. package/dist/saga.cjs +0 -11
  205. package/dist/saga.cjs.map +0 -1
  206. package/dist/saga.d.cts +0 -164
  207. package/dist/saga.d.ts +0 -164
  208. package/dist/saga.js +0 -11
  209. package/dist/saga.js.map +0 -1
  210. package/dist/singleflight.cjs +0 -2
  211. package/dist/singleflight.cjs.map +0 -1
  212. package/dist/singleflight.d.cts +0 -145
  213. package/dist/singleflight.d.ts +0 -145
  214. package/dist/singleflight.js +0 -2
  215. package/dist/singleflight.js.map +0 -1
  216. package/dist/slugs.cjs +0 -2
  217. package/dist/slugs.cjs.map +0 -1
  218. package/dist/slugs.d.cts +0 -67
  219. package/dist/slugs.d.ts +0 -67
  220. package/dist/slugs.js +0 -2
  221. package/dist/slugs.js.map +0 -1
  222. package/dist/streaming.cjs +0 -9
  223. package/dist/streaming.cjs.map +0 -1
  224. package/dist/streaming.d.cts +0 -596
  225. package/dist/streaming.d.ts +0 -596
  226. package/dist/streaming.js +0 -9
  227. package/dist/streaming.js.map +0 -1
  228. package/dist/tagged-error.cjs +0 -2
  229. package/dist/tagged-error.cjs.map +0 -1
  230. package/dist/tagged-error.d.cts +0 -275
  231. package/dist/tagged-error.d.ts +0 -275
  232. package/dist/tagged-error.js +0 -2
  233. package/dist/tagged-error.js.map +0 -1
  234. package/dist/types-DQmzO9f4.d.ts +0 -323
  235. package/dist/types-qBUOYi-4.d.cts +0 -323
  236. package/dist/webhook.cjs +0 -7
  237. package/dist/webhook.cjs.map +0 -1
  238. package/dist/webhook.d.cts +0 -499
  239. package/dist/webhook.d.ts +0 -499
  240. package/dist/webhook.js +0 -7
  241. package/dist/webhook.js.map +0 -1
@@ -1,211 +0,0 @@
1
- import { R as Result, c as AsyncResult } from './run-entry-D2MmJFj9.cjs';
2
- import './errors.cjs';
3
- import './tagged-error.cjs';
4
- import './slugs.cjs';
5
-
6
- /**
7
- * Circuit Breaker for Steps
8
- *
9
- * Prevents cascading failures by tracking step failure rates and
10
- * short-circuiting calls when a threshold is exceeded.
11
- *
12
- * Uses the circuit breaker pattern with three states:
13
- * - CLOSED: Normal operation (steps executing)
14
- * - OPEN: Fast-fail mode (steps blocked)
15
- * - HALF_OPEN: Testing if service recovered
16
- *
17
- * @example
18
- * ```typescript
19
- * import { createCircuitBreaker } from 'awaitly';
20
- *
21
- * const breaker = createCircuitBreaker({
22
- * failureThreshold: 5,
23
- * resetTimeout: 30000,
24
- * halfOpenMax: 3,
25
- * });
26
- *
27
- * const result = await workflow(async ({ step }) => {
28
- * const data = await breaker.execute(
29
- * () => step(() => callExternalApi()),
30
- * { name: 'external-api' }
31
- * );
32
- * return data;
33
- * });
34
- * ```
35
- */
36
-
37
- /**
38
- * Circuit breaker state.
39
- */
40
- type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
41
- /**
42
- * Configuration for circuit breaker behavior.
43
- */
44
- interface CircuitBreakerConfig {
45
- /**
46
- * Number of failures within the window before opening the circuit.
47
- * @default 5
48
- */
49
- failureThreshold: number;
50
- /**
51
- * Time in ms to wait before transitioning from OPEN to HALF_OPEN.
52
- * @default 30000 (30 seconds)
53
- */
54
- resetTimeout: number;
55
- /**
56
- * Time window in ms for counting failures.
57
- * Failures older than this are discarded.
58
- * @default 60000 (1 minute)
59
- */
60
- windowSize: number;
61
- /**
62
- * Maximum number of test requests allowed in HALF_OPEN state.
63
- * If all succeed, circuit closes. If any fail, circuit reopens.
64
- * @default 3
65
- */
66
- halfOpenMax: number;
67
- /**
68
- * Optional callback when circuit state changes.
69
- */
70
- onStateChange?: (from: CircuitState, to: CircuitState, name?: string) => void;
71
- }
72
- /**
73
- * Error thrown when the circuit is open and calls are blocked.
74
- */
75
- declare class CircuitOpenError extends Error {
76
- readonly type: "CIRCUIT_OPEN";
77
- readonly circuitName: string;
78
- readonly state: CircuitState;
79
- readonly retryAfterMs: number;
80
- constructor(options: {
81
- circuitName: string;
82
- state: CircuitState;
83
- retryAfterMs: number;
84
- message?: string;
85
- });
86
- }
87
- /**
88
- * Type guard for CircuitOpenError.
89
- */
90
- declare function isCircuitOpenError(error: unknown): error is CircuitOpenError;
91
- /**
92
- * Circuit breaker statistics.
93
- */
94
- interface CircuitBreakerStats {
95
- state: CircuitState;
96
- failureCount: number;
97
- successCount: number;
98
- lastFailureTime: number | null;
99
- lastSuccessTime: number | null;
100
- halfOpenSuccesses: number;
101
- }
102
- /**
103
- * Circuit breaker instance for protecting external calls.
104
- */
105
- interface CircuitBreaker {
106
- /**
107
- * Execute an operation with circuit breaker protection.
108
- * Throws CircuitOpenError if the circuit is open.
109
- *
110
- * @param operation - The operation to execute
111
- * @param options - Optional name for logging/metrics
112
- * @returns The operation result
113
- * @throws CircuitOpenError if circuit is open
114
- */
115
- execute<T>(operation: () => T | Promise<T>, options?: {
116
- name?: string;
117
- }): Promise<T>;
118
- /**
119
- * Execute a Result-returning operation with circuit breaker protection.
120
- * Returns a CircuitOpenError result instead of throwing.
121
- *
122
- * @param operation - The operation returning a Result
123
- * @param options - Optional name for logging/metrics
124
- * @returns Result with the value or CircuitOpenError
125
- */
126
- executeResult<T, E>(operation: () => Result<T, E> | AsyncResult<T, E>, options?: {
127
- name?: string;
128
- }): AsyncResult<T, E | CircuitOpenError>;
129
- /**
130
- * Get current circuit state.
131
- */
132
- getState(): CircuitState;
133
- /**
134
- * Get circuit breaker statistics.
135
- */
136
- getStats(): CircuitBreakerStats;
137
- /**
138
- * Manually reset the circuit breaker to CLOSED state.
139
- */
140
- reset(): void;
141
- /**
142
- * Manually open the circuit (for testing or manual intervention).
143
- */
144
- forceOpen(): void;
145
- /**
146
- * Record a manual success (useful for health checks).
147
- */
148
- recordSuccess(): void;
149
- /**
150
- * Record a manual failure (useful for health checks).
151
- */
152
- recordFailure(error?: unknown): void;
153
- }
154
- /**
155
- * Create a circuit breaker instance.
156
- *
157
- * @param name - Name for this circuit breaker (used in errors and logging)
158
- * @param config - Configuration options
159
- * @returns A CircuitBreaker instance
160
- *
161
- * @example
162
- * ```typescript
163
- * const apiBreaker = createCircuitBreaker('external-api', {
164
- * failureThreshold: 5,
165
- * resetTimeout: 30000,
166
- * });
167
- *
168
- * // In workflow
169
- * const data = await apiBreaker.execute(() =>
170
- * step(() => fetchFromApi(id))
171
- * );
172
- * ```
173
- */
174
- declare function createCircuitBreaker(name: string, config?: Partial<CircuitBreakerConfig>): CircuitBreaker;
175
- /**
176
- * Preset configurations for common use cases.
177
- */
178
- declare const circuitBreakerPresets: {
179
- /**
180
- * Aggressive circuit breaker for critical paths.
181
- * Opens quickly (3 failures) and recovers slowly (60s).
182
- */
183
- readonly critical: {
184
- failureThreshold: number;
185
- resetTimeout: number;
186
- windowSize: number;
187
- halfOpenMax: number;
188
- };
189
- /**
190
- * Standard circuit breaker for typical API calls.
191
- * Balanced between stability and availability.
192
- */
193
- readonly standard: {
194
- failureThreshold: number;
195
- resetTimeout: number;
196
- windowSize: number;
197
- halfOpenMax: number;
198
- };
199
- /**
200
- * Lenient circuit breaker for non-critical operations.
201
- * Opens slowly (10 failures) and recovers quickly (15s).
202
- */
203
- readonly lenient: {
204
- failureThreshold: number;
205
- resetTimeout: number;
206
- windowSize: number;
207
- halfOpenMax: number;
208
- };
209
- };
210
-
211
- export { type CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerStats, CircuitOpenError, type CircuitState, circuitBreakerPresets, createCircuitBreaker, isCircuitOpenError };
@@ -1,211 +0,0 @@
1
- import { R as Result, c as AsyncResult } from './run-entry-Dduz-is2.js';
2
- import './errors.js';
3
- import './tagged-error.js';
4
- import './slugs.js';
5
-
6
- /**
7
- * Circuit Breaker for Steps
8
- *
9
- * Prevents cascading failures by tracking step failure rates and
10
- * short-circuiting calls when a threshold is exceeded.
11
- *
12
- * Uses the circuit breaker pattern with three states:
13
- * - CLOSED: Normal operation (steps executing)
14
- * - OPEN: Fast-fail mode (steps blocked)
15
- * - HALF_OPEN: Testing if service recovered
16
- *
17
- * @example
18
- * ```typescript
19
- * import { createCircuitBreaker } from 'awaitly';
20
- *
21
- * const breaker = createCircuitBreaker({
22
- * failureThreshold: 5,
23
- * resetTimeout: 30000,
24
- * halfOpenMax: 3,
25
- * });
26
- *
27
- * const result = await workflow(async ({ step }) => {
28
- * const data = await breaker.execute(
29
- * () => step(() => callExternalApi()),
30
- * { name: 'external-api' }
31
- * );
32
- * return data;
33
- * });
34
- * ```
35
- */
36
-
37
- /**
38
- * Circuit breaker state.
39
- */
40
- type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
41
- /**
42
- * Configuration for circuit breaker behavior.
43
- */
44
- interface CircuitBreakerConfig {
45
- /**
46
- * Number of failures within the window before opening the circuit.
47
- * @default 5
48
- */
49
- failureThreshold: number;
50
- /**
51
- * Time in ms to wait before transitioning from OPEN to HALF_OPEN.
52
- * @default 30000 (30 seconds)
53
- */
54
- resetTimeout: number;
55
- /**
56
- * Time window in ms for counting failures.
57
- * Failures older than this are discarded.
58
- * @default 60000 (1 minute)
59
- */
60
- windowSize: number;
61
- /**
62
- * Maximum number of test requests allowed in HALF_OPEN state.
63
- * If all succeed, circuit closes. If any fail, circuit reopens.
64
- * @default 3
65
- */
66
- halfOpenMax: number;
67
- /**
68
- * Optional callback when circuit state changes.
69
- */
70
- onStateChange?: (from: CircuitState, to: CircuitState, name?: string) => void;
71
- }
72
- /**
73
- * Error thrown when the circuit is open and calls are blocked.
74
- */
75
- declare class CircuitOpenError extends Error {
76
- readonly type: "CIRCUIT_OPEN";
77
- readonly circuitName: string;
78
- readonly state: CircuitState;
79
- readonly retryAfterMs: number;
80
- constructor(options: {
81
- circuitName: string;
82
- state: CircuitState;
83
- retryAfterMs: number;
84
- message?: string;
85
- });
86
- }
87
- /**
88
- * Type guard for CircuitOpenError.
89
- */
90
- declare function isCircuitOpenError(error: unknown): error is CircuitOpenError;
91
- /**
92
- * Circuit breaker statistics.
93
- */
94
- interface CircuitBreakerStats {
95
- state: CircuitState;
96
- failureCount: number;
97
- successCount: number;
98
- lastFailureTime: number | null;
99
- lastSuccessTime: number | null;
100
- halfOpenSuccesses: number;
101
- }
102
- /**
103
- * Circuit breaker instance for protecting external calls.
104
- */
105
- interface CircuitBreaker {
106
- /**
107
- * Execute an operation with circuit breaker protection.
108
- * Throws CircuitOpenError if the circuit is open.
109
- *
110
- * @param operation - The operation to execute
111
- * @param options - Optional name for logging/metrics
112
- * @returns The operation result
113
- * @throws CircuitOpenError if circuit is open
114
- */
115
- execute<T>(operation: () => T | Promise<T>, options?: {
116
- name?: string;
117
- }): Promise<T>;
118
- /**
119
- * Execute a Result-returning operation with circuit breaker protection.
120
- * Returns a CircuitOpenError result instead of throwing.
121
- *
122
- * @param operation - The operation returning a Result
123
- * @param options - Optional name for logging/metrics
124
- * @returns Result with the value or CircuitOpenError
125
- */
126
- executeResult<T, E>(operation: () => Result<T, E> | AsyncResult<T, E>, options?: {
127
- name?: string;
128
- }): AsyncResult<T, E | CircuitOpenError>;
129
- /**
130
- * Get current circuit state.
131
- */
132
- getState(): CircuitState;
133
- /**
134
- * Get circuit breaker statistics.
135
- */
136
- getStats(): CircuitBreakerStats;
137
- /**
138
- * Manually reset the circuit breaker to CLOSED state.
139
- */
140
- reset(): void;
141
- /**
142
- * Manually open the circuit (for testing or manual intervention).
143
- */
144
- forceOpen(): void;
145
- /**
146
- * Record a manual success (useful for health checks).
147
- */
148
- recordSuccess(): void;
149
- /**
150
- * Record a manual failure (useful for health checks).
151
- */
152
- recordFailure(error?: unknown): void;
153
- }
154
- /**
155
- * Create a circuit breaker instance.
156
- *
157
- * @param name - Name for this circuit breaker (used in errors and logging)
158
- * @param config - Configuration options
159
- * @returns A CircuitBreaker instance
160
- *
161
- * @example
162
- * ```typescript
163
- * const apiBreaker = createCircuitBreaker('external-api', {
164
- * failureThreshold: 5,
165
- * resetTimeout: 30000,
166
- * });
167
- *
168
- * // In workflow
169
- * const data = await apiBreaker.execute(() =>
170
- * step(() => fetchFromApi(id))
171
- * );
172
- * ```
173
- */
174
- declare function createCircuitBreaker(name: string, config?: Partial<CircuitBreakerConfig>): CircuitBreaker;
175
- /**
176
- * Preset configurations for common use cases.
177
- */
178
- declare const circuitBreakerPresets: {
179
- /**
180
- * Aggressive circuit breaker for critical paths.
181
- * Opens quickly (3 failures) and recovers slowly (60s).
182
- */
183
- readonly critical: {
184
- failureThreshold: number;
185
- resetTimeout: number;
186
- windowSize: number;
187
- halfOpenMax: number;
188
- };
189
- /**
190
- * Standard circuit breaker for typical API calls.
191
- * Balanced between stability and availability.
192
- */
193
- readonly standard: {
194
- failureThreshold: number;
195
- resetTimeout: number;
196
- windowSize: number;
197
- halfOpenMax: number;
198
- };
199
- /**
200
- * Lenient circuit breaker for non-critical operations.
201
- * Opens slowly (10 failures) and recovers quickly (15s).
202
- */
203
- readonly lenient: {
204
- failureThreshold: number;
205
- resetTimeout: number;
206
- windowSize: number;
207
- halfOpenMax: number;
208
- };
209
- };
210
-
211
- export { type CircuitBreaker, type CircuitBreakerConfig, type CircuitBreakerStats, CircuitOpenError, type CircuitState, circuitBreakerPresets, createCircuitBreaker, isCircuitOpenError };
@@ -1,7 +0,0 @@
1
- var Me={"step-require-id":"step-require-id","step-no-immediate-execution":"step-no-immediate-execution","step-require-thunk-for-key":"step-require-thunk-for-key","step-no-bare-await":"step-no-bare-await","step-no-try-catch-wrap":"step-no-try-catch-wrap","step-stable-cache-keys":"step-stable-cache-keys","workflow-no-floating":"workflow-no-floating","workflow-options-position":"workflow-options-position","workflow-callback-shape":"workflow-callback-shape","workflow-no-callable-form":"workflow-no-callable-form","workflow-no-dynamic-import":"workflow-no-dynamic-import","result-no-floating":"result-no-floating","result-require-handling":"result-require-handling","result-no-double-wrap":"result-no-double-wrap","result-no-manual-propagation":"result-no-manual-propagation","result-no-direct-ok-err":"result-no-direct-ok-err","error-check-unexpected-first":"error-check-unexpected-first","error-access-cause":"error-access-cause","error-normalize":"error-normalize","error-no-throw-in-deps":"error-no-throw-in-deps","concurrency-no-promise-all":"concurrency-no-promise-all","concurrency-no-promise-race":"concurrency-no-promise-race","concurrency-no-promise-allsettled":"concurrency-no-promise-allsettled","runtime-step-timeout":"runtime-step-timeout","runtime-step-aborted":"runtime-step-aborted","runtime-retry-exhausted":"runtime-retry-exhausted","runtime-rate-limit":"runtime-rate-limit","runtime-circuit-open":"runtime-circuit-open","runtime-unexpected":"runtime-unexpected","runtime-resolver-not-found":"runtime-resolver-not-found","runtime-saga-compensation":"runtime-saga-compensation"};function Ee(o){return`https://jagreehal.github.io/awaitly/rules/#${o}`}var Xe=Object.keys(Me);var te=class extends Error{_tag};function B(o,e){return class extends te{_tag=o;constructor(c,E){let O=e?.message?e.message(c??{}):o;if(super(O),this.name=o,e?.slug!==void 0){if(!e.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${e.slug}")`);Object.defineProperty(this,"code",{value:e.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:e.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:Ee(e.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),c&&typeof c=="object"){let T;if(e?.slug!==void 0){let{_tag:a,name:D,message:v,stack:N,code:K,hint:i,docsUrl:C,...U}=c;T=U}else{let{_tag:a,name:D,message:v,stack:N,...K}=c;T=K}let S=Object.prototype.hasOwnProperty.call(T,"cause"),w=S?T.cause:void 0;S&&delete T.cause;let P=E?.cause!==void 0;if(S&&P)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,T),S&&(this.cause=w),P&&(this.cause=E?.cause)}else E?.cause!==void 0&&(this.cause=E.cause)}}}Object.defineProperty(B,Symbol.hasInstance,{value:o=>o instanceof te});(O=>{function o(T){return T instanceof Error}O.isError=o;function e(T){return T instanceof te}O.isTaggedError=e;function c(T,S){let w=T._tag,P=S[w];return P(T)}O.match=c;function E(T,S,w){let P=T._tag,a=S[P];return a?a(T):w(T)}O.matchPartial=E})(B||={});var ye=class extends B("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:e=>e.operation?`TimeoutError: ${e.operation} timed out after ${e.ms}ms`:`TimeoutError: Operation timed out after ${e.ms}ms`}){},we=class extends B("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:e=>e.operation?`RetryExhaustedError: ${e.operation} failed after ${e.attempts} attempts`:`RetryExhaustedError: Operation failed after ${e.attempts} attempts`}){},fe=class extends B("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:e=>e.limiterName?`RateLimitError: Rate limit exceeded for ${e.limiterName}${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${e.retryAfterMs?`, retry after ${e.retryAfterMs}ms`:""}`}){},ge=class extends B("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:e=>`CircuitBreakerOpenError: Circuit ${e.circuitName} is ${e.state??"OPEN"}${e.retryAfterMs?`, retry after ${Math.ceil(e.retryAfterMs/1e3)}s`:""}`}){},Te=class extends B("ValidationError",{message:e=>`ValidationError: Invalid ${e.field} - ${e.reason}`}){},ke=class extends B("NotFoundError",{message:e=>e.id?`NotFoundError: ${e.resource} with id ${e.id} not found`:`NotFoundError: ${e.resource} not found`}){},Re=class extends B("UnauthorizedError",{message:e=>e.reason?`UnauthorizedError: ${e.reason}`:e.action&&e.resource?`UnauthorizedError: Not authorized to ${e.action} ${e.resource}`:"UnauthorizedError: Access denied"}){},xe=class extends B("NetworkError",{message:e=>e.url?`NetworkError: ${e.reason} (${e.url})`:`NetworkError: ${e.reason}`}){},he=class extends B("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:e=>`CompensationError: Failed to compensate step ${e.step}`}){},se=class extends B("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:e=>`UnexpectedError: ${e.cause instanceof Error?e.cause.message:String(e.cause??"unknown")}`}){};function Ie(o){let e=o.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!e)return;let c=parseFloat(e[1]),E=e[2].toLowerCase();return{_tag:"Duration",millis:c*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[E]??1)}}function De(o){return new se({cause:o})}function W(o){return{ok:!0,value:o}}function F(o,e){let c=e?.cause;return{ok:!1,error:o,...c!==void 0?{cause:c}:{}}}function Ue(o){if(o==null)return"unknown";if(typeof o=="string")return o.trim()||"unknown";if(typeof o=="object"){let e=o;if(typeof e._tag=="string"){let c=e._tag.trim();if(c)return c}if(typeof e.tag=="string"){let c=e.tag.trim();if(c)return c}if(typeof e.code=="string"){let c=e.code.trim();if(c)return c}else if(typeof e.code=="number")return String(e.code);if(o instanceof Error&&o.name){let c=o.name.trim();if(c)return c}}return"unknown"}function Ne(o,e){if(!(!e||!o))return e[o]}function Fe(o){let{intent:e,domain:c,owner:E,tags:O,stateChanges:T,emits:S,calls:w}=o;if(!e&&!c&&!E&&!O?.length&&!T?.length&&!S?.length&&!w?.length)return;let P={};return e&&(P.intent=e),c&&(P.domain=c),E&&(P.owner=E),O?.length&&(P.tags=O),T?.length&&(P.stateChanges=T),S?.length&&(P.emits=S),w?.length&&(P.calls=w),P}function $(o,e,c,E,O){let T=Ue(o),S=Ne(T,e),w={tag:T,origin:c};return S!==void 0&&(w.classification=S),E!==void 0&&(w.attempt=E),O!==void 0&&(w.cumulativeDurationMs=O),w}var Z=Symbol.for("step_timeout_marker");function Ce(o){return typeof o!="object"||o===null?!1:o.type==="STEP_TIMEOUT"?!0:Z in o}function Ke(o){if(!(typeof o!="object"||o===null)){if(o.type==="STEP_TIMEOUT"){let e=o;return{timeoutMs:e.timeoutMs,stepName:e.stepName,stepKey:e.stepKey,attempt:e.attempt}}if(Z in o)return o[Z]}}var _e=Symbol("early-exit");function je(o,e){return{[_e]:!0,error:o,meta:e}}function Be(o){return typeof o=="object"&&o!==null&&o[_e]===!0}var Pe=Symbol("mapper-exception");function X(o){return{[Pe]:!0,thrown:o}}function Le(o){return typeof o=="object"&&o!==null&&o[Pe]===!0}function me(o,e){let{backoff:c,initialDelay:E,maxDelay:O,jitter:T}=e,S;switch(c){case"fixed":S=E;break;case"linear":S=E*o;break;case"exponential":S=E*Math.pow(2,o-1);break}if(S=Math.min(S,O),T){let w=S*.25*Math.random();S=S+w}return Math.floor(S)}function de(o){return new Promise(e=>setTimeout(e,o))}var be=Symbol("timeout"),ae=Symbol("timeout-option");function $e(o){return typeof o=="object"&&o!==null&&o[ae]===!0}async function He(o,e,c,E){let O=new AbortController,T=e.onTimeout??"error",S=()=>typeof T=="function"?T({name:c.name,key:c.key,ms:e.ms}):e.error??{type:"STEP_TIMEOUT",stepName:c.name,stepKey:c.key,timeoutMs:e.ms,attempt:c.attempt},w;E?.aborted&&O.abort(E.reason);let P;E&&!E.aborted&&(P=()=>O.abort(E.reason),E.addEventListener("abort",P,{once:!0}));let a=new Promise((v,N)=>{w=setTimeout(()=>{if(T!=="disconnect"&&O.abort(),T==="option"){N({[ae]:!0,ms:e.ms});return}N({[be]:!0,error:S()})},e.ms)}),D;e.signal?D=Promise.resolve(o(O.signal)):D=Promise.resolve(o());try{return await Promise.race([D,a])}catch(v){if(typeof v=="object"&&v!==null&&v[ae]===!0)throw{[ae]:!0,ms:e.ms};if(typeof v=="object"&&v!==null&&v[be]===!0){T==="disconnect"&&D.catch(()=>{});let N=v.error;if(typeof N=="object"&&N!==null&&N.type!=="STEP_TIMEOUT"){let K={timeoutMs:e.ms,stepName:c.name,stepKey:c.key,attempt:c.attempt};Z in N?N[Z]=K:Object.defineProperty(N,Z,{value:K,enumerable:!1,writable:!0,configurable:!1})}throw N}throw v}finally{clearTimeout(w),P&&E&&E.removeEventListener("abort",P)}}var Q={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function Se(o,e){let{onError:c,onEvent:E,catchUnexpected:O,workflowId:T,workflowName:S,context:w,_workflowSignal:P}=e&&typeof e=="object"?e:{},a=T??crypto.randomUUID(),D=O??De,v=[],N=0,K=p=>p??`step_${++N}`,i=p=>{let H=p.context!==void 0||w===void 0?p:{...p,context:w},Y=S!==void 0&&H.workflowName===void 0?{...H,workflowName:S}:H;if(Y.type==="step_success"){let ne=Y.stepId;for(let oe=v.length-1;oe>=0;oe--){let V=v[oe];if(V.type==="race"&&!V.winnerId){V.winnerId=ne;break}}}E?.(Y,w)},C=je,U=p=>Be(p),j=(p,H)=>p,L=p=>typeof p=="function"?!1:!!(p&&typeof p=="object"&&"ok"in p||p&&typeof p=="object"&&"then"in p&&typeof p.then=="function");try{let H=function(s){let m={};for(let[r,n]of Object.entries(s))if(typeof n=="function")m[r]=n;else if(n&&typeof n=="object"&&"fn"in n)m[r]=n.fn;else throw new TypeError(`step.all: operation "${r}" must be a function or { fn, errors? } object`);return m},Y=function(s,m){let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),t=!1;v.push({scopeId:r,type:"parallel"});let u=()=>{if(t)return;t=!0;let l=v.findIndex(d=>d.scopeId===r);l!==-1&&v.splice(l,1),i({type:"scope_end",workflowId:a,scopeId:r,ts:Date.now(),durationMs:performance.now()-n})};i({type:"scope_start",workflowId:a,scopeId:r,scopeType:"parallel",name:s,ts:Date.now()});try{let l=await m();if(u(),!l.ok)throw c?.(l.error,s,w),C(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw u(),l}})()},ne=function(s,m){let r=Object.keys(s),n=m.name??`Parallel(${r.join(", ")})`,t=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),l=!1;v.push({scopeId:t,type:"parallel"});let d=()=>{if(l)return;l=!0;let y=v.findIndex(f=>f.scopeId===t);y!==-1&&v.splice(y,1),i({type:"scope_end",workflowId:a,scopeId:t,ts:Date.now(),durationMs:performance.now()-u})};i({type:"scope_start",workflowId:a,scopeId:t,scopeType:"parallel",name:n,ts:Date.now()});try{let y=await new Promise(k=>{if(r.length===0){k([]);return}let A=!1,I=r.length,R=new Array(r.length);for(let M=0;M<r.length;M++){let x=r[M],b=M;Promise.resolve(s[x]()).catch(h=>F({type:"PROMISE_REJECTED",cause:h},{cause:{type:"PROMISE_REJECTION",reason:h}})).then(h=>{if(!A){if(!h.ok){A=!0,k([{key:x,result:h}]);return}R[b]={key:x,result:h},I--,I===0&&k(R)}})}});d();let f={};for(let{key:k,result:A}of y){if(!A.ok)throw c?.(A.error,k,w),C(A.error,{origin:"result",resultCause:A.cause});f[k]=A.value}return f}catch(y){throw d(),y}})()};var ze=H,Je=Y,Ge=ne;let p=(s,m,r)=>(async()=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let n=r??{},t=Fe(n),u=s,l=n.key??s,d=n.key??s,{description:y,retry:f,timeout:k}=n,A=K(l),I=E,R=I?performance.now():0,x=L(m)?()=>m:m,h={attempts:Math.max(1,f?.attempts??1),backoff:f?.backoff??Q.backoff,initialDelay:f?.initialDelay??Q.initialDelay,maxDelay:f?.maxDelay??Q.maxDelay,jitter:f?.jitter??Q.jitter,shouldRetry:f?.shouldRetry??Q.shouldRetry,onRetry:f?.onRetry??Q.onRetry};E&&i({type:"step_start",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),...t&&{metadata:t}});let G;for(let _=1;_<=h.attempts;_++){let Oe=I?performance.now():0;try{let g;if(k?g=await He(x,k,{name:u,key:l,attempt:_},P):g=await x(),g.ok){let J=performance.now()-R;return i({type:"step_success",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:J,...t&&{metadata:t}}),d&&i({type:"step_complete",workflowId:a,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:J,result:g,...t&&{metadata:t}}),g.value}if(G=g,_<h.attempts&&h.shouldRetry(g.error,_)){let J=me(_,h);i({type:"step_retry",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:J,error:g.error,...t&&{metadata:t},diagnostics:$(g.error,n.errorMeta,"result",_,performance.now()-R)}),h.onRetry(g.error,_,J),await de(J);continue}h.attempts>1&&i({type:"step_retries_exhausted",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:_,lastError:g.error,...t&&{metadata:t},diagnostics:$(g.error,n.errorMeta,"result",_,performance.now()-R)});break}catch(g){let J=performance.now()-Oe;if($e(g)){let q=g.ms;i({type:"step_timeout",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),timeoutMs:q,attempt:_,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"timeout",_)}),i({type:"step_success",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:performance.now()-R,...t&&{metadata:t}}),d&&i({type:"step_complete",workflowId:a,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:performance.now()-R,result:W(void 0),...t&&{metadata:t}});return}if(U(g))throw i({type:"step_aborted",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:J,...t&&{metadata:t}}),g;if(Ce(g)){let q=Ke(g),ve=k?.ms??q?.timeoutMs??0;if(i({type:"step_timeout",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),timeoutMs:ve,attempt:_,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"timeout",_)}),_<h.attempts&&h.shouldRetry(g,_)){let pe=me(_,h);i({type:"step_retry",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:pe,error:g,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"timeout",_,performance.now()-R)}),h.onRetry(g,_,pe),await de(pe);continue}h.attempts>1&&i({type:"step_retries_exhausted",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:_,lastError:g,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"timeout",_,performance.now()-R)});let le=performance.now()-R;throw i({type:"step_error",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:le,error:g,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"timeout",_,le)}),d&&i({type:"step_complete",workflowId:a,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:le,result:F(g,{cause:g}),meta:{origin:"throw",thrown:g},...t&&{metadata:t}}),c?.(g,u,w),C(g,{origin:"throw",thrown:g})}if(_<h.attempts&&h.shouldRetry(g,_)){let q=me(_,h);i({type:"step_retry",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),attempt:_+1,maxAttempts:h.attempts,delayMs:q,error:g,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"throw",_,performance.now()-R)}),h.onRetry(g,_,q),await de(q);continue}h.attempts>1&&!Ce(g)&&i({type:"step_retries_exhausted",workflowId:a,stepId:A,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-R,attempts:_,lastError:g,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"throw",_,performance.now()-R)});let ce=performance.now()-R,ee;try{ee=D(g)}catch(q){throw X(q)}throw i({type:"step_error",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:ce,error:ee,...t&&{metadata:t},diagnostics:$(g,n.errorMeta,"throw",_,ce)}),d&&i({type:"step_complete",workflowId:a,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:ce,result:F(ee,{cause:g}),meta:{origin:"throw",thrown:g},...t&&{metadata:t}}),c?.(ee,u,w),C(ee,{origin:"throw",thrown:g})}}let z=G,ie=performance.now()-R,ue=j(z.error,{origin:"result",resultCause:z.cause});throw i({type:"step_error",workflowId:a,stepId:A,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:ie,error:ue,...t&&{metadata:t},diagnostics:$(z.error,n.errorMeta,"result",h.attempts,ie)}),d&&i({type:"step_complete",workflowId:a,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:ie,result:z,meta:{origin:"result",resultCause:z.cause},...t&&{metadata:t}}),c?.(ue,u,w),C(ue,{origin:"result",resultCause:z.cause})})();p.try=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.try() requires an explicit string ID as the first argument. Example: step.try("parse", () => JSON.parse(str), { error: "PARSE_ERROR" })');let n="error"in r?()=>r.error:r.onError;if(r.retry||r.timeout)return p.retry(s,async()=>{try{return W(await m())}catch(y){return F(n(y),{cause:y})}},{attempts:r.retry?.attempts??1,...r.retry??{},key:r.key,timeout:r.timeout});let t=r.key??s,u=s,l=s,d=E;return(async()=>{let y=d?performance.now():0;E&&i({type:"step_start",workflowId:a,stepId:l,stepKey:t,name:u,ts:Date.now()});try{let f=await m(),k=performance.now()-y;return i({type:"step_success",workflowId:a,stepId:l,stepKey:t,name:u,ts:Date.now(),durationMs:k}),t&&i({type:"step_complete",workflowId:a,stepKey:t,name:u,ts:Date.now(),durationMs:k,result:W(f)}),f}catch(f){let k=n(f),A=performance.now()-y,I=j(k,{origin:"throw",thrown:f});throw i({type:"step_error",workflowId:a,stepId:l,stepKey:t,name:u,ts:Date.now(),durationMs:A,error:I}),t&&i({type:"step_complete",workflowId:a,stepKey:t,name:u,ts:Date.now(),durationMs:A,result:F(k,{cause:f}),meta:{origin:"throw",thrown:f}}),c?.(I,u,w),C(I,{origin:"throw",thrown:f})}})()},p.fromResult=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.fromResult() requires an explicit string ID as the first argument. Example: step.fromResult("callProvider", () => callProvider(input), { onError: (e) => ({ type: "FAILED" }) })');let n=r.key??s,t=s,u=s,l="error"in r?()=>r.error:r.onError,d=E;return(async()=>{let y=d?performance.now():0;E&&i({type:"step_start",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now()});let f=await m();if(f.ok){let k=performance.now()-y;return i({type:"step_success",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:k}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:k,result:W(f.value)}),f.value}else{let k=l(f.error),A=performance.now()-y,I=j(k,{origin:"result",resultCause:f.error});throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:A,error:I}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:A,result:F(k,{cause:f.error}),meta:{origin:"result",resultCause:f.error}}),c?.(I,t,w),C(I,{origin:"result",resultCause:f.error})}})()},p.fromNullable=(s,m,r,n)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.fromNullable() requires an explicit string ID as the first argument. Example: step.fromNullable("getUser", () => db.find(id), () => ({ type: "NOT_FOUND" }))');return p(s,async()=>{let t=await m();return t!=null?W(t):F(r())},n)},p.retry=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.retry() requires an explicit string ID as the first argument. Example: step.retry("fetchData", () => fetchData(), { attempts: 3 })');return p(s,m,{key:r.key??s,retry:{attempts:r.attempts,backoff:r.backoff,initialDelay:r.initialDelay,maxDelay:r.maxDelay,jitter:r.jitter,shouldRetry:r.shouldRetry,onRetry:r.onRetry},timeout:r.timeout})},p.withTimeout=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.withTimeout() requires an explicit string ID as the first argument. Example: step.withTimeout("slowOp", () => slowOp(), { ms: 5000 })');return p(s,m,{key:r.key??s,timeout:r})},p.sleep=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let n=typeof m=="string"?Ie(m):m;if(!n)throw new Error(`step.sleep: invalid duration '${m}'`);let t=n.millis,u=r?.signal;return p(s,async()=>{if(P?.aborted||u?.aborted){let l=new Error("Sleep aborted");throw l.name="AbortError",l}return new Promise((l,d)=>{let y={timeoutId:void 0},f=()=>{y.timeoutId&&clearTimeout(y.timeoutId);let k=new Error("Sleep aborted");k.name="AbortError",d(k)};P?.addEventListener("abort",f,{once:!0}),u?.addEventListener("abort",f,{once:!0}),y.timeoutId=setTimeout(()=>{P?.removeEventListener("abort",f),u?.removeEventListener("abort",f),l(W(void 0))},t)})},{key:r?.key??s,description:r?.description})},p.all=((...s)=>{if(typeof s[0]!="string")throw new TypeError("step.all(name, ...): first argument must be a string (step name). Example: step.all('Fetch data', { user: () => fetchUser(), posts: () => fetchPosts() })");let m=s[0],r=s[1];if(typeof r=="function")return Y(m,r);if(r&&typeof r=="object"&&!Array.isArray(r)){let t=H(r);return ne(t,{name:m})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(s,m)=>{let r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),t=!1,u={scopeId:r,type:"race",winnerId:void 0};v.push(u);let l=()=>{if(t)return;t=!0;let d=v.findIndex(y=>y.scopeId===r);d!==-1&&v.splice(d,1),i({type:"scope_end",workflowId:a,scopeId:r,ts:Date.now(),durationMs:performance.now()-n,winnerId:u.winnerId})};i({type:"scope_start",workflowId:a,scopeId:r,scopeType:"race",name:s,ts:Date.now()});try{let d=await m();if(l(),!d.ok)throw c?.(d.error,s,w),C(d.error,{origin:"result",resultCause:d.cause});return d.value}catch(d){throw l(),d}})()},p.if=(s,m,r)=>r(),p.label=p.if,p.branch=async(s,m)=>{let{condition:r,then:n,else:t}=m;if(r())return await n();if(t)return await t()},p.arm=(s,m)=>({fn:s,errors:m}),p.forEach=async(s,m,r)=>{let n=[],t=r.maxIterations,u=0,l="run"in r,d=Symbol.asyncIterator in m?m:(async function*(){yield*m})();for await(let y of d){if(t!==void 0&&u>=t)break;let f;l?f=await r.run(y,u):f=await r.item.handler(y,u,p),n.push(f),u++}return n},p.item=s=>({__forEachItemHandler:!0,handler:s}),p.dep=(s,m)=>m,p.workflow=(s,m,r)=>p(s,m,r),p.map=async(s,m,r,n)=>{let t=n?.concurrency??m.length;return p(s,()=>t>=m.length?Ae(m.map((u,l)=>r(u,l))):(async()=>{let u=[];for(let l=0;l<m.length;l+=t){let d=m.slice(l,l+t),y=await Ae(d.map((f,k)=>r(f,l+k)));if(!y.ok)return y;u.push(...y.value)}return W(u)})(),{key:n?.key})},p.withFallback=(s,m,r)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.withFallback() requires an explicit string ID as the first argument. Example: step.withFallback("getUser", () => fetchUser(id), { fallback: () => fetchFromCache(id) })');let n=r.key??s,t=s,u=K(n),l=E;return(async()=>{let d=l?performance.now():0;E&&i({type:"step_start",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now()});let y;try{y=await m()}catch(R){if(U(R))throw i({type:"step_aborted",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:performance.now()-d}),R;let M;try{M=D(R)}catch(b){throw X(b)}if(r.on!==void 0&&r.on!==M){let b=performance.now()-d;throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:b,error:M}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:b,result:F(M,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(M,t,w),C(M,{origin:"throw",thrown:R})}let x;try{x=await r.fallback()}catch(b){if(U(b))throw i({type:"step_aborted",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:performance.now()-d}),b;let h;try{h=D(b)}catch(z){throw X(z)}let G=performance.now()-d;throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:G,error:h}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:G,result:F(h,{cause:b}),meta:{origin:"throw",thrown:b}}),c?.(h,t,w),C(h,{origin:"throw",thrown:b})}if(x.ok){let b=performance.now()-d;return i({type:"step_success",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:b}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:b,result:x,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(M)}}),x.value}else{let b=performance.now()-d,h=j(x.error,{origin:"result",resultCause:x.cause});throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:b,error:h}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:b,result:x,meta:{origin:"result",resultCause:x.cause}}),c?.(h,t,w),C(h,{origin:"result",resultCause:x.cause})}}if(y.ok){let R=performance.now()-d;return i({type:"step_success",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:R}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:R,result:y}),y.value}let f=y.error;if(r.on!==void 0&&r.on!==f){let R=performance.now()-d,M=j(f,{origin:"result",resultCause:y.cause});throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:R,error:M}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:R,result:y,meta:{origin:"result",resultCause:y.cause}}),c?.(M,t,w),C(M,{origin:"result",resultCause:y.cause})}let k;try{k=await r.fallback()}catch(R){if(U(R))throw i({type:"step_aborted",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:performance.now()-d}),R;let M;try{M=D(R)}catch(b){throw X(b)}let x=performance.now()-d;throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:x,error:M}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:x,result:F(M,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(M,t,w),C(M,{origin:"throw",thrown:R})}if(k.ok){let R=performance.now()-d;return i({type:"step_success",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:R}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:R,result:k,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(f)}}),k.value}let A=performance.now()-d,I=j(k.error,{origin:"result",resultCause:k.cause});throw i({type:"step_error",workflowId:a,stepId:u,stepKey:n,name:t,ts:Date.now(),durationMs:A,error:I}),n&&i({type:"step_complete",workflowId:a,stepKey:n,name:t,ts:Date.now(),durationMs:A,result:k,meta:{origin:"result",resultCause:k.cause}}),c?.(I,t,w),C(I,{origin:"result",resultCause:k.cause})})()},p.withResource=(s,m)=>{if(typeof s!="string"||s.length===0)throw new Error('[awaitly] step.withResource() requires an explicit string ID as the first argument. Example: step.withResource("useDb", { acquire: () => connect(), use: (db) => query(db), release: (db) => db.close() })');let r=s,n=s,t=K(r),u=E;return(async()=>{let l=u?performance.now():0;E&&i({type:"step_start",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now()});let d;try{d=await m.acquire()}catch(x){if(U(x))throw i({type:"step_aborted",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:performance.now()-l}),x;let b;try{b=D(x)}catch(G){throw X(G)}let h=performance.now()-l;throw i({type:"step_error",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:h,error:b}),r&&i({type:"step_complete",workflowId:a,stepKey:r,name:n,ts:Date.now(),durationMs:h,result:F(b,{cause:x}),meta:{origin:"throw",thrown:x}}),c?.(b,n,w),C(b,{origin:"throw",thrown:x})}if(!d.ok){let x=performance.now()-l,b=j(d.error,{origin:"result",resultCause:d.cause});throw i({type:"step_error",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:x,error:b}),r&&i({type:"step_complete",workflowId:a,stepKey:r,name:n,ts:Date.now(),durationMs:x,result:d,meta:{origin:"result",resultCause:d.cause}}),c?.(b,n,w),C(b,{origin:"result",resultCause:d.cause})}let y=d.value,f,k,A=!1;try{f=await m.use(y)}catch(x){if(U(x)){try{await m.release(y)}catch(b){console.warn(`[awaitly] step.withResource("${s}"): release threw after earlyExit:`,b)}throw x}k=x,A=!0}try{await m.release(y)}catch(x){console.warn(`[awaitly] step.withResource("${s}"): release threw:`,x)}if(A){let x;try{x=D(k)}catch(h){throw X(h)}let b=performance.now()-l;throw i({type:"step_error",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:b,error:x}),r&&i({type:"step_complete",workflowId:a,stepKey:r,name:n,ts:Date.now(),durationMs:b,result:F(x,{cause:k}),meta:{origin:"throw",thrown:k}}),c?.(x,n,w),C(x,{origin:"throw",thrown:k})}let I=f;if(I.ok){let x=performance.now()-l;return i({type:"step_success",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:x}),r&&i({type:"step_complete",workflowId:a,stepKey:r,name:n,ts:Date.now(),durationMs:x,result:I}),I.value}let R=performance.now()-l,M=j(I.error,{origin:"result",resultCause:I.cause});throw i({type:"step_error",workflowId:a,stepId:t,stepKey:r,name:n,ts:Date.now(),durationMs:R,error:M}),r&&i({type:"step_complete",workflowId:a,stepKey:r,name:n,ts:Date.now(),durationMs:R,result:I,meta:{origin:"result",resultCause:I.cause}}),c?.(M,n,w),C(M,{origin:"result",resultCause:I.cause})})()};let V=await o({step:p});if(process.env.NODE_ENV!=="production"&&V!==null&&typeof V=="object"&&"ok"in V&&typeof V.ok=="boolean"){let s=V;(s.ok===!0&&"value"in s||s.ok===!1&&"error"in s)&&console.warn(`awaitly: Workflow executor returned a Result-like object. Return raw values, not ok() or err().
2
-
3
- Incorrect: return ok({ data });
4
- Correct: return { data };
5
-
6
- See: https://jagreehal.github.io/awaitly/guides/troubleshooting/#returning-ok-from-workflow-executor-double-wrapping`)}return W(V)}catch(p){if(Le(p))throw p.thrown;if(U(p)){let Y=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return F(p.error,{cause:Y})}let H=D(p);return c?.(H,"unexpected",w),F(H,{cause:p})}}Se.strict=(o,e)=>Se(o,e);async function Ae(o){return o.length===0?W([]):new Promise(e=>{let c=!1,E=o.length,O=new Array(o.length);for(let T=0;T<o.length;T++){let S=T;Promise.resolve(o[S]).catch(w=>F({type:"PROMISE_REJECTED",cause:w},{cause:{type:"PROMISE_REJECTION",reason:w}})).then(w=>{if(!c){if(!w.ok){c=!0,e(w);return}O[S]=w.value,E--,E===0&&e(W(O))}})}})}var re=class extends Error{type="CIRCUIT_OPEN";circuitName;state;retryAfterMs;constructor(e){super(e.message??`Circuit breaker "${e.circuitName}" is ${e.state}. Retry after ${Math.ceil(e.retryAfterMs/1e3)}s`),this.name="CircuitOpenError",this.circuitName=e.circuitName,this.state=e.state,this.retryAfterMs=e.retryAfterMs}};function Ve(o){return typeof o=="object"&&o!==null&&o.type==="CIRCUIT_OPEN"}var We={failureThreshold:5,resetTimeout:3e4,windowSize:6e4,halfOpenMax:3};function qe(o,e){let c={...We,...e},E="CLOSED",O=[],T=null,S=null,w=0,P=0;function a(){let C=Date.now();O=O.filter(U=>C-U.timestamp<c.windowSize)}function D(C){if(E!==C){let U=E;E=C,C==="HALF_OPEN"&&(P=0),c.onStateChange?.(U,C,o)}}function v(){return E!=="OPEN"||T===null?!1:Date.now()-T>=c.resetTimeout?(D("HALF_OPEN"),!0):!1}function N(){S=Date.now(),w++,E==="HALF_OPEN"&&(P++,P>=c.halfOpenMax&&(D("CLOSED"),O=[]))}function K(C){let U=Date.now();T=U,a(),O.push({timestamp:U,error:C}),(E==="HALF_OPEN"||E==="CLOSED"&&O.length>=c.failureThreshold)&&D("OPEN")}function i(){if(E==="CLOSED")return 0;if(E==="OPEN"){if(v())return 0;let C=Date.now(),U=T?C-T:0;return Math.max(0,c.resetTimeout-U)}return 0}return{async execute(C,U){let j=i();if(j>0)throw new re({circuitName:o,state:E,retryAfterMs:j});try{let L=await C();return N(),L}catch(L){throw K(L),L}},async executeResult(C,U){let j=i();if(j>0)return F(new re({circuitName:o,state:E,retryAfterMs:j}));try{let L=await C();return L.ok?N():K(L.error),L}catch(L){throw K(L),L}},getState(){return E==="OPEN"&&v(),E},getStats(){return a(),{state:this.getState(),failureCount:O.length,successCount:w,lastFailureTime:T,lastSuccessTime:S,halfOpenSuccesses:P}},reset(){D("CLOSED"),O=[],P=0},forceOpen(){T=Date.now(),D("OPEN")},recordSuccess(){N()},recordFailure(C){K(C??new Error("Manual failure"))}}}var Ye={critical:{failureThreshold:3,resetTimeout:6e4,windowSize:3e4,halfOpenMax:1},standard:{failureThreshold:5,resetTimeout:3e4,windowSize:6e4,halfOpenMax:3},lenient:{failureThreshold:10,resetTimeout:15e3,windowSize:12e4,halfOpenMax:5}};export{re as CircuitOpenError,Ye as circuitBreakerPresets,qe as createCircuitBreaker,Ve as isCircuitOpenError};
7
- //# sourceMappingURL=circuit-breaker.js.map