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
package/dist/batch.d.cts DELETED
@@ -1,200 +0,0 @@
1
- import { c as AsyncResult } from './run-entry-D2MmJFj9.cjs';
2
- import './errors.cjs';
3
- import './tagged-error.cjs';
4
- import './slugs.cjs';
5
-
6
- /**
7
- * awaitly/batch
8
- *
9
- * Batch processing utilities with progress tracking and checkpoints.
10
- * Useful for I/O-heavy operations like generating embeddings, API calls, or database writes.
11
- *
12
- * Tree-shakable - only import if needed.
13
- *
14
- * @example
15
- * ```typescript
16
- * import { processInBatches, ok, err, type AsyncResult } from 'awaitly';
17
- *
18
- * // Generate embeddings in batches with progress tracking
19
- * const embedText = async (text: string): AsyncResult<number[], 'EMBED_ERROR'> => {
20
- * const response = await fetch('/api/embed', { body: text });
21
- * return response.ok ? ok(await response.json()) : err('EMBED_ERROR');
22
- * };
23
- *
24
- * const checkpoint = async (): AsyncResult<void, 'DB_ERROR'> => {
25
- * await db.checkpoint();
26
- * return ok(undefined);
27
- * };
28
- *
29
- * const result = await processInBatches(
30
- * texts,
31
- * embedText,
32
- * { batchSize: 20, concurrency: 3, batchDelayMs: 50 },
33
- * {
34
- * afterBatch: checkpoint,
35
- * onProgress: (p) => console.log(`${p.percent}% complete`),
36
- * }
37
- * );
38
- * ```
39
- */
40
-
41
- /**
42
- * Configuration for batch processing.
43
- */
44
- interface BatchConfig {
45
- /**
46
- * Number of items to process per batch.
47
- * Lower values = more frequent checkpoints, less memory pressure.
48
- * Higher values = fewer checkpoints, more throughput.
49
- * @default 20
50
- */
51
- batchSize: number;
52
- /**
53
- * Maximum concurrent operations within a batch.
54
- * Controls parallelism for I/O-bound operations.
55
- * @default 5
56
- */
57
- concurrency: number;
58
- /**
59
- * Delay in milliseconds between batches.
60
- * Provides backpressure to allow event loop breathing and GC.
61
- * Set to 0 for no delay.
62
- * @default 0
63
- */
64
- batchDelayMs?: number;
65
- }
66
- /**
67
- * Progress information for batch processing.
68
- */
69
- interface BatchProgress {
70
- /** Current batch number (1-indexed) */
71
- batch: number;
72
- /** Total number of batches */
73
- totalBatches: number;
74
- /** Items processed so far */
75
- processed: number;
76
- /** Total items to process */
77
- total: number;
78
- /** Percentage complete (0-100) */
79
- percent: number;
80
- }
81
- /**
82
- * Options for batch processing.
83
- */
84
- interface BatchOptions<E> {
85
- /**
86
- * Hook called after each batch completes successfully.
87
- * Useful for checkpointing (e.g., flushing database WAL).
88
- * If this returns an error, processing stops.
89
- */
90
- afterBatch?: () => AsyncResult<void, E>;
91
- /**
92
- * Callback for progress reporting.
93
- * Called after each batch completes.
94
- */
95
- onProgress?: (progress: BatchProgress) => void;
96
- }
97
- /**
98
- * Error that occurred during batch processing.
99
- */
100
- interface BatchProcessingError<E> {
101
- type: "BATCH_PROCESSING_ERROR";
102
- /** The underlying error from the process function or afterBatch hook */
103
- error: E;
104
- /** Index of the item that failed (if process function failed) */
105
- itemIndex?: number;
106
- /** Batch number where the error occurred (1-indexed) */
107
- batchNumber: number;
108
- }
109
- /**
110
- * Error for invalid batch configuration.
111
- */
112
- interface InvalidBatchConfigError {
113
- type: "INVALID_BATCH_CONFIG";
114
- /** Description of what's wrong with the config */
115
- reason: string;
116
- /** The invalid field name */
117
- field: "batchSize" | "concurrency";
118
- /** The invalid value */
119
- value: number;
120
- }
121
- /**
122
- * Type guard for BatchProcessingError.
123
- */
124
- declare function isBatchProcessingError<E>(error: unknown): error is BatchProcessingError<E>;
125
- /**
126
- * Type guard for InvalidBatchConfigError.
127
- */
128
- declare function isInvalidBatchConfigError(error: unknown): error is InvalidBatchConfigError;
129
- /**
130
- * Process items in batches with bounded concurrency, progress tracking, and checkpoints.
131
- *
132
- * This function is designed for I/O-heavy operations where you need to:
133
- * - Control memory pressure by processing in smaller batches
134
- * - Checkpoint progress (e.g., flush database WAL) between batches
135
- * - Add backpressure delays to allow GC and event loop breathing
136
- * - Report progress to the user
137
- *
138
- * Processing stops on the first error encountered.
139
- *
140
- * @param items - Array of items to process
141
- * @param process - Function to process each item, returns AsyncResult
142
- * @param config - Batch configuration (size, concurrency, delay)
143
- * @param options - Optional hooks for afterBatch and progress reporting
144
- * @returns AsyncResult containing all processed results, or an error
145
- *
146
- * @example
147
- * ```typescript
148
- * // Basic usage
149
- * const results = await processInBatches(
150
- * items,
151
- * async (item) => ok(await transform(item)),
152
- * { batchSize: 10, concurrency: 3 }
153
- * );
154
- *
155
- * // With checkpoints and progress
156
- * const results = await processInBatches(
157
- * items,
158
- * processItem,
159
- * { batchSize: 20, concurrency: 5, batchDelayMs: 50 },
160
- * {
161
- * afterBatch: () => db.checkpoint(),
162
- * onProgress: (p) => updateProgressBar(p.percent),
163
- * }
164
- * );
165
- * ```
166
- */
167
- declare function processInBatches<T, R, E>(items: readonly T[], process: (item: T, index: number) => AsyncResult<R, E>, config: BatchConfig, options?: BatchOptions<E>): AsyncResult<R[], E | BatchProcessingError<E> | InvalidBatchConfigError>;
168
- /**
169
- * Preset configurations for common batch processing scenarios.
170
- */
171
- declare const batchPresets: {
172
- /**
173
- * Conservative settings for memory-constrained environments.
174
- * Good for WASM, serverless, or when processing large payloads.
175
- */
176
- readonly conservative: {
177
- batchSize: number;
178
- concurrency: number;
179
- batchDelayMs: number;
180
- };
181
- /**
182
- * Balanced settings for typical workloads.
183
- */
184
- readonly balanced: {
185
- batchSize: number;
186
- concurrency: number;
187
- batchDelayMs: number;
188
- };
189
- /**
190
- * Aggressive settings for maximum throughput.
191
- * Use when memory is not a concern.
192
- */
193
- readonly aggressive: {
194
- batchSize: number;
195
- concurrency: number;
196
- batchDelayMs: number;
197
- };
198
- };
199
-
200
- export { type BatchConfig, type BatchOptions, type BatchProcessingError, type BatchProgress, type InvalidBatchConfigError, batchPresets, isBatchProcessingError, isInvalidBatchConfigError, processInBatches };
package/dist/batch.d.ts DELETED
@@ -1,200 +0,0 @@
1
- import { 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
- * awaitly/batch
8
- *
9
- * Batch processing utilities with progress tracking and checkpoints.
10
- * Useful for I/O-heavy operations like generating embeddings, API calls, or database writes.
11
- *
12
- * Tree-shakable - only import if needed.
13
- *
14
- * @example
15
- * ```typescript
16
- * import { processInBatches, ok, err, type AsyncResult } from 'awaitly';
17
- *
18
- * // Generate embeddings in batches with progress tracking
19
- * const embedText = async (text: string): AsyncResult<number[], 'EMBED_ERROR'> => {
20
- * const response = await fetch('/api/embed', { body: text });
21
- * return response.ok ? ok(await response.json()) : err('EMBED_ERROR');
22
- * };
23
- *
24
- * const checkpoint = async (): AsyncResult<void, 'DB_ERROR'> => {
25
- * await db.checkpoint();
26
- * return ok(undefined);
27
- * };
28
- *
29
- * const result = await processInBatches(
30
- * texts,
31
- * embedText,
32
- * { batchSize: 20, concurrency: 3, batchDelayMs: 50 },
33
- * {
34
- * afterBatch: checkpoint,
35
- * onProgress: (p) => console.log(`${p.percent}% complete`),
36
- * }
37
- * );
38
- * ```
39
- */
40
-
41
- /**
42
- * Configuration for batch processing.
43
- */
44
- interface BatchConfig {
45
- /**
46
- * Number of items to process per batch.
47
- * Lower values = more frequent checkpoints, less memory pressure.
48
- * Higher values = fewer checkpoints, more throughput.
49
- * @default 20
50
- */
51
- batchSize: number;
52
- /**
53
- * Maximum concurrent operations within a batch.
54
- * Controls parallelism for I/O-bound operations.
55
- * @default 5
56
- */
57
- concurrency: number;
58
- /**
59
- * Delay in milliseconds between batches.
60
- * Provides backpressure to allow event loop breathing and GC.
61
- * Set to 0 for no delay.
62
- * @default 0
63
- */
64
- batchDelayMs?: number;
65
- }
66
- /**
67
- * Progress information for batch processing.
68
- */
69
- interface BatchProgress {
70
- /** Current batch number (1-indexed) */
71
- batch: number;
72
- /** Total number of batches */
73
- totalBatches: number;
74
- /** Items processed so far */
75
- processed: number;
76
- /** Total items to process */
77
- total: number;
78
- /** Percentage complete (0-100) */
79
- percent: number;
80
- }
81
- /**
82
- * Options for batch processing.
83
- */
84
- interface BatchOptions<E> {
85
- /**
86
- * Hook called after each batch completes successfully.
87
- * Useful for checkpointing (e.g., flushing database WAL).
88
- * If this returns an error, processing stops.
89
- */
90
- afterBatch?: () => AsyncResult<void, E>;
91
- /**
92
- * Callback for progress reporting.
93
- * Called after each batch completes.
94
- */
95
- onProgress?: (progress: BatchProgress) => void;
96
- }
97
- /**
98
- * Error that occurred during batch processing.
99
- */
100
- interface BatchProcessingError<E> {
101
- type: "BATCH_PROCESSING_ERROR";
102
- /** The underlying error from the process function or afterBatch hook */
103
- error: E;
104
- /** Index of the item that failed (if process function failed) */
105
- itemIndex?: number;
106
- /** Batch number where the error occurred (1-indexed) */
107
- batchNumber: number;
108
- }
109
- /**
110
- * Error for invalid batch configuration.
111
- */
112
- interface InvalidBatchConfigError {
113
- type: "INVALID_BATCH_CONFIG";
114
- /** Description of what's wrong with the config */
115
- reason: string;
116
- /** The invalid field name */
117
- field: "batchSize" | "concurrency";
118
- /** The invalid value */
119
- value: number;
120
- }
121
- /**
122
- * Type guard for BatchProcessingError.
123
- */
124
- declare function isBatchProcessingError<E>(error: unknown): error is BatchProcessingError<E>;
125
- /**
126
- * Type guard for InvalidBatchConfigError.
127
- */
128
- declare function isInvalidBatchConfigError(error: unknown): error is InvalidBatchConfigError;
129
- /**
130
- * Process items in batches with bounded concurrency, progress tracking, and checkpoints.
131
- *
132
- * This function is designed for I/O-heavy operations where you need to:
133
- * - Control memory pressure by processing in smaller batches
134
- * - Checkpoint progress (e.g., flush database WAL) between batches
135
- * - Add backpressure delays to allow GC and event loop breathing
136
- * - Report progress to the user
137
- *
138
- * Processing stops on the first error encountered.
139
- *
140
- * @param items - Array of items to process
141
- * @param process - Function to process each item, returns AsyncResult
142
- * @param config - Batch configuration (size, concurrency, delay)
143
- * @param options - Optional hooks for afterBatch and progress reporting
144
- * @returns AsyncResult containing all processed results, or an error
145
- *
146
- * @example
147
- * ```typescript
148
- * // Basic usage
149
- * const results = await processInBatches(
150
- * items,
151
- * async (item) => ok(await transform(item)),
152
- * { batchSize: 10, concurrency: 3 }
153
- * );
154
- *
155
- * // With checkpoints and progress
156
- * const results = await processInBatches(
157
- * items,
158
- * processItem,
159
- * { batchSize: 20, concurrency: 5, batchDelayMs: 50 },
160
- * {
161
- * afterBatch: () => db.checkpoint(),
162
- * onProgress: (p) => updateProgressBar(p.percent),
163
- * }
164
- * );
165
- * ```
166
- */
167
- declare function processInBatches<T, R, E>(items: readonly T[], process: (item: T, index: number) => AsyncResult<R, E>, config: BatchConfig, options?: BatchOptions<E>): AsyncResult<R[], E | BatchProcessingError<E> | InvalidBatchConfigError>;
168
- /**
169
- * Preset configurations for common batch processing scenarios.
170
- */
171
- declare const batchPresets: {
172
- /**
173
- * Conservative settings for memory-constrained environments.
174
- * Good for WASM, serverless, or when processing large payloads.
175
- */
176
- readonly conservative: {
177
- batchSize: number;
178
- concurrency: number;
179
- batchDelayMs: number;
180
- };
181
- /**
182
- * Balanced settings for typical workloads.
183
- */
184
- readonly balanced: {
185
- batchSize: number;
186
- concurrency: number;
187
- batchDelayMs: number;
188
- };
189
- /**
190
- * Aggressive settings for maximum throughput.
191
- * Use when memory is not a concern.
192
- */
193
- readonly aggressive: {
194
- batchSize: number;
195
- concurrency: number;
196
- batchDelayMs: number;
197
- };
198
- };
199
-
200
- export { type BatchConfig, type BatchOptions, type BatchProcessingError, type BatchProgress, type InvalidBatchConfigError, batchPresets, isBatchProcessingError, isInvalidBatchConfigError, processInBatches };
package/dist/batch.js DELETED
@@ -1,7 +0,0 @@
1
- var Ue={"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 we(r){return`https://jagreehal.github.io/awaitly/rules/#${r}`}var Xe=Object.keys(Ue);var te=class extends Error{_tag};function F(r,t){return class extends te{_tag=r;constructor(c,g){let A=t?.message?t.message(c??{}):r;if(super(A),this.name=r,t?.slug!==void 0){if(!t.hint)throw new TypeError(`TaggedError: 'hint' is required when 'slug' is set (slug: "${t.slug}")`);Object.defineProperty(this,"code",{value:t.slug,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"hint",{value:t.hint,enumerable:!0,writable:!1,configurable:!1}),Object.defineProperty(this,"docsUrl",{value:we(t.slug),enumerable:!0,writable:!1,configurable:!1})}if(Object.setPrototypeOf(this,new.target.prototype),c&&typeof c=="object"){let w;if(t?.slug!==void 0){let{_tag:s,name:M,message:v,stack:D,code:N,hint:i,docsUrl:U,...j}=c;w=j}else{let{_tag:s,name:M,message:v,stack:D,...N}=c;w=N}let k=Object.prototype.hasOwnProperty.call(w,"cause"),E=k?w.cause:void 0;k&&delete w.cause;let _=g?.cause!==void 0;if(k&&_)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,w),k&&(this.cause=E),_&&(this.cause=g?.cause)}else g?.cause!==void 0&&(this.cause=g.cause)}}}Object.defineProperty(F,Symbol.hasInstance,{value:r=>r instanceof te});(A=>{function r(w){return w instanceof Error}A.isError=r;function t(w){return w instanceof te}A.isTaggedError=t;function c(w,k){let E=w._tag,_=k[E];return _(w)}A.match=c;function g(w,k,E){let _=w._tag,s=k[_];return s?s(w):E(w)}A.matchPartial=g})(F||={});var fe=class extends F("TimeoutError",{slug:"runtime-step-timeout",hint:"Increase the step's timeout option, or check why the upstream operation is slow.",message:t=>t.operation?`TimeoutError: ${t.operation} timed out after ${t.ms}ms`:`TimeoutError: Operation timed out after ${t.ms}ms`}){},Te=class extends F("RetryExhaustedError",{slug:"runtime-retry-exhausted",hint:"All retry attempts failed. Inspect lastError and decide whether to surface it or compensate.",message:t=>t.operation?`RetryExhaustedError: ${t.operation} failed after ${t.attempts} attempts`:`RetryExhaustedError: Operation failed after ${t.attempts} attempts`}){},ge=class extends F("RateLimitError",{slug:"runtime-rate-limit",hint:"Wait retryAfterMs before retrying, or apply step.cache to deduplicate calls.",message:t=>t.limiterName?`RateLimitError: Rate limit exceeded for ${t.limiterName}${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`:`RateLimitError: Rate limit exceeded${t.retryAfterMs?`, retry after ${t.retryAfterMs}ms`:""}`}){},ke=class extends F("CircuitBreakerOpenError",{slug:"runtime-circuit-open",hint:"The circuit is open. Wait for it to half-open or fall back to a degraded path.",message:t=>`CircuitBreakerOpenError: Circuit ${t.circuitName} is ${t.state??"OPEN"}${t.retryAfterMs?`, retry after ${Math.ceil(t.retryAfterMs/1e3)}s`:""}`}){},Re=class extends F("ValidationError",{message:t=>`ValidationError: Invalid ${t.field} - ${t.reason}`}){},xe=class extends F("NotFoundError",{message:t=>t.id?`NotFoundError: ${t.resource} with id ${t.id} not found`:`NotFoundError: ${t.resource} not found`}){},he=class extends F("UnauthorizedError",{message:t=>t.reason?`UnauthorizedError: ${t.reason}`:t.action&&t.resource?`UnauthorizedError: Not authorized to ${t.action} ${t.resource}`:"UnauthorizedError: Access denied"}){},Ce=class extends F("NetworkError",{message:t=>t.url?`NetworkError: ${t.reason} (${t.url})`:`NetworkError: ${t.reason}`}){},be=class extends F("CompensationError",{slug:"runtime-saga-compensation",hint:"A saga compensation step failed. Inspect compensationError and ensure compensation is idempotent.",message:t=>`CompensationError: Failed to compensate step ${t.step}`}){},se=class extends F("UnexpectedError",{slug:"runtime-unexpected",hint:"An unexpected exception escaped a step. Inspect cause; consider returning a typed Result instead of throwing.",message:t=>`UnexpectedError: ${t.cause instanceof Error?t.cause.message:String(t.cause??"unknown")}`}){};function Le(r){let t=r.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let c=parseFloat(t[1]),g=t[2].toLowerCase();return{_tag:"Duration",millis:c*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[g]??1)}}function Ne(r){return new se({cause:r})}function B(r){return{ok:!0,value:r}}function L(r,t){let c=t?.cause;return{ok:!1,error:r,...c!==void 0?{cause:c}:{}}}function Fe(r){if(r==null)return"unknown";if(typeof r=="string")return r.trim()||"unknown";if(typeof r=="object"){let t=r;if(typeof t._tag=="string"){let c=t._tag.trim();if(c)return c}if(typeof t.tag=="string"){let c=t.tag.trim();if(c)return c}if(typeof t.code=="string"){let c=t.code.trim();if(c)return c}else if(typeof t.code=="number")return String(t.code);if(r instanceof Error&&r.name){let c=r.name.trim();if(c)return c}}return"unknown"}function je(r,t){if(!(!t||!r))return t[r]}function Be(r){let{intent:t,domain:c,owner:g,tags:A,stateChanges:w,emits:k,calls:E}=r;if(!t&&!c&&!g&&!A?.length&&!w?.length&&!k?.length&&!E?.length)return;let _={};return t&&(_.intent=t),c&&(_.domain=c),g&&(_.owner=g),A?.length&&(_.tags=A),w?.length&&(_.stateChanges=w),k?.length&&(_.emits=k),E?.length&&(_.calls=E),_}function W(r,t,c,g,A){let w=Fe(r),k=je(w,t),E={tag:w,origin:c};return k!==void 0&&(E.classification=k),g!==void 0&&(E.attempt=g),A!==void 0&&(E.cumulativeDurationMs=A),E}var Z=Symbol.for("step_timeout_marker");function Se(r){return typeof r!="object"||r===null?!1:r.type==="STEP_TIMEOUT"?!0:Z in r}function Ke(r){if(!(typeof r!="object"||r===null)){if(r.type==="STEP_TIMEOUT"){let t=r;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(Z in r)return r[Z]}}var ve=Symbol("early-exit");function We(r,t){return{[ve]:!0,error:r,meta:t}}function He(r){return typeof r=="object"&&r!==null&&r[ve]===!0}var Me=Symbol("mapper-exception");function G(r){return{[Me]:!0,thrown:r}}function Ve(r){return typeof r=="object"&&r!==null&&r[Me]===!0}function de(r,t){let{backoff:c,initialDelay:g,maxDelay:A,jitter:w}=t,k;switch(c){case"fixed":k=g;break;case"linear":k=g*r;break;case"exponential":k=g*Math.pow(2,r-1);break}if(k=Math.min(k,A),w){let E=k*.25*Math.random();k=k+E}return Math.floor(k)}function Ee(r){return new Promise(t=>setTimeout(t,r))}var Ae=Symbol("timeout"),ae=Symbol("timeout-option");function qe(r){return typeof r=="object"&&r!==null&&r[ae]===!0}async function $e(r,t,c,g){let A=new AbortController,w=t.onTimeout??"error",k=()=>typeof w=="function"?w({name:c.name,key:c.key,ms:t.ms}):t.error??{type:"STEP_TIMEOUT",stepName:c.name,stepKey:c.key,timeoutMs:t.ms,attempt:c.attempt},E;g?.aborted&&A.abort(g.reason);let _;g&&!g.aborted&&(_=()=>A.abort(g.reason),g.addEventListener("abort",_,{once:!0}));let s=new Promise((v,D)=>{E=setTimeout(()=>{if(w!=="disconnect"&&A.abort(),w==="option"){D({[ae]:!0,ms:t.ms});return}D({[Ae]:!0,error:k()})},t.ms)}),M;t.signal?M=Promise.resolve(r(A.signal)):M=Promise.resolve(r());try{return await Promise.race([M,s])}catch(v){if(typeof v=="object"&&v!==null&&v[ae]===!0)throw{[ae]:!0,ms:t.ms};if(typeof v=="object"&&v!==null&&v[Ae]===!0){w==="disconnect"&&M.catch(()=>{});let D=v.error;if(typeof D=="object"&&D!==null&&D.type!=="STEP_TIMEOUT"){let N={timeoutMs:t.ms,stepName:c.name,stepKey:c.key,attempt:c.attempt};Z in D?D[Z]=N:Object.defineProperty(D,Z,{value:N,enumerable:!1,writable:!0,configurable:!1})}throw D}throw v}finally{clearTimeout(E),_&&g&&g.removeEventListener("abort",_)}}var J={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function Pe(r,t){let{onError:c,onEvent:g,catchUnexpected:A,workflowId:w,workflowName:k,context:E,_workflowSignal:_}=t&&typeof t=="object"?t:{},s=w??crypto.randomUUID(),M=A??Ne,v=[],D=0,N=p=>p??`step_${++D}`,i=p=>{let V=p.context!==void 0||E===void 0?p:{...p,context:E},z=k!==void 0&&V.workflowName===void 0?{...V,workflowName:k}:V;if(z.type==="step_success"){let ne=z.stepId;for(let oe=v.length-1;oe>=0;oe--){let q=v[oe];if(q.type==="race"&&!q.winnerId){q.winnerId=ne;break}}}g?.(z,E)},U=We,j=p=>He(p),H=(p,V)=>p,K=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 V=function(a){let m={};for(let[n,o]of Object.entries(a))if(typeof o=="function")m[n]=o;else if(o&&typeof o=="object"&&"fn"in o)m[n]=o.fn;else throw new TypeError(`step.all: operation "${n}" must be a function or { fn, errors? } object`);return m},z=function(a,m){let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),e=!1;v.push({scopeId:n,type:"parallel"});let u=()=>{if(e)return;e=!0;let l=v.findIndex(d=>d.scopeId===n);l!==-1&&v.splice(l,1),i({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o})};i({type:"scope_start",workflowId:s,scopeId:n,scopeType:"parallel",name:a,ts:Date.now()});try{let l=await m();if(u(),!l.ok)throw c?.(l.error,a,E),U(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw u(),l}})()},ne=function(a,m){let n=Object.keys(a),o=m.name??`Parallel(${n.join(", ")})`,e=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let u=performance.now(),l=!1;v.push({scopeId:e,type:"parallel"});let d=()=>{if(l)return;l=!0;let y=v.findIndex(f=>f.scopeId===e);y!==-1&&v.splice(y,1),i({type:"scope_end",workflowId:s,scopeId:e,ts:Date.now(),durationMs:performance.now()-u})};i({type:"scope_start",workflowId:s,scopeId:e,scopeType:"parallel",name:o,ts:Date.now()});try{let y=await new Promise(R=>{if(n.length===0){R([]);return}let S=!1,O=n.length,x=new Array(n.length);for(let I=0;I<n.length;I++){let h=n[I],b=I;Promise.resolve(a[h]()).catch(C=>L({type:"PROMISE_REJECTED",cause:C},{cause:{type:"PROMISE_REJECTION",reason:C}})).then(C=>{if(!S){if(!C.ok){S=!0,R([{key:h,result:C}]);return}x[b]={key:h,result:C},O--,O===0&&R(x)}})}});d();let f={};for(let{key:R,result:S}of y){if(!S.ok)throw c?.(S.error,R,E),U(S.error,{origin:"result",resultCause:S.cause});f[R]=S.value}return f}catch(y){throw d(),y}})()};var ye=V,ie=z,re=ne;let p=(a,m,n)=>(async()=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step() requires an explicit string ID as the first argument. Example: step("fetchUser", () => fetchUser(id))');let o=n??{},e=Be(o),u=a,l=o.key??a,d=o.key??a,{description:y,retry:f,timeout:R}=o,S=N(l),O=g,x=O?performance.now():0,h=K(m)?()=>m:m,C={attempts:Math.max(1,f?.attempts??1),backoff:f?.backoff??J.backoff,initialDelay:f?.initialDelay??J.initialDelay,maxDelay:f?.maxDelay??J.maxDelay,jitter:f?.jitter??J.jitter,shouldRetry:f?.shouldRetry??J.shouldRetry,onRetry:f?.onRetry??J.onRetry};g&&i({type:"step_start",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),...e&&{metadata:e}});let X;for(let P=1;P<=C.attempts;P++){let Oe=O?performance.now():0;try{let T;if(R?T=await $e(h,R,{name:u,key:l,attempt:P},_):T=await h(),T.ok){let Q=performance.now()-x;return i({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:Q,...e&&{metadata:e}}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:Q,result:T,...e&&{metadata:e}}),T.value}if(X=T,P<C.attempts&&C.shouldRetry(T.error,P)){let Q=de(P,C);i({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),attempt:P+1,maxAttempts:C.attempts,delayMs:Q,error:T.error,...e&&{metadata:e},diagnostics:W(T.error,o.errorMeta,"result",P,performance.now()-x)}),C.onRetry(T.error,P,Q),await Ee(Q);continue}C.attempts>1&&i({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-x,attempts:P,lastError:T.error,...e&&{metadata:e},diagnostics:W(T.error,o.errorMeta,"result",P,performance.now()-x)});break}catch(T){let Q=performance.now()-Oe;if(qe(T)){let $=T.ms;i({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),timeoutMs:$,attempt:P,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"timeout",P)}),i({type:"step_success",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:performance.now()-x,...e&&{metadata:e}}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:performance.now()-x,result:B(void 0),...e&&{metadata:e}});return}if(j(T))throw i({type:"step_aborted",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:Q,...e&&{metadata:e}}),T;if(Se(T)){let $=Ke(T),De=R?.ms??$?.timeoutMs??0;if(i({type:"step_timeout",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),timeoutMs:De,attempt:P,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"timeout",P)}),P<C.attempts&&C.shouldRetry(T,P)){let me=de(P,C);i({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),attempt:P+1,maxAttempts:C.attempts,delayMs:me,error:T,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"timeout",P,performance.now()-x)}),C.onRetry(T,P,me),await Ee(me);continue}C.attempts>1&&i({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-x,attempts:P,lastError:T,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"timeout",P,performance.now()-x)});let pe=performance.now()-x;throw i({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:pe,error:T,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"timeout",P,pe)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:pe,result:L(T,{cause:T}),meta:{origin:"throw",thrown:T},...e&&{metadata:e}}),c?.(T,u,E),U(T,{origin:"throw",thrown:T})}if(P<C.attempts&&C.shouldRetry(T,P)){let $=de(P,C);i({type:"step_retry",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),attempt:P+1,maxAttempts:C.attempts,delayMs:$,error:T,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"throw",P,performance.now()-x)}),C.onRetry(T,P,$),await Ee($);continue}C.attempts>1&&!Se(T)&&i({type:"step_retries_exhausted",workflowId:s,stepId:S,stepKey:l,name:u,ts:Date.now(),durationMs:performance.now()-x,attempts:P,lastError:T,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"throw",P,performance.now()-x)});let le=performance.now()-x,ee;try{ee=M(T)}catch($){throw G($)}throw i({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:le,error:ee,...e&&{metadata:e},diagnostics:W(T,o.errorMeta,"throw",P,le)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:le,result:L(ee,{cause:T}),meta:{origin:"throw",thrown:T},...e&&{metadata:e}}),c?.(ee,u,E),U(ee,{origin:"throw",thrown:T})}}let Y=X,ue=performance.now()-x,ce=H(Y.error,{origin:"result",resultCause:Y.cause});throw i({type:"step_error",workflowId:s,stepId:S,stepKey:l,name:u,description:y,ts:Date.now(),durationMs:ue,error:ce,...e&&{metadata:e},diagnostics:W(Y.error,o.errorMeta,"result",C.attempts,ue)}),d&&i({type:"step_complete",workflowId:s,stepKey:d,name:u,description:y,ts:Date.now(),durationMs:ue,result:Y,meta:{origin:"result",resultCause:Y.cause},...e&&{metadata:e}}),c?.(ce,u,E),U(ce,{origin:"result",resultCause:Y.cause})})();p.try=(a,m,n)=>{if(typeof a!="string"||a.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 o="error"in n?()=>n.error:n.onError;if(n.retry||n.timeout)return p.retry(a,async()=>{try{return B(await m())}catch(y){return L(o(y),{cause:y})}},{attempts:n.retry?.attempts??1,...n.retry??{},key:n.key,timeout:n.timeout});let e=n.key??a,u=a,l=a,d=g;return(async()=>{let y=d?performance.now():0;g&&i({type:"step_start",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now()});try{let f=await m(),R=performance.now()-y;return i({type:"step_success",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now(),durationMs:R}),e&&i({type:"step_complete",workflowId:s,stepKey:e,name:u,ts:Date.now(),durationMs:R,result:B(f)}),f}catch(f){let R=o(f),S=performance.now()-y,O=H(R,{origin:"throw",thrown:f});throw i({type:"step_error",workflowId:s,stepId:l,stepKey:e,name:u,ts:Date.now(),durationMs:S,error:O}),e&&i({type:"step_complete",workflowId:s,stepKey:e,name:u,ts:Date.now(),durationMs:S,result:L(R,{cause:f}),meta:{origin:"throw",thrown:f}}),c?.(O,u,E),U(O,{origin:"throw",thrown:f})}})()},p.fromResult=(a,m,n)=>{if(typeof a!="string"||a.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 o=n.key??a,e=a,u=a,l="error"in n?()=>n.error:n.onError,d=g;return(async()=>{let y=d?performance.now():0;g&&i({type:"step_start",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now()});let f=await m();if(f.ok){let R=performance.now()-y;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:R}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:R,result:B(f.value)}),f.value}else{let R=l(f.error),S=performance.now()-y,O=H(R,{origin:"result",resultCause:f.error});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:S,error:O}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:S,result:L(R,{cause:f.error}),meta:{origin:"result",resultCause:f.error}}),c?.(O,e,E),U(O,{origin:"result",resultCause:f.error})}})()},p.fromNullable=(a,m,n,o)=>{if(typeof a!="string"||a.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(a,async()=>{let e=await m();return e!=null?B(e):L(n())},o)},p.retry=(a,m,n)=>{if(typeof a!="string"||a.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(a,m,{key:n.key??a,retry:{attempts:n.attempts,backoff:n.backoff,initialDelay:n.initialDelay,maxDelay:n.maxDelay,jitter:n.jitter,shouldRetry:n.shouldRetry,onRetry:n.onRetry},timeout:n.timeout})},p.withTimeout=(a,m,n)=>{if(typeof a!="string"||a.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(a,m,{key:n.key??a,timeout:n})},p.sleep=(a,m,n)=>{if(typeof a!="string"||a.length===0)throw new Error('[awaitly] step.sleep() requires an explicit string ID as the first argument. Example: step.sleep("delay", "5s")');let o=typeof m=="string"?Le(m):m;if(!o)throw new Error(`step.sleep: invalid duration '${m}'`);let e=o.millis,u=n?.signal;return p(a,async()=>{if(_?.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 R=new Error("Sleep aborted");R.name="AbortError",d(R)};_?.addEventListener("abort",f,{once:!0}),u?.addEventListener("abort",f,{once:!0}),y.timeoutId=setTimeout(()=>{_?.removeEventListener("abort",f),u?.removeEventListener("abort",f),l(B(void 0))},e)})},{key:n?.key??a,description:n?.description})},p.all=((...a)=>{if(typeof a[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=a[0],n=a[1];if(typeof n=="function")return z(m,n);if(n&&typeof n=="object"&&!Array.isArray(n)){let e=V(n);return ne(e,{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=(a,m)=>{let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),e=!1,u={scopeId:n,type:"race",winnerId:void 0};v.push(u);let l=()=>{if(e)return;e=!0;let d=v.findIndex(y=>y.scopeId===n);d!==-1&&v.splice(d,1),i({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o,winnerId:u.winnerId})};i({type:"scope_start",workflowId:s,scopeId:n,scopeType:"race",name:a,ts:Date.now()});try{let d=await m();if(l(),!d.ok)throw c?.(d.error,a,E),U(d.error,{origin:"result",resultCause:d.cause});return d.value}catch(d){throw l(),d}})()},p.if=(a,m,n)=>n(),p.label=p.if,p.branch=async(a,m)=>{let{condition:n,then:o,else:e}=m;if(n())return await o();if(e)return await e()},p.arm=(a,m)=>({fn:a,errors:m}),p.forEach=async(a,m,n)=>{let o=[],e=n.maxIterations,u=0,l="run"in n,d=Symbol.asyncIterator in m?m:(async function*(){yield*m})();for await(let y of d){if(e!==void 0&&u>=e)break;let f;l?f=await n.run(y,u):f=await n.item.handler(y,u,p),o.push(f),u++}return o},p.item=a=>({__forEachItemHandler:!0,handler:a}),p.dep=(a,m)=>m,p.workflow=(a,m,n)=>p(a,m,n),p.map=async(a,m,n,o)=>{let e=o?.concurrency??m.length;return p(a,()=>e>=m.length?_e(m.map((u,l)=>n(u,l))):(async()=>{let u=[];for(let l=0;l<m.length;l+=e){let d=m.slice(l,l+e),y=await _e(d.map((f,R)=>n(f,l+R)));if(!y.ok)return y;u.push(...y.value)}return B(u)})(),{key:o?.key})},p.withFallback=(a,m,n)=>{if(typeof a!="string"||a.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 o=n.key??a,e=a,u=N(o),l=g;return(async()=>{let d=l?performance.now():0;g&&i({type:"step_start",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now()});let y;try{y=await m()}catch(x){if(j(x))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),x;let I;try{I=M(x)}catch(b){throw G(b)}if(n.on!==void 0&&n.on!==I){let b=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:b,error:I}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:b,result:L(I,{cause:x}),meta:{origin:"throw",thrown:x}}),c?.(I,e,E),U(I,{origin:"throw",thrown:x})}let h;try{h=await n.fallback()}catch(b){if(j(b))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),b;let C;try{C=M(b)}catch(Y){throw G(Y)}let X=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:X,error:C}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:X,result:L(C,{cause:b}),meta:{origin:"throw",thrown:b}}),c?.(C,e,E),U(C,{origin:"throw",thrown:b})}if(h.ok){let b=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:b}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:b,result:h,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(I)}}),h.value}else{let b=performance.now()-d,C=H(h.error,{origin:"result",resultCause:h.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:b,error:C}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:b,result:h,meta:{origin:"result",resultCause:h.cause}}),c?.(C,e,E),U(C,{origin:"result",resultCause:h.cause})}}if(y.ok){let x=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:x}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:x,result:y}),y.value}let f=y.error;if(n.on!==void 0&&n.on!==f){let x=performance.now()-d,I=H(f,{origin:"result",resultCause:y.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:x,error:I}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:x,result:y,meta:{origin:"result",resultCause:y.cause}}),c?.(I,e,E),U(I,{origin:"result",resultCause:y.cause})}let R;try{R=await n.fallback()}catch(x){if(j(x))throw i({type:"step_aborted",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:performance.now()-d}),x;let I;try{I=M(x)}catch(b){throw G(b)}let h=performance.now()-d;throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:h,error:I}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:h,result:L(I,{cause:x}),meta:{origin:"throw",thrown:x}}),c?.(I,e,E),U(I,{origin:"throw",thrown:x})}if(R.ok){let x=performance.now()-d;return i({type:"step_success",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:x}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:x,result:R,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(f)}}),R.value}let S=performance.now()-d,O=H(R.error,{origin:"result",resultCause:R.cause});throw i({type:"step_error",workflowId:s,stepId:u,stepKey:o,name:e,ts:Date.now(),durationMs:S,error:O}),o&&i({type:"step_complete",workflowId:s,stepKey:o,name:e,ts:Date.now(),durationMs:S,result:R,meta:{origin:"result",resultCause:R.cause}}),c?.(O,e,E),U(O,{origin:"result",resultCause:R.cause})})()},p.withResource=(a,m)=>{if(typeof a!="string"||a.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 n=a,o=a,e=N(n),u=g;return(async()=>{let l=u?performance.now():0;g&&i({type:"step_start",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now()});let d;try{d=await m.acquire()}catch(h){if(j(h))throw i({type:"step_aborted",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:performance.now()-l}),h;let b;try{b=M(h)}catch(X){throw G(X)}let C=performance.now()-l;throw i({type:"step_error",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:C,error:b}),n&&i({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:C,result:L(b,{cause:h}),meta:{origin:"throw",thrown:h}}),c?.(b,o,E),U(b,{origin:"throw",thrown:h})}if(!d.ok){let h=performance.now()-l,b=H(d.error,{origin:"result",resultCause:d.cause});throw i({type:"step_error",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:h,error:b}),n&&i({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:h,result:d,meta:{origin:"result",resultCause:d.cause}}),c?.(b,o,E),U(b,{origin:"result",resultCause:d.cause})}let y=d.value,f,R,S=!1;try{f=await m.use(y)}catch(h){if(j(h)){try{await m.release(y)}catch(b){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,b)}throw h}R=h,S=!0}try{await m.release(y)}catch(h){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,h)}if(S){let h;try{h=M(R)}catch(C){throw G(C)}let b=performance.now()-l;throw i({type:"step_error",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:b,error:h}),n&&i({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:b,result:L(h,{cause:R}),meta:{origin:"throw",thrown:R}}),c?.(h,o,E),U(h,{origin:"throw",thrown:R})}let O=f;if(O.ok){let h=performance.now()-l;return i({type:"step_success",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:h}),n&&i({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:h,result:O}),O.value}let x=performance.now()-l,I=H(O.error,{origin:"result",resultCause:O.cause});throw i({type:"step_error",workflowId:s,stepId:e,stepKey:n,name:o,ts:Date.now(),durationMs:x,error:I}),n&&i({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:x,result:O,meta:{origin:"result",resultCause:O.cause}}),c?.(I,o,E),U(I,{origin:"result",resultCause:O.cause})})()};let q=await r({step:p});if(process.env.NODE_ENV!=="production"&&q!==null&&typeof q=="object"&&"ok"in q&&typeof q.ok=="boolean"){let a=q;(a.ok===!0&&"value"in a||a.ok===!1&&"error"in a)&&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 B(q)}catch(p){if(Ve(p))throw p.thrown;if(j(p)){let z=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return L(p.error,{cause:z})}let V=M(p);return c?.(V,"unexpected",E),L(V,{cause:p})}}Pe.strict=(r,t)=>Pe(r,t);async function _e(r){return r.length===0?B([]):new Promise(t=>{let c=!1,g=r.length,A=new Array(r.length);for(let w=0;w<r.length;w++){let k=w;Promise.resolve(r[k]).catch(E=>L({type:"PROMISE_REJECTED",cause:E},{cause:{type:"PROMISE_REJECTION",reason:E}})).then(E=>{if(!c){if(!E.ok){c=!0,t(E);return}A[k]=E.value,g--,g===0&&t(B(A))}})}})}function ze(r){return typeof r=="object"&&r!==null&&r.type==="QUEUE_FULL"}function Ie(r,t){let{maxConcurrent:c,strategy:g="queue",maxQueueSize:A=1/0}=t,w=0,k=[];async function E(){if(w<c){w++;return}if(g==="reject")throw{type:"QUEUE_FULL",limiterName:r,queueSize:k.length,maxQueueSize:A};if(k.length>=A)throw{type:"QUEUE_FULL",limiterName:r,queueSize:k.length,maxQueueSize:A};return new Promise((s,M)=>{k.push({resolve:s,reject:M})})}function _(){w--,k.length>0&&w<c&&(w++,k.shift()?.resolve())}return{async execute(s){await E();try{return await s()}finally{_()}},async executeAll(s){let M=new Array(s.length),v=[];for(let D=0;D<s.length;D++){let N=D,i=this.execute(s[N]).then(U=>{M[N]=U});v.push(i)}return await Promise.all(v),M},async executeResult(s){try{await E()}catch(M){if(ze(M))return L(M);throw M}try{return await s()}finally{_()}},getStats(){return{activeCount:w,maxConcurrent:c,queueSize:k.length,maxQueueSize:A}},reset(){for(w=0;k.length>0;)k.shift()?.reject(new Error("Limiter reset"))}}}function Ye(r){return typeof r=="object"&&r!==null&&r.type==="BATCH_PROCESSING_ERROR"}function ct(r){return typeof r=="object"&&r!==null&&r.type==="INVALID_BATCH_CONFIG"}var Qe=r=>new Promise(t=>setTimeout(t,r));async function lt(r,t,c,g){let{batchSize:A,concurrency:w,batchDelayMs:k=0}=c,{afterBatch:E,onProgress:_}=g??{};if(!Number.isInteger(A)||A<1)return L({type:"INVALID_BATCH_CONFIG",reason:"batchSize must be a positive integer",field:"batchSize",value:A});if(!Number.isInteger(w)||w<1)return L({type:"INVALID_BATCH_CONFIG",reason:"concurrency must be a positive integer",field:"concurrency",value:w});if(r.length===0)return B([]);let s=[],M=Math.ceil(r.length/A),v=Ie("batch-processor",{maxConcurrent:w});for(let D=0;D<M;D++){let N=D*A,i=Math.min(N+A,r.length),U=r.slice(N,i),j=D+1,H=U.map((K,ye)=>async()=>{let ie=N+ye,re=await t(K,ie);if(!re.ok)throw{type:"BATCH_PROCESSING_ERROR",error:re.error,itemIndex:ie,batchNumber:j};return re.value});try{let K=await v.executeAll(H);s.push(...K)}catch(K){if(Ye(K))return L(K);throw K}if(_?.({batch:j,totalBatches:M,processed:s.length,total:r.length,percent:Math.round(s.length/r.length*100)}),E){let K=await E();if(!K.ok)return L({type:"BATCH_PROCESSING_ERROR",error:K.error,batchNumber:j})}k>0&&D<M-1&&await Qe(k)}return B(s)}var pt={conservative:{batchSize:20,concurrency:3,batchDelayMs:50},balanced:{batchSize:50,concurrency:5,batchDelayMs:10},aggressive:{batchSize:100,concurrency:10,batchDelayMs:0}};export{pt as batchPresets,Ye as isBatchProcessingError,ct as isInvalidBatchConfigError,lt as processInBatches};
7
- //# sourceMappingURL=batch.js.map