ravenflow 0.3.1 → 0.4.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/README.md +124 -266
- package/dist/index.d.mts +175 -634
- package/dist/index.d.ts +175 -634
- package/dist/index.js +2787 -2663
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2790 -2621
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -11
- package/LICENSE +0 -21
package/dist/index.d.ts
CHANGED
|
@@ -1,673 +1,214 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Job, Queue, QueueEvents, ConnectionOptions, Worker, WorkerOptions } from 'bullmq';
|
|
1
|
+
import { Job, ConnectionOptions } from 'bullmq';
|
|
3
2
|
import pino from 'pino';
|
|
4
|
-
import { IndexSpecification, CreateIndexesOptions, Document, Collection, Db, AnyBulkWriteOperation } from 'mongodb';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
delay: number;
|
|
13
|
-
};
|
|
4
|
+
declare const CONTINUATION: unique symbol;
|
|
5
|
+
interface Continuation<TPayload> {
|
|
6
|
+
readonly [CONTINUATION]: true;
|
|
7
|
+
readonly params: TPayload;
|
|
8
|
+
readonly delayMs?: number;
|
|
9
|
+
readonly deduplicationId?: string;
|
|
14
10
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
perMinute: z.ZodNumber;
|
|
19
|
-
}, z.core.$strip>]>;
|
|
20
|
-
type RateLimitConfig = z.infer<typeof zRateLimitConfig>;
|
|
21
|
-
interface MemoryEtlStepConfig {
|
|
22
|
-
rateLimit?: RateLimitConfig;
|
|
23
|
-
}
|
|
24
|
-
interface StepConfig extends MemoryEtlStepConfig {
|
|
25
|
-
attempts?: number;
|
|
26
|
-
backoff?: {
|
|
27
|
-
type: "fixed" | "exponential";
|
|
28
|
-
delay: number;
|
|
29
|
-
};
|
|
30
|
-
queue?: string;
|
|
31
|
-
}
|
|
32
|
-
interface EtlExtractResult<TRaw, TCursor> {
|
|
33
|
-
data: TRaw[];
|
|
34
|
-
cursor: TCursor | null;
|
|
35
|
-
hasMore: boolean;
|
|
36
|
-
}
|
|
37
|
-
declare const zJobStatus: z.ZodEnum<{
|
|
38
|
-
pending: "pending";
|
|
39
|
-
in_progress: "in_progress";
|
|
40
|
-
completed: "completed";
|
|
41
|
-
failed: "failed";
|
|
42
|
-
stalled: "stalled";
|
|
43
|
-
}>;
|
|
44
|
-
type JobStatus = z.infer<typeof zJobStatus>;
|
|
45
|
-
|
|
46
|
-
interface SimpleJobConfig<TData, TReturn> extends BaseJobConfig {
|
|
47
|
-
type: "simple";
|
|
48
|
-
handler: (job: Job, params: TData) => Promise<TReturn>;
|
|
49
|
-
}
|
|
50
|
-
declare function defineSimpleJob<TData, TReturn>(config: Omit<SimpleJobConfig<TData, TReturn>, "type">): SimpleJobConfig<TData, TReturn>;
|
|
51
|
-
|
|
52
|
-
interface MemoryEtlJobConfig<TRaw, TProcessed, TCursor = number> extends BaseJobConfig {
|
|
53
|
-
type: "memory-etl";
|
|
54
|
-
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
55
|
-
transform: (data: TRaw) => Promise<TProcessed>;
|
|
56
|
-
load: (data: TProcessed[]) => Promise<void>;
|
|
57
|
-
steps?: {
|
|
58
|
-
extract?: MemoryEtlStepConfig;
|
|
59
|
-
transform?: MemoryEtlStepConfig;
|
|
60
|
-
load?: MemoryEtlStepConfig;
|
|
61
|
-
};
|
|
11
|
+
interface ContinueOptions {
|
|
12
|
+
delayMs?: number;
|
|
13
|
+
deduplicationId?: string;
|
|
62
14
|
}
|
|
63
|
-
declare function defineMemoryEtlJob<TRaw, TProcessed, TCursor = number>(config: Omit<MemoryEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): MemoryEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
64
|
-
|
|
65
|
-
interface DistributedEtlJobConfig<TRaw, TProcessed, TCursor = number> extends BaseJobConfig {
|
|
66
|
-
type: "distributed-etl";
|
|
67
|
-
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
68
|
-
transform: (data: TRaw) => Promise<TProcessed>;
|
|
69
|
-
load: (data: TProcessed[]) => Promise<void>;
|
|
70
|
-
steps?: {
|
|
71
|
-
extract?: StepConfig;
|
|
72
|
-
transform?: StepConfig;
|
|
73
|
-
load?: StepConfig;
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
declare function defineDistributedEtlJob<TRaw, TProcessed, TCursor = number>(config: Omit<DistributedEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): DistributedEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
77
|
-
|
|
78
|
-
interface StatefulEtlJobConfig<TRaw, TProcessed, TCursor = string> extends BaseJobConfig {
|
|
79
|
-
type: "stateful-etl";
|
|
80
|
-
extract: (cursor: TCursor | null) => Promise<EtlExtractResult<TRaw, TCursor>>;
|
|
81
|
-
transform: (data: TRaw) => Promise<TProcessed>;
|
|
82
|
-
load: (data: TProcessed[]) => Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* When true, only one run of this job can be active at a time.
|
|
85
|
-
* If a run is already pending or in_progress (with a live heartbeat), the new trigger is skipped.
|
|
86
|
-
* Defaults to false — each trigger creates an independent run.
|
|
87
|
-
*/
|
|
88
|
-
singletonRun?: boolean;
|
|
89
|
-
stallTimeoutMs?: number;
|
|
90
|
-
maxStallRetries?: number;
|
|
91
|
-
steps?: {
|
|
92
|
-
extract?: StepConfig;
|
|
93
|
-
transform?: StepConfig;
|
|
94
|
-
load?: StepConfig;
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
declare function defineStatefulEtlJob<TRaw, TProcessed, TCursor = string>(config: Omit<StatefulEtlJobConfig<TRaw, TProcessed, TCursor>, "type">): StatefulEtlJobConfig<TRaw, TProcessed, TCursor>;
|
|
98
|
-
|
|
99
|
-
type TokenBucketInterval = "second" | "minute" | "hour" | "day" | "week";
|
|
100
|
-
interface TokenBucketJobConfig extends BaseJobConfig {
|
|
101
|
-
type: "token-bucket";
|
|
102
|
-
cron: string;
|
|
103
|
-
rate?: {
|
|
104
|
-
amount: number;
|
|
105
|
-
interval: TokenBucketInterval;
|
|
106
|
-
};
|
|
107
|
-
getBudget?: () => Promise<number> | number;
|
|
108
|
-
maxCarryOver?: number;
|
|
109
|
-
consumeTimeout?: number;
|
|
110
|
-
consume: (tokens: number) => Promise<number | void> | number | void;
|
|
111
|
-
}
|
|
112
|
-
declare function defineTokenBucketJob(config: Omit<TokenBucketJobConfig, "type">): TokenBucketJobConfig;
|
|
113
|
-
|
|
114
|
-
type JobConfig = SimpleJobConfig<any, any> | MemoryEtlJobConfig<any, any, any> | DistributedEtlJobConfig<any, any, any> | StatefulEtlJobConfig<any, any, any> | TokenBucketJobConfig;
|
|
115
|
-
|
|
116
|
-
interface RetentionConfig {
|
|
117
|
-
/** Number of completed jobs to keep per queue. Set to 0 to remove immediately. */
|
|
118
|
-
completed?: number;
|
|
119
|
-
/** Number of failed jobs to keep per queue. Set to 0 to remove immediately. */
|
|
120
|
-
failed?: number;
|
|
121
|
-
}
|
|
122
|
-
interface RavenflowConfig<TJobs extends string = string> {
|
|
123
|
-
defaultQueue: string;
|
|
124
|
-
jobs: Record<TJobs, JobConfig>;
|
|
125
|
-
}
|
|
126
|
-
type JobNames<T extends RavenflowConfig> = T extends RavenflowConfig<infer TJobs> ? TJobs : never;
|
|
127
|
-
declare function defineConfig<const T extends RavenflowConfig>(config: T): T;
|
|
128
|
-
|
|
129
|
-
interface EtlResult {
|
|
130
|
-
extractedCount: number;
|
|
131
|
-
transformedCount: number;
|
|
132
|
-
loadedCount: number;
|
|
133
|
-
}
|
|
134
|
-
type JobProxy<T extends JobConfig> = T extends SimpleJobConfig<infer TData, infer TReturn> ? {
|
|
135
|
-
send: (params: TData) => Promise<Job<TData, TReturn>>;
|
|
136
|
-
sendAndWait: (params: TData) => Promise<TReturn>;
|
|
137
|
-
} : T extends MemoryEtlJobConfig<any, any, any> ? {
|
|
138
|
-
send: () => Promise<void>;
|
|
139
|
-
sendAndWait: () => Promise<EtlResult>;
|
|
140
|
-
} : T extends DistributedEtlJobConfig<any, any> ? {
|
|
141
|
-
send: () => Promise<void>;
|
|
142
|
-
sendAndWait: () => Promise<EtlResult>;
|
|
143
|
-
} : T extends StatefulEtlJobConfig<any, any, any> ? {
|
|
144
|
-
send: () => Promise<void>;
|
|
145
|
-
sendAndWait: () => Promise<void>;
|
|
146
|
-
} : T extends TokenBucketJobConfig ? {
|
|
147
|
-
send: () => Promise<void>;
|
|
148
|
-
sendAndWait: () => Promise<void>;
|
|
149
|
-
} : never;
|
|
150
|
-
type JobsProxy<TJobs extends Record<string, JobConfig>> = {
|
|
151
|
-
[K in keyof TJobs]: JobProxy<TJobs[K]>;
|
|
152
|
-
};
|
|
153
15
|
|
|
154
16
|
type Logger = pino.Logger;
|
|
155
17
|
interface LoggerOptions {
|
|
156
18
|
level?: "trace" | "debug" | "info" | "warn" | "error" | "fatal";
|
|
157
19
|
pretty?: boolean;
|
|
158
20
|
}
|
|
159
|
-
declare function initLogger(options?: LoggerOptions): Logger;
|
|
160
|
-
declare function getLogger(): Logger;
|
|
161
|
-
|
|
162
|
-
type QueueStore = Record<string, {
|
|
163
|
-
queue: Queue;
|
|
164
|
-
events: QueueEvents;
|
|
165
|
-
}>;
|
|
166
21
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
22
|
+
interface JobContext<TParams> {
|
|
23
|
+
params: TParams;
|
|
24
|
+
deduplicationId?: string;
|
|
25
|
+
continueWith(params: TParams, options?: ContinueOptions): Continuation<TParams>;
|
|
26
|
+
job: Job;
|
|
27
|
+
logger: Logger;
|
|
28
|
+
signal: AbortSignal;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface BackoffPolicy {
|
|
32
|
+
type: "fixed" | "exponential";
|
|
33
|
+
delayMs: number;
|
|
34
|
+
jitter?: number;
|
|
35
|
+
}
|
|
36
|
+
type DeduplicatePolicy<TPayload> = true | ((params: TPayload) => string);
|
|
37
|
+
type PacePolicy = {
|
|
38
|
+
perSecond: number;
|
|
39
|
+
perMinute?: never;
|
|
40
|
+
perHour?: never;
|
|
41
|
+
} | {
|
|
42
|
+
perMinute: number;
|
|
43
|
+
perSecond?: never;
|
|
44
|
+
perHour?: never;
|
|
45
|
+
} | {
|
|
46
|
+
perHour: number;
|
|
47
|
+
perSecond?: never;
|
|
48
|
+
perMinute?: never;
|
|
49
|
+
};
|
|
179
50
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
type BucketGranularity = "hour" | "day";
|
|
185
|
-
interface IncrementStatsInput {
|
|
186
|
-
success: boolean;
|
|
187
|
-
durationMs?: number;
|
|
188
|
-
}
|
|
189
|
-
interface JobStatsDoc {
|
|
190
|
-
jobType: string;
|
|
191
|
-
bucketStart: Date;
|
|
192
|
-
granularity: BucketGranularity;
|
|
193
|
-
count: number;
|
|
194
|
-
success: number;
|
|
195
|
-
failed: number;
|
|
196
|
-
totalDurationMs: number;
|
|
197
|
-
createdAt: Date;
|
|
198
|
-
updatedAt: Date;
|
|
199
|
-
}
|
|
200
|
-
interface JobErrorDoc {
|
|
201
|
-
signature: string;
|
|
202
|
-
jobType: string;
|
|
203
|
-
message: string;
|
|
204
|
-
stack: string;
|
|
205
|
-
count: number;
|
|
206
|
-
firstSeenAt: Date;
|
|
207
|
-
lastSeenAt: Date;
|
|
208
|
-
createdAt: Date;
|
|
209
|
-
updatedAt: Date;
|
|
210
|
-
/** Normalized `Error.cause` chain beyond the top-level error. OMITTED when empty. */
|
|
211
|
-
causeChain?: Array<{
|
|
212
|
-
message: string;
|
|
213
|
-
name: string;
|
|
214
|
-
}>;
|
|
215
|
-
}
|
|
216
|
-
interface RecordOccurrenceInput {
|
|
217
|
-
jobType: string;
|
|
218
|
-
error: unknown;
|
|
219
|
-
}
|
|
220
|
-
interface TopErrorsOptions {
|
|
221
|
-
limit: number;
|
|
222
|
-
jobType?: string;
|
|
223
|
-
/**
|
|
224
|
-
* When set, restricts results to errors whose `lastSeenAt >= since`.
|
|
225
|
-
* Dashboard health views pass the range start (e.g. 7 days ago, UTC midnight)
|
|
226
|
-
* so "top errors" matches the displayed range; omitting returns all errors
|
|
227
|
-
* back to the collection's 90-day TTL boundary.
|
|
228
|
-
*/
|
|
229
|
-
since?: Date;
|
|
230
|
-
}
|
|
231
|
-
interface JobFailureDoc {
|
|
232
|
-
jobId: string;
|
|
233
|
-
jobType: string;
|
|
234
|
-
input: string;
|
|
235
|
-
errorMessage: string;
|
|
236
|
-
errorStack: string;
|
|
237
|
-
logs: string;
|
|
238
|
-
failedAt: Date;
|
|
239
|
-
createdAt: Date;
|
|
240
|
-
/** Normalized `Error.cause` chain beyond the top-level error. OMITTED when empty. */
|
|
241
|
-
causeChain?: Array<{
|
|
242
|
-
message: string;
|
|
243
|
-
name: string;
|
|
244
|
-
}>;
|
|
245
|
-
}
|
|
246
|
-
interface RecordFailureInput {
|
|
247
|
-
jobId: string;
|
|
248
|
-
jobType: string;
|
|
249
|
-
input: unknown;
|
|
250
|
-
error: unknown;
|
|
251
|
-
failedAt: Date;
|
|
252
|
-
logs?: string;
|
|
51
|
+
type JobTrigger = CronTrigger | SpoolTriggerDeclaration;
|
|
52
|
+
interface CronTrigger {
|
|
53
|
+
cron: string;
|
|
54
|
+
spool?: never;
|
|
253
55
|
}
|
|
254
|
-
interface
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
toDate?: Date | null;
|
|
258
|
-
skip?: number;
|
|
259
|
-
limit?: number;
|
|
56
|
+
interface SpoolTriggerDeclaration {
|
|
57
|
+
spool: SpoolTrigger;
|
|
58
|
+
cron?: never;
|
|
260
59
|
}
|
|
261
|
-
|
|
262
|
-
declare const JOB_FAILURES_MESSAGE_MAX_CHARS = 2000;
|
|
263
|
-
declare const JOB_FAILURES_STACK_MAX_CHARS = 8000;
|
|
264
|
-
declare const JOB_FAILURES_LOGS_MAX_CHARS = 500000;
|
|
265
|
-
interface WorkerQueueEntry {
|
|
60
|
+
interface SpoolTrigger {
|
|
266
61
|
name: string;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
workerId: string;
|
|
271
|
-
hostname: string;
|
|
272
|
-
pid: number;
|
|
273
|
-
queues: WorkerQueueEntry[];
|
|
274
|
-
startedAt: Date;
|
|
275
|
-
lastHeartbeatAt: Date;
|
|
276
|
-
createdAt: Date;
|
|
277
|
-
updatedAt: Date;
|
|
278
|
-
}
|
|
279
|
-
interface RegisterWorkerInput {
|
|
280
|
-
workerId: string;
|
|
281
|
-
hostname: string;
|
|
282
|
-
pid: number;
|
|
283
|
-
queues: WorkerQueueEntry[];
|
|
284
|
-
startedAt: Date;
|
|
285
|
-
}
|
|
286
|
-
interface UpsertWorkerQueueInput {
|
|
287
|
-
workerId: string;
|
|
288
|
-
queue: WorkerQueueEntry;
|
|
289
|
-
}
|
|
290
|
-
/**
|
|
291
|
-
* Read shape for the `job_configs` collection — what `JobConfigsRepo.getConfig`
|
|
292
|
-
* returns (with persistence timestamps stripped, or synthesized for absent records).
|
|
293
|
-
*
|
|
294
|
-
* Distinct from `JobConfig` (in `src/types/job/unions.ts`), which is the discriminated
|
|
295
|
-
* union of job-definition types (simple / memory-etl / distributed-etl / etc.) used
|
|
296
|
-
* at app-registration time. `JobConfigEntry` is the runtime persistence shape for
|
|
297
|
-
* dashboard-managed per-job-type settings (enabled flag + free-form metadata).
|
|
298
|
-
*/
|
|
299
|
-
interface JobConfigEntry {
|
|
300
|
-
jobType: string;
|
|
301
|
-
enabled: boolean;
|
|
302
|
-
metadata: Record<string, unknown>;
|
|
62
|
+
tickMs?: number;
|
|
63
|
+
canPull?: () => boolean | Promise<boolean>;
|
|
64
|
+
expireUnclaimedAfterMs?: number;
|
|
303
65
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
* there is, by definition, persisted, so the timestamps are always real).
|
|
308
|
-
*/
|
|
309
|
-
interface JobConfigDoc extends JobConfigEntry {
|
|
310
|
-
createdAt: Date;
|
|
311
|
-
updatedAt: Date;
|
|
66
|
+
interface DeclaredTrigger {
|
|
67
|
+
cron?: string;
|
|
68
|
+
spool?: SpoolTrigger;
|
|
312
69
|
}
|
|
313
70
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
71
|
+
type TriggerFor<TPayload> = SatisfiableByNothing<TPayload> extends true ? JobTrigger : SpoolTriggerDeclaration | CronRefused;
|
|
72
|
+
type CronTriggerFor<TPayload> = SatisfiableByNothing<TPayload> extends true ? CronTrigger : CronRefused;
|
|
73
|
+
type SatisfiableByNothing<TPayload> = AcceptsUndefined<TPayload> extends true ? true : AcceptsEmptyObject<TPayload>;
|
|
74
|
+
type AcceptsUndefined<TPayload> = undefined extends TPayload ? true : false;
|
|
75
|
+
type AcceptsEmptyObject<TPayload> = {} extends TPayload ? true : false;
|
|
76
|
+
interface CronRefused {
|
|
77
|
+
cron?: CronNeedsAPayloadNothingHasToProvide;
|
|
78
|
+
spool?: never;
|
|
319
79
|
}
|
|
80
|
+
type CronNeedsAPayloadNothingHasToProvide = "a cron trigger has nothing to pass this job: make every field of its payload optional, or declare the payload as void";
|
|
320
81
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
82
|
+
interface JobDefinition<TPayload, TResult> {
|
|
83
|
+
queue?: string;
|
|
84
|
+
attempts?: number;
|
|
85
|
+
backoff?: BackoffPolicy;
|
|
86
|
+
trigger?: TriggerFor<TPayload>;
|
|
87
|
+
deduplicate?: DeduplicatePolicy<TPayload>;
|
|
88
|
+
pace?: PacePolicy;
|
|
89
|
+
handler: JobHandler<TPayload, TResult>;
|
|
90
|
+
}
|
|
91
|
+
type JobHandler<TPayload, TResult> = (ctx: JobContext<TPayload>) => Promise<TResult | Continuation<TPayload>>;
|
|
92
|
+
type SpoolFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {
|
|
93
|
+
trigger: SpoolTriggerDeclaration;
|
|
94
|
+
pace: PacePolicy;
|
|
95
|
+
};
|
|
96
|
+
type ClockFedJob<TPayload, TResult> = JobDefinition<TPayload, TResult> & {
|
|
97
|
+
trigger: CronTrigger;
|
|
98
|
+
};
|
|
99
|
+
declare function defineJob<TPayload, TResult>(definition: JobDefinitionWith<SpoolTriggerDeclaration, TPayload, TResult> & {
|
|
100
|
+
pace: PacePolicy;
|
|
101
|
+
}): SpoolFedJob<TPayload, TResult>;
|
|
102
|
+
declare function defineJob<TPayload, TResult>(definition: JobDefinitionWith<CronTriggerFor<TPayload>, TPayload, TResult>): ClockFedJob<TPayload, TResult>;
|
|
103
|
+
declare function defineJob<TPayload, TResult>(definition: UnspooledJobDefinition<TPayload, TResult>): JobDefinition<TPayload, TResult>;
|
|
104
|
+
type JobDefinitionWith<TTrigger, TPayload, TResult> = Omit<JobDefinition<TPayload, TResult>, "trigger"> & {
|
|
105
|
+
trigger: TTrigger;
|
|
106
|
+
};
|
|
107
|
+
type UnspooledJobDefinition<TPayload, TResult> = Omit<JobDefinition<TPayload, TResult>, "trigger"> & {
|
|
108
|
+
trigger?: CronTriggerFor<TPayload>;
|
|
109
|
+
};
|
|
342
110
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
* invalid `durationMs`; otherwise no side effects.
|
|
352
|
-
*
|
|
353
|
-
* NOTE: `now` is captured at builder invocation time, NOT at BatchWriter flush
|
|
354
|
-
* time — `createdAt`, `updatedAt`, and `bucketStart` all reflect the event's
|
|
355
|
-
* wall-clock, not the flush wall-clock. Aggregations are therefore correctly
|
|
356
|
-
* attributed to the hour/day the event occurred, even if the batch flush is
|
|
357
|
-
* delayed by the buffer timer.
|
|
358
|
-
*/
|
|
359
|
-
toIncrementStatsOps(jobType: string, input: IncrementStatsInput): AnyBulkWriteOperation<JobStatsDoc>[];
|
|
360
|
-
incrementStats(jobType: string, input: IncrementStatsInput): Promise<void>;
|
|
361
|
-
getStats(jobType: string, fromDate: Date, toDate: Date, granularity: BucketGranularity): Promise<JobStatsDoc[]>;
|
|
362
|
-
/**
|
|
363
|
-
* Fetches every stats document in the given range + granularity, across ALL
|
|
364
|
-
* jobTypes. Intended for dashboard views that need a cross-jobType overview
|
|
365
|
-
* (e.g., "7-day health per job type") without a prior enumeration step.
|
|
366
|
-
*
|
|
367
|
-
* Result order: `bucketStart` ascending, then `jobType` ascending. Caller is
|
|
368
|
-
* responsible for grouping by jobType client-side if desired.
|
|
369
|
-
*
|
|
370
|
-
* Applies the same `MAX_GET_STATS_RESULTS` cap as `getStats` — a single query
|
|
371
|
-
* across all jobTypes × buckets × granularity is bounded, but the cap keeps
|
|
372
|
-
* the method safe under accidental wide-range queries.
|
|
373
|
-
*/
|
|
374
|
-
getStatsAllJobTypes(fromDate: Date, toDate: Date, granularity: BucketGranularity): Promise<JobStatsDoc[]>;
|
|
375
|
-
private upsertBucket;
|
|
376
|
-
private buildBucketOp;
|
|
377
|
-
private buildBucketPayload;
|
|
378
|
-
private validateDurationMs;
|
|
111
|
+
interface AnyJob {
|
|
112
|
+
queue?: string;
|
|
113
|
+
attempts?: number;
|
|
114
|
+
backoff?: BackoffPolicy;
|
|
115
|
+
trigger?: DeclaredTrigger;
|
|
116
|
+
deduplicate?: DeduplicatePolicy<never>;
|
|
117
|
+
pace?: PacePolicy;
|
|
118
|
+
handler: (ctx: JobContext<never>) => Promise<unknown>;
|
|
379
119
|
}
|
|
380
120
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
* is first observed under jobType A, subsequent occurrences under jobType B do NOT
|
|
389
|
-
* overwrite the stored value. The signature is the identity of the error; a signature
|
|
390
|
-
* appearing across multiple job types indicates shared infrastructure failure (e.g.
|
|
391
|
-
* ECONNRESET from the shared DB) and is worth surfacing on the first-observed job.
|
|
392
|
-
*/
|
|
393
|
-
recordOccurrence(input: RecordOccurrenceInput): Promise<void>;
|
|
394
|
-
/**
|
|
395
|
-
* Builds the bulk write operation for `recordOccurrence` WITHOUT executing it.
|
|
396
|
-
* Returns a single upsert op matching the direct-call shape bit-for-bit.
|
|
397
|
-
*
|
|
398
|
-
* NOTE: `now` is captured at builder invocation time, NOT at BatchWriter flush
|
|
399
|
-
* time — firstSeenAt / lastSeenAt reflect the event's wall-clock, not the
|
|
400
|
-
* flush wall-clock. This preserves the semantic that these timestamps track
|
|
401
|
-
* the error's occurrence, not the observability pipeline's delay.
|
|
402
|
-
*/
|
|
403
|
-
toRecordOccurrenceOp(input: RecordOccurrenceInput): AnyBulkWriteOperation<JobErrorDoc>;
|
|
404
|
-
private buildRecordOccurrencePayload;
|
|
405
|
-
topErrors(options: TopErrorsOptions): Promise<JobErrorDoc[]>;
|
|
121
|
+
interface RavenflowConfig<TJobs extends string = string> {
|
|
122
|
+
defaultQueue: string;
|
|
123
|
+
jobs: Record<TJobs, AnyJob>;
|
|
124
|
+
logger?: LoggerOptions;
|
|
125
|
+
queuesRetention?: QueuesRetentionConfig;
|
|
126
|
+
jobResultsRetentionHours?: number;
|
|
127
|
+
aggregatedResultsRetentionHours?: number;
|
|
406
128
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
protected indexes(): IndexDescriptor[];
|
|
411
|
-
recordFailure(input: RecordFailureInput): Promise<void>;
|
|
412
|
-
/**
|
|
413
|
-
* Builds the bulk write operation for `recordFailure` WITHOUT executing it.
|
|
414
|
-
* Returns a single insertOne op matching the direct-call document shape
|
|
415
|
-
* bit-for-bit. Intended for the event-hooks layer (Story 1.7) to push through
|
|
416
|
-
* a `BatchWriter`. Throws synchronously on invalid input using the same error
|
|
417
|
-
* messages as `recordFailure`.
|
|
418
|
-
*/
|
|
419
|
-
toRecordFailureOp(input: RecordFailureInput): AnyBulkWriteOperation<JobFailureDoc>;
|
|
420
|
-
private buildFailureDoc;
|
|
421
|
-
private validateFailureInput;
|
|
422
|
-
listFailures(options: ListFailuresOptions): Promise<{
|
|
423
|
-
items: JobFailureDoc[];
|
|
424
|
-
total: number;
|
|
425
|
-
}>;
|
|
426
|
-
getFailure(jobId: string): Promise<JobFailureDoc | null>;
|
|
427
|
-
private serializeInputValue;
|
|
428
|
-
private capLogs;
|
|
129
|
+
interface QueuesRetentionConfig {
|
|
130
|
+
completedCount?: number;
|
|
131
|
+
failedCount?: number;
|
|
429
132
|
}
|
|
133
|
+
declare function defineConfig<const T extends RavenflowConfig>(config: T): T;
|
|
430
134
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
getConfig(jobType: string): Promise<JobConfigEntry>;
|
|
435
|
-
setEnabled(jobType: string, enabled: boolean): Promise<void>;
|
|
436
|
-
listAll(): Promise<JobConfigDoc[]>;
|
|
437
|
-
isEnabled(jobType: string): Promise<boolean>;
|
|
438
|
-
/**
|
|
439
|
-
* Idempotent bulk upsert of every registered jobType + its metadata
|
|
440
|
-
* projection (Story 5.1 D5.1-a). Called once per `RavenflowApp` instance
|
|
441
|
-
* inside `initializeMonitoring()`.
|
|
442
|
-
*
|
|
443
|
-
* Semantics:
|
|
444
|
-
* - `$setOnInsert { enabled: true, createdAt }` — the enabled flag is
|
|
445
|
-
* set to the default ONLY on initial insert. An operator-toggled
|
|
446
|
-
* `enabled: false` is NEVER overwritten by a subsequent boot.
|
|
447
|
-
* - `$set { metadata }` — metadata is always refreshed from code config
|
|
448
|
-
* (code is source of truth for non-user-writable fields).
|
|
449
|
-
* - `$currentDate { updatedAt }` — timestamp bumps every call.
|
|
450
|
-
*
|
|
451
|
-
* Metadata projection (narrow + stable — see D5.1-h):
|
|
452
|
-
* - `type`: jobConfig.type (always present in the discriminated union).
|
|
453
|
-
* - `queue`: jobConfig.queue ?? null (null = inherits defaultQueue).
|
|
454
|
-
* - `cron`: jobConfig.cron if present (token-bucket only today), else null.
|
|
455
|
-
*
|
|
456
|
-
* Additional type-specific fields (token-bucket's `rate`, distributed-etl's
|
|
457
|
-
* `steps`) are NOT extracted — BSON can't serialize the function references
|
|
458
|
-
* they contain, and the dashboard surface consumes only `type`/`queue`/`cron`
|
|
459
|
-
* in V1. Future stories can widen this projection without a schema change.
|
|
460
|
-
*
|
|
461
|
-
* Failure mode: `bulkWrite` is the only I/O. Empty input short-circuits
|
|
462
|
-
* because the driver rejects empty ops arrays.
|
|
463
|
-
*/
|
|
464
|
-
ensureEntries(jobs: Record<string, JobConfig>): Promise<void>;
|
|
465
|
-
private validateJobType;
|
|
135
|
+
interface SpoolPurgeReport {
|
|
136
|
+
dropped: number;
|
|
137
|
+
inFlight: number;
|
|
466
138
|
}
|
|
467
139
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
140
|
+
type JobsProxy<TJobs extends Record<string, AnyJob>> = {
|
|
141
|
+
[K in keyof TJobs]: JobProxy<TJobs[K]>;
|
|
142
|
+
};
|
|
143
|
+
type JobProxy<T extends AnyJob> = T extends JobDefinition<infer TPayload, infer TResult> ? SendOrIngest<T, TPayload, TResult> & {
|
|
144
|
+
controls: ControlsOf<T>;
|
|
145
|
+
} : never;
|
|
146
|
+
type SendOrIngest<T extends AnyJob, TPayload, TResult> = T extends {
|
|
147
|
+
trigger: SpoolTriggerDeclaration;
|
|
148
|
+
} ? SpoolIngest<TPayload> : JobSend<TPayload, TResult>;
|
|
149
|
+
interface JobSend<TPayload, TResult> {
|
|
150
|
+
send(params: TPayload, options?: SendOptions): Promise<Job<TPayload, TResult>>;
|
|
151
|
+
}
|
|
152
|
+
interface SendOptions {
|
|
153
|
+
delayMs?: number;
|
|
154
|
+
priority?: number;
|
|
155
|
+
deduplicationId?: string;
|
|
156
|
+
}
|
|
157
|
+
interface SpoolIngest<TItem> {
|
|
158
|
+
push(item: TItem): Promise<string>;
|
|
159
|
+
pushMany(items: TItem[]): Promise<string[]>;
|
|
160
|
+
}
|
|
161
|
+
type ControlsOf<T extends AnyJob> = T extends {
|
|
162
|
+
trigger: SpoolTriggerDeclaration;
|
|
163
|
+
} ? SpoolFedControls : T extends {
|
|
164
|
+
trigger: CronTrigger;
|
|
165
|
+
} ? ClockFedControls : ExecutionControls;
|
|
166
|
+
interface ExecutionControls {
|
|
167
|
+
pauseExecution(): Promise<void>;
|
|
168
|
+
resumeExecution(): Promise<void>;
|
|
169
|
+
}
|
|
170
|
+
interface TriggerControls {
|
|
171
|
+
pauseTrigger(): Promise<void>;
|
|
172
|
+
resumeTrigger(): Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
interface IngestControls {
|
|
175
|
+
pauseIngest(): Promise<void>;
|
|
176
|
+
resumeIngest(): Promise<void>;
|
|
177
|
+
}
|
|
178
|
+
interface ClockFedControls extends ExecutionControls, TriggerControls {
|
|
179
|
+
}
|
|
180
|
+
interface SpoolFedControls extends ExecutionControls, TriggerControls, IngestControls {
|
|
181
|
+
purgeBacklog(): Promise<SpoolPurgeReport>;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
interface RavenflowClient<TConfig extends RavenflowConfig = RavenflowConfig> {
|
|
185
|
+
readonly jobs: JobsProxy<TConfig["jobs"]>;
|
|
186
|
+
close(): Promise<void>;
|
|
478
187
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
private readonly hostname;
|
|
483
|
-
private readonly pid;
|
|
484
|
-
private readonly _workerId;
|
|
485
|
-
private readonly startedAt;
|
|
486
|
-
private readonly clock;
|
|
487
|
-
private timer;
|
|
488
|
-
private started;
|
|
489
|
-
private registered;
|
|
490
|
-
constructor(repo: WorkersRepo, options?: WorkerRegistryOptions);
|
|
491
|
-
get workerId(): string;
|
|
492
|
-
registerQueue(queue: WorkerQueueEntry): Promise<void>;
|
|
493
|
-
start(): Promise<void>;
|
|
494
|
-
stop(): Promise<void>;
|
|
495
|
-
private doHeartbeat;
|
|
496
|
-
private static validateHeartbeatInterval;
|
|
497
|
-
private static validateQueueEntry;
|
|
188
|
+
interface RavenflowClientOptions {
|
|
189
|
+
redis: ConnectionOptions;
|
|
190
|
+
mongo: string;
|
|
498
191
|
}
|
|
499
192
|
|
|
500
|
-
|
|
501
|
-
/** Max ops buffered before a size-triggered flush. Must be in [1000, 5000]. */
|
|
502
|
-
maxBufferSize: number;
|
|
503
|
-
/** Interval between time-triggered flushes in ms. Default 30000. Also used as `maxTimeMS` on bulkWrite. */
|
|
504
|
-
flushIntervalMs?: number;
|
|
505
|
-
}
|
|
193
|
+
declare function createRavenflowClient<TConfig extends RavenflowConfig>(config: TConfig, options: RavenflowClientOptions): RavenflowClient<TConfig>;
|
|
506
194
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
private readonly hardCapSize;
|
|
511
|
-
private readonly flushIntervalMs;
|
|
512
|
-
private buffer;
|
|
513
|
-
private timer;
|
|
514
|
-
private flushing;
|
|
515
|
-
private drained;
|
|
516
|
-
constructor(collection: Collection<T>, config: BatchWriterConfig);
|
|
517
|
-
push(operation: AnyBulkWriteOperation<T>): void;
|
|
518
|
-
drain(): Promise<void>;
|
|
519
|
-
private flush;
|
|
520
|
-
private doFlush;
|
|
521
|
-
private enforceHardCap;
|
|
522
|
-
private startTimer;
|
|
523
|
-
private stopTimer;
|
|
524
|
-
private resetTimer;
|
|
525
|
-
private validateConfig;
|
|
195
|
+
interface RavenflowWorker {
|
|
196
|
+
start(): Promise<void>;
|
|
197
|
+
close(): Promise<void>;
|
|
526
198
|
}
|
|
527
199
|
|
|
528
|
-
interface
|
|
529
|
-
host: string;
|
|
530
|
-
port?: number;
|
|
531
|
-
username?: string;
|
|
532
|
-
password?: string;
|
|
533
|
-
database?: string;
|
|
534
|
-
}
|
|
535
|
-
interface RavenflowAppOptions {
|
|
200
|
+
interface RavenflowWorkerOptions {
|
|
536
201
|
redis: ConnectionOptions;
|
|
537
|
-
mongo
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
enabled?: boolean;
|
|
542
|
-
heartbeatIntervalMs?: number;
|
|
543
|
-
batchWriter?: {
|
|
544
|
-
maxBufferSize?: number;
|
|
545
|
-
flushIntervalMs?: number;
|
|
546
|
-
};
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
declare class RavenflowApp<TConfig extends RavenflowConfig = RavenflowConfig> {
|
|
550
|
-
protected redisConnection: ConnectionOptions;
|
|
551
|
-
protected defaultConcurrency: number;
|
|
552
|
-
protected config: TConfig;
|
|
553
|
-
protected mongoUri: string | null;
|
|
554
|
-
jobs: JobsProxy<TConfig["jobs"]>;
|
|
555
|
-
protected jobConfigs: Record<JobNames<TConfig>, JobConfig>;
|
|
556
|
-
protected queues: QueueStore;
|
|
557
|
-
protected workers: Worker[];
|
|
558
|
-
protected stallWatcher: StallWatcher | null;
|
|
559
|
-
protected workersRepo: WorkersRepo | null;
|
|
560
|
-
protected workerRegistry: WorkerRegistry | null;
|
|
561
|
-
protected jobStatsRepo: JobStatsRepo | null;
|
|
562
|
-
protected jobErrorsRepo: JobErrorsRepo | null;
|
|
563
|
-
protected jobFailuresRepo: JobFailuresRepo | null;
|
|
564
|
-
protected jobConfigsRepo: JobConfigsRepo | null;
|
|
565
|
-
protected jobStatsBatchWriter: BatchWriter<JobStatsDoc> | null;
|
|
566
|
-
protected jobErrorsBatchWriter: BatchWriter<JobErrorDoc> | null;
|
|
567
|
-
protected jobFailuresBatchWriter: BatchWriter<JobFailureDoc> | null;
|
|
568
|
-
protected monitoringInitPromise: Promise<void> | null;
|
|
569
|
-
protected readonly monitoringOptions: {
|
|
570
|
-
enabled: boolean;
|
|
571
|
-
heartbeatIntervalMs: number | undefined;
|
|
572
|
-
batchWriter: BatchWriterConfig;
|
|
573
|
-
};
|
|
574
|
-
constructor(config: TConfig, options: RavenflowAppOptions);
|
|
575
|
-
startWorker(queueName: string, options?: {
|
|
576
|
-
concurrency?: number;
|
|
577
|
-
}): Promise<void>;
|
|
578
|
-
protected initializeMonitoring(queueName: string, concurrency: number): Promise<void>;
|
|
579
|
-
close(): Promise<void>;
|
|
202
|
+
mongo: string;
|
|
203
|
+
queue: string;
|
|
204
|
+
concurrency?: number;
|
|
205
|
+
withdrawal?: WithdrawalOptions;
|
|
580
206
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
declare function captureJobLogs(queue: Queue, jobId: string, maxChars: number): Promise<string>;
|
|
585
|
-
|
|
586
|
-
interface EventHooksOptions {
|
|
587
|
-
queue: Queue;
|
|
588
|
-
jobConfigs: Record<string, JobConfig>;
|
|
589
|
-
jobStatsRepo: JobStatsRepo;
|
|
590
|
-
jobErrorsRepo: JobErrorsRepo;
|
|
591
|
-
jobFailuresRepo: JobFailuresRepo;
|
|
592
|
-
jobStatsBatchWriter: BatchWriter<JobStatsDoc>;
|
|
593
|
-
jobErrorsBatchWriter: BatchWriter<JobErrorDoc>;
|
|
594
|
-
jobFailuresBatchWriter: BatchWriter<JobFailureDoc>;
|
|
595
|
-
logsMaxChars?: number;
|
|
207
|
+
interface WithdrawalOptions {
|
|
208
|
+
afterMs?: number;
|
|
209
|
+
onWithdraw?: (reason: string) => void | Promise<void>;
|
|
596
210
|
}
|
|
597
|
-
declare function attachEventHooks(worker: Worker, options: EventHooksOptions): void;
|
|
598
|
-
|
|
599
|
-
/**
|
|
600
|
-
* Inlined minute-count constants. Mirrors BullMQ's `MetricsTime` enum
|
|
601
|
-
* (bullmq@5.63.1) but severs the import edge so consumers of this constant
|
|
602
|
-
* don't pull BullMQ into their bundle. Values are pure math (minutes in
|
|
603
|
-
* the named window) and therefore stable across BullMQ versions. Lives
|
|
604
|
-
* here instead of `index.ts` to avoid an import cycle
|
|
605
|
-
* (`index.ts` → `./app/index` → `./app/app` → `worker-manager`).
|
|
606
|
-
*/
|
|
607
|
-
declare const METRICS_TIME: {
|
|
608
|
-
readonly ONE_MINUTE: 1;
|
|
609
|
-
readonly FIVE_MINUTES: 5;
|
|
610
|
-
readonly FIFTEEN_MINUTES: 15;
|
|
611
|
-
readonly THIRTY_MINUTES: 30;
|
|
612
|
-
readonly ONE_HOUR: 60;
|
|
613
|
-
readonly ONE_DAY: 1440;
|
|
614
|
-
readonly ONE_WEEK: 10080;
|
|
615
|
-
readonly TWO_WEEKS: 20160;
|
|
616
|
-
readonly ONE_MONTH: 80640;
|
|
617
|
-
};
|
|
618
|
-
/**
|
|
619
|
-
* Default BullMQ metrics configuration applied to every ravenflow-managed
|
|
620
|
-
* Worker. Enables the per-minute data-point collection read by the
|
|
621
|
-
* ravenflow-dashboard Jobs-per-Second indicator (Epic 4 Story 4.2).
|
|
622
|
-
*
|
|
623
|
-
* Without this default, BullMQ's `collectMetrics` Lua function is a no-op on
|
|
624
|
-
* every `moveToFinished` — `queue.getMetrics('completed')` would return
|
|
625
|
-
* `{ meta: { count: 0 }, data: [] }` indefinitely for Ravenflow-managed
|
|
626
|
-
* queues (silent false-negative under real throughput).
|
|
627
|
-
*
|
|
628
|
-
* `ONE_WEEK = 10_080` minutes ≈ 7 days of minute-resolution history at a
|
|
629
|
-
* Redis footprint of ~10 KB/queue/week. Callers may override via the
|
|
630
|
-
* `workerOpts.metrics` parameter on `createWorker` (e.g. to disable
|
|
631
|
-
* collection or pick a shorter window).
|
|
632
|
-
*
|
|
633
|
-
* Frozen so the exported reference cannot be mutated by a caller (shared
|
|
634
|
-
* default would otherwise bleed globally across `createWorker` calls).
|
|
635
|
-
*/
|
|
636
|
-
declare const DEFAULT_WORKER_METRICS: NonNullable<WorkerOptions["metrics"]>;
|
|
637
|
-
|
|
638
|
-
/**
|
|
639
|
-
* Delay (ms) applied to jobs whose jobType is `enabled: false`. After this
|
|
640
|
-
* window BullMQ returns the job to the `waiting` set and a worker picks it
|
|
641
|
-
* up again; the gate re-evaluates. When the jobType re-enables the next
|
|
642
|
-
* attempt passes the check and dispatches normally.
|
|
643
|
-
*
|
|
644
|
-
* 60 seconds strikes the balance between "pause takes effect quickly" and
|
|
645
|
-
* "don't hammer Redis / Mongo with redefer churn" (D5.1-b).
|
|
646
|
-
*/
|
|
647
|
-
declare const DISABLED_JOB_DEFER_DELAY_MS = 60000;
|
|
648
|
-
/**
|
|
649
|
-
* Worker-side defer gate for disabled jobTypes (Story 5.1 D5.1-b).
|
|
650
|
-
*
|
|
651
|
-
* When the jobType's `enabled` flag is `false` in `job_configs`, this
|
|
652
|
-
* helper moves the job to `delayed` with a +60s timestamp, increments
|
|
653
|
-
* the cumulative `disabledDeferCount` on `job.progress`, and throws
|
|
654
|
-
* `DelayedError` — the BullMQ-canonical signal for "I moved this job to
|
|
655
|
-
* delayed, don't mark completed/failed" (verified against
|
|
656
|
-
* node_modules/bullmq/dist/esm/classes/errors/delayed-error.d.ts:9
|
|
657
|
-
* bullmq@5.63.1).
|
|
658
|
-
*
|
|
659
|
-
* When the jobType is enabled (or no row exists — default is `true`),
|
|
660
|
-
* this is a no-op and the caller proceeds to normal dispatch.
|
|
661
|
-
*
|
|
662
|
-
* The `token` argument is the processor lambda's 2nd BullMQ argument
|
|
663
|
-
* (verified against node_modules/bullmq/dist/esm/classes/job.d.ts:444
|
|
664
|
-
* bullmq@5.63.1 — moveToDelayed(timestamp, token?) — passing undefined
|
|
665
|
-
* is accepted but may fail under lock contention with renewLock).
|
|
666
|
-
*/
|
|
667
|
-
declare function deferIfDisabled(job: Job, jobConfigs: Record<string, JobConfig>, jobConfigsRepo: JobConfigsRepo, token: string | undefined): Promise<void>;
|
|
668
|
-
|
|
669
|
-
declare function computeBucketStart(ts: Date, granularity: BucketGranularity): Date;
|
|
670
211
|
|
|
671
|
-
declare function
|
|
212
|
+
declare function createRavenflowWorker(config: RavenflowConfig, options: RavenflowWorkerOptions): RavenflowWorker;
|
|
672
213
|
|
|
673
|
-
export {
|
|
214
|
+
export { type JobDefinition, type RavenflowClient, type RavenflowConfig, type RavenflowWorker, type RavenflowWorkerOptions, createRavenflowClient, createRavenflowWorker, defineConfig, defineJob };
|