awaitly 1.35.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 +29 -4
  14. package/dist/result.d.ts +29 -4
  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-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
  24. package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
  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 +3 -168
  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-By77n4Fa.d.ts +0 -15
  75. package/dist/di-OJfsohf-.d.cts +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-4sV7mTqj.d.cts +0 -72
  123. package/dist/guards-BIX05ALH.d.ts +0 -72
  124. package/dist/hitl-DFn4Xa_l.d.cts +0 -468
  125. package/dist/hitl-DU5VpKq7.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-CnvBryQB.d.ts +0 -417
  133. package/dist/index-DEZEf8Fs.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-B-8PjnSR.d.cts +0 -831
  149. package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
  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-BziYHFkD.d.ts +0 -323
  235. package/dist/types-C5jLEUqY.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-DGs0tySr.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-BOuNyVoO.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 Fe={"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(e){return`https://jagreehal.github.io/awaitly/rules/#${e}`}var tr=Object.keys(Fe);var se=class extends Error{_tag};function j(e,t){return class extends se{_tag=e;constructor(f,b){let x=t?.message?t.message(f??{}):e;if(super(x),this.name=e,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),f&&typeof f=="object"){let u;if(t?.slug!==void 0){let{_tag:_,name:C,message:U,stack:s,code:L,hint:F,docsUrl:Z,...q}=f;u=q}else{let{_tag:_,name:C,message:U,stack:s,...L}=f;u=L}let d=Object.prototype.hasOwnProperty.call(u,"cause"),A=d?u.cause:void 0;d&&delete u.cause;let O=b?.cause!==void 0;if(d&&O)throw new TypeError("TaggedError: cannot provide 'cause' in props when also setting ErrorOptions.cause");Object.assign(this,u),d&&(this.cause=A),O&&(this.cause=b?.cause)}else b?.cause!==void 0&&(this.cause=b.cause)}}}Object.defineProperty(j,Symbol.hasInstance,{value:e=>e instanceof se});(x=>{function e(u){return u instanceof Error}x.isError=e;function t(u){return u instanceof se}x.isTaggedError=t;function f(u,d){let A=u._tag,O=d[A];return O(u)}x.match=f;function b(u,d,A){let O=u._tag,_=d[O];return _?_(u):A(u)}x.matchPartial=b})(j||={});var Te=class extends j("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`}){},ke=class extends j("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`}){},Re=class extends j("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`:""}`}){},ge=class extends j("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`:""}`}){},xe=class extends j("ValidationError",{message:t=>`ValidationError: Invalid ${t.field} - ${t.reason}`}){},Ce=class extends j("NotFoundError",{message:t=>t.id?`NotFoundError: ${t.resource} with id ${t.id} not found`:`NotFoundError: ${t.resource} not found`}){},he=class extends j("UnauthorizedError",{message:t=>t.reason?`UnauthorizedError: ${t.reason}`:t.action&&t.resource?`UnauthorizedError: Not authorized to ${t.action} ${t.resource}`:"UnauthorizedError: Access denied"}){},be=class extends j("NetworkError",{message:t=>t.url?`NetworkError: ${t.reason} (${t.url})`:`NetworkError: ${t.reason}`}){},Ae=class extends j("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}`}){},ie=class extends j("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 Se(e){return{ok:!0,value:e}}var je=e=>typeof e=="object"&&e!==null&&"ok"in e&&typeof e.ok=="boolean"&&(e.ok?"value"in e:"error"in e),Pe=(e,t)=>{let f={},b=new Map;for(let x of Object.keys(e)){let u=e[x];typeof u=="function"&&(f[x]=(...d)=>{let A=(b.get(x)??0)+1;b.set(x,A);let O=A===1?x:`${x}#${A}`;return t(O,async()=>{let _=await u(...d);return je(_)?_:Se(_)})})}return f};function Ke(e){let t=e.trim().match(/^(\d+(?:\.\d+)?)\s*(ms|s|m|h|d)$/i);if(!t)return;let f=parseFloat(t[1]),b=t[2].toLowerCase();return{_tag:"Duration",millis:f*({ms:1,s:1e3,m:6e4,h:36e5,d:864e5}[b]??1)}}function Be(e){return new ie({cause:e})}function B(e){return{ok:!0,value:e}}function N(e,t){let f=t?.cause;return{ok:!1,error:e,...f!==void 0?{cause:f}:{}}}function Ve(e){if(e==null)return"unknown";if(typeof e=="string")return e.trim()||"unknown";if(typeof e=="object"){let t=e;if(typeof t._tag=="string"){let f=t._tag.trim();if(f)return f}if(typeof t.tag=="string"){let f=t.tag.trim();if(f)return f}if(typeof t.code=="string"){let f=t.code.trim();if(f)return f}else if(typeof t.code=="number")return String(t.code);if(e instanceof Error&&e.name){let f=e.name.trim();if(f)return f}}return"unknown"}function We(e,t){if(!(!t||!e))return t[e]}function He(e){let{intent:t,domain:f,owner:b,tags:x,stateChanges:u,emits:d,calls:A}=e;if(!t&&!f&&!b&&!x?.length&&!u?.length&&!d?.length&&!A?.length)return;let O={};return t&&(O.intent=t),f&&(O.domain=f),b&&(O.owner=b),x?.length&&(O.tags=x),u?.length&&(O.stateChanges=u),d?.length&&(O.emits=d),A?.length&&(O.calls=A),O}function W(e,t,f,b,x){let u=Ve(e),d=We(u,t),A={tag:u,origin:f};return d!==void 0&&(A.classification=d),b!==void 0&&(A.attempt=b),x!==void 0&&(A.cumulativeDurationMs=x),A}var te=Symbol.for("step_timeout_marker");function ve(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:te in e}function qe(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let t=e;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(te in e)return e[te]}}var Ie=Symbol("early-exit");function $e(e,t){return{[Ie]:!0,error:e,meta:t}}function ze(e){return typeof e=="object"&&e!==null&&e[Ie]===!0}var Me=Symbol("mapper-exception");function ee(e){return{[Me]:!0,thrown:e}}function Ye(e){return typeof e=="object"&&e!==null&&e[Me]===!0}function de(e,t){let{backoff:f,initialDelay:b,maxDelay:x,jitter:u}=t,d;switch(f){case"fixed":d=b;break;case"linear":d=b*e;break;case"exponential":d=b*Math.pow(2,e-1);break}if(d=Math.min(d,x),u){let A=d*.25*Math.random();d=d+A}return Math.floor(d)}function ye(e){return new Promise(t=>setTimeout(t,e))}var _e=Symbol("timeout"),ue=Symbol("timeout-option");function Je(e){return typeof e=="object"&&e!==null&&e[ue]===!0}async function Ge(e,t,f,b){let x=new AbortController,u=t.onTimeout??"error",d=()=>typeof u=="function"?u({name:f.name,key:f.key,ms:t.ms}):t.error??{type:"STEP_TIMEOUT",stepName:f.name,stepKey:f.key,timeoutMs:t.ms,attempt:f.attempt},A;b?.aborted&&x.abort(b.reason);let O;b&&!b.aborted&&(O=()=>x.abort(b.reason),b.addEventListener("abort",O,{once:!0}));let _=new Promise((U,s)=>{A=setTimeout(()=>{if(u!=="disconnect"&&x.abort(),u==="option"){s({[ue]:!0,ms:t.ms});return}s({[_e]:!0,error:d()})},t.ms)}),C;t.signal?C=Promise.resolve(e(x.signal)):C=Promise.resolve(e());try{return await Promise.race([C,_])}catch(U){if(typeof U=="object"&&U!==null&&U[ue]===!0)throw{[ue]:!0,ms:t.ms};if(typeof U=="object"&&U!==null&&U[_e]===!0){u==="disconnect"&&C.catch(()=>{});let s=U.error;if(typeof s=="object"&&s!==null&&s.type!=="STEP_TIMEOUT"){let L={timeoutMs:t.ms,stepName:f.name,stepKey:f.key,attempt:f.attempt};te in s?s[te]=L:Object.defineProperty(s,te,{value:L,enumerable:!1,writable:!0,configurable:!1})}throw s}throw U}finally{clearTimeout(A),O&&b&&b.removeEventListener("abort",O)}}var re={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,shouldRetry:()=>!0,onRetry:()=>{}};async function fe(e,t,f){if(typeof e!="function"){let p=e,K=t;if(typeof K!="function")throw new TypeError("[awaitly] run(deps, fn) requires a callback as the second argument. Example: run({ getUser }, async (s) => s.getUser(id))");return fe(({step:Q})=>K(Pe(p,Q),{step:Q}),f)}let b=e,x=t,{onError:u,onEvent:d,catchUnexpected:A,workflowId:O,workflowName:_,context:C,_workflowSignal:U}=x&&typeof x=="object"?x:{},s=O??crypto.randomUUID(),L=A??Be,F=[],Z=0,q=p=>p??`step_${++Z}`,c=p=>{let K=p.context!==void 0||C===void 0?p:{...p,context:C},z=_!==void 0&&K.workflowName===void 0?{...K,workflowName:_}:K;if(z.type==="step_success"){let Q=z.stepId;for(let ae=F.length-1;ae>=0;ae--){let H=F[ae];if(H.type==="race"&&!H.winnerId){H.winnerId=Q;break}}}d?.(z,C)},I=$e,$=p=>ze(p),V=(p,K)=>p,ne=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 K=function(a){let E={};for(let[n,o]of Object.entries(a))if(typeof o=="function")E[n]=o;else if(o&&typeof o=="object"&&"fn"in o)E[n]=o.fn;else throw new TypeError(`step.all: operation "${n}" must be a function or { fn, errors? } object`);return E},z=function(a,E){let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),r=!1;F.push({scopeId:n,type:"parallel"});let i=()=>{if(r)return;r=!0;let l=F.findIndex(m=>m.scopeId===n);l!==-1&&F.splice(l,1),c({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o})};c({type:"scope_start",workflowId:s,scopeId:n,scopeType:"parallel",name:a,ts:Date.now()});try{let l=await E();if(i(),!l.ok)throw u?.(l.error,a,C),I(l.error,{origin:"result",resultCause:l.cause});return l.value}catch(l){throw i(),l}})()},Q=function(a,E){let n=Object.keys(a),o=E.name??`Parallel(${n.join(", ")})`,r=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let i=performance.now(),l=!1;F.push({scopeId:r,type:"parallel"});let m=()=>{if(l)return;l=!0;let y=F.findIndex(w=>w.scopeId===r);y!==-1&&F.splice(y,1),c({type:"scope_end",workflowId:s,scopeId:r,ts:Date.now(),durationMs:performance.now()-i})};c({type:"scope_start",workflowId:s,scopeId:r,scopeType:"parallel",name:o,ts:Date.now()});try{let y=await new Promise(k=>{if(n.length===0){k([]);return}let P=!1,D=n.length,R=new Array(n.length);for(let M=0;M<n.length;M++){let g=n[M],S=M;Promise.resolve(a[g]()).catch(h=>N({type:"PROMISE_REJECTED",cause:h},{cause:{type:"PROMISE_REJECTION",reason:h}})).then(h=>{if(!P){if(!h.ok){P=!0,k([{key:g,result:h}]);return}R[S]={key:g,result:h},D--,D===0&&k(R)}})}});m();let w={};for(let{key:k,result:P}of y){if(!P.ok)throw u?.(P.error,k,C),I(P.error,{origin:"result",resultCause:P.cause});w[k]=P.value}return w}catch(y){throw m(),y}})()};var Ue=K,er=z,rr=Q;let p=(a,E,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??{},r=He(o),i=a,l=o.key??a,m=o.key??a,{description:y,retry:w,timeout:k}=o,P=q(l),D=d,R=D?performance.now():0,g=ne(E)?()=>E:E,h={attempts:Math.max(1,w?.attempts??1),backoff:w?.backoff??re.backoff,initialDelay:w?.initialDelay??re.initialDelay,maxDelay:w?.maxDelay??re.maxDelay,jitter:w?.jitter??re.jitter,shouldRetry:w?.shouldRetry??re.shouldRetry,onRetry:w?.onRetry??re.onRetry};d&&c({type:"step_start",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),...r&&{metadata:r}});let X;for(let v=1;v<=h.attempts;v++){let Ne=D?performance.now():0;try{let T;if(k?T=await Ge(g,k,{name:i,key:l,attempt:v},U):T=await g(),T.ok){let G=performance.now()-R;return c({type:"step_success",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:G,...r&&{metadata:r}}),m&&c({type:"step_complete",workflowId:s,stepKey:m,name:i,description:y,ts:Date.now(),durationMs:G,result:T,...r&&{metadata:r}}),T.value}if(X=T,v<h.attempts&&h.shouldRetry(T.error,v)){let G=de(v,h);c({type:"step_retry",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),attempt:v+1,maxAttempts:h.attempts,delayMs:G,error:T.error,...r&&{metadata:r},diagnostics:W(T.error,o.errorMeta,"result",v,performance.now()-R)}),h.onRetry(T.error,v,G),await ye(G);continue}h.attempts>1&&c({type:"step_retries_exhausted",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:T.error,...r&&{metadata:r},diagnostics:W(T.error,o.errorMeta,"result",v,performance.now()-R)});break}catch(T){let G=performance.now()-Ne;if(Je(T)){let Y=T.ms;c({type:"step_timeout",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),timeoutMs:Y,attempt:v,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"timeout",v)}),c({type:"step_success",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:performance.now()-R,...r&&{metadata:r}}),m&&c({type:"step_complete",workflowId:s,stepKey:m,name:i,description:y,ts:Date.now(),durationMs:performance.now()-R,result:B(void 0),...r&&{metadata:r}});return}if($(T))throw c({type:"step_aborted",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:G,...r&&{metadata:r}}),T;if(ve(T)){let Y=qe(T),Le=k?.ms??Y?.timeoutMs??0;if(c({type:"step_timeout",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),timeoutMs:Le,attempt:v,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"timeout",v)}),v<h.attempts&&h.shouldRetry(T,v)){let me=de(v,h);c({type:"step_retry",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),attempt:v+1,maxAttempts:h.attempts,delayMs:me,error:T,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"timeout",v,performance.now()-R)}),h.onRetry(T,v,me),await ye(me);continue}h.attempts>1&&c({type:"step_retries_exhausted",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:T,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"timeout",v,performance.now()-R)});let Ee=performance.now()-R;throw c({type:"step_error",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:Ee,error:T,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"timeout",v,Ee)}),m&&c({type:"step_complete",workflowId:s,stepKey:m,name:i,description:y,ts:Date.now(),durationMs:Ee,result:N(T,{cause:T}),meta:{origin:"throw",thrown:T},...r&&{metadata:r}}),u?.(T,i,C),I(T,{origin:"throw",thrown:T})}if(v<h.attempts&&h.shouldRetry(T,v)){let Y=de(v,h);c({type:"step_retry",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),attempt:v+1,maxAttempts:h.attempts,delayMs:Y,error:T,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"throw",v,performance.now()-R)}),h.onRetry(T,v,Y),await ye(Y);continue}h.attempts>1&&!ve(T)&&c({type:"step_retries_exhausted",workflowId:s,stepId:P,stepKey:l,name:i,ts:Date.now(),durationMs:performance.now()-R,attempts:v,lastError:T,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"throw",v,performance.now()-R)});let pe=performance.now()-R,oe;try{oe=L(T)}catch(Y){throw ee(Y)}throw c({type:"step_error",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:pe,error:oe,...r&&{metadata:r},diagnostics:W(T,o.errorMeta,"throw",v,pe)}),m&&c({type:"step_complete",workflowId:s,stepKey:m,name:i,description:y,ts:Date.now(),durationMs:pe,result:N(oe,{cause:T}),meta:{origin:"throw",thrown:T},...r&&{metadata:r}}),u?.(oe,i,C),I(oe,{origin:"throw",thrown:T})}}let J=X,ce=performance.now()-R,le=V(J.error,{origin:"result",resultCause:J.cause});throw c({type:"step_error",workflowId:s,stepId:P,stepKey:l,name:i,description:y,ts:Date.now(),durationMs:ce,error:le,...r&&{metadata:r},diagnostics:W(J.error,o.errorMeta,"result",h.attempts,ce)}),m&&c({type:"step_complete",workflowId:s,stepKey:m,name:i,description:y,ts:Date.now(),durationMs:ce,result:J,meta:{origin:"result",resultCause:J.cause},...r&&{metadata:r}}),u?.(le,i,C),I(le,{origin:"result",resultCause:J.cause})})();p.try=(a,E,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 E())}catch(y){return N(o(y),{cause:y})}},{attempts:n.retry?.attempts??1,...n.retry??{},key:n.key,timeout:n.timeout});let r=n.key??a,i=a,l=a,m=d;return(async()=>{let y=m?performance.now():0;d&&c({type:"step_start",workflowId:s,stepId:l,stepKey:r,name:i,ts:Date.now()});try{let w=await E(),k=performance.now()-y;return c({type:"step_success",workflowId:s,stepId:l,stepKey:r,name:i,ts:Date.now(),durationMs:k}),r&&c({type:"step_complete",workflowId:s,stepKey:r,name:i,ts:Date.now(),durationMs:k,result:B(w)}),w}catch(w){let k=o(w),P=performance.now()-y,D=V(k,{origin:"throw",thrown:w});throw c({type:"step_error",workflowId:s,stepId:l,stepKey:r,name:i,ts:Date.now(),durationMs:P,error:D}),r&&c({type:"step_complete",workflowId:s,stepKey:r,name:i,ts:Date.now(),durationMs:P,result:N(k,{cause:w}),meta:{origin:"throw",thrown:w}}),u?.(D,i,C),I(D,{origin:"throw",thrown:w})}})()},p.fromResult=(a,E,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,r=a,i=a,l="error"in n?()=>n.error:n.onError,m=d;return(async()=>{let y=m?performance.now():0;d&&c({type:"step_start",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now()});let w=await E();if(w.ok){let k=performance.now()-y;return c({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:k}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:k,result:B(w.value)}),w.value}else{let k=l(w.error),P=performance.now()-y,D=V(k,{origin:"result",resultCause:w.error});throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:P,error:D}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:P,result:N(k,{cause:w.error}),meta:{origin:"result",resultCause:w.error}}),u?.(D,r,C),I(D,{origin:"result",resultCause:w.error})}})()},p.fromNullable=(a,E,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 r=await E();return r!=null?B(r):N(n())},o)},p.retry=(a,E,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,E,{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,E,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,E,{key:n.key??a,timeout:n})},p.sleep=(a,E,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 E=="string"?Ke(E):E;if(!o)throw new Error(`step.sleep: invalid duration '${E}'`);let r=o.millis,i=n?.signal;return p(a,async()=>{if(U?.aborted||i?.aborted){let l=new Error("Sleep aborted");throw l.name="AbortError",l}return new Promise((l,m)=>{let y={timeoutId:void 0},w=()=>{y.timeoutId&&clearTimeout(y.timeoutId);let k=new Error("Sleep aborted");k.name="AbortError",m(k)};U?.addEventListener("abort",w,{once:!0}),i?.addEventListener("abort",w,{once:!0}),y.timeoutId=setTimeout(()=>{U?.removeEventListener("abort",w),i?.removeEventListener("abort",w),l(B(void 0))},r)})},{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 E=a[0],n=a[1];if(typeof n=="function")return z(E,n);if(n&&typeof n=="object"&&!Array.isArray(n)){let r=K(n);return Q(r,{name:E})}throw new TypeError("step.all(name, ...): second argument must be a function (array form) or an object of operations (object form).")}),p.race=(a,E)=>{let n=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let o=performance.now(),r=!1,i={scopeId:n,type:"race",winnerId:void 0};F.push(i);let l=()=>{if(r)return;r=!0;let m=F.findIndex(y=>y.scopeId===n);m!==-1&&F.splice(m,1),c({type:"scope_end",workflowId:s,scopeId:n,ts:Date.now(),durationMs:performance.now()-o,winnerId:i.winnerId})};c({type:"scope_start",workflowId:s,scopeId:n,scopeType:"race",name:a,ts:Date.now()});try{let m=await E();if(l(),!m.ok)throw u?.(m.error,a,C),I(m.error,{origin:"result",resultCause:m.cause});return m.value}catch(m){throw l(),m}})()},p.if=(a,E,n)=>n(),p.label=p.if,p.branch=async(a,E)=>{let{condition:n,then:o,else:r}=E;if(n())return await o();if(r)return await r()},p.arm=(a,E)=>({fn:a,errors:E}),p.forEach=async(a,E,n)=>{let o=[],r=n.maxIterations,i=0,l="run"in n,m=Symbol.asyncIterator in E?E:(async function*(){yield*E})();for await(let y of m){if(r!==void 0&&i>=r)break;let w;l?w=await n.run(y,i):w=await n.item.handler(y,i,p),o.push(w),i++}return o},p.item=a=>({__forEachItemHandler:!0,handler:a}),p.dep=(a,E)=>E,p.workflow=(a,E,n)=>p(a,E,n),p.map=async(a,E,n,o)=>{let r=o?.concurrency??E.length;return p(a,()=>r>=E.length?Oe(E.map((i,l)=>n(i,l))):(async()=>{let i=[];for(let l=0;l<E.length;l+=r){let m=E.slice(l,l+r),y=await Oe(m.map((w,k)=>n(w,l+k)));if(!y.ok)return y;i.push(...y.value)}return B(i)})(),{key:o?.key})},p.withFallback=(a,E,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,r=a,i=q(o),l=d;return(async()=>{let m=l?performance.now():0;d&&c({type:"step_start",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now()});let y;try{y=await E()}catch(R){if($(R))throw c({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:performance.now()-m}),R;let M;try{M=L(R)}catch(S){throw ee(S)}if(n.on!==void 0&&n.on!==M){let S=performance.now()-m;throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:S,error:M}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:S,result:N(M,{cause:R}),meta:{origin:"throw",thrown:R}}),u?.(M,r,C),I(M,{origin:"throw",thrown:R})}let g;try{g=await n.fallback()}catch(S){if($(S))throw c({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:performance.now()-m}),S;let h;try{h=L(S)}catch(J){throw ee(J)}let X=performance.now()-m;throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:X,error:h}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:X,result:N(h,{cause:S}),meta:{origin:"throw",thrown:S}}),u?.(h,r,C),I(h,{origin:"throw",thrown:S})}if(g.ok){let S=performance.now()-m;return c({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:S}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:S,result:g,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(M)}}),g.value}else{let S=performance.now()-m,h=V(g.error,{origin:"result",resultCause:g.cause});throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:S,error:h}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:S,result:g,meta:{origin:"result",resultCause:g.cause}}),u?.(h,r,C),I(h,{origin:"result",resultCause:g.cause})}}if(y.ok){let R=performance.now()-m;return c({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:R}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:R,result:y}),y.value}let w=y.error;if(n.on!==void 0&&n.on!==w){let R=performance.now()-m,M=V(w,{origin:"result",resultCause:y.cause});throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:R,error:M}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:R,result:y,meta:{origin:"result",resultCause:y.cause}}),u?.(M,r,C),I(M,{origin:"result",resultCause:y.cause})}let k;try{k=await n.fallback()}catch(R){if($(R))throw c({type:"step_aborted",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:performance.now()-m}),R;let M;try{M=L(R)}catch(S){throw ee(S)}let g=performance.now()-m;throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:g,error:M}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:g,result:N(M,{cause:R}),meta:{origin:"throw",thrown:R}}),u?.(M,r,C),I(M,{origin:"throw",thrown:R})}if(k.ok){let R=performance.now()-m;return c({type:"step_success",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:R}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:R,result:k,meta:{origin:"fallback",fallbackUsed:!0,fallbackReason:String(w)}}),k.value}let P=performance.now()-m,D=V(k.error,{origin:"result",resultCause:k.cause});throw c({type:"step_error",workflowId:s,stepId:i,stepKey:o,name:r,ts:Date.now(),durationMs:P,error:D}),o&&c({type:"step_complete",workflowId:s,stepKey:o,name:r,ts:Date.now(),durationMs:P,result:k,meta:{origin:"result",resultCause:k.cause}}),u?.(D,r,C),I(D,{origin:"result",resultCause:k.cause})})()},p.withResource=(a,E)=>{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,r=q(n),i=d;return(async()=>{let l=i?performance.now():0;d&&c({type:"step_start",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now()});let m;try{m=await E.acquire()}catch(g){if($(g))throw c({type:"step_aborted",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:performance.now()-l}),g;let S;try{S=L(g)}catch(X){throw ee(X)}let h=performance.now()-l;throw c({type:"step_error",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:h,error:S}),n&&c({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:h,result:N(S,{cause:g}),meta:{origin:"throw",thrown:g}}),u?.(S,o,C),I(S,{origin:"throw",thrown:g})}if(!m.ok){let g=performance.now()-l,S=V(m.error,{origin:"result",resultCause:m.cause});throw c({type:"step_error",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:g,error:S}),n&&c({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:g,result:m,meta:{origin:"result",resultCause:m.cause}}),u?.(S,o,C),I(S,{origin:"result",resultCause:m.cause})}let y=m.value,w,k,P=!1;try{w=await E.use(y)}catch(g){if($(g)){try{await E.release(y)}catch(S){console.warn(`[awaitly] step.withResource("${a}"): release threw after earlyExit:`,S)}throw g}k=g,P=!0}try{await E.release(y)}catch(g){console.warn(`[awaitly] step.withResource("${a}"): release threw:`,g)}if(P){let g;try{g=L(k)}catch(h){throw ee(h)}let S=performance.now()-l;throw c({type:"step_error",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:S,error:g}),n&&c({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:S,result:N(g,{cause:k}),meta:{origin:"throw",thrown:k}}),u?.(g,o,C),I(g,{origin:"throw",thrown:k})}let D=w;if(D.ok){let g=performance.now()-l;return c({type:"step_success",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:g}),n&&c({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:g,result:D}),D.value}let R=performance.now()-l,M=V(D.error,{origin:"result",resultCause:D.cause});throw c({type:"step_error",workflowId:s,stepId:r,stepKey:n,name:o,ts:Date.now(),durationMs:R,error:M}),n&&c({type:"step_complete",workflowId:s,stepKey:n,name:o,ts:Date.now(),durationMs:R,result:D,meta:{origin:"result",resultCause:D.cause}}),u?.(M,o,C),I(M,{origin:"result",resultCause:D.cause})})()};let H=await b({step:p});if(process.env.NODE_ENV!=="production"&&H!==null&&typeof H=="object"&&"ok"in H&&typeof H.ok=="boolean"){let a=H;(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(H)}catch(p){if(Ye(p))throw p.thrown;if($(p)){let z=p.meta.origin==="throw"?p.meta.thrown:p.meta.origin==="result"?p.meta.resultCause:void 0;return N(p.error,{cause:z})}let K=L(p);return u?.(K,"unexpected",C),N(K,{cause:p})}}fe.strict=(e,t)=>fe(e,t);async function Oe(e){return e.length===0?B([]):new Promise(t=>{let f=!1,b=e.length,x=new Array(e.length);for(let u=0;u<e.length;u++){let d=u;Promise.resolve(e[d]).catch(A=>N({type:"PROMISE_REJECTED",cause:A},{cause:{type:"PROMISE_REJECTION",reason:A}})).then(A=>{if(!f){if(!A.ok){f=!0,t(A);return}x[d]=A.value,b--,b===0&&t(B(x))}})}})}function Qe(e){return typeof e=="object"&&e!==null&&e.type==="QUEUE_FULL"}function De(e,t){let{maxConcurrent:f,strategy:b="queue",maxQueueSize:x=1/0}=t,u=0,d=[];async function A(){if(u<f){u++;return}if(b==="reject")throw{type:"QUEUE_FULL",limiterName:e,queueSize:d.length,maxQueueSize:x};if(d.length>=x)throw{type:"QUEUE_FULL",limiterName:e,queueSize:d.length,maxQueueSize:x};return new Promise((_,C)=>{d.push({resolve:_,reject:C})})}function O(){u--,d.length>0&&u<f&&(u++,d.shift()?.resolve())}return{async execute(_){await A();try{return await _()}finally{O()}},async executeAll(_){let C=new Array(_.length),U=[];for(let s=0;s<_.length;s++){let L=s,F=this.execute(_[L]).then(Z=>{C[L]=Z});U.push(F)}return await Promise.all(U),C},async executeResult(_){try{await A()}catch(C){if(Qe(C))return N(C);throw C}try{return await _()}finally{O()}},getStats(){return{activeCount:u,maxConcurrent:f,queueSize:d.length,maxQueueSize:x}},reset(){for(u=0;d.length>0;)d.shift()?.reject(new Error("Limiter reset"))}}}function Xe(e){return typeof e=="object"&&e!==null&&e.type==="BATCH_PROCESSING_ERROR"}function kr(e){return typeof e=="object"&&e!==null&&e.type==="INVALID_BATCH_CONFIG"}var Ze=e=>new Promise(t=>setTimeout(t,e));async function Rr(e,t,f,b){let{batchSize:x,concurrency:u,batchDelayMs:d=0}=f,{afterBatch:A,onProgress:O}=b??{};if(!Number.isInteger(x)||x<1)return N({type:"INVALID_BATCH_CONFIG",reason:"batchSize must be a positive integer",field:"batchSize",value:x});if(!Number.isInteger(u)||u<1)return N({type:"INVALID_BATCH_CONFIG",reason:"concurrency must be a positive integer",field:"concurrency",value:u});if(e.length===0)return B([]);let _=[],C=Math.ceil(e.length/x),U=De("batch-processor",{maxConcurrent:u});for(let s=0;s<C;s++){let L=s*x,F=Math.min(L+x,e.length),Z=e.slice(L,F),q=s+1,c=Z.map((I,$)=>async()=>{let V=L+$,ne=await t(I,V);if(!ne.ok)throw{type:"BATCH_PROCESSING_ERROR",error:ne.error,itemIndex:V,batchNumber:q};return ne.value});try{let I=await U.executeAll(c);_.push(...I)}catch(I){if(Xe(I))return N(I);throw I}if(O?.({batch:q,totalBatches:C,processed:_.length,total:e.length,percent:Math.round(_.length/e.length*100)}),A){let I=await A();if(!I.ok)return N({type:"BATCH_PROCESSING_ERROR",error:I.error,batchNumber:q})}d>0&&s<C-1&&await Ze(d)}return B(_)}var gr={conservative:{batchSize:20,concurrency:3,batchDelayMs:50},balanced:{batchSize:50,concurrency:5,batchDelayMs:10},aggressive:{batchSize:100,concurrency:10,batchDelayMs:0}};export{gr as batchPresets,Xe as isBatchProcessingError,kr as isInvalidBatchConfigError,Rr as processInBatches};
7
- //# sourceMappingURL=batch.js.map