ravenflow 0.1.0 → 0.2.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/README.md +294 -30
- package/dist/index.d.mts +181 -47
- package/dist/index.d.ts +181 -47
- package/dist/index.js +1369 -203
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1362 -203
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -11
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { Job, Queue, QueueEvents, ConnectionOptions, Worker } from 'bullmq';
|
|
3
|
+
import pino from 'pino';
|
|
3
4
|
|
|
4
|
-
interface RavenflowConfig<TQueues extends string = string, TJobs extends string = string> {
|
|
5
|
-
defaultQueue: TQueues;
|
|
6
|
-
queues: TQueues[];
|
|
7
|
-
jobs: Record<TJobs, JobConfig>;
|
|
8
|
-
}
|
|
9
|
-
type JobNames<T extends RavenflowConfig> = T extends RavenflowConfig<infer _, infer TJobs> ? TJobs : never;
|
|
10
|
-
type QueueNames<T extends RavenflowConfig> = T extends RavenflowConfig<infer TQueues, infer _> ? TQueues : never;
|
|
11
5
|
interface BaseJobConfig {
|
|
12
|
-
|
|
6
|
+
queue?: string;
|
|
13
7
|
cron?: string;
|
|
14
8
|
attempts?: number;
|
|
15
9
|
backoff?: {
|
|
@@ -17,67 +11,207 @@ interface BaseJobConfig {
|
|
|
17
11
|
delay: number;
|
|
18
12
|
};
|
|
19
13
|
}
|
|
14
|
+
declare const zRateLimitConfig: z.ZodUnion<readonly [z.ZodObject<{
|
|
15
|
+
perSecond: z.ZodNumber;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
perMinute: z.ZodNumber;
|
|
18
|
+
}, z.core.$strip>]>;
|
|
19
|
+
type RateLimitConfig = z.infer<typeof zRateLimitConfig>;
|
|
20
|
+
interface MemoryEtlStepConfig {
|
|
21
|
+
rateLimit?: RateLimitConfig;
|
|
22
|
+
}
|
|
23
|
+
interface StepConfig extends MemoryEtlStepConfig {
|
|
24
|
+
attempts?: number;
|
|
25
|
+
backoff?: {
|
|
26
|
+
type: "fixed" | "exponential";
|
|
27
|
+
delay: number;
|
|
28
|
+
};
|
|
29
|
+
queue?: string;
|
|
30
|
+
}
|
|
31
|
+
interface EtlExtractResult<TRaw, TCursor> {
|
|
32
|
+
data: TRaw[];
|
|
33
|
+
cursor: TCursor | null;
|
|
34
|
+
hasMore: boolean;
|
|
35
|
+
}
|
|
36
|
+
declare const zJobStatus: z.ZodEnum<{
|
|
37
|
+
pending: "pending";
|
|
38
|
+
in_progress: "in_progress";
|
|
39
|
+
completed: "completed";
|
|
40
|
+
failed: "failed";
|
|
41
|
+
stalled: "stalled";
|
|
42
|
+
}>;
|
|
43
|
+
type JobStatus = z.infer<typeof zJobStatus>;
|
|
44
|
+
|
|
20
45
|
interface SimpleJobConfig<TData, TReturn> extends BaseJobConfig {
|
|
21
|
-
type: "
|
|
46
|
+
type: "simple";
|
|
22
47
|
handler: (job: Job, params: TData) => Promise<TReturn>;
|
|
23
48
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
49
|
+
declare function defineSimpleJob<TData, TReturn>(config: Omit<SimpleJobConfig<TData, TReturn>, "type">): SimpleJobConfig<TData, TReturn>;
|
|
50
|
+
|
|
51
|
+
interface MemoryEtlJobConfig<TRaw, TProcessed, TCursor = number> extends BaseJobConfig {
|
|
52
|
+
type: "memory-etl";
|
|
53
|
+
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
54
|
+
transform: (data: TRaw) => Promise<TProcessed>;
|
|
55
|
+
load: (data: TProcessed[]) => Promise<void>;
|
|
56
|
+
steps?: {
|
|
57
|
+
extract?: MemoryEtlStepConfig;
|
|
58
|
+
transform?: MemoryEtlStepConfig;
|
|
59
|
+
load?: MemoryEtlStepConfig;
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
declare function defineMemoryEtlJob<TRaw, TProcessed, TCursor = number>(config: Omit<MemoryEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): MemoryEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
63
|
+
|
|
64
|
+
interface DistributedEtlJobConfig<TRaw, TProcessed, TCursor = number> extends BaseJobConfig {
|
|
65
|
+
type: "distributed-etl";
|
|
66
|
+
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
67
|
+
transform: (data: TRaw) => Promise<TProcessed>;
|
|
68
|
+
load: (data: TProcessed[]) => Promise<void>;
|
|
69
|
+
steps?: {
|
|
70
|
+
extract?: StepConfig;
|
|
71
|
+
transform?: StepConfig;
|
|
72
|
+
load?: StepConfig;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
declare function defineDistributedEtlJob<TRaw, TProcessed, TCursor = number>(config: Omit<DistributedEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): DistributedEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
76
|
+
|
|
77
|
+
interface StatefulEtlJobConfig<TRaw, TProcessed, TCursor = string> extends BaseJobConfig {
|
|
78
|
+
type: "stateful-etl";
|
|
79
|
+
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
30
80
|
transform: (data: TRaw) => Promise<TProcessed>;
|
|
31
81
|
load: (data: TProcessed[]) => Promise<void>;
|
|
32
|
-
|
|
82
|
+
/**
|
|
83
|
+
* When true, only one run of this job can be active at a time.
|
|
84
|
+
* If a run is already pending or in_progress (with a live heartbeat), the new trigger is skipped.
|
|
85
|
+
* Defaults to false — each trigger creates an independent run.
|
|
86
|
+
*/
|
|
87
|
+
singletonRun?: boolean;
|
|
88
|
+
stallTimeoutMs?: number;
|
|
89
|
+
maxStallRetries?: number;
|
|
90
|
+
steps?: {
|
|
91
|
+
extract?: StepConfig;
|
|
92
|
+
transform?: StepConfig;
|
|
93
|
+
load?: StepConfig;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
declare function defineStatefulEtlJob<TRaw, TProcessed, TCursor = string>(config: Omit<StatefulEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): StatefulEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
97
|
+
|
|
98
|
+
interface TokenBucketJobConfig<TItem, TResult> extends BaseJobConfig {
|
|
99
|
+
type: "token-bucket";
|
|
100
|
+
cron: string;
|
|
101
|
+
rate: {
|
|
102
|
+
amount: number;
|
|
103
|
+
interval: "minute" | "hour" | "day";
|
|
104
|
+
};
|
|
105
|
+
activeHours?: {
|
|
106
|
+
start: number;
|
|
107
|
+
end: number;
|
|
108
|
+
timezone?: string;
|
|
109
|
+
};
|
|
110
|
+
maxPerBeat?: number;
|
|
111
|
+
getItems: (budget: number) => Promise<TItem[]>;
|
|
112
|
+
process: (item: TItem) => Promise<TResult>;
|
|
113
|
+
steps?: {
|
|
114
|
+
process?: StepConfig;
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
declare function defineTokenBucketJob<TItem, TResult>(config: Omit<TokenBucketJobConfig<TItem, TResult>, "type">): TokenBucketJobConfig<TItem, TResult>;
|
|
118
|
+
|
|
119
|
+
type JobConfig = SimpleJobConfig<any, any> | MemoryEtlJobConfig<any, any, any> | DistributedEtlJobConfig<any, any, any> | StatefulEtlJobConfig<any, any, any> | TokenBucketJobConfig<any, any>;
|
|
120
|
+
|
|
121
|
+
interface RetentionConfig {
|
|
122
|
+
/** Number of completed jobs to keep per queue. Set to 0 to remove immediately. */
|
|
123
|
+
completed?: number;
|
|
124
|
+
/** Number of failed jobs to keep per queue. Set to 0 to remove immediately. */
|
|
125
|
+
failed?: number;
|
|
126
|
+
}
|
|
127
|
+
interface RavenflowConfig<TJobs extends string = string> {
|
|
128
|
+
defaultQueue: string;
|
|
129
|
+
jobs: Record<TJobs, JobConfig>;
|
|
130
|
+
}
|
|
131
|
+
type JobNames<T extends RavenflowConfig> = T extends RavenflowConfig<infer TJobs> ? TJobs : never;
|
|
132
|
+
declare function defineConfig<const T extends RavenflowConfig>(config: T): T;
|
|
133
|
+
|
|
134
|
+
interface EtlResult {
|
|
135
|
+
extractedCount: number;
|
|
136
|
+
transformedCount: number;
|
|
137
|
+
loadedCount: number;
|
|
33
138
|
}
|
|
34
|
-
type JobConfig = SimpleJobConfig<any, any> | EtlJobConfig<any, any>;
|
|
35
139
|
type JobProxy<T extends JobConfig> = T extends SimpleJobConfig<infer TData, infer TReturn> ? {
|
|
36
140
|
send: (params: TData) => Promise<Job<TData, TReturn>>;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
141
|
+
sendAndWait: (params: TData) => Promise<TReturn>;
|
|
142
|
+
} : T extends MemoryEtlJobConfig<any, any, any> ? {
|
|
143
|
+
send: () => Promise<void>;
|
|
144
|
+
sendAndWait: () => Promise<EtlResult>;
|
|
145
|
+
} : T extends DistributedEtlJobConfig<any, any> ? {
|
|
146
|
+
send: () => Promise<void>;
|
|
147
|
+
sendAndWait: () => Promise<EtlResult>;
|
|
148
|
+
} : T extends StatefulEtlJobConfig<any, any, any> ? {
|
|
149
|
+
send: () => Promise<void>;
|
|
150
|
+
sendAndWait: () => Promise<void>;
|
|
151
|
+
} : T extends TokenBucketJobConfig<any, any> ? {
|
|
152
|
+
send: () => Promise<void>;
|
|
153
|
+
sendAndWait: () => Promise<void>;
|
|
42
154
|
} : never;
|
|
43
155
|
type JobsProxy<TJobs extends Record<string, JobConfig>> = {
|
|
44
156
|
[K in keyof TJobs]: JobProxy<TJobs[K]>;
|
|
45
157
|
};
|
|
46
158
|
|
|
159
|
+
type Logger = pino.Logger;
|
|
47
160
|
interface LoggerOptions {
|
|
48
161
|
level?: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
49
162
|
pretty?: boolean;
|
|
50
163
|
}
|
|
51
|
-
declare function
|
|
52
|
-
|
|
164
|
+
declare function initLogger(options?: LoggerOptions): Logger;
|
|
165
|
+
declare function getLogger(): Logger;
|
|
166
|
+
|
|
167
|
+
type QueueStore = Record<string, {
|
|
168
|
+
queue: Queue;
|
|
169
|
+
events: QueueEvents;
|
|
170
|
+
}>;
|
|
171
|
+
|
|
172
|
+
declare class StallWatcher {
|
|
173
|
+
private readonly workerQueue;
|
|
174
|
+
private readonly statefulEtlConfigs;
|
|
175
|
+
private readonly userQueues;
|
|
176
|
+
constructor(jobConfigs: Record<string, JobConfig>, userQueues: Record<string, {
|
|
177
|
+
queue: Queue;
|
|
178
|
+
}>, defaultQueue: string, workerQueue: Queue);
|
|
179
|
+
canProcess(jobName: string): boolean;
|
|
180
|
+
start(): Promise<void>;
|
|
181
|
+
stop(): Promise<void>;
|
|
182
|
+
process(job: Job): Promise<void>;
|
|
183
|
+
}
|
|
53
184
|
|
|
185
|
+
interface MongoConnectionObject {
|
|
186
|
+
host: string;
|
|
187
|
+
port?: number;
|
|
188
|
+
username?: string;
|
|
189
|
+
password?: string;
|
|
190
|
+
database?: string;
|
|
191
|
+
}
|
|
192
|
+
interface RavenflowAppOptions {
|
|
193
|
+
redis: ConnectionOptions;
|
|
194
|
+
mongo?: string | MongoConnectionObject;
|
|
195
|
+
retention?: RetentionConfig;
|
|
196
|
+
logger?: LoggerOptions;
|
|
197
|
+
}
|
|
54
198
|
declare class RavenflowApp<TConfig extends RavenflowConfig = RavenflowConfig> {
|
|
55
|
-
protected
|
|
199
|
+
protected redisConnection: ConnectionOptions;
|
|
56
200
|
protected defaultConcurrency: number;
|
|
57
|
-
protected logger: Logger;
|
|
58
201
|
protected config: TConfig;
|
|
202
|
+
protected mongoUri: string | null;
|
|
59
203
|
jobs: JobsProxy<TConfig["jobs"]>;
|
|
60
204
|
protected jobConfigs: Record<JobNames<TConfig>, JobConfig>;
|
|
61
|
-
protected queues:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
private initQueues;
|
|
67
|
-
private initJobs;
|
|
68
|
-
private sendJob;
|
|
69
|
-
startWorker(queueName: QueueNames<TConfig>, options?: {
|
|
205
|
+
protected queues: QueueStore;
|
|
206
|
+
protected workers: Worker[];
|
|
207
|
+
protected stallWatcher: StallWatcher | null;
|
|
208
|
+
constructor(config: TConfig, options: RavenflowAppOptions);
|
|
209
|
+
startWorker(queueName: string, options?: {
|
|
70
210
|
concurrency?: number;
|
|
71
|
-
}): void
|
|
72
|
-
|
|
73
|
-
private setupWorkerEvents;
|
|
74
|
-
private syncJobSchedulers;
|
|
75
|
-
processJob(job: Job): Promise<any>;
|
|
211
|
+
}): Promise<void>;
|
|
212
|
+
close(): Promise<void>;
|
|
76
213
|
}
|
|
77
214
|
|
|
78
|
-
declare function createRavenflowApp<TConfig extends RavenflowConfig>(config: TConfig,
|
|
79
|
-
level?: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
80
|
-
pretty?: boolean;
|
|
81
|
-
}): RavenflowApp<TConfig>;
|
|
215
|
+
declare function createRavenflowApp<TConfig extends RavenflowConfig>(config: TConfig, options: RavenflowAppOptions): RavenflowApp<TConfig>;
|
|
82
216
|
|
|
83
|
-
export { type
|
|
217
|
+
export { type DistributedEtlJobConfig, type EtlExtractResult, type EtlResult, type JobConfig, type JobStatus, type Logger, type LoggerOptions, type MemoryEtlJobConfig, type MemoryEtlStepConfig, type MongoConnectionObject, type RateLimitConfig, RavenflowApp, type RavenflowAppOptions, type RavenflowConfig, type RetentionConfig, type SimpleJobConfig, type StatefulEtlJobConfig, type StepConfig, type TokenBucketJobConfig, createRavenflowApp, defineConfig, defineDistributedEtlJob, defineMemoryEtlJob, defineSimpleJob, defineStatefulEtlJob, defineTokenBucketJob, getLogger, initLogger };
|