flowfn 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1305 -0
- package/dist/index.d.ts +1305 -0
- package/dist/index.js +3180 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3088 -0
- package/dist/index.mjs.map +1 -0
- package/docs/API.md +801 -0
- package/docs/USAGE.md +619 -0
- package/package.json +75 -0
- package/src/adapters/base.ts +46 -0
- package/src/adapters/memory.ts +183 -0
- package/src/adapters/postgres/index.ts +383 -0
- package/src/adapters/postgres/postgres.test.ts +100 -0
- package/src/adapters/postgres/schema.ts +110 -0
- package/src/adapters/redis.test.ts +124 -0
- package/src/adapters/redis.ts +331 -0
- package/src/core/flow-fn.test.ts +70 -0
- package/src/core/flow-fn.ts +198 -0
- package/src/core/metrics.ts +198 -0
- package/src/core/scheduler.test.ts +80 -0
- package/src/core/scheduler.ts +154 -0
- package/src/index.ts +57 -0
- package/src/monitoring/health.ts +261 -0
- package/src/patterns/backoff.ts +30 -0
- package/src/patterns/batching.ts +248 -0
- package/src/patterns/circuit-breaker.test.ts +52 -0
- package/src/patterns/circuit-breaker.ts +52 -0
- package/src/patterns/priority.ts +146 -0
- package/src/patterns/rate-limit.ts +290 -0
- package/src/patterns/retry.test.ts +62 -0
- package/src/queue/batch.test.ts +35 -0
- package/src/queue/dependencies.test.ts +33 -0
- package/src/queue/dlq.ts +222 -0
- package/src/queue/job.ts +67 -0
- package/src/queue/queue.ts +243 -0
- package/src/queue/types.ts +153 -0
- package/src/queue/worker.ts +66 -0
- package/src/storage/event-log.ts +205 -0
- package/src/storage/job-storage.ts +206 -0
- package/src/storage/workflow-storage.ts +182 -0
- package/src/stream/stream.ts +194 -0
- package/src/stream/types.ts +81 -0
- package/src/utils/hashing.ts +29 -0
- package/src/utils/id-generator.ts +109 -0
- package/src/utils/serialization.ts +142 -0
- package/src/utils/time.ts +167 -0
- package/src/workflow/advanced.test.ts +43 -0
- package/src/workflow/events.test.ts +39 -0
- package/src/workflow/types.ts +132 -0
- package/src/workflow/workflow.test.ts +55 -0
- package/src/workflow/workflow.ts +422 -0
- package/tests/dlq.test.ts +205 -0
- package/tests/health.test.ts +228 -0
- package/tests/integration.test.ts +253 -0
- package/tests/stream.test.ts +233 -0
- package/tests/workflow.test.ts +286 -0
- package/tsconfig.json +17 -0
- package/tsup.config.ts +10 -0
- package/vitest.config.ts +15 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1305 @@
|
|
|
1
|
+
import EventEmitter from 'eventemitter3';
|
|
2
|
+
import Redis, { RedisOptions } from 'ioredis';
|
|
3
|
+
|
|
4
|
+
interface Queue<T = any> {
|
|
5
|
+
name: string;
|
|
6
|
+
add(name: string, data: T, opts?: JobOptions): Promise<Job<T>>;
|
|
7
|
+
addBulk(jobs: Array<{
|
|
8
|
+
name: string;
|
|
9
|
+
data: T;
|
|
10
|
+
opts?: JobOptions;
|
|
11
|
+
}>): Promise<Job<T>[]>;
|
|
12
|
+
process(handler: JobHandler<T>): void;
|
|
13
|
+
process(name: string, handler: JobHandler<T>): void;
|
|
14
|
+
process(concurrency: number, handler: JobHandler<T>): void;
|
|
15
|
+
process(name: string, concurrency: number, handler: JobHandler<T>): void;
|
|
16
|
+
processBatch(name: string, batchSize: number, handler: BatchHandler<T>): void;
|
|
17
|
+
processBatch(name: string, options: BatchOptions$1, handler: BatchHandler<T>): void;
|
|
18
|
+
pause(): Promise<void>;
|
|
19
|
+
resume(): Promise<void>;
|
|
20
|
+
drain(): Promise<void>;
|
|
21
|
+
clean(grace: number, status: JobStatus): Promise<number>;
|
|
22
|
+
getDLQ?(): any;
|
|
23
|
+
getJob(jobId: string): Promise<Job<T> | null>;
|
|
24
|
+
getJobs(status: JobStatus): Promise<Job<T>[]>;
|
|
25
|
+
getJobCounts(): Promise<QueueStats>;
|
|
26
|
+
on(event: QueueEvent, handler: (...args: any[]) => void): void;
|
|
27
|
+
close(): Promise<void>;
|
|
28
|
+
}
|
|
29
|
+
type QueueEvent = "completed" | "failed" | "stalled" | "progress" | "waiting" | "active";
|
|
30
|
+
interface Job<T = any> {
|
|
31
|
+
id: string;
|
|
32
|
+
name: string;
|
|
33
|
+
data: T;
|
|
34
|
+
opts: JobOptions;
|
|
35
|
+
state: JobStatus;
|
|
36
|
+
progress: number;
|
|
37
|
+
returnvalue?: any;
|
|
38
|
+
timestamp: number;
|
|
39
|
+
processedOn?: number;
|
|
40
|
+
finishedOn?: number;
|
|
41
|
+
delay: number;
|
|
42
|
+
attemptsMade: number;
|
|
43
|
+
failedReason?: string;
|
|
44
|
+
stacktrace?: string[];
|
|
45
|
+
update(data: Partial<T>): Promise<void>;
|
|
46
|
+
log(message: string): Promise<void>;
|
|
47
|
+
updateProgress(progress: number): Promise<void>;
|
|
48
|
+
moveToCompleted(returnValue: any): Promise<void>;
|
|
49
|
+
moveToFailed(error: Error): Promise<void>;
|
|
50
|
+
retry(): Promise<void>;
|
|
51
|
+
discard(): Promise<void>;
|
|
52
|
+
waitUntilFinished(): Promise<any>;
|
|
53
|
+
}
|
|
54
|
+
type JobStatus = "waiting" | "active" | "completed" | "failed" | "delayed" | "paused";
|
|
55
|
+
interface JobOptions {
|
|
56
|
+
priority?: number;
|
|
57
|
+
delay?: number;
|
|
58
|
+
attempts?: number;
|
|
59
|
+
backoff?: BackoffOptions;
|
|
60
|
+
lifo?: boolean;
|
|
61
|
+
timeout?: number;
|
|
62
|
+
removeOnComplete?: boolean | number;
|
|
63
|
+
removeOnFail?: boolean | number;
|
|
64
|
+
stackTraceLimit?: number;
|
|
65
|
+
jobId?: string;
|
|
66
|
+
preventDuplicates?: boolean;
|
|
67
|
+
deduplicationKey?: string;
|
|
68
|
+
waitFor?: string[];
|
|
69
|
+
}
|
|
70
|
+
interface BackoffOptions {
|
|
71
|
+
type: "fixed" | "exponential" | "custom";
|
|
72
|
+
delay: number;
|
|
73
|
+
maxDelay?: number;
|
|
74
|
+
}
|
|
75
|
+
interface QueueOptions {
|
|
76
|
+
defaultJobOptions?: JobOptions;
|
|
77
|
+
limiter?: RateLimiterOptions;
|
|
78
|
+
cache?: CacheOptions;
|
|
79
|
+
dlq?: {
|
|
80
|
+
enabled: boolean;
|
|
81
|
+
maxRetries?: number;
|
|
82
|
+
queueName?: string;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
interface RateLimiterOptions {
|
|
86
|
+
max: number;
|
|
87
|
+
duration: number;
|
|
88
|
+
}
|
|
89
|
+
interface CacheOptions {
|
|
90
|
+
enabled: boolean;
|
|
91
|
+
ttl: number;
|
|
92
|
+
keyGenerator?: (job: Job) => string;
|
|
93
|
+
}
|
|
94
|
+
interface QueueStats {
|
|
95
|
+
waiting: number;
|
|
96
|
+
active: number;
|
|
97
|
+
completed: number;
|
|
98
|
+
failed: number;
|
|
99
|
+
delayed: number;
|
|
100
|
+
paused: number;
|
|
101
|
+
}
|
|
102
|
+
type JobHandler<T> = (job: Job<T>) => Promise<any>;
|
|
103
|
+
type BatchHandler<T> = (jobs: Job<T>[]) => Promise<any[]>;
|
|
104
|
+
interface BatchOptions$1 {
|
|
105
|
+
batchSize: number;
|
|
106
|
+
maxWait?: number;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface StreamOptions {
|
|
110
|
+
maxLength?: number;
|
|
111
|
+
retention?: number;
|
|
112
|
+
partitions?: number;
|
|
113
|
+
}
|
|
114
|
+
interface Stream<T = any> {
|
|
115
|
+
name: string;
|
|
116
|
+
publish(data: T, options?: PublishOptions): Promise<string>;
|
|
117
|
+
publishBatch(messages: Array<{
|
|
118
|
+
data: T;
|
|
119
|
+
options?: PublishOptions;
|
|
120
|
+
}>): Promise<string[]>;
|
|
121
|
+
subscribe(handler: MessageHandler<T>, options?: SubscribeOptions): Promise<Subscription>;
|
|
122
|
+
createConsumer(consumerId: string, options: ConsumerOptions): Consumer<T>;
|
|
123
|
+
getInfo(): Promise<StreamInfo>;
|
|
124
|
+
trim(strategy: TrimStrategy): Promise<number>;
|
|
125
|
+
getMessages(start: string, end: string, count?: number): Promise<Message<T>[]>;
|
|
126
|
+
close(): Promise<void>;
|
|
127
|
+
}
|
|
128
|
+
interface Message<T = any> {
|
|
129
|
+
id: string;
|
|
130
|
+
stream: string;
|
|
131
|
+
data: T;
|
|
132
|
+
headers?: Record<string, string>;
|
|
133
|
+
timestamp: number;
|
|
134
|
+
partition?: number;
|
|
135
|
+
offset?: number;
|
|
136
|
+
key?: string;
|
|
137
|
+
ack(): Promise<void>;
|
|
138
|
+
nack(requeue?: boolean): Promise<void>;
|
|
139
|
+
}
|
|
140
|
+
interface PublishOptions {
|
|
141
|
+
key?: string;
|
|
142
|
+
headers?: Record<string, string>;
|
|
143
|
+
partition?: number;
|
|
144
|
+
}
|
|
145
|
+
interface SubscribeOptions {
|
|
146
|
+
}
|
|
147
|
+
interface ConsumerOptions {
|
|
148
|
+
groupId: string;
|
|
149
|
+
fromBeginning?: boolean;
|
|
150
|
+
autoCommit?: boolean;
|
|
151
|
+
commitInterval?: number;
|
|
152
|
+
maxInFlight?: number;
|
|
153
|
+
}
|
|
154
|
+
interface Consumer<T = any> {
|
|
155
|
+
subscribe(handler: MessageHandler<T>): Promise<void>;
|
|
156
|
+
pause(): Promise<void>;
|
|
157
|
+
resume(): Promise<void>;
|
|
158
|
+
close(): Promise<void>;
|
|
159
|
+
}
|
|
160
|
+
type MessageHandler<T> = (message: Message<T>) => Promise<void>;
|
|
161
|
+
interface Subscription {
|
|
162
|
+
unsubscribe(): Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
interface StreamInfo {
|
|
165
|
+
name: string;
|
|
166
|
+
length: number;
|
|
167
|
+
groups: number;
|
|
168
|
+
}
|
|
169
|
+
interface TrimStrategy {
|
|
170
|
+
maxLength?: number;
|
|
171
|
+
maxAgeSeconds?: number;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
interface WorkflowContext<T = any> {
|
|
175
|
+
workflowId: string;
|
|
176
|
+
executionId: string;
|
|
177
|
+
input: T;
|
|
178
|
+
state: Record<string, any>;
|
|
179
|
+
metadata: Record<string, any>;
|
|
180
|
+
set(key: string, value: any): void;
|
|
181
|
+
get(key: string): any;
|
|
182
|
+
sleep(ms: number): Promise<void>;
|
|
183
|
+
waitForEvent(event: string, timeout?: number): Promise<any>;
|
|
184
|
+
}
|
|
185
|
+
interface Workflow<T = any> {
|
|
186
|
+
id: string;
|
|
187
|
+
name: string;
|
|
188
|
+
execute(input: T): Promise<WorkflowExecution>;
|
|
189
|
+
getExecution(executionId: string): Promise<WorkflowExecution>;
|
|
190
|
+
listExecutions(options?: ListOptions$1): Promise<WorkflowExecution[]>;
|
|
191
|
+
cancelExecution(executionId: string): Promise<void>;
|
|
192
|
+
retryExecution(executionId: string): Promise<WorkflowExecution>;
|
|
193
|
+
getExecutionHistory(executionId: string): Promise<WorkflowEvent[]>;
|
|
194
|
+
getMetrics(): Promise<WorkflowMetrics>;
|
|
195
|
+
}
|
|
196
|
+
interface WorkflowExecution {
|
|
197
|
+
id: string;
|
|
198
|
+
workflowId: string;
|
|
199
|
+
status: ExecutionStatus;
|
|
200
|
+
input: any;
|
|
201
|
+
output?: any;
|
|
202
|
+
error?: any;
|
|
203
|
+
state?: Record<string, any>;
|
|
204
|
+
startedAt: number;
|
|
205
|
+
completedAt?: number;
|
|
206
|
+
createdAt?: number;
|
|
207
|
+
updatedAt?: number;
|
|
208
|
+
}
|
|
209
|
+
type ExecutionStatus = "pending" | "running" | "completed" | "failed" | "cancelled";
|
|
210
|
+
interface WorkflowEvent {
|
|
211
|
+
timestamp: number;
|
|
212
|
+
type: string;
|
|
213
|
+
step?: string;
|
|
214
|
+
data?: any;
|
|
215
|
+
}
|
|
216
|
+
interface WorkflowMetrics {
|
|
217
|
+
totalExecutions: number;
|
|
218
|
+
successRate: number;
|
|
219
|
+
avgDuration: number;
|
|
220
|
+
}
|
|
221
|
+
interface ListOptions$1 {
|
|
222
|
+
status?: ExecutionStatus;
|
|
223
|
+
limit?: number;
|
|
224
|
+
offset?: number;
|
|
225
|
+
}
|
|
226
|
+
type StepHandler<T, R> = (ctx: WorkflowContext<T>, ...args: any[]) => Promise<R>;
|
|
227
|
+
type ErrorHandler<T> = (ctx: WorkflowContext<T>, error: Error) => Promise<void>;
|
|
228
|
+
type CompensateHandler<T> = (ctx: WorkflowContext<T>) => Promise<void>;
|
|
229
|
+
interface BranchOptions<T> {
|
|
230
|
+
condition: (ctx: WorkflowContext<T>) => boolean | Promise<boolean>;
|
|
231
|
+
then: WorkflowBuilder<T>;
|
|
232
|
+
else?: WorkflowBuilder<T>;
|
|
233
|
+
}
|
|
234
|
+
interface SagaDefinition<T> {
|
|
235
|
+
execute: StepHandler<T, any>;
|
|
236
|
+
compensate: CompensateHandler<T>;
|
|
237
|
+
}
|
|
238
|
+
interface ApprovalOptions<T> {
|
|
239
|
+
timeout: number;
|
|
240
|
+
data?: (ctx: WorkflowContext<T>) => any;
|
|
241
|
+
onTimeout?: (ctx: WorkflowContext<T>) => Promise<void>;
|
|
242
|
+
}
|
|
243
|
+
interface EventOptions {
|
|
244
|
+
timeout?: number;
|
|
245
|
+
}
|
|
246
|
+
type Duration$1 = {
|
|
247
|
+
ms?: number;
|
|
248
|
+
seconds?: number;
|
|
249
|
+
minutes?: number;
|
|
250
|
+
hours?: number;
|
|
251
|
+
days?: number;
|
|
252
|
+
};
|
|
253
|
+
interface WorkflowBuilder<T = any> {
|
|
254
|
+
input<I>(): WorkflowBuilder<I>;
|
|
255
|
+
step<R>(name: string, handler: StepHandler<T, R>): WorkflowBuilder<T>;
|
|
256
|
+
parallel(steps: StepHandler<T, any>[]): WorkflowBuilder<T>;
|
|
257
|
+
branch(options: BranchOptions<T>): WorkflowBuilder<T>;
|
|
258
|
+
saga(name: string, saga: SagaDefinition<T>): WorkflowBuilder<T>;
|
|
259
|
+
delay(duration: Duration$1): WorkflowBuilder<T>;
|
|
260
|
+
delayUntil(condition: (ctx: WorkflowContext<T>) => number): WorkflowBuilder<T>;
|
|
261
|
+
waitForApproval(approver: string, options: ApprovalOptions<T>): WorkflowBuilder<T>;
|
|
262
|
+
waitForEvent(event: string, options?: EventOptions): WorkflowBuilder<T>;
|
|
263
|
+
onError(step: string, handler: ErrorHandler<T>): WorkflowBuilder<T>;
|
|
264
|
+
compensate(step: string, handler: CompensateHandler<T>): WorkflowBuilder<T>;
|
|
265
|
+
build(): Workflow<T>;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
interface FlowAdapter {
|
|
269
|
+
enqueue(queue: string, job: Job): Promise<string>;
|
|
270
|
+
dequeue(queue: string): Promise<Job | null>;
|
|
271
|
+
ack(queue: string, jobId: string): Promise<void>;
|
|
272
|
+
nack(queue: string, jobId: string, requeue?: boolean): Promise<void>;
|
|
273
|
+
publish(stream: string, message: Message): Promise<string>;
|
|
274
|
+
subscribe(stream: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
275
|
+
consume(stream: string, group: string, consumer: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
276
|
+
createConsumerGroup(stream: string, group: string): Promise<void>;
|
|
277
|
+
saveWorkflowState(workflowId: string, state: WorkflowExecution): Promise<void>;
|
|
278
|
+
loadWorkflowState(workflowId: string): Promise<WorkflowExecution | null>;
|
|
279
|
+
getJob(queue: string, jobId: string): Promise<Job | null>;
|
|
280
|
+
getJobs(queue: string, status: string): Promise<Job[]>;
|
|
281
|
+
getAllJobs(queue: string): Promise<Job[]>;
|
|
282
|
+
cleanJobs(queue: string, grace: number, status: string): Promise<number>;
|
|
283
|
+
getQueueStats(queue: string): Promise<QueueStats>;
|
|
284
|
+
getStreamInfo(stream: string): Promise<StreamInfo>;
|
|
285
|
+
cleanup(): Promise<void>;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
interface ScheduleOptions {
|
|
289
|
+
pattern?: string;
|
|
290
|
+
timezone?: string;
|
|
291
|
+
data?: any;
|
|
292
|
+
startDate?: Date;
|
|
293
|
+
endDate?: Date;
|
|
294
|
+
limit?: number;
|
|
295
|
+
every?: number;
|
|
296
|
+
}
|
|
297
|
+
declare class Scheduler {
|
|
298
|
+
private tasks;
|
|
299
|
+
schedule(name: string, pattern: string | ScheduleOptions, handler: Function): Promise<void>;
|
|
300
|
+
repeat(name: string, options: any, handler: Function): Promise<void>;
|
|
301
|
+
private plan;
|
|
302
|
+
list(): Promise<any[]>;
|
|
303
|
+
cancel(name: string): Promise<void>;
|
|
304
|
+
pause(name: string): Promise<void>;
|
|
305
|
+
resume(name: string): Promise<void>;
|
|
306
|
+
close(): Promise<void>;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
interface MetricDataPoint {
|
|
310
|
+
timestamp: number;
|
|
311
|
+
value: number;
|
|
312
|
+
tags?: Record<string, string>;
|
|
313
|
+
}
|
|
314
|
+
interface TimeSeriesMetrics {
|
|
315
|
+
dataPoints: MetricDataPoint[];
|
|
316
|
+
min: number;
|
|
317
|
+
max: number;
|
|
318
|
+
avg: number;
|
|
319
|
+
sum: number;
|
|
320
|
+
count: number;
|
|
321
|
+
p50?: number;
|
|
322
|
+
p95?: number;
|
|
323
|
+
p99?: number;
|
|
324
|
+
}
|
|
325
|
+
declare class MetricsManager {
|
|
326
|
+
private adapter;
|
|
327
|
+
private metrics;
|
|
328
|
+
private maxDataPoints;
|
|
329
|
+
constructor(adapter: FlowAdapter);
|
|
330
|
+
/**
|
|
331
|
+
* Record a metric data point
|
|
332
|
+
*/
|
|
333
|
+
record(name: string, value: number, tags?: Record<string, string>): void;
|
|
334
|
+
/**
|
|
335
|
+
* Get time series for a metric
|
|
336
|
+
*/
|
|
337
|
+
getTimeSeries(name: string, options?: {
|
|
338
|
+
tags?: Record<string, string>;
|
|
339
|
+
since?: number;
|
|
340
|
+
limit?: number;
|
|
341
|
+
}): TimeSeriesMetrics | null;
|
|
342
|
+
private calculateAggregations;
|
|
343
|
+
private percentile;
|
|
344
|
+
private getMetricKey;
|
|
345
|
+
getQueueMetrics(name: string): Promise<any>;
|
|
346
|
+
getStreamMetrics(name: string): Promise<any>;
|
|
347
|
+
getWorkflowMetrics(name: string): Promise<any>;
|
|
348
|
+
getSystemMetrics(): Promise<any>;
|
|
349
|
+
/**
|
|
350
|
+
* Clear old metrics
|
|
351
|
+
*/
|
|
352
|
+
cleanup(maxAge: number): void;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Monitoring and health check system for FlowFn
|
|
357
|
+
*/
|
|
358
|
+
interface HealthStatus {
|
|
359
|
+
healthy: boolean;
|
|
360
|
+
timestamp: number;
|
|
361
|
+
checks: HealthCheck[];
|
|
362
|
+
details?: Record<string, any>;
|
|
363
|
+
}
|
|
364
|
+
interface HealthCheck {
|
|
365
|
+
name: string;
|
|
366
|
+
status: "pass" | "fail" | "warn";
|
|
367
|
+
message?: string;
|
|
368
|
+
responseTime?: number;
|
|
369
|
+
details?: Record<string, any>;
|
|
370
|
+
}
|
|
371
|
+
interface MonitoringMetrics {
|
|
372
|
+
queues?: {
|
|
373
|
+
[queueName: string]: {
|
|
374
|
+
waiting: number;
|
|
375
|
+
active: number;
|
|
376
|
+
completed: number;
|
|
377
|
+
failed: number;
|
|
378
|
+
delayed: number;
|
|
379
|
+
throughput: number;
|
|
380
|
+
avgDuration: number;
|
|
381
|
+
errorRate: number;
|
|
382
|
+
};
|
|
383
|
+
};
|
|
384
|
+
streams?: {
|
|
385
|
+
[streamName: string]: {
|
|
386
|
+
messageCount: number;
|
|
387
|
+
publishRate: number;
|
|
388
|
+
consumerCount: number;
|
|
389
|
+
lag: number;
|
|
390
|
+
};
|
|
391
|
+
};
|
|
392
|
+
workflows?: {
|
|
393
|
+
[workflowName: string]: {
|
|
394
|
+
totalExecutions: number;
|
|
395
|
+
running: number;
|
|
396
|
+
completed: number;
|
|
397
|
+
failed: number;
|
|
398
|
+
successRate: number;
|
|
399
|
+
avgDuration: number;
|
|
400
|
+
};
|
|
401
|
+
};
|
|
402
|
+
system?: {
|
|
403
|
+
uptime: number;
|
|
404
|
+
memoryUsage: number;
|
|
405
|
+
cpuUsage?: number;
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
interface HealthChecker {
|
|
409
|
+
/**
|
|
410
|
+
* Perform health check
|
|
411
|
+
*/
|
|
412
|
+
check(): Promise<HealthStatus>;
|
|
413
|
+
/**
|
|
414
|
+
* Add custom health check
|
|
415
|
+
*/
|
|
416
|
+
addCheck(name: string, checker: () => Promise<HealthCheck>): void;
|
|
417
|
+
/**
|
|
418
|
+
* Remove health check
|
|
419
|
+
*/
|
|
420
|
+
removeCheck(name: string): void;
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Health checker implementation
|
|
424
|
+
*/
|
|
425
|
+
declare class HealthCheckerImpl implements HealthChecker {
|
|
426
|
+
private checks;
|
|
427
|
+
private startTime;
|
|
428
|
+
constructor();
|
|
429
|
+
addCheck(name: string, checker: () => Promise<HealthCheck>): void;
|
|
430
|
+
removeCheck(name: string): void;
|
|
431
|
+
check(): Promise<HealthStatus>;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Event tracking for monitoring
|
|
435
|
+
*/
|
|
436
|
+
interface TrackedEvent {
|
|
437
|
+
id: string;
|
|
438
|
+
type: string;
|
|
439
|
+
category: "queue" | "stream" | "workflow" | "system";
|
|
440
|
+
severity: "info" | "warn" | "error";
|
|
441
|
+
message: string;
|
|
442
|
+
timestamp: number;
|
|
443
|
+
metadata?: Record<string, any>;
|
|
444
|
+
}
|
|
445
|
+
interface EventTracker {
|
|
446
|
+
/**
|
|
447
|
+
* Track an event
|
|
448
|
+
*/
|
|
449
|
+
track(event: Omit<TrackedEvent, "id" | "timestamp">): void;
|
|
450
|
+
/**
|
|
451
|
+
* Get events
|
|
452
|
+
*/
|
|
453
|
+
getEvents(filter?: {
|
|
454
|
+
category?: string;
|
|
455
|
+
severity?: string;
|
|
456
|
+
since?: number;
|
|
457
|
+
limit?: number;
|
|
458
|
+
}): TrackedEvent[];
|
|
459
|
+
/**
|
|
460
|
+
* Clear old events
|
|
461
|
+
*/
|
|
462
|
+
cleanup(maxAge: number): number;
|
|
463
|
+
}
|
|
464
|
+
declare class MemoryEventTracker implements EventTracker {
|
|
465
|
+
private events;
|
|
466
|
+
private maxEvents;
|
|
467
|
+
track(event: Omit<TrackedEvent, "id" | "timestamp">): void;
|
|
468
|
+
getEvents(filter?: {
|
|
469
|
+
category?: string;
|
|
470
|
+
severity?: string;
|
|
471
|
+
since?: number;
|
|
472
|
+
limit?: number;
|
|
473
|
+
}): TrackedEvent[];
|
|
474
|
+
cleanup(maxAge: number): number;
|
|
475
|
+
clear(): void;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
interface FlowFnConfig {
|
|
479
|
+
adapter: FlowAdapter | "memory" | "redis" | "postgres" | "d1" | "sqs" | "kafka";
|
|
480
|
+
namespace?: string;
|
|
481
|
+
defaultJobOptions?: any;
|
|
482
|
+
defaultQueueOptions?: QueueOptions;
|
|
483
|
+
defaultStreamOptions?: StreamOptions;
|
|
484
|
+
telemetry?: {
|
|
485
|
+
enabled: boolean;
|
|
486
|
+
provider?: "opentelemetry" | "custom";
|
|
487
|
+
};
|
|
488
|
+
onError?: (error: Error, context: any) => void;
|
|
489
|
+
}
|
|
490
|
+
interface FlowFn {
|
|
491
|
+
queue<T = any>(name: string, options?: QueueOptions): Queue<T>;
|
|
492
|
+
listQueues(): Promise<string[]>;
|
|
493
|
+
stream<T = any>(name: string, options?: StreamOptions): Stream<T>;
|
|
494
|
+
listStreams(): Promise<string[]>;
|
|
495
|
+
workflow<T = any>(name: string): WorkflowBuilder<T>;
|
|
496
|
+
listWorkflows(): Promise<Workflow[]>;
|
|
497
|
+
scheduler(): Scheduler;
|
|
498
|
+
metrics: MetricsManager;
|
|
499
|
+
healthCheck(): Promise<HealthStatus>;
|
|
500
|
+
getEventTracker(): EventTracker;
|
|
501
|
+
on(event: string, handler: (...args: any[]) => void): void;
|
|
502
|
+
off(event: string, handler: (...args: any[]) => void): void;
|
|
503
|
+
close(): Promise<void>;
|
|
504
|
+
}
|
|
505
|
+
declare class FlowFnImpl extends EventEmitter implements FlowFn {
|
|
506
|
+
private adapter;
|
|
507
|
+
private queues;
|
|
508
|
+
private streams;
|
|
509
|
+
private _metrics;
|
|
510
|
+
private _scheduler;
|
|
511
|
+
private healthChecker;
|
|
512
|
+
private eventTracker;
|
|
513
|
+
private startTime;
|
|
514
|
+
constructor(config: FlowFnConfig);
|
|
515
|
+
private setupHealthChecks;
|
|
516
|
+
queue<T = any>(name: string, options?: QueueOptions): Queue<T>;
|
|
517
|
+
listQueues(): Promise<string[]>;
|
|
518
|
+
stream<T = any>(name: string, options?: StreamOptions): Stream<T>;
|
|
519
|
+
listStreams(): Promise<string[]>;
|
|
520
|
+
workflow<T = any>(name: string): WorkflowBuilder<T>;
|
|
521
|
+
listWorkflows(): Promise<Workflow[]>;
|
|
522
|
+
scheduler(): Scheduler;
|
|
523
|
+
get metrics(): MetricsManager;
|
|
524
|
+
healthCheck(): Promise<HealthStatus>;
|
|
525
|
+
/**
|
|
526
|
+
* Get event tracker
|
|
527
|
+
*/
|
|
528
|
+
getEventTracker(): EventTracker;
|
|
529
|
+
close(): Promise<void>;
|
|
530
|
+
}
|
|
531
|
+
declare function createFlow(config: FlowFnConfig): FlowFn;
|
|
532
|
+
|
|
533
|
+
interface WorkerOptions {
|
|
534
|
+
flow: FlowFn;
|
|
535
|
+
queues: string[];
|
|
536
|
+
concurrency?: number | Record<string, number>;
|
|
537
|
+
settings?: {
|
|
538
|
+
stalledInterval?: number;
|
|
539
|
+
maxStalledCount?: number;
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
declare class Worker extends EventEmitter {
|
|
543
|
+
private flow;
|
|
544
|
+
private queueNames;
|
|
545
|
+
private concurrency;
|
|
546
|
+
private queues;
|
|
547
|
+
constructor(options: WorkerOptions);
|
|
548
|
+
run(): Promise<void>;
|
|
549
|
+
register(queueName: string, handler: (job: Job) => Promise<any>): void;
|
|
550
|
+
close(): Promise<void>;
|
|
551
|
+
}
|
|
552
|
+
declare function createWorker(options: WorkerOptions): Worker;
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Dead-Letter Queue (DLQ) implementation for FlowFn
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
interface DLQOptions {
|
|
559
|
+
/**
|
|
560
|
+
* Queue name for dead-letter jobs
|
|
561
|
+
*/
|
|
562
|
+
queueName?: string;
|
|
563
|
+
/**
|
|
564
|
+
* Maximum retries before moving to DLQ
|
|
565
|
+
*/
|
|
566
|
+
maxRetries?: number;
|
|
567
|
+
/**
|
|
568
|
+
* Time to live for DLQ items (ms)
|
|
569
|
+
*/
|
|
570
|
+
ttl?: number;
|
|
571
|
+
/**
|
|
572
|
+
* Handler called when job moves to DLQ
|
|
573
|
+
*/
|
|
574
|
+
onDLQ?: (job: Job, reason: string) => void | Promise<void>;
|
|
575
|
+
}
|
|
576
|
+
interface DLQJob<T = any> extends Job<T> {
|
|
577
|
+
/**
|
|
578
|
+
* Original queue name
|
|
579
|
+
*/
|
|
580
|
+
originalQueue: string;
|
|
581
|
+
/**
|
|
582
|
+
* Reason for DLQ
|
|
583
|
+
*/
|
|
584
|
+
dlqReason: string;
|
|
585
|
+
/**
|
|
586
|
+
* Timestamp when moved to DLQ
|
|
587
|
+
*/
|
|
588
|
+
dlqTimestamp: number;
|
|
589
|
+
/**
|
|
590
|
+
* All error messages from attempts
|
|
591
|
+
*/
|
|
592
|
+
errors: string[];
|
|
593
|
+
}
|
|
594
|
+
interface DLQManager {
|
|
595
|
+
/**
|
|
596
|
+
* Move job to DLQ
|
|
597
|
+
*/
|
|
598
|
+
moveToDLQ<T>(job: Job<T>, reason: string): Promise<DLQJob<T>>;
|
|
599
|
+
/**
|
|
600
|
+
* Get all DLQ jobs
|
|
601
|
+
*/
|
|
602
|
+
getAll(): Promise<DLQJob[]>;
|
|
603
|
+
/**
|
|
604
|
+
* Get DLQ jobs by original queue
|
|
605
|
+
*/
|
|
606
|
+
getByQueue(queueName: string): Promise<DLQJob[]>;
|
|
607
|
+
/**
|
|
608
|
+
* Retry a DLQ job
|
|
609
|
+
*/
|
|
610
|
+
retry<T>(jobId: string): Promise<Job<T>>;
|
|
611
|
+
/**
|
|
612
|
+
* Retry all DLQ jobs from a queue
|
|
613
|
+
*/
|
|
614
|
+
retryAll(queueName: string): Promise<number>;
|
|
615
|
+
/**
|
|
616
|
+
* Delete a DLQ job
|
|
617
|
+
*/
|
|
618
|
+
delete(jobId: string): Promise<void>;
|
|
619
|
+
/**
|
|
620
|
+
* Clean expired DLQ jobs
|
|
621
|
+
*/
|
|
622
|
+
clean(maxAge: number): Promise<number>;
|
|
623
|
+
/**
|
|
624
|
+
* Get DLQ stats
|
|
625
|
+
*/
|
|
626
|
+
getStats(): Promise<{
|
|
627
|
+
total: number;
|
|
628
|
+
byQueue: Record<string, number>;
|
|
629
|
+
}>;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* In-memory DLQ implementation
|
|
633
|
+
*/
|
|
634
|
+
declare class MemoryDLQManager implements DLQManager {
|
|
635
|
+
private dlqJobs;
|
|
636
|
+
private options;
|
|
637
|
+
constructor(options?: DLQOptions);
|
|
638
|
+
moveToDLQ<T>(job: Job<T>, reason: string): Promise<DLQJob<T>>;
|
|
639
|
+
getAll(): Promise<DLQJob[]>;
|
|
640
|
+
getByQueue(queueName: string): Promise<DLQJob[]>;
|
|
641
|
+
retry<T>(jobId: string): Promise<Job<T>>;
|
|
642
|
+
retryAll(queueName: string): Promise<number>;
|
|
643
|
+
delete(jobId: string): Promise<void>;
|
|
644
|
+
clean(maxAge: number): Promise<number>;
|
|
645
|
+
getStats(): Promise<{
|
|
646
|
+
total: number;
|
|
647
|
+
byQueue: Record<string, number>;
|
|
648
|
+
}>;
|
|
649
|
+
/**
|
|
650
|
+
* Clear all DLQ jobs (for testing)
|
|
651
|
+
*/
|
|
652
|
+
clear(): void;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
declare class MemoryAdapter implements FlowAdapter {
|
|
656
|
+
private queues;
|
|
657
|
+
private allJobs;
|
|
658
|
+
private streams;
|
|
659
|
+
private streamEmitters;
|
|
660
|
+
private workflowStates;
|
|
661
|
+
enqueue(queueName: string, job: Job): Promise<string>;
|
|
662
|
+
dequeue(queueName: string): Promise<Job | null>;
|
|
663
|
+
ack(queue: string, jobId: string): Promise<void>;
|
|
664
|
+
nack(queueName: string, jobId: string, requeue?: boolean): Promise<void>;
|
|
665
|
+
getJob(queueName: string, jobId: string): Promise<Job | null>;
|
|
666
|
+
getJobs(queue: string, status: string): Promise<Job[]>;
|
|
667
|
+
getAllJobs(queue: string): Promise<Job[]>;
|
|
668
|
+
cleanJobs(queue: string, grace: number, status: string): Promise<number>;
|
|
669
|
+
publish(streamName: string, message: Message): Promise<string>;
|
|
670
|
+
subscribe(streamName: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
671
|
+
consume(stream: string, group: string, consumer: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
672
|
+
createConsumerGroup(stream: string, group: string): Promise<void>;
|
|
673
|
+
saveWorkflowState(workflowId: string, state: WorkflowExecution): Promise<void>;
|
|
674
|
+
loadWorkflowState(workflowId: string): Promise<WorkflowExecution | null>;
|
|
675
|
+
getQueueStats(queueName: string): Promise<QueueStats>;
|
|
676
|
+
getStreamInfo(streamName: string): Promise<StreamInfo>;
|
|
677
|
+
cleanup(): Promise<void>;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
interface RedisAdapterOptions {
|
|
681
|
+
connection?: Redis | RedisOptions;
|
|
682
|
+
prefix?: string;
|
|
683
|
+
}
|
|
684
|
+
declare class RedisAdapter implements FlowAdapter {
|
|
685
|
+
private redis;
|
|
686
|
+
private prefix;
|
|
687
|
+
private subscriptions;
|
|
688
|
+
constructor(options?: RedisAdapterOptions);
|
|
689
|
+
private key;
|
|
690
|
+
enqueue(queueName: string, job: Job): Promise<string>;
|
|
691
|
+
dequeue(queueName: string): Promise<Job | null>;
|
|
692
|
+
ack(queue: string, jobId: string): Promise<void>;
|
|
693
|
+
nack(queueName: string, jobId: string, requeue?: boolean): Promise<void>;
|
|
694
|
+
publish(streamName: string, message: Message): Promise<string>;
|
|
695
|
+
subscribe(streamName: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
696
|
+
consume(streamName: string, group: string, consumer: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
697
|
+
createConsumerGroup(stream: string, group: string): Promise<void>;
|
|
698
|
+
saveWorkflowState(workflowId: string, state: WorkflowExecution): Promise<void>;
|
|
699
|
+
loadWorkflowState(workflowId: string): Promise<WorkflowExecution | null>;
|
|
700
|
+
getJob(queue: string, jobId: string): Promise<Job | null>;
|
|
701
|
+
getJobs(queue: string, status: string): Promise<Job[]>;
|
|
702
|
+
getAllJobs(queue: string): Promise<Job[]>;
|
|
703
|
+
cleanJobs(queue: string, grace: number, status: string): Promise<number>;
|
|
704
|
+
getQueueStats(queueName: string): Promise<QueueStats>;
|
|
705
|
+
getStreamInfo(streamName: string): Promise<StreamInfo>;
|
|
706
|
+
cleanup(): Promise<void>;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
interface PostgresAdapterOptions {
|
|
710
|
+
db: any;
|
|
711
|
+
schema?: string;
|
|
712
|
+
pollInterval?: number;
|
|
713
|
+
}
|
|
714
|
+
declare class PostgresAdapter implements FlowAdapter {
|
|
715
|
+
private db;
|
|
716
|
+
private pollInterval;
|
|
717
|
+
private activeSubscriptions;
|
|
718
|
+
constructor(options: PostgresAdapterOptions);
|
|
719
|
+
enqueue(queueName: string, job: Job): Promise<string>;
|
|
720
|
+
dequeue(queueName: string): Promise<Job | null>;
|
|
721
|
+
ack(queue: string, jobId: string): Promise<void>;
|
|
722
|
+
nack(queue: string, jobId: string, requeue?: boolean): Promise<void>;
|
|
723
|
+
publish(streamName: string, message: Message): Promise<string>;
|
|
724
|
+
subscribe(streamName: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
725
|
+
createConsumerGroup(stream: string, group: string): Promise<void>;
|
|
726
|
+
saveWorkflowState(workflowId: string, state: WorkflowExecution): Promise<void>;
|
|
727
|
+
loadWorkflowState(executionId: string): Promise<WorkflowExecution | null>;
|
|
728
|
+
getJob(queue: string, jobId: string): Promise<Job | null>;
|
|
729
|
+
getQueueStats(queueName: string): Promise<QueueStats>;
|
|
730
|
+
getStreamInfo(streamName: string): Promise<StreamInfo>;
|
|
731
|
+
consume(stream: string, group: string, consumer: string, handler: MessageHandler<any>): Promise<Subscription>;
|
|
732
|
+
getJobs(queue: string, status: string): Promise<Job[]>;
|
|
733
|
+
getAllJobs(queue: string): Promise<Job[]>;
|
|
734
|
+
cleanJobs(queue: string, grace: number, status: string): Promise<number>;
|
|
735
|
+
cleanup(): Promise<void>;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
declare function calculateBackoff(attemptsMade: number, options: BackoffOptions): number;
|
|
739
|
+
|
|
740
|
+
interface CircuitBreakerOptions {
|
|
741
|
+
threshold: number;
|
|
742
|
+
timeout: number;
|
|
743
|
+
resetTimeout?: number;
|
|
744
|
+
}
|
|
745
|
+
type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';
|
|
746
|
+
declare function circuitBreaker<T>(options: CircuitBreakerOptions, handler: (job: Job<T>) => Promise<any>): (job: Job<T>) => Promise<any>;
|
|
747
|
+
|
|
748
|
+
/**
|
|
749
|
+
* Rate limiting pattern for FlowFn
|
|
750
|
+
*/
|
|
751
|
+
interface RateLimitOptions {
|
|
752
|
+
/**
|
|
753
|
+
* Maximum number of requests allowed
|
|
754
|
+
*/
|
|
755
|
+
limit: number;
|
|
756
|
+
/**
|
|
757
|
+
* Time window in milliseconds
|
|
758
|
+
*/
|
|
759
|
+
window: number;
|
|
760
|
+
/**
|
|
761
|
+
* Strategy for handling rate limit exceeded
|
|
762
|
+
*/
|
|
763
|
+
strategy?: "throw" | "delay" | "drop";
|
|
764
|
+
/**
|
|
765
|
+
* Custom key generator for partitioning rate limits
|
|
766
|
+
*/
|
|
767
|
+
keyGenerator?: (...args: any[]) => string;
|
|
768
|
+
}
|
|
769
|
+
interface RateLimitResult {
|
|
770
|
+
allowed: boolean;
|
|
771
|
+
remaining: number;
|
|
772
|
+
resetAt: number;
|
|
773
|
+
retryAfter?: number;
|
|
774
|
+
}
|
|
775
|
+
declare class RateLimiter {
|
|
776
|
+
private counters;
|
|
777
|
+
private options;
|
|
778
|
+
constructor(options: RateLimitOptions);
|
|
779
|
+
/**
|
|
780
|
+
* Check if request is allowed
|
|
781
|
+
*/
|
|
782
|
+
check(key?: string): Promise<RateLimitResult>;
|
|
783
|
+
/**
|
|
784
|
+
* Execute a function with rate limiting
|
|
785
|
+
*/
|
|
786
|
+
execute<T>(fn: () => Promise<T>, key?: string): Promise<T>;
|
|
787
|
+
/**
|
|
788
|
+
* Clear all rate limit counters
|
|
789
|
+
*/
|
|
790
|
+
reset(): void;
|
|
791
|
+
/**
|
|
792
|
+
* Clear rate limit counter for specific key
|
|
793
|
+
*/
|
|
794
|
+
resetKey(key: string): void;
|
|
795
|
+
/**
|
|
796
|
+
* Get current limit info for a key
|
|
797
|
+
*/
|
|
798
|
+
getInfo(key?: string): RateLimitResult;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Create a rate limiter
|
|
802
|
+
*/
|
|
803
|
+
declare function createRateLimiter(options: RateLimitOptions): RateLimiter;
|
|
804
|
+
/**
|
|
805
|
+
* Sliding window rate limiter (more accurate)
|
|
806
|
+
*/
|
|
807
|
+
declare class SlidingWindowRateLimiter {
|
|
808
|
+
private requests;
|
|
809
|
+
private options;
|
|
810
|
+
constructor(options: RateLimitOptions);
|
|
811
|
+
check(key?: string): Promise<RateLimitResult>;
|
|
812
|
+
execute<T>(fn: () => Promise<T>, key?: string): Promise<T>;
|
|
813
|
+
reset(): void;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Token bucket rate limiter
|
|
817
|
+
*/
|
|
818
|
+
declare class TokenBucketRateLimiter {
|
|
819
|
+
private buckets;
|
|
820
|
+
private capacity;
|
|
821
|
+
private refillRate;
|
|
822
|
+
private refillInterval;
|
|
823
|
+
constructor(options: {
|
|
824
|
+
capacity: number;
|
|
825
|
+
refillRate: number;
|
|
826
|
+
refillInterval?: number;
|
|
827
|
+
});
|
|
828
|
+
private refill;
|
|
829
|
+
check(key?: string, cost?: number): Promise<RateLimitResult>;
|
|
830
|
+
reset(): void;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Batching utilities for FlowFn
|
|
835
|
+
*/
|
|
836
|
+
interface BatchOptions {
|
|
837
|
+
/**
|
|
838
|
+
* Maximum number of items per batch
|
|
839
|
+
*/
|
|
840
|
+
maxSize: number;
|
|
841
|
+
/**
|
|
842
|
+
* Maximum time to wait before flushing batch (ms)
|
|
843
|
+
*/
|
|
844
|
+
maxWait?: number;
|
|
845
|
+
/**
|
|
846
|
+
* Minimum size before processing (default: 1)
|
|
847
|
+
*/
|
|
848
|
+
minSize?: number;
|
|
849
|
+
}
|
|
850
|
+
interface BatchProcessor<T, R> {
|
|
851
|
+
/**
|
|
852
|
+
* Process a batch of items
|
|
853
|
+
*/
|
|
854
|
+
(items: T[]): Promise<R[]>;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Batch accumulator for collecting and processing items in batches
|
|
858
|
+
*/
|
|
859
|
+
declare class BatchAccumulator<T, R = any> {
|
|
860
|
+
private batch;
|
|
861
|
+
private timer;
|
|
862
|
+
private options;
|
|
863
|
+
private processor;
|
|
864
|
+
private pending;
|
|
865
|
+
constructor(processor: BatchProcessor<T, R>, options: BatchOptions);
|
|
866
|
+
/**
|
|
867
|
+
* Add an item to the batch
|
|
868
|
+
*/
|
|
869
|
+
add(item: T): Promise<R>;
|
|
870
|
+
/**
|
|
871
|
+
* Manually flush the current batch
|
|
872
|
+
*/
|
|
873
|
+
flush(): Promise<void>;
|
|
874
|
+
/**
|
|
875
|
+
* Get current batch size
|
|
876
|
+
*/
|
|
877
|
+
size(): number;
|
|
878
|
+
/**
|
|
879
|
+
* Clear the batch without processing
|
|
880
|
+
*/
|
|
881
|
+
clear(): void;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Create a batched version of a function
|
|
885
|
+
*/
|
|
886
|
+
declare function batch<T, R>(fn: (items: T[]) => Promise<R[]>, options: BatchOptions): (item: T) => Promise<R>;
|
|
887
|
+
/**
|
|
888
|
+
* Batch array into chunks
|
|
889
|
+
*/
|
|
890
|
+
declare function chunk<T>(array: T[], size: number): T[][];
|
|
891
|
+
/**
|
|
892
|
+
* Process array in batches with delay between batches
|
|
893
|
+
*/
|
|
894
|
+
declare function processBatches<T, R>(items: T[], processor: (batch: T[]) => Promise<R[]>, options: {
|
|
895
|
+
batchSize: number;
|
|
896
|
+
delayMs?: number;
|
|
897
|
+
}): Promise<R[]>;
|
|
898
|
+
/**
|
|
899
|
+
* Batch write operations with auto-flush
|
|
900
|
+
*/
|
|
901
|
+
declare class BatchWriter<T> {
|
|
902
|
+
private accumulator;
|
|
903
|
+
constructor(writer: (items: T[]) => Promise<void>, options: BatchOptions);
|
|
904
|
+
write(item: T): Promise<void>;
|
|
905
|
+
flush(): Promise<void>;
|
|
906
|
+
size(): number;
|
|
907
|
+
clear(): void;
|
|
908
|
+
}
|
|
909
|
+
/**
|
|
910
|
+
* Group items by a key function and process in batches
|
|
911
|
+
*/
|
|
912
|
+
declare function batchByKey<T, R>(items: T[], keyFn: (item: T) => string, processor: (key: string, items: T[]) => Promise<R[]>, options?: {
|
|
913
|
+
concurrency?: number;
|
|
914
|
+
}): Promise<R[]>;
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* Priority queue pattern for FlowFn
|
|
918
|
+
*/
|
|
919
|
+
interface PriorityItem<T> {
|
|
920
|
+
value: T;
|
|
921
|
+
priority: number;
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Priority queue implementation using binary heap
|
|
925
|
+
*/
|
|
926
|
+
declare class PriorityQueue<T> {
|
|
927
|
+
private heap;
|
|
928
|
+
private compareFn;
|
|
929
|
+
constructor(mode?: "min" | "max");
|
|
930
|
+
/**
|
|
931
|
+
* Add item with priority
|
|
932
|
+
*/
|
|
933
|
+
enqueue(value: T, priority: number): void;
|
|
934
|
+
/**
|
|
935
|
+
* Remove and return highest priority item
|
|
936
|
+
*/
|
|
937
|
+
dequeue(): T | undefined;
|
|
938
|
+
/**
|
|
939
|
+
* Peek at highest priority item without removing
|
|
940
|
+
*/
|
|
941
|
+
peek(): T | undefined;
|
|
942
|
+
/**
|
|
943
|
+
* Get queue size
|
|
944
|
+
*/
|
|
945
|
+
size(): number;
|
|
946
|
+
/**
|
|
947
|
+
* Check if queue is empty
|
|
948
|
+
*/
|
|
949
|
+
isEmpty(): boolean;
|
|
950
|
+
/**
|
|
951
|
+
* Clear the queue
|
|
952
|
+
*/
|
|
953
|
+
clear(): void;
|
|
954
|
+
/**
|
|
955
|
+
* Convert to array (sorted by priority)
|
|
956
|
+
*/
|
|
957
|
+
toArray(): T[];
|
|
958
|
+
private bubbleUp;
|
|
959
|
+
private bubbleDown;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Generate a hash for job deduplication
|
|
964
|
+
*/
|
|
965
|
+
declare function hashJob(data: any, options?: {
|
|
966
|
+
algorithm?: string;
|
|
967
|
+
}): string;
|
|
968
|
+
/**
|
|
969
|
+
* Generate a deduplication key from job name and data
|
|
970
|
+
*/
|
|
971
|
+
declare function generateDeduplicationKey(name: string, data: any): string;
|
|
972
|
+
/**
|
|
973
|
+
* Check if two job payloads are equivalent
|
|
974
|
+
*/
|
|
975
|
+
declare function areJobsEquivalent(job1: any, job2: any): boolean;
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* ID generation strategies
|
|
979
|
+
*/
|
|
980
|
+
type IdStrategy = "uuid-v4" | "uuid-v5" | "uuid-v1" | "nanoid" | "incremental" | "custom";
|
|
981
|
+
interface IdGeneratorOptions {
|
|
982
|
+
strategy?: IdStrategy;
|
|
983
|
+
namespace?: string;
|
|
984
|
+
prefix?: string;
|
|
985
|
+
customGenerator?: () => string;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Generate a unique identifier based on the specified strategy
|
|
989
|
+
*/
|
|
990
|
+
declare function generateId(options?: IdGeneratorOptions): string;
|
|
991
|
+
/**
|
|
992
|
+
* Generate a job ID with optional prefix
|
|
993
|
+
*/
|
|
994
|
+
declare function generateJobId(prefix?: string): string;
|
|
995
|
+
/**
|
|
996
|
+
* Generate a workflow execution ID
|
|
997
|
+
*/
|
|
998
|
+
declare function generateExecutionId(prefix?: string): string;
|
|
999
|
+
/**
|
|
1000
|
+
* Generate a message ID for streams
|
|
1001
|
+
*/
|
|
1002
|
+
declare function generateMessageId(prefix?: string): string;
|
|
1003
|
+
/**
|
|
1004
|
+
* Generate a deterministic ID based on content (useful for idempotency)
|
|
1005
|
+
*/
|
|
1006
|
+
declare function generateDeterministicId(content: string | object, prefix?: string): string;
|
|
1007
|
+
|
|
1008
|
+
/**
|
|
1009
|
+
* Time utility functions for FlowFn
|
|
1010
|
+
*/
|
|
1011
|
+
/**
|
|
1012
|
+
* Duration units
|
|
1013
|
+
*/
|
|
1014
|
+
interface Duration {
|
|
1015
|
+
milliseconds?: number;
|
|
1016
|
+
seconds?: number;
|
|
1017
|
+
minutes?: number;
|
|
1018
|
+
hours?: number;
|
|
1019
|
+
days?: number;
|
|
1020
|
+
weeks?: number;
|
|
1021
|
+
}
|
|
1022
|
+
/**
|
|
1023
|
+
* Convert duration object to milliseconds
|
|
1024
|
+
*/
|
|
1025
|
+
declare function toMilliseconds(duration: Duration): number;
|
|
1026
|
+
/**
|
|
1027
|
+
* Convert milliseconds to duration object
|
|
1028
|
+
*/
|
|
1029
|
+
declare function fromMilliseconds(ms: number): Duration;
|
|
1030
|
+
/**
|
|
1031
|
+
* Format duration as human-readable string
|
|
1032
|
+
*/
|
|
1033
|
+
declare function formatDuration(duration: Duration): string;
|
|
1034
|
+
/**
|
|
1035
|
+
* Sleep for specified milliseconds
|
|
1036
|
+
*/
|
|
1037
|
+
declare function sleep(ms: number): Promise<void>;
|
|
1038
|
+
/**
|
|
1039
|
+
* Sleep for specified duration
|
|
1040
|
+
*/
|
|
1041
|
+
declare function sleepDuration(duration: Duration): Promise<void>;
|
|
1042
|
+
/**
|
|
1043
|
+
* Create a timeout promise
|
|
1044
|
+
*/
|
|
1045
|
+
declare function timeout<T>(promise: Promise<T>, ms: number, message?: string): Promise<T>;
|
|
1046
|
+
/**
|
|
1047
|
+
* Get current timestamp in milliseconds
|
|
1048
|
+
*/
|
|
1049
|
+
declare function now(): number;
|
|
1050
|
+
/**
|
|
1051
|
+
* Calculate delay until a specific timestamp
|
|
1052
|
+
*/
|
|
1053
|
+
declare function delayUntil(timestamp: number): number;
|
|
1054
|
+
/**
|
|
1055
|
+
* Check if a timestamp is in the past
|
|
1056
|
+
*/
|
|
1057
|
+
declare function isPast(timestamp: number): boolean;
|
|
1058
|
+
/**
|
|
1059
|
+
* Check if a timestamp is in the future
|
|
1060
|
+
*/
|
|
1061
|
+
declare function isFuture(timestamp: number): boolean;
|
|
1062
|
+
/**
|
|
1063
|
+
* Add duration to timestamp
|
|
1064
|
+
*/
|
|
1065
|
+
declare function addDuration(timestamp: number, duration: Duration): number;
|
|
1066
|
+
/**
|
|
1067
|
+
* Parse cron-like duration string (e.g., "5m", "1h", "30s")
|
|
1068
|
+
*/
|
|
1069
|
+
declare function parseDuration(str: string): number;
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Serialization utilities for FlowFn
|
|
1073
|
+
*/
|
|
1074
|
+
interface SerializationOptions {
|
|
1075
|
+
pretty?: boolean;
|
|
1076
|
+
includeUndefined?: boolean;
|
|
1077
|
+
dateFormat?: "iso" | "timestamp";
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Serialize job data to JSON string
|
|
1081
|
+
*/
|
|
1082
|
+
declare function serialize<T = any>(data: T, options?: SerializationOptions): string;
|
|
1083
|
+
/**
|
|
1084
|
+
* Deserialize JSON string to object
|
|
1085
|
+
*/
|
|
1086
|
+
declare function deserialize<T = any>(json: string): T;
|
|
1087
|
+
/**
|
|
1088
|
+
* Safely serialize data with circular reference handling
|
|
1089
|
+
*/
|
|
1090
|
+
declare function serializeSafe<T = any>(data: T, options?: SerializationOptions): string;
|
|
1091
|
+
/**
|
|
1092
|
+
* Clone an object using serialization
|
|
1093
|
+
*/
|
|
1094
|
+
declare function cloneViaSerialization<T>(obj: T): T;
|
|
1095
|
+
/**
|
|
1096
|
+
* Serialize with compression (base64 encode)
|
|
1097
|
+
*/
|
|
1098
|
+
declare function serializeCompressed<T = any>(data: T): string;
|
|
1099
|
+
/**
|
|
1100
|
+
* Deserialize compressed data
|
|
1101
|
+
*/
|
|
1102
|
+
declare function deserializeCompressed<T = any>(compressed: string): T;
|
|
1103
|
+
/**
|
|
1104
|
+
* Check if a value is serializable
|
|
1105
|
+
*/
|
|
1106
|
+
declare function isSerializable(value: any): boolean;
|
|
1107
|
+
/**
|
|
1108
|
+
* Get size of serialized data in bytes
|
|
1109
|
+
*/
|
|
1110
|
+
declare function getSerializedSize(data: any): number;
|
|
1111
|
+
|
|
1112
|
+
/**
|
|
1113
|
+
* Storage abstraction for FlowFn job persistence
|
|
1114
|
+
*/
|
|
1115
|
+
|
|
1116
|
+
interface JobStorage {
|
|
1117
|
+
/**
|
|
1118
|
+
* Save a job
|
|
1119
|
+
*/
|
|
1120
|
+
save(queue: string, job: Job): Promise<void>;
|
|
1121
|
+
/**
|
|
1122
|
+
* Get a job by ID
|
|
1123
|
+
*/
|
|
1124
|
+
get(queue: string, jobId: string): Promise<Job | null>;
|
|
1125
|
+
/**
|
|
1126
|
+
* Get jobs by status
|
|
1127
|
+
*/
|
|
1128
|
+
getByStatus(queue: string, status: JobStatus): Promise<Job[]>;
|
|
1129
|
+
/**
|
|
1130
|
+
* Get all jobs for a queue
|
|
1131
|
+
*/
|
|
1132
|
+
getAll(queue: string): Promise<Job[]>;
|
|
1133
|
+
/**
|
|
1134
|
+
* Update job status
|
|
1135
|
+
*/
|
|
1136
|
+
updateStatus(queue: string, jobId: string, status: JobStatus): Promise<void>;
|
|
1137
|
+
/**
|
|
1138
|
+
* Update job data
|
|
1139
|
+
*/
|
|
1140
|
+
update(queue: string, jobId: string, updates: Partial<Job>): Promise<void>;
|
|
1141
|
+
/**
|
|
1142
|
+
* Delete a job
|
|
1143
|
+
*/
|
|
1144
|
+
delete(queue: string, jobId: string): Promise<void>;
|
|
1145
|
+
/**
|
|
1146
|
+
* Delete jobs older than grace period with given status
|
|
1147
|
+
*/
|
|
1148
|
+
clean(queue: string, grace: number, status: JobStatus): Promise<number>;
|
|
1149
|
+
/**
|
|
1150
|
+
* Get job count by status
|
|
1151
|
+
*/
|
|
1152
|
+
count(queue: string, status?: JobStatus): Promise<number>;
|
|
1153
|
+
/**
|
|
1154
|
+
* Check if job exists with deduplication key
|
|
1155
|
+
*/
|
|
1156
|
+
existsByDeduplicationKey(queue: string, key: string): Promise<boolean>;
|
|
1157
|
+
}
|
|
1158
|
+
/**
|
|
1159
|
+
* In-memory implementation of JobStorage
|
|
1160
|
+
*/
|
|
1161
|
+
declare class MemoryJobStorage implements JobStorage {
|
|
1162
|
+
private jobs;
|
|
1163
|
+
private deduplicationKeys;
|
|
1164
|
+
save(queue: string, job: Job): Promise<void>;
|
|
1165
|
+
get(queue: string, jobId: string): Promise<Job | null>;
|
|
1166
|
+
getByStatus(queue: string, status: JobStatus): Promise<Job[]>;
|
|
1167
|
+
getAll(queue: string): Promise<Job[]>;
|
|
1168
|
+
updateStatus(queue: string, jobId: string, status: JobStatus): Promise<void>;
|
|
1169
|
+
update(queue: string, jobId: string, updates: Partial<Job>): Promise<void>;
|
|
1170
|
+
delete(queue: string, jobId: string): Promise<void>;
|
|
1171
|
+
clean(queue: string, grace: number, status: JobStatus): Promise<number>;
|
|
1172
|
+
count(queue: string, status?: JobStatus): Promise<number>;
|
|
1173
|
+
existsByDeduplicationKey(queue: string, key: string): Promise<boolean>;
|
|
1174
|
+
/**
|
|
1175
|
+
* Clear all jobs
|
|
1176
|
+
*/
|
|
1177
|
+
clear(): void;
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
/**
|
|
1181
|
+
* Workflow state storage abstraction
|
|
1182
|
+
*/
|
|
1183
|
+
|
|
1184
|
+
interface WorkflowStorage {
|
|
1185
|
+
/**
|
|
1186
|
+
* Save workflow execution state
|
|
1187
|
+
*/
|
|
1188
|
+
save(workflowId: string, execution: WorkflowExecution): Promise<void>;
|
|
1189
|
+
/**
|
|
1190
|
+
* Get workflow execution by ID
|
|
1191
|
+
*/
|
|
1192
|
+
get(executionId: string): Promise<WorkflowExecution | null>;
|
|
1193
|
+
/**
|
|
1194
|
+
* List executions for a workflow
|
|
1195
|
+
*/
|
|
1196
|
+
list(workflowId: string, options?: ListOptions): Promise<WorkflowExecution[]>;
|
|
1197
|
+
/**
|
|
1198
|
+
* Update execution status
|
|
1199
|
+
*/
|
|
1200
|
+
updateStatus(executionId: string, status: string): Promise<void>;
|
|
1201
|
+
/**
|
|
1202
|
+
* Update execution state
|
|
1203
|
+
*/
|
|
1204
|
+
updateState(executionId: string, state: Record<string, any>): Promise<void>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Delete an execution
|
|
1207
|
+
*/
|
|
1208
|
+
delete(executionId: string): Promise<void>;
|
|
1209
|
+
/**
|
|
1210
|
+
* Clean old executions
|
|
1211
|
+
*/
|
|
1212
|
+
clean(workflowId: string, grace: number): Promise<number>;
|
|
1213
|
+
}
|
|
1214
|
+
interface ListOptions {
|
|
1215
|
+
status?: string;
|
|
1216
|
+
limit?: number;
|
|
1217
|
+
offset?: number;
|
|
1218
|
+
sortBy?: "createdAt" | "updatedAt";
|
|
1219
|
+
sortOrder?: "asc" | "desc";
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* In-memory workflow storage implementation
|
|
1223
|
+
*/
|
|
1224
|
+
declare class MemoryWorkflowStorage implements WorkflowStorage {
|
|
1225
|
+
private executions;
|
|
1226
|
+
private workflowIndex;
|
|
1227
|
+
save(workflowId: string, execution: WorkflowExecution): Promise<void>;
|
|
1228
|
+
get(executionId: string): Promise<WorkflowExecution | null>;
|
|
1229
|
+
list(workflowId: string, options?: ListOptions): Promise<WorkflowExecution[]>;
|
|
1230
|
+
updateStatus(executionId: string, status: ExecutionStatus): Promise<void>;
|
|
1231
|
+
updateState(executionId: string, state: Record<string, any>): Promise<void>;
|
|
1232
|
+
delete(executionId: string): Promise<void>;
|
|
1233
|
+
clean(workflowId: string, grace: number): Promise<number>;
|
|
1234
|
+
/**
|
|
1235
|
+
* Clear all executions
|
|
1236
|
+
*/
|
|
1237
|
+
clear(): void;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/**
|
|
1241
|
+
* Event log for event sourcing pattern
|
|
1242
|
+
*/
|
|
1243
|
+
interface Event {
|
|
1244
|
+
id: string;
|
|
1245
|
+
type: string;
|
|
1246
|
+
aggregateId: string;
|
|
1247
|
+
aggregateType: string;
|
|
1248
|
+
data: any;
|
|
1249
|
+
metadata?: Record<string, any>;
|
|
1250
|
+
timestamp: number;
|
|
1251
|
+
version: number;
|
|
1252
|
+
}
|
|
1253
|
+
interface EventFilter {
|
|
1254
|
+
aggregateId?: string;
|
|
1255
|
+
aggregateType?: string;
|
|
1256
|
+
types?: string[];
|
|
1257
|
+
fromVersion?: number;
|
|
1258
|
+
toVersion?: number;
|
|
1259
|
+
fromTimestamp?: number;
|
|
1260
|
+
toTimestamp?: number;
|
|
1261
|
+
limit?: number;
|
|
1262
|
+
offset?: number;
|
|
1263
|
+
}
|
|
1264
|
+
interface EventLog {
|
|
1265
|
+
/**
|
|
1266
|
+
* Append event to the log
|
|
1267
|
+
*/
|
|
1268
|
+
append(event: Omit<Event, "id" | "timestamp" | "version">): Promise<Event>;
|
|
1269
|
+
/**
|
|
1270
|
+
* Get events by filter
|
|
1271
|
+
*/
|
|
1272
|
+
getEvents(filter: EventFilter): Promise<Event[]>;
|
|
1273
|
+
/**
|
|
1274
|
+
* Get events for an aggregate
|
|
1275
|
+
*/
|
|
1276
|
+
getAggregateEvents(aggregateId: string, fromVersion?: number): Promise<Event[]>;
|
|
1277
|
+
/**
|
|
1278
|
+
* Get latest version for an aggregate
|
|
1279
|
+
*/
|
|
1280
|
+
getLatestVersion(aggregateId: string): Promise<number>;
|
|
1281
|
+
/**
|
|
1282
|
+
* Subscribe to event stream
|
|
1283
|
+
*/
|
|
1284
|
+
subscribe(handler: (event: Event) => void | Promise<void>, filter?: EventFilter): () => void;
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* In-memory event log implementation
|
|
1288
|
+
*/
|
|
1289
|
+
declare class MemoryEventLog implements EventLog {
|
|
1290
|
+
private events;
|
|
1291
|
+
private aggregateVersions;
|
|
1292
|
+
private subscribers;
|
|
1293
|
+
append(event: Omit<Event, "id" | "timestamp" | "version">): Promise<Event>;
|
|
1294
|
+
getEvents(filter: EventFilter): Promise<Event[]>;
|
|
1295
|
+
getAggregateEvents(aggregateId: string, fromVersion?: number): Promise<Event[]>;
|
|
1296
|
+
getLatestVersion(aggregateId: string): Promise<number>;
|
|
1297
|
+
subscribe(handler: (event: Event) => void | Promise<void>, filter?: EventFilter): () => void;
|
|
1298
|
+
private matchesFilter;
|
|
1299
|
+
/**
|
|
1300
|
+
* Clear all events
|
|
1301
|
+
*/
|
|
1302
|
+
clear(): void;
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
export { type ApprovalOptions, type BackoffOptions, BatchAccumulator, type BatchHandler, type BatchOptions$1 as BatchOptions, BatchWriter, type BatchOptions as BatchingOptions, type BranchOptions, type CacheOptions, type CircuitBreakerOptions, type CircuitState, type CompensateHandler, type Consumer, type ConsumerOptions, type DLQJob, type DLQManager, type DLQOptions, type Duration$1 as Duration, type ErrorHandler, type Event, type EventFilter, type EventLog, type EventOptions, type EventTracker, type ExecutionStatus, type FlowAdapter, type FlowFn, type FlowFnConfig, FlowFnImpl, type HealthCheck, type HealthChecker, HealthCheckerImpl, type HealthStatus, type IdGeneratorOptions, type IdStrategy, type Job, type JobHandler, type JobOptions, type JobStatus, type JobStorage, type ListOptions$1 as ListOptions, MemoryAdapter, MemoryDLQManager, MemoryEventLog, MemoryEventTracker, MemoryJobStorage, MemoryWorkflowStorage, type Message, type MessageHandler, type MetricDataPoint, MetricsManager, type MonitoringMetrics, PostgresAdapter, type PostgresAdapterOptions, type PriorityItem, PriorityQueue, type PublishOptions, type Queue, type QueueEvent, type QueueOptions, type QueueStats, type RateLimitOptions, type RateLimitResult, RateLimiter, type RateLimiterOptions, RedisAdapter, type RedisAdapterOptions, type SagaDefinition, type ScheduleOptions, Scheduler, type SerializationOptions, SlidingWindowRateLimiter, type StepHandler, type ListOptions as StorageListOptions, type Stream, type StreamInfo, type StreamOptions, type SubscribeOptions, type Subscription, type Duration as TimeDuration, type TimeSeriesMetrics, TokenBucketRateLimiter, type TrackedEvent, type TrimStrategy, Worker, type WorkerOptions, type Workflow, type WorkflowBuilder, type WorkflowContext, type WorkflowEvent, type WorkflowExecution, type WorkflowMetrics, type WorkflowStorage, addDuration, areJobsEquivalent, batch, batchByKey, calculateBackoff, chunk, circuitBreaker, cloneViaSerialization, createFlow, createRateLimiter, createWorker, delayUntil, deserialize, deserializeCompressed, formatDuration, fromMilliseconds, generateDeduplicationKey, generateDeterministicId, generateExecutionId, generateId, generateJobId, generateMessageId, getSerializedSize, hashJob, isFuture, isPast, isSerializable, now, parseDuration, processBatches, serialize, serializeCompressed, serializeSafe, sleep, sleepDuration, timeout, toMilliseconds };
|