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.
- package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
- package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
- package/dist/errors-DtXvrCiO.d.cts +708 -0
- package/dist/errors-DtXvrCiO.d.ts +708 -0
- package/dist/index.cjs +4594 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1970 -141
- package/dist/index.d.ts +1970 -141
- package/dist/index.js +4398 -1
- package/dist/index.js.map +1 -1
- package/dist/result.cjs +641 -1
- package/dist/result.cjs.map +1 -1
- package/dist/result.d.cts +29 -4
- package/dist/result.d.ts +29 -4
- package/dist/result.js +561 -1
- package/dist/result.js.map +1 -1
- package/dist/testing.cjs +4202 -8
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +2 -6
- package/dist/testing.d.ts +2 -6
- package/dist/testing.js +4154 -8
- package/dist/testing.js.map +1 -1
- package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
- package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
- package/dist/workflow.cjs +7096 -6
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +3346 -22
- package/dist/workflow.d.ts +3346 -22
- package/dist/workflow.js +6929 -6
- package/dist/workflow.js.map +1 -1
- package/package.json +3 -168
- package/dist/adapters.cjs +0 -7
- package/dist/adapters.cjs.map +0 -1
- package/dist/adapters.d.cts +0 -179
- package/dist/adapters.d.ts +0 -179
- package/dist/adapters.js +0 -7
- package/dist/adapters.js.map +0 -1
- package/dist/batch.cjs +0 -7
- package/dist/batch.cjs.map +0 -1
- package/dist/batch.d.cts +0 -200
- package/dist/batch.d.ts +0 -200
- package/dist/batch.js +0 -7
- package/dist/batch.js.map +0 -1
- package/dist/bind-deps.cjs +0 -2
- package/dist/bind-deps.cjs.map +0 -1
- package/dist/bind-deps.d.cts +0 -28
- package/dist/bind-deps.d.ts +0 -28
- package/dist/bind-deps.js +0 -2
- package/dist/bind-deps.js.map +0 -1
- package/dist/cache.cjs +0 -2
- package/dist/cache.cjs.map +0 -1
- package/dist/cache.d.cts +0 -269
- package/dist/cache.d.ts +0 -269
- package/dist/cache.js +0 -2
- package/dist/cache.js.map +0 -1
- package/dist/circuit-breaker.cjs +0 -7
- package/dist/circuit-breaker.cjs.map +0 -1
- package/dist/circuit-breaker.d.cts +0 -211
- package/dist/circuit-breaker.d.ts +0 -211
- package/dist/circuit-breaker.js +0 -7
- package/dist/circuit-breaker.js.map +0 -1
- package/dist/conditional.cjs +0 -2
- package/dist/conditional.cjs.map +0 -1
- package/dist/conditional.d.cts +0 -252
- package/dist/conditional.d.ts +0 -252
- package/dist/conditional.js +0 -2
- package/dist/conditional.js.map +0 -1
- package/dist/core.cjs +0 -7
- package/dist/core.cjs.map +0 -1
- package/dist/core.d.cts +0 -5
- package/dist/core.d.ts +0 -5
- package/dist/core.js +0 -7
- package/dist/core.js.map +0 -1
- package/dist/di-By77n4Fa.d.ts +0 -15
- package/dist/di-OJfsohf-.d.cts +0 -15
- package/dist/diagnostics.cjs +0 -8
- package/dist/diagnostics.cjs.map +0 -1
- package/dist/diagnostics.d.cts +0 -68
- package/dist/diagnostics.d.ts +0 -68
- package/dist/diagnostics.js +0 -8
- package/dist/diagnostics.js.map +0 -1
- package/dist/durable.cjs +0 -11
- package/dist/durable.cjs.map +0 -1
- package/dist/durable.d.cts +0 -9
- package/dist/durable.d.ts +0 -9
- package/dist/durable.js +0 -11
- package/dist/durable.js.map +0 -1
- package/dist/duration.cjs +0 -2
- package/dist/duration.cjs.map +0 -1
- package/dist/duration.js +0 -2
- package/dist/duration.js.map +0 -1
- package/dist/engine.cjs +0 -11
- package/dist/engine.cjs.map +0 -1
- package/dist/engine.d.cts +0 -115
- package/dist/engine.d.ts +0 -115
- package/dist/engine.js +0 -11
- package/dist/engine.js.map +0 -1
- package/dist/errors.cjs +0 -2
- package/dist/errors.cjs.map +0 -1
- package/dist/errors.d.cts +0 -361
- package/dist/errors.d.ts +0 -361
- package/dist/errors.js +0 -2
- package/dist/errors.js.map +0 -1
- package/dist/fetch.cjs +0 -7
- package/dist/fetch.cjs.map +0 -1
- package/dist/fetch.d.cts +0 -86
- package/dist/fetch.d.ts +0 -86
- package/dist/fetch.js +0 -7
- package/dist/fetch.js.map +0 -1
- package/dist/flow.cjs +0 -7
- package/dist/flow.cjs.map +0 -1
- package/dist/flow.d.cts +0 -163
- package/dist/flow.d.ts +0 -163
- package/dist/flow.js +0 -7
- package/dist/flow.js.map +0 -1
- package/dist/functional.cjs +0 -2
- package/dist/functional.cjs.map +0 -1
- package/dist/functional.d.cts +0 -444
- package/dist/functional.d.ts +0 -444
- package/dist/functional.js +0 -2
- package/dist/functional.js.map +0 -1
- package/dist/guards-4sV7mTqj.d.cts +0 -72
- package/dist/guards-BIX05ALH.d.ts +0 -72
- package/dist/hitl-DFn4Xa_l.d.cts +0 -468
- package/dist/hitl-DU5VpKq7.d.ts +0 -468
- package/dist/hitl.cjs +0 -7
- package/dist/hitl.cjs.map +0 -1
- package/dist/hitl.d.cts +0 -442
- package/dist/hitl.d.ts +0 -442
- package/dist/hitl.js +0 -7
- package/dist/hitl.js.map +0 -1
- package/dist/index-CnvBryQB.d.ts +0 -417
- package/dist/index-DEZEf8Fs.d.cts +0 -417
- package/dist/match-entry-DjI2bLpD.d.cts +0 -209
- package/dist/match-entry-DjI2bLpD.d.ts +0 -209
- package/dist/match.cjs +0 -2
- package/dist/match.cjs.map +0 -1
- package/dist/match.d.cts +0 -1
- package/dist/match.d.ts +0 -1
- package/dist/match.js +0 -2
- package/dist/match.js.map +0 -1
- package/dist/otel.cjs +0 -2
- package/dist/otel.cjs.map +0 -1
- package/dist/otel.d.cts +0 -188
- package/dist/otel.d.ts +0 -188
- package/dist/otel.js +0 -2
- package/dist/otel.js.map +0 -1
- package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
- package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
- package/dist/persistence.cjs +0 -2
- package/dist/persistence.cjs.map +0 -1
- package/dist/persistence.d.cts +0 -7
- package/dist/persistence.d.ts +0 -7
- package/dist/persistence.js +0 -2
- package/dist/persistence.js.map +0 -1
- package/dist/policies.cjs +0 -2
- package/dist/policies.cjs.map +0 -1
- package/dist/policies.d.cts +0 -379
- package/dist/policies.d.ts +0 -379
- package/dist/policies.js +0 -2
- package/dist/policies.js.map +0 -1
- package/dist/ratelimit.cjs +0 -7
- package/dist/ratelimit.cjs.map +0 -1
- package/dist/ratelimit.d.cts +0 -458
- package/dist/ratelimit.d.ts +0 -458
- package/dist/ratelimit.js +0 -7
- package/dist/ratelimit.js.map +0 -1
- package/dist/reliability.cjs +0 -11
- package/dist/reliability.cjs.map +0 -1
- package/dist/reliability.d.cts +0 -11
- package/dist/reliability.d.ts +0 -11
- package/dist/reliability.js +0 -11
- package/dist/reliability.js.map +0 -1
- package/dist/resolver.cjs +0 -7
- package/dist/resolver.cjs.map +0 -1
- package/dist/resolver.d.cts +0 -68
- package/dist/resolver.d.ts +0 -68
- package/dist/resolver.js +0 -7
- package/dist/resolver.js.map +0 -1
- package/dist/resource.cjs +0 -7
- package/dist/resource.cjs.map +0 -1
- package/dist/resource.d.cts +0 -174
- package/dist/resource.d.ts +0 -174
- package/dist/resource.js +0 -7
- package/dist/resource.js.map +0 -1
- package/dist/result/retry.cjs +0 -2
- package/dist/result/retry.cjs.map +0 -1
- package/dist/result/retry.d.cts +0 -70
- package/dist/result/retry.d.ts +0 -70
- package/dist/result/retry.js +0 -2
- package/dist/result/retry.js.map +0 -1
- package/dist/retry.cjs +0 -2
- package/dist/retry.cjs.map +0 -1
- package/dist/retry.d.cts +0 -388
- package/dist/retry.d.ts +0 -388
- package/dist/retry.js +0 -2
- package/dist/retry.js.map +0 -1
- package/dist/run.cjs +0 -7
- package/dist/run.cjs.map +0 -1
- package/dist/run.d.cts +0 -4
- package/dist/run.d.ts +0 -4
- package/dist/run.js +0 -7
- package/dist/run.js.map +0 -1
- package/dist/saga.cjs +0 -11
- package/dist/saga.cjs.map +0 -1
- package/dist/saga.d.cts +0 -164
- package/dist/saga.d.ts +0 -164
- package/dist/saga.js +0 -11
- package/dist/saga.js.map +0 -1
- package/dist/singleflight.cjs +0 -2
- package/dist/singleflight.cjs.map +0 -1
- package/dist/singleflight.d.cts +0 -145
- package/dist/singleflight.d.ts +0 -145
- package/dist/singleflight.js +0 -2
- package/dist/singleflight.js.map +0 -1
- package/dist/slugs.cjs +0 -2
- package/dist/slugs.cjs.map +0 -1
- package/dist/slugs.d.cts +0 -67
- package/dist/slugs.d.ts +0 -67
- package/dist/slugs.js +0 -2
- package/dist/slugs.js.map +0 -1
- package/dist/streaming.cjs +0 -9
- package/dist/streaming.cjs.map +0 -1
- package/dist/streaming.d.cts +0 -596
- package/dist/streaming.d.ts +0 -596
- package/dist/streaming.js +0 -9
- package/dist/streaming.js.map +0 -1
- package/dist/tagged-error.cjs +0 -2
- package/dist/tagged-error.cjs.map +0 -1
- package/dist/tagged-error.d.cts +0 -275
- package/dist/tagged-error.d.ts +0 -275
- package/dist/tagged-error.js +0 -2
- package/dist/tagged-error.js.map +0 -1
- package/dist/types-BziYHFkD.d.ts +0 -323
- package/dist/types-C5jLEUqY.d.cts +0 -323
- package/dist/webhook.cjs +0 -7
- package/dist/webhook.cjs.map +0 -1
- package/dist/webhook.d.cts +0 -499
- package/dist/webhook.d.ts +0 -499
- package/dist/webhook.js +0 -7
- 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
|