@nicnocquee/dataqueue 1.24.0 → 1.26.0-beta.20260223195940
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 +44 -0
- package/ai/build-docs-content.ts +96 -0
- package/ai/build-llms-full.ts +42 -0
- package/ai/docs-content.json +278 -0
- package/ai/rules/advanced.md +132 -0
- package/ai/rules/basic.md +159 -0
- package/ai/rules/react-dashboard.md +83 -0
- package/ai/skills/dataqueue-advanced/SKILL.md +320 -0
- package/ai/skills/dataqueue-core/SKILL.md +234 -0
- package/ai/skills/dataqueue-react/SKILL.md +189 -0
- package/dist/cli.cjs +1149 -14
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.d.cts +66 -1
- package/dist/cli.d.ts +66 -1
- package/dist/cli.js +1146 -13
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +4630 -928
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1033 -15
- package/dist/index.d.ts +1033 -15
- package/dist/index.js +4626 -929
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.cjs +186 -0
- package/dist/mcp-server.cjs.map +1 -0
- package/dist/mcp-server.d.cts +32 -0
- package/dist/mcp-server.d.ts +32 -0
- package/dist/mcp-server.js +175 -0
- package/dist/mcp-server.js.map +1 -0
- package/migrations/1751131910825_add_timeout_seconds_to_job_queue.sql +2 -2
- package/migrations/1751186053000_add_job_events_table.sql +12 -8
- package/migrations/1751984773000_add_tags_to_job_queue.sql +1 -1
- package/migrations/1765809419000_add_force_kill_on_timeout_to_job_queue.sql +1 -1
- package/migrations/1771100000000_add_idempotency_key_to_job_queue.sql +7 -0
- package/migrations/1781200000000_add_wait_support.sql +12 -0
- package/migrations/1781200000001_create_waitpoints_table.sql +18 -0
- package/migrations/1781200000002_add_performance_indexes.sql +34 -0
- package/migrations/1781200000003_add_progress_to_job_queue.sql +7 -0
- package/migrations/1781200000004_create_cron_schedules_table.sql +33 -0
- package/migrations/1781200000005_add_retry_config_to_job_queue.sql +17 -0
- package/package.json +40 -23
- package/src/backend.ts +328 -0
- package/src/backends/postgres.ts +2040 -0
- package/src/backends/redis-scripts.ts +865 -0
- package/src/backends/redis.test.ts +1906 -0
- package/src/backends/redis.ts +1792 -0
- package/src/cli.test.ts +82 -6
- package/src/cli.ts +73 -10
- package/src/cron.test.ts +126 -0
- package/src/cron.ts +40 -0
- package/src/db-util.ts +4 -2
- package/src/index.test.ts +688 -1
- package/src/index.ts +277 -39
- package/src/init-command.test.ts +449 -0
- package/src/init-command.ts +709 -0
- package/src/install-mcp-command.test.ts +216 -0
- package/src/install-mcp-command.ts +185 -0
- package/src/install-rules-command.test.ts +218 -0
- package/src/install-rules-command.ts +233 -0
- package/src/install-skills-command.test.ts +176 -0
- package/src/install-skills-command.ts +124 -0
- package/src/mcp-server.test.ts +162 -0
- package/src/mcp-server.ts +231 -0
- package/src/processor.test.ts +559 -18
- package/src/processor.ts +456 -49
- package/src/queue.test.ts +682 -6
- package/src/queue.ts +135 -944
- package/src/supervisor.test.ts +340 -0
- package/src/supervisor.ts +162 -0
- package/src/test-util.ts +32 -0
- package/src/types.ts +726 -17
- package/src/wait.test.ts +698 -0
- package/LICENSE +0 -21
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
|
+
import * as pg from 'pg';
|
|
1
2
|
import { Pool } from 'pg';
|
|
3
|
+
import { Cron } from 'croner';
|
|
2
4
|
|
|
3
5
|
type JobType<PayloadMap> = keyof PayloadMap & string;
|
|
6
|
+
/**
|
|
7
|
+
* Abstract database client interface for transactional job creation.
|
|
8
|
+
* Compatible with `pg.Pool`, `pg.PoolClient`, `pg.Client`, or any object
|
|
9
|
+
* that exposes a `.query()` method matching the `pg` signature.
|
|
10
|
+
*/
|
|
11
|
+
interface DatabaseClient {
|
|
12
|
+
query(text: string, values?: any[]): Promise<{
|
|
13
|
+
rows: any[];
|
|
14
|
+
rowCount: number | null;
|
|
15
|
+
}>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Options for `addJob()` beyond the job itself.
|
|
19
|
+
* Use `db` to insert the job within an existing database transaction.
|
|
20
|
+
*/
|
|
21
|
+
interface AddJobOptions {
|
|
22
|
+
/**
|
|
23
|
+
* An external database client (e.g., a `pg.PoolClient` inside a transaction).
|
|
24
|
+
* When provided, the INSERT runs on this client instead of the internal pool,
|
|
25
|
+
* so the job is part of the caller's transaction.
|
|
26
|
+
*
|
|
27
|
+
* **PostgreSQL only.** Throws if used with the Redis backend.
|
|
28
|
+
*/
|
|
29
|
+
db?: DatabaseClient;
|
|
30
|
+
}
|
|
4
31
|
interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
5
32
|
jobType: T;
|
|
6
33
|
payload: PayloadMap[T];
|
|
@@ -61,6 +88,38 @@ interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
|
61
88
|
* Tags for this job. Used for grouping, searching, or batch operations.
|
|
62
89
|
*/
|
|
63
90
|
tags?: string[];
|
|
91
|
+
/**
|
|
92
|
+
* Optional idempotency key. When provided, ensures that only one job exists for a given key.
|
|
93
|
+
* If a job with the same idempotency key already exists, `addJob` returns the existing job's ID
|
|
94
|
+
* instead of creating a duplicate.
|
|
95
|
+
*
|
|
96
|
+
* Useful for preventing duplicate jobs caused by retries, double-clicks, webhook replays,
|
|
97
|
+
* or serverless function re-invocations.
|
|
98
|
+
*
|
|
99
|
+
* The key is unique across the entire `job_queue` table regardless of job status.
|
|
100
|
+
* Once a key exists, it cannot be reused until the job is cleaned up (via `cleanupOldJobs`).
|
|
101
|
+
*/
|
|
102
|
+
idempotencyKey?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Base delay between retries in seconds. When `retryBackoff` is true (the default),
|
|
105
|
+
* this is the base for exponential backoff: `retryDelay * 2^attempts`.
|
|
106
|
+
* When `retryBackoff` is false, retries use this fixed delay.
|
|
107
|
+
* @default 60
|
|
108
|
+
*/
|
|
109
|
+
retryDelay?: number;
|
|
110
|
+
/**
|
|
111
|
+
* Whether to use exponential backoff for retries. When true, delay doubles
|
|
112
|
+
* with each attempt and includes jitter to prevent thundering herd.
|
|
113
|
+
* When false, a fixed `retryDelay` is used between every retry.
|
|
114
|
+
* @default true
|
|
115
|
+
*/
|
|
116
|
+
retryBackoff?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Maximum delay between retries in seconds. Caps the exponential backoff
|
|
119
|
+
* so retries never wait longer than this value. Only meaningful when
|
|
120
|
+
* `retryBackoff` is true. No limit when omitted.
|
|
121
|
+
*/
|
|
122
|
+
retryDelayMax?: number;
|
|
64
123
|
}
|
|
65
124
|
/**
|
|
66
125
|
* Options for editing a pending job.
|
|
@@ -79,7 +138,9 @@ declare enum JobEventType {
|
|
|
79
138
|
Failed = "failed",
|
|
80
139
|
Cancelled = "cancelled",
|
|
81
140
|
Retried = "retried",
|
|
82
|
-
Edited = "edited"
|
|
141
|
+
Edited = "edited",
|
|
142
|
+
Prolonged = "prolonged",
|
|
143
|
+
Waiting = "waiting"
|
|
83
144
|
}
|
|
84
145
|
interface JobEvent {
|
|
85
146
|
id: number;
|
|
@@ -93,7 +154,7 @@ declare enum FailureReason {
|
|
|
93
154
|
HandlerError = "handler_error",
|
|
94
155
|
NoHandler = "no_handler"
|
|
95
156
|
}
|
|
96
|
-
type JobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled';
|
|
157
|
+
type JobStatus = 'pending' | 'processing' | 'completed' | 'failed' | 'cancelled' | 'waiting';
|
|
97
158
|
interface JobRecord<PayloadMap, T extends JobType<PayloadMap>> {
|
|
98
159
|
id: number;
|
|
99
160
|
jobType: T;
|
|
@@ -150,8 +211,202 @@ interface JobRecord<PayloadMap, T extends JobType<PayloadMap>> {
|
|
|
150
211
|
* Tags for this job. Used for grouping, searching, or batch operations.
|
|
151
212
|
*/
|
|
152
213
|
tags?: string[];
|
|
214
|
+
/**
|
|
215
|
+
* The idempotency key for this job, if one was provided when the job was created.
|
|
216
|
+
*/
|
|
217
|
+
idempotencyKey?: string | null;
|
|
218
|
+
/**
|
|
219
|
+
* The time the job is waiting until (for time-based waits).
|
|
220
|
+
*/
|
|
221
|
+
waitUntil?: Date | null;
|
|
222
|
+
/**
|
|
223
|
+
* The waitpoint token ID the job is waiting for (for token-based waits).
|
|
224
|
+
*/
|
|
225
|
+
waitTokenId?: string | null;
|
|
226
|
+
/**
|
|
227
|
+
* Step data for the job. Stores completed step results for replay on re-invocation.
|
|
228
|
+
*/
|
|
229
|
+
stepData?: Record<string, any>;
|
|
230
|
+
/**
|
|
231
|
+
* Progress percentage for the job (0-100), or null if no progress has been reported.
|
|
232
|
+
* Updated by the handler via `ctx.setProgress(percent)`.
|
|
233
|
+
*/
|
|
234
|
+
progress?: number | null;
|
|
235
|
+
/**
|
|
236
|
+
* Base delay between retries in seconds, or null if using legacy default.
|
|
237
|
+
*/
|
|
238
|
+
retryDelay?: number | null;
|
|
239
|
+
/**
|
|
240
|
+
* Whether exponential backoff is enabled for retries, or null if using legacy default.
|
|
241
|
+
*/
|
|
242
|
+
retryBackoff?: boolean | null;
|
|
243
|
+
/**
|
|
244
|
+
* Maximum delay cap for retries in seconds, or null if no cap.
|
|
245
|
+
*/
|
|
246
|
+
retryDelayMax?: number | null;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Callback registered via `onTimeout`. Invoked when the timeout fires, before the AbortSignal is triggered.
|
|
250
|
+
* Return a number (ms) to extend the timeout, or return nothing to let the timeout proceed.
|
|
251
|
+
*/
|
|
252
|
+
type OnTimeoutCallback = () => number | void | undefined;
|
|
253
|
+
/**
|
|
254
|
+
* Context object passed to job handlers as the third argument.
|
|
255
|
+
* Provides mechanisms to extend the job's timeout while it's running,
|
|
256
|
+
* as well as step tracking and wait capabilities.
|
|
257
|
+
*/
|
|
258
|
+
interface JobContext {
|
|
259
|
+
/**
|
|
260
|
+
* Proactively reset the timeout deadline.
|
|
261
|
+
* - If `ms` is provided, sets the deadline to `ms` milliseconds from now.
|
|
262
|
+
* - If omitted, resets the deadline to the original `timeoutMs` from now (heartbeat-style).
|
|
263
|
+
* - No-op if the job has no timeout set or if `forceKillOnTimeout` is true.
|
|
264
|
+
*/
|
|
265
|
+
prolong: (ms?: number) => void;
|
|
266
|
+
/**
|
|
267
|
+
* Register a callback that is invoked when the timeout fires, **before** the AbortSignal is triggered.
|
|
268
|
+
* - If the callback returns a number > 0, the timeout is reset to that many ms from now.
|
|
269
|
+
* - If the callback returns `undefined`, `null`, `0`, or a negative number, the timeout proceeds normally.
|
|
270
|
+
* - The callback may be invoked multiple times if the job keeps extending.
|
|
271
|
+
* - Only one callback can be registered; subsequent calls replace the previous one.
|
|
272
|
+
* - No-op if the job has no timeout set or if `forceKillOnTimeout` is true.
|
|
273
|
+
*/
|
|
274
|
+
onTimeout: (callback: OnTimeoutCallback) => void;
|
|
275
|
+
/**
|
|
276
|
+
* Execute a named step with memoization. If the step was already completed
|
|
277
|
+
* in a previous invocation (e.g., before a wait), the cached result is returned
|
|
278
|
+
* without re-executing the function.
|
|
279
|
+
*
|
|
280
|
+
* Step names must be unique within a handler and stable across re-invocations.
|
|
281
|
+
*
|
|
282
|
+
* @param stepName - A unique identifier for this step.
|
|
283
|
+
* @param fn - The function to execute. Its return value is cached.
|
|
284
|
+
* @returns The result of the step (from cache or fresh execution).
|
|
285
|
+
*/
|
|
286
|
+
run: <T>(stepName: string, fn: () => Promise<T>) => Promise<T>;
|
|
287
|
+
/**
|
|
288
|
+
* Wait for a specified duration before continuing execution.
|
|
289
|
+
* The job will be paused and resumed after the duration elapses.
|
|
290
|
+
*
|
|
291
|
+
* When this is called, the handler throws a WaitSignal internally.
|
|
292
|
+
* The job is set to 'waiting' status and will be re-invoked after the
|
|
293
|
+
* specified duration. All steps completed via `ctx.run()` before this
|
|
294
|
+
* call will be replayed from cache on re-invocation.
|
|
295
|
+
*
|
|
296
|
+
* @param duration - The duration to wait (e.g., `{ hours: 1 }`, `{ days: 7 }`).
|
|
297
|
+
*/
|
|
298
|
+
waitFor: (duration: WaitDuration) => Promise<void>;
|
|
299
|
+
/**
|
|
300
|
+
* Wait until a specific date/time before continuing execution.
|
|
301
|
+
* The job will be paused and resumed at (or after) the specified date.
|
|
302
|
+
*
|
|
303
|
+
* @param date - The date to wait until.
|
|
304
|
+
*/
|
|
305
|
+
waitUntil: (date: Date) => Promise<void>;
|
|
306
|
+
/**
|
|
307
|
+
* Create a waitpoint token. The token can be completed externally
|
|
308
|
+
* (by calling `jobQueue.completeToken()`) to resume a waiting job.
|
|
309
|
+
*
|
|
310
|
+
* Tokens can be created inside handlers or outside (via `jobQueue.createToken()`).
|
|
311
|
+
*
|
|
312
|
+
* @param options - Optional token configuration (timeout, tags).
|
|
313
|
+
* @returns A token object with `id` that can be passed to `waitForToken()`.
|
|
314
|
+
*/
|
|
315
|
+
createToken: (options?: CreateTokenOptions) => Promise<WaitToken>;
|
|
316
|
+
/**
|
|
317
|
+
* Wait for a waitpoint token to be completed by an external signal.
|
|
318
|
+
* The job will be paused until `jobQueue.completeToken(tokenId, data)` is called
|
|
319
|
+
* or the token times out.
|
|
320
|
+
*
|
|
321
|
+
* @param tokenId - The ID of the token to wait for.
|
|
322
|
+
* @returns A result object indicating success or timeout.
|
|
323
|
+
*/
|
|
324
|
+
waitForToken: <T = any>(tokenId: string) => Promise<WaitTokenResult<T>>;
|
|
325
|
+
/**
|
|
326
|
+
* Report progress for this job (0-100).
|
|
327
|
+
* The value is persisted to the database and can be read by clients
|
|
328
|
+
* via `getJob()` or the React SDK's `useJob()` hook.
|
|
329
|
+
*
|
|
330
|
+
* @param percent - Progress percentage (0-100). Values are rounded to the nearest integer.
|
|
331
|
+
* @throws If percent is outside the 0-100 range.
|
|
332
|
+
*/
|
|
333
|
+
setProgress: (percent: number) => Promise<void>;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Duration specification for `ctx.waitFor()`.
|
|
337
|
+
* At least one field must be provided. Fields are additive.
|
|
338
|
+
*/
|
|
339
|
+
interface WaitDuration {
|
|
340
|
+
seconds?: number;
|
|
341
|
+
minutes?: number;
|
|
342
|
+
hours?: number;
|
|
343
|
+
days?: number;
|
|
344
|
+
weeks?: number;
|
|
345
|
+
months?: number;
|
|
346
|
+
years?: number;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Options for creating a waitpoint token.
|
|
350
|
+
*/
|
|
351
|
+
interface CreateTokenOptions {
|
|
352
|
+
/**
|
|
353
|
+
* Maximum time to wait for the token to be completed.
|
|
354
|
+
* Accepts a duration string like '10m', '1h', '24h', '7d'.
|
|
355
|
+
* If not provided, the token has no timeout.
|
|
356
|
+
*/
|
|
357
|
+
timeout?: string;
|
|
358
|
+
/**
|
|
359
|
+
* Tags to attach to the token for filtering.
|
|
360
|
+
*/
|
|
361
|
+
tags?: string[];
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* A waitpoint token returned by `ctx.createToken()`.
|
|
365
|
+
*/
|
|
366
|
+
interface WaitToken {
|
|
367
|
+
/** The unique token ID. */
|
|
368
|
+
id: string;
|
|
153
369
|
}
|
|
154
|
-
|
|
370
|
+
/**
|
|
371
|
+
* Result of `ctx.waitForToken()`.
|
|
372
|
+
*/
|
|
373
|
+
type WaitTokenResult<T = any> = {
|
|
374
|
+
ok: true;
|
|
375
|
+
output: T;
|
|
376
|
+
} | {
|
|
377
|
+
ok: false;
|
|
378
|
+
error: string;
|
|
379
|
+
};
|
|
380
|
+
/**
|
|
381
|
+
* Internal signal thrown by wait methods to pause handler execution.
|
|
382
|
+
* This is not a real error -- the processor catches it and transitions the job to 'waiting' status.
|
|
383
|
+
*/
|
|
384
|
+
declare class WaitSignal extends Error {
|
|
385
|
+
readonly type: 'duration' | 'date' | 'token';
|
|
386
|
+
readonly waitUntil: Date | undefined;
|
|
387
|
+
readonly tokenId: string | undefined;
|
|
388
|
+
readonly stepData: Record<string, any>;
|
|
389
|
+
readonly isWaitSignal = true;
|
|
390
|
+
constructor(type: 'duration' | 'date' | 'token', waitUntil: Date | undefined, tokenId: string | undefined, stepData: Record<string, any>);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Status of a waitpoint token.
|
|
394
|
+
*/
|
|
395
|
+
type WaitpointStatus = 'waiting' | 'completed' | 'timed_out';
|
|
396
|
+
/**
|
|
397
|
+
* A waitpoint record from the database.
|
|
398
|
+
*/
|
|
399
|
+
interface WaitpointRecord {
|
|
400
|
+
id: string;
|
|
401
|
+
jobId: number | null;
|
|
402
|
+
status: WaitpointStatus;
|
|
403
|
+
output: any;
|
|
404
|
+
timeoutAt: Date | null;
|
|
405
|
+
createdAt: Date;
|
|
406
|
+
completedAt: Date | null;
|
|
407
|
+
tags: string[] | null;
|
|
408
|
+
}
|
|
409
|
+
type JobHandler<PayloadMap, T extends keyof PayloadMap> = (payload: PayloadMap[T], signal: AbortSignal, ctx: JobContext) => Promise<void>;
|
|
155
410
|
type JobHandlers<PayloadMap> = {
|
|
156
411
|
[K in keyof PayloadMap]: JobHandler<PayloadMap, K>;
|
|
157
412
|
};
|
|
@@ -195,8 +450,18 @@ interface Processor {
|
|
|
195
450
|
startInBackground: () => void;
|
|
196
451
|
/**
|
|
197
452
|
* Stop the job processor that runs in the background.
|
|
453
|
+
* Does not wait for in-flight jobs to complete.
|
|
198
454
|
*/
|
|
199
455
|
stop: () => void;
|
|
456
|
+
/**
|
|
457
|
+
* Stop the job processor and wait for all in-flight jobs to complete.
|
|
458
|
+
* Useful for graceful shutdown (e.g., SIGTERM handling).
|
|
459
|
+
* No new batches will be started after calling this method.
|
|
460
|
+
*
|
|
461
|
+
* @param timeoutMs - Maximum time to wait for in-flight jobs (default: 30000ms).
|
|
462
|
+
* If jobs don't complete within this time, the promise resolves anyway.
|
|
463
|
+
*/
|
|
464
|
+
stopAndDrain: (timeoutMs?: number) => Promise<void>;
|
|
200
465
|
/**
|
|
201
466
|
* Check if the job processor is running.
|
|
202
467
|
*/
|
|
@@ -209,6 +474,88 @@ interface Processor {
|
|
|
209
474
|
*/
|
|
210
475
|
start: () => Promise<number>;
|
|
211
476
|
}
|
|
477
|
+
interface SupervisorOptions {
|
|
478
|
+
/**
|
|
479
|
+
* How often the maintenance loop runs, in milliseconds.
|
|
480
|
+
* @default 60000 (1 minute)
|
|
481
|
+
*/
|
|
482
|
+
intervalMs?: number;
|
|
483
|
+
/**
|
|
484
|
+
* Reclaim jobs stuck in `processing` longer than this many minutes.
|
|
485
|
+
* @default 10
|
|
486
|
+
*/
|
|
487
|
+
stuckJobsTimeoutMinutes?: number;
|
|
488
|
+
/**
|
|
489
|
+
* Auto-delete completed jobs older than this many days. Set to 0 to disable.
|
|
490
|
+
* @default 30
|
|
491
|
+
*/
|
|
492
|
+
cleanupJobsDaysToKeep?: number;
|
|
493
|
+
/**
|
|
494
|
+
* Auto-delete job events older than this many days. Set to 0 to disable.
|
|
495
|
+
* @default 30
|
|
496
|
+
*/
|
|
497
|
+
cleanupEventsDaysToKeep?: number;
|
|
498
|
+
/**
|
|
499
|
+
* Batch size for cleanup deletions.
|
|
500
|
+
* @default 1000
|
|
501
|
+
*/
|
|
502
|
+
cleanupBatchSize?: number;
|
|
503
|
+
/**
|
|
504
|
+
* Whether to reclaim stuck jobs each cycle.
|
|
505
|
+
* @default true
|
|
506
|
+
*/
|
|
507
|
+
reclaimStuckJobs?: boolean;
|
|
508
|
+
/**
|
|
509
|
+
* Whether to expire timed-out waitpoint tokens each cycle.
|
|
510
|
+
* @default true
|
|
511
|
+
*/
|
|
512
|
+
expireTimedOutTokens?: boolean;
|
|
513
|
+
/**
|
|
514
|
+
* Called when a maintenance task throws. One failure does not block other tasks.
|
|
515
|
+
* @default console.error
|
|
516
|
+
*/
|
|
517
|
+
onError?: (error: Error) => void;
|
|
518
|
+
/** Enable verbose logging. */
|
|
519
|
+
verbose?: boolean;
|
|
520
|
+
}
|
|
521
|
+
interface SupervisorRunResult {
|
|
522
|
+
/** Number of stuck jobs reclaimed back to pending. */
|
|
523
|
+
reclaimedJobs: number;
|
|
524
|
+
/** Number of old completed jobs deleted. */
|
|
525
|
+
cleanedUpJobs: number;
|
|
526
|
+
/** Number of old job events deleted. */
|
|
527
|
+
cleanedUpEvents: number;
|
|
528
|
+
/** Number of timed-out waitpoint tokens expired. */
|
|
529
|
+
expiredTokens: number;
|
|
530
|
+
}
|
|
531
|
+
interface Supervisor {
|
|
532
|
+
/**
|
|
533
|
+
* Run all maintenance tasks once and return the results.
|
|
534
|
+
* Ideal for serverless or cron-triggered invocations.
|
|
535
|
+
*/
|
|
536
|
+
start: () => Promise<SupervisorRunResult>;
|
|
537
|
+
/**
|
|
538
|
+
* Start the maintenance loop in the background.
|
|
539
|
+
* Runs every `intervalMs` milliseconds (default: 60 000).
|
|
540
|
+
* Call `stop()` or `stopAndDrain()` to halt the loop.
|
|
541
|
+
*/
|
|
542
|
+
startInBackground: () => void;
|
|
543
|
+
/**
|
|
544
|
+
* Stop the background maintenance loop immediately.
|
|
545
|
+
* Does not wait for an in-flight maintenance run to complete.
|
|
546
|
+
*/
|
|
547
|
+
stop: () => void;
|
|
548
|
+
/**
|
|
549
|
+
* Stop the background loop and wait for the current maintenance run
|
|
550
|
+
* (if any) to finish before resolving.
|
|
551
|
+
*
|
|
552
|
+
* @param timeoutMs - Maximum time to wait (default: 30 000 ms).
|
|
553
|
+
* If the run does not finish within this time the promise resolves anyway.
|
|
554
|
+
*/
|
|
555
|
+
stopAndDrain: (timeoutMs?: number) => Promise<void>;
|
|
556
|
+
/** Whether the background maintenance loop is currently running. */
|
|
557
|
+
isRunning: () => boolean;
|
|
558
|
+
}
|
|
212
559
|
interface DatabaseSSLConfig {
|
|
213
560
|
/**
|
|
214
561
|
* CA certificate as PEM string or file path. If the value starts with 'file://', it will be loaded from file, otherwise treated as PEM string.
|
|
@@ -227,8 +574,16 @@ interface DatabaseSSLConfig {
|
|
|
227
574
|
*/
|
|
228
575
|
rejectUnauthorized?: boolean;
|
|
229
576
|
}
|
|
230
|
-
|
|
231
|
-
|
|
577
|
+
/**
|
|
578
|
+
* Configuration for PostgreSQL backend (default).
|
|
579
|
+
* Backward-compatible: omitting `backend` defaults to 'postgres'.
|
|
580
|
+
*
|
|
581
|
+
* Provide either `databaseConfig` (the library creates a pool) or `pool`
|
|
582
|
+
* (bring your own `pg.Pool`). At least one must be set.
|
|
583
|
+
*/
|
|
584
|
+
interface PostgresJobQueueConfig {
|
|
585
|
+
backend?: 'postgres';
|
|
586
|
+
databaseConfig?: {
|
|
232
587
|
connectionString?: string;
|
|
233
588
|
host?: string;
|
|
234
589
|
port?: number;
|
|
@@ -236,15 +591,196 @@ interface JobQueueConfig {
|
|
|
236
591
|
user?: string;
|
|
237
592
|
password?: string;
|
|
238
593
|
ssl?: DatabaseSSLConfig;
|
|
594
|
+
/**
|
|
595
|
+
* Maximum number of clients in the pool (default: 10).
|
|
596
|
+
* Increase when running multiple processors in the same process.
|
|
597
|
+
*/
|
|
598
|
+
max?: number;
|
|
599
|
+
/**
|
|
600
|
+
* Minimum number of idle clients in the pool (default: 0).
|
|
601
|
+
*/
|
|
602
|
+
min?: number;
|
|
603
|
+
/**
|
|
604
|
+
* Milliseconds a client must sit idle before being closed (default: 10000).
|
|
605
|
+
*/
|
|
606
|
+
idleTimeoutMillis?: number;
|
|
607
|
+
/**
|
|
608
|
+
* Milliseconds to wait for a connection before throwing (default: 0, no timeout).
|
|
609
|
+
*/
|
|
610
|
+
connectionTimeoutMillis?: number;
|
|
239
611
|
};
|
|
612
|
+
/**
|
|
613
|
+
* Bring your own `pg.Pool` instance. When provided, `databaseConfig` is
|
|
614
|
+
* ignored and the library will not close the pool on shutdown.
|
|
615
|
+
*/
|
|
616
|
+
pool?: pg.Pool;
|
|
240
617
|
verbose?: boolean;
|
|
241
618
|
}
|
|
619
|
+
/**
|
|
620
|
+
* TLS configuration for the Redis connection.
|
|
621
|
+
*/
|
|
622
|
+
interface RedisTLSConfig {
|
|
623
|
+
ca?: string;
|
|
624
|
+
cert?: string;
|
|
625
|
+
key?: string;
|
|
626
|
+
rejectUnauthorized?: boolean;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Configuration for Redis backend.
|
|
630
|
+
*
|
|
631
|
+
* Provide either `redisConfig` (the library creates an ioredis client) or
|
|
632
|
+
* `client` (bring your own ioredis instance). At least one must be set.
|
|
633
|
+
*/
|
|
634
|
+
interface RedisJobQueueConfig {
|
|
635
|
+
backend: 'redis';
|
|
636
|
+
redisConfig?: {
|
|
637
|
+
/** Redis URL (e.g. redis://localhost:6379) */
|
|
638
|
+
url?: string;
|
|
639
|
+
host?: string;
|
|
640
|
+
port?: number;
|
|
641
|
+
password?: string;
|
|
642
|
+
/** Redis database number (default: 0) */
|
|
643
|
+
db?: number;
|
|
644
|
+
tls?: RedisTLSConfig;
|
|
645
|
+
/**
|
|
646
|
+
* Key prefix for all Redis keys (default: 'dq:').
|
|
647
|
+
* Useful to namespace multiple queues in the same Redis instance.
|
|
648
|
+
*/
|
|
649
|
+
keyPrefix?: string;
|
|
650
|
+
};
|
|
651
|
+
/**
|
|
652
|
+
* Bring your own ioredis client instance. When provided, `redisConfig` is
|
|
653
|
+
* ignored and the library will not close the client on shutdown.
|
|
654
|
+
* Use `keyPrefix` to set the key namespace (default: 'dq:').
|
|
655
|
+
*/
|
|
656
|
+
client?: unknown;
|
|
657
|
+
/**
|
|
658
|
+
* Key prefix when using an external `client`. Ignored when `redisConfig` is used
|
|
659
|
+
* (set `redisConfig.keyPrefix` instead). Default: 'dq:'.
|
|
660
|
+
*/
|
|
661
|
+
keyPrefix?: string;
|
|
662
|
+
verbose?: boolean;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Job queue configuration — discriminated union.
|
|
666
|
+
* If `backend` is omitted, PostgreSQL is used.
|
|
667
|
+
*/
|
|
668
|
+
type JobQueueConfig = PostgresJobQueueConfig | RedisJobQueueConfig;
|
|
669
|
+
/** @deprecated Use JobQueueConfig instead. Alias kept for backward compat. */
|
|
670
|
+
type JobQueueConfigLegacy = PostgresJobQueueConfig;
|
|
242
671
|
type TagQueryMode = 'exact' | 'all' | 'any' | 'none';
|
|
672
|
+
/**
|
|
673
|
+
* Status of a cron schedule.
|
|
674
|
+
*/
|
|
675
|
+
type CronScheduleStatus = 'active' | 'paused';
|
|
676
|
+
/**
|
|
677
|
+
* Options for creating a recurring cron schedule.
|
|
678
|
+
* Each schedule defines a recurring job that is automatically enqueued
|
|
679
|
+
* when its cron expression matches.
|
|
680
|
+
*/
|
|
681
|
+
interface CronScheduleOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
682
|
+
/** Unique human-readable name for the schedule. */
|
|
683
|
+
scheduleName: string;
|
|
684
|
+
/** Standard cron expression (5 fields, e.g. "0 * * * *"). */
|
|
685
|
+
cronExpression: string;
|
|
686
|
+
/** Job type from the PayloadMap. */
|
|
687
|
+
jobType: T;
|
|
688
|
+
/** Payload for each job instance. */
|
|
689
|
+
payload: PayloadMap[T];
|
|
690
|
+
/** Maximum retry attempts for each job instance (default: 3). */
|
|
691
|
+
maxAttempts?: number;
|
|
692
|
+
/** Priority for each job instance (default: 0). */
|
|
693
|
+
priority?: number;
|
|
694
|
+
/** Timeout in milliseconds for each job instance. */
|
|
695
|
+
timeoutMs?: number;
|
|
696
|
+
/** Whether to force-kill the job on timeout (default: false). */
|
|
697
|
+
forceKillOnTimeout?: boolean;
|
|
698
|
+
/** Tags for each job instance. */
|
|
699
|
+
tags?: string[];
|
|
700
|
+
/** IANA timezone string for cron evaluation (default: "UTC"). */
|
|
701
|
+
timezone?: string;
|
|
702
|
+
/**
|
|
703
|
+
* Whether to allow overlapping job instances (default: false).
|
|
704
|
+
* When false, a new job will not be enqueued if the previous instance
|
|
705
|
+
* is still pending, processing, or waiting.
|
|
706
|
+
*/
|
|
707
|
+
allowOverlap?: boolean;
|
|
708
|
+
/** Base delay between retries in seconds for each job instance (default: 60). */
|
|
709
|
+
retryDelay?: number;
|
|
710
|
+
/** Whether to use exponential backoff for retries (default: true). */
|
|
711
|
+
retryBackoff?: boolean;
|
|
712
|
+
/** Maximum delay cap for retries in seconds. */
|
|
713
|
+
retryDelayMax?: number;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* A persisted cron schedule record.
|
|
717
|
+
*/
|
|
718
|
+
interface CronScheduleRecord {
|
|
719
|
+
id: number;
|
|
720
|
+
scheduleName: string;
|
|
721
|
+
cronExpression: string;
|
|
722
|
+
jobType: string;
|
|
723
|
+
payload: any;
|
|
724
|
+
maxAttempts: number;
|
|
725
|
+
priority: number;
|
|
726
|
+
timeoutMs: number | null;
|
|
727
|
+
forceKillOnTimeout: boolean;
|
|
728
|
+
tags: string[] | undefined;
|
|
729
|
+
timezone: string;
|
|
730
|
+
allowOverlap: boolean;
|
|
731
|
+
status: CronScheduleStatus;
|
|
732
|
+
lastEnqueuedAt: Date | null;
|
|
733
|
+
lastJobId: number | null;
|
|
734
|
+
nextRunAt: Date | null;
|
|
735
|
+
createdAt: Date;
|
|
736
|
+
updatedAt: Date;
|
|
737
|
+
retryDelay: number | null;
|
|
738
|
+
retryBackoff: boolean | null;
|
|
739
|
+
retryDelayMax: number | null;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Options for editing an existing cron schedule.
|
|
743
|
+
* All fields are optional; only provided fields are updated.
|
|
744
|
+
*/
|
|
745
|
+
interface EditCronScheduleOptions {
|
|
746
|
+
cronExpression?: string;
|
|
747
|
+
payload?: any;
|
|
748
|
+
maxAttempts?: number;
|
|
749
|
+
priority?: number;
|
|
750
|
+
timeoutMs?: number | null;
|
|
751
|
+
forceKillOnTimeout?: boolean;
|
|
752
|
+
tags?: string[] | null;
|
|
753
|
+
timezone?: string;
|
|
754
|
+
allowOverlap?: boolean;
|
|
755
|
+
retryDelay?: number | null;
|
|
756
|
+
retryBackoff?: boolean | null;
|
|
757
|
+
retryDelayMax?: number | null;
|
|
758
|
+
}
|
|
243
759
|
interface JobQueue<PayloadMap> {
|
|
244
760
|
/**
|
|
245
761
|
* Add a job to the job queue.
|
|
762
|
+
*
|
|
763
|
+
* @param job - The job to enqueue.
|
|
764
|
+
* @param options - Optional. Pass `{ db }` with an external database client
|
|
765
|
+
* to insert the job within an existing transaction (PostgreSQL only).
|
|
766
|
+
*/
|
|
767
|
+
addJob: <T extends JobType<PayloadMap>>(job: JobOptions<PayloadMap, T>, options?: AddJobOptions) => Promise<number>;
|
|
768
|
+
/**
|
|
769
|
+
* Add multiple jobs to the queue in a single operation.
|
|
770
|
+
*
|
|
771
|
+
* More efficient than calling `addJob` in a loop because it batches the
|
|
772
|
+
* INSERT into a single database round-trip (PostgreSQL) or a single
|
|
773
|
+
* atomic Lua script (Redis).
|
|
774
|
+
*
|
|
775
|
+
* Returns an array of job IDs in the same order as the input array.
|
|
776
|
+
* Each job may independently have an `idempotencyKey`; duplicates
|
|
777
|
+
* resolve to the existing job's ID without creating a new row.
|
|
778
|
+
*
|
|
779
|
+
* @param jobs - Array of jobs to enqueue.
|
|
780
|
+
* @param options - Optional. Pass `{ db }` with an external database client
|
|
781
|
+
* to insert the jobs within an existing transaction (PostgreSQL only).
|
|
246
782
|
*/
|
|
247
|
-
|
|
783
|
+
addJobs: <T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions) => Promise<number[]>;
|
|
248
784
|
/**
|
|
249
785
|
* Get a job by its ID.
|
|
250
786
|
*/
|
|
@@ -271,9 +807,10 @@ interface JobQueue<PayloadMap> {
|
|
|
271
807
|
*/
|
|
272
808
|
getAllJobs: <T extends JobType<PayloadMap>>(limit?: number, offset?: number) => Promise<JobRecord<PayloadMap, T>[]>;
|
|
273
809
|
/**
|
|
274
|
-
* Get jobs by filters.
|
|
275
|
-
|
|
276
|
-
*
|
|
810
|
+
* Get jobs by filters, with pagination support.
|
|
811
|
+
* - Use `cursor` for efficient keyset pagination (recommended for large datasets).
|
|
812
|
+
* - Use `limit` and `offset` for traditional pagination.
|
|
813
|
+
* - Do not combine `cursor` with `offset`.
|
|
277
814
|
*/
|
|
278
815
|
getJobs: <T extends JobType<PayloadMap>>(filters?: {
|
|
279
816
|
jobType?: string;
|
|
@@ -289,7 +826,9 @@ interface JobQueue<PayloadMap> {
|
|
|
289
826
|
values: string[];
|
|
290
827
|
mode?: TagQueryMode;
|
|
291
828
|
};
|
|
292
|
-
|
|
829
|
+
/** Cursor for keyset pagination. Only return jobs with id < cursor. */
|
|
830
|
+
cursor?: number;
|
|
831
|
+
}, limit?: number, offset?: number) => Promise<JobRecord<PayloadMap, T>[]>;
|
|
293
832
|
/**
|
|
294
833
|
* Retry a job given its ID.
|
|
295
834
|
* - This will set the job status back to 'pending', clear the locked_at and locked_by, and allow it to be picked up by other workers.
|
|
@@ -297,8 +836,18 @@ interface JobQueue<PayloadMap> {
|
|
|
297
836
|
retryJob: (jobId: number) => Promise<void>;
|
|
298
837
|
/**
|
|
299
838
|
* Cleanup jobs that are older than the specified number of days.
|
|
839
|
+
* Deletes in batches for scale safety.
|
|
840
|
+
* @param daysToKeep - Number of days to retain completed jobs (default 30).
|
|
841
|
+
* @param batchSize - Number of rows to delete per batch (default 1000 for PostgreSQL, 200 for Redis).
|
|
842
|
+
*/
|
|
843
|
+
cleanupOldJobs: (daysToKeep?: number, batchSize?: number) => Promise<number>;
|
|
844
|
+
/**
|
|
845
|
+
* Cleanup job events that are older than the specified number of days.
|
|
846
|
+
* Deletes in batches for scale safety.
|
|
847
|
+
* @param daysToKeep - Number of days to retain events (default 30).
|
|
848
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
300
849
|
*/
|
|
301
|
-
|
|
850
|
+
cleanupOldJobEvents: (daysToKeep?: number, batchSize?: number) => Promise<number>;
|
|
302
851
|
/**
|
|
303
852
|
* Cancel a job given its ID.
|
|
304
853
|
* - This will set the job status to 'cancelled' and clear the locked_at and locked_by.
|
|
@@ -376,14 +925,460 @@ interface JobQueue<PayloadMap> {
|
|
|
376
925
|
* Create a job processor. Handlers must be provided per-processor.
|
|
377
926
|
*/
|
|
378
927
|
createProcessor: (handlers: JobHandlers<PayloadMap>, options?: ProcessorOptions) => Processor;
|
|
928
|
+
/**
|
|
929
|
+
* Create a background supervisor that automatically reclaims stuck jobs,
|
|
930
|
+
* cleans up old completed jobs/events, and expires timed-out waitpoint
|
|
931
|
+
* tokens on a configurable interval.
|
|
932
|
+
*/
|
|
933
|
+
createSupervisor: (options?: SupervisorOptions) => Supervisor;
|
|
379
934
|
/**
|
|
380
935
|
* Get the job events for a job.
|
|
381
936
|
*/
|
|
382
937
|
getJobEvents: (jobId: number) => Promise<JobEvent[]>;
|
|
383
938
|
/**
|
|
384
|
-
*
|
|
939
|
+
* Create a waitpoint token.
|
|
940
|
+
* Tokens can be completed externally to resume a waiting job.
|
|
941
|
+
* Can be called outside of handlers (e.g., from an API route).
|
|
942
|
+
*
|
|
943
|
+
* @param options - Optional token configuration (timeout, tags).
|
|
944
|
+
* @returns A token object with `id`.
|
|
945
|
+
*/
|
|
946
|
+
createToken: (options?: CreateTokenOptions) => Promise<WaitToken>;
|
|
947
|
+
/**
|
|
948
|
+
* Complete a waitpoint token, resuming the associated waiting job.
|
|
949
|
+
* Can be called from anywhere (API routes, external services, etc.).
|
|
950
|
+
*
|
|
951
|
+
* @param tokenId - The ID of the token to complete.
|
|
952
|
+
* @param data - Optional data to pass to the waiting handler.
|
|
953
|
+
*/
|
|
954
|
+
completeToken: (tokenId: string, data?: any) => Promise<void>;
|
|
955
|
+
/**
|
|
956
|
+
* Retrieve a waitpoint token by its ID.
|
|
957
|
+
*
|
|
958
|
+
* @param tokenId - The ID of the token to retrieve.
|
|
959
|
+
* @returns The token record, or null if not found.
|
|
960
|
+
*/
|
|
961
|
+
getToken: (tokenId: string) => Promise<WaitpointRecord | null>;
|
|
962
|
+
/**
|
|
963
|
+
* Expire timed-out waitpoint tokens and resume their associated jobs.
|
|
964
|
+
* Call this periodically (e.g., alongside `reclaimStuckJobs`).
|
|
965
|
+
*
|
|
966
|
+
* @returns The number of tokens that were expired.
|
|
967
|
+
*/
|
|
968
|
+
expireTimedOutTokens: () => Promise<number>;
|
|
969
|
+
/**
|
|
970
|
+
* Add a recurring cron schedule. The processor automatically enqueues
|
|
971
|
+
* due cron jobs before each batch, so no manual triggering is needed.
|
|
972
|
+
*
|
|
973
|
+
* @returns The ID of the created schedule.
|
|
974
|
+
* @throws If the cron expression is invalid or the schedule name is already taken.
|
|
975
|
+
*/
|
|
976
|
+
addCronJob: <T extends JobType<PayloadMap>>(options: CronScheduleOptions<PayloadMap, T>) => Promise<number>;
|
|
977
|
+
/**
|
|
978
|
+
* Get a cron schedule by its ID.
|
|
979
|
+
*/
|
|
980
|
+
getCronJob: (id: number) => Promise<CronScheduleRecord | null>;
|
|
981
|
+
/**
|
|
982
|
+
* Get a cron schedule by its unique name.
|
|
983
|
+
*/
|
|
984
|
+
getCronJobByName: (name: string) => Promise<CronScheduleRecord | null>;
|
|
985
|
+
/**
|
|
986
|
+
* List all cron schedules, optionally filtered by status.
|
|
987
|
+
*/
|
|
988
|
+
listCronJobs: (status?: CronScheduleStatus) => Promise<CronScheduleRecord[]>;
|
|
989
|
+
/**
|
|
990
|
+
* Remove a cron schedule by its ID. Does not cancel any already-enqueued jobs.
|
|
991
|
+
*/
|
|
992
|
+
removeCronJob: (id: number) => Promise<void>;
|
|
993
|
+
/**
|
|
994
|
+
* Pause a cron schedule. Paused schedules are skipped by `enqueueDueCronJobs()`.
|
|
995
|
+
*/
|
|
996
|
+
pauseCronJob: (id: number) => Promise<void>;
|
|
997
|
+
/**
|
|
998
|
+
* Resume a paused cron schedule.
|
|
999
|
+
*/
|
|
1000
|
+
resumeCronJob: (id: number) => Promise<void>;
|
|
1001
|
+
/**
|
|
1002
|
+
* Edit an existing cron schedule. Only provided fields are updated.
|
|
1003
|
+
* If `cronExpression` or `timezone` changes, `nextRunAt` is recalculated.
|
|
1004
|
+
*/
|
|
1005
|
+
editCronJob: (id: number, updates: EditCronScheduleOptions) => Promise<void>;
|
|
1006
|
+
/**
|
|
1007
|
+
* Check all active cron schedules and enqueue jobs for any whose
|
|
1008
|
+
* `nextRunAt` has passed. When `allowOverlap` is false (the default),
|
|
1009
|
+
* a new job is not enqueued if the previous instance is still
|
|
1010
|
+
* pending, processing, or waiting.
|
|
1011
|
+
*
|
|
1012
|
+
* **Note:** The processor calls this automatically before each batch,
|
|
1013
|
+
* so you typically do not need to call it yourself. It is exposed for
|
|
1014
|
+
* manual use in tests or one-off scripts.
|
|
1015
|
+
*
|
|
1016
|
+
* @returns The number of jobs that were enqueued.
|
|
1017
|
+
*/
|
|
1018
|
+
enqueueDueCronJobs: () => Promise<number>;
|
|
1019
|
+
/**
|
|
1020
|
+
* Get the PostgreSQL database pool.
|
|
1021
|
+
* Throws if the backend is not PostgreSQL.
|
|
1022
|
+
*/
|
|
1023
|
+
getPool: () => pg.Pool;
|
|
1024
|
+
/**
|
|
1025
|
+
* Get the Redis client instance (ioredis).
|
|
1026
|
+
* Throws if the backend is not Redis.
|
|
1027
|
+
*/
|
|
1028
|
+
getRedisClient: () => unknown;
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
/**
|
|
1032
|
+
* Filter options used by getJobs, cancelAllUpcomingJobs, editAllPendingJobs
|
|
1033
|
+
*/
|
|
1034
|
+
interface JobFilters {
|
|
1035
|
+
jobType?: string;
|
|
1036
|
+
priority?: number;
|
|
1037
|
+
runAt?: Date | {
|
|
1038
|
+
gt?: Date;
|
|
1039
|
+
gte?: Date;
|
|
1040
|
+
lt?: Date;
|
|
1041
|
+
lte?: Date;
|
|
1042
|
+
eq?: Date;
|
|
1043
|
+
};
|
|
1044
|
+
tags?: {
|
|
1045
|
+
values: string[];
|
|
1046
|
+
mode?: TagQueryMode;
|
|
1047
|
+
};
|
|
1048
|
+
/**
|
|
1049
|
+
* Cursor for keyset pagination. When provided, only return jobs with id < cursor.
|
|
1050
|
+
* This is more efficient than OFFSET for large datasets.
|
|
1051
|
+
* Cannot be used together with offset.
|
|
1052
|
+
*/
|
|
1053
|
+
cursor?: number;
|
|
1054
|
+
}
|
|
1055
|
+
/**
|
|
1056
|
+
* Fields that can be updated on a job
|
|
1057
|
+
*/
|
|
1058
|
+
interface JobUpdates {
|
|
1059
|
+
payload?: any;
|
|
1060
|
+
maxAttempts?: number;
|
|
1061
|
+
priority?: number;
|
|
1062
|
+
runAt?: Date | null;
|
|
1063
|
+
timeoutMs?: number | null;
|
|
1064
|
+
tags?: string[] | null;
|
|
1065
|
+
retryDelay?: number | null;
|
|
1066
|
+
retryBackoff?: boolean | null;
|
|
1067
|
+
retryDelayMax?: number | null;
|
|
1068
|
+
}
|
|
1069
|
+
/**
|
|
1070
|
+
* Input shape for creating a cron schedule in the backend.
|
|
1071
|
+
* This is the backend-level version of CronScheduleOptions.
|
|
1072
|
+
*/
|
|
1073
|
+
interface CronScheduleInput {
|
|
1074
|
+
scheduleName: string;
|
|
1075
|
+
cronExpression: string;
|
|
1076
|
+
jobType: string;
|
|
1077
|
+
payload: any;
|
|
1078
|
+
maxAttempts: number;
|
|
1079
|
+
priority: number;
|
|
1080
|
+
timeoutMs: number | null;
|
|
1081
|
+
forceKillOnTimeout: boolean;
|
|
1082
|
+
tags: string[] | undefined;
|
|
1083
|
+
timezone: string;
|
|
1084
|
+
allowOverlap: boolean;
|
|
1085
|
+
nextRunAt: Date | null;
|
|
1086
|
+
retryDelay: number | null;
|
|
1087
|
+
retryBackoff: boolean | null;
|
|
1088
|
+
retryDelayMax: number | null;
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Abstract backend interface that both PostgreSQL and Redis implement.
|
|
1092
|
+
* All storage operations go through this interface so the processor
|
|
1093
|
+
* and public API are backend-agnostic.
|
|
1094
|
+
*/
|
|
1095
|
+
interface QueueBackend {
|
|
1096
|
+
/**
|
|
1097
|
+
* Add a job and return its numeric ID.
|
|
1098
|
+
*
|
|
1099
|
+
* @param job - Job configuration.
|
|
1100
|
+
* @param options - Optional. Pass `{ db }` to run the INSERT on an external
|
|
1101
|
+
* client (e.g., inside a transaction). PostgreSQL only.
|
|
1102
|
+
*/
|
|
1103
|
+
addJob<PayloadMap, T extends JobType<PayloadMap>>(job: JobOptions<PayloadMap, T>, options?: AddJobOptions): Promise<number>;
|
|
1104
|
+
/**
|
|
1105
|
+
* Add multiple jobs in a single operation and return their IDs.
|
|
1106
|
+
*
|
|
1107
|
+
* IDs are returned in the same order as the input array.
|
|
1108
|
+
* Each job may independently have an `idempotencyKey`; duplicates
|
|
1109
|
+
* resolve to the existing job's ID without creating a new row.
|
|
1110
|
+
*
|
|
1111
|
+
* @param jobs - Array of job configurations.
|
|
1112
|
+
* @param options - Optional. Pass `{ db }` to run the INSERTs on an external
|
|
1113
|
+
* client (e.g., inside a transaction). PostgreSQL only.
|
|
1114
|
+
*/
|
|
1115
|
+
addJobs<PayloadMap, T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions): Promise<number[]>;
|
|
1116
|
+
/** Get a single job by ID, or null if not found. */
|
|
1117
|
+
getJob<PayloadMap, T extends JobType<PayloadMap>>(id: number): Promise<JobRecord<PayloadMap, T> | null>;
|
|
1118
|
+
/** Get jobs filtered by status, ordered by createdAt DESC. */
|
|
1119
|
+
getJobsByStatus<PayloadMap, T extends JobType<PayloadMap>>(status: string, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1120
|
+
/** Get all jobs, ordered by createdAt DESC. */
|
|
1121
|
+
getAllJobs<PayloadMap, T extends JobType<PayloadMap>>(limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1122
|
+
/** Get jobs matching arbitrary filters, ordered by createdAt DESC. */
|
|
1123
|
+
getJobs<PayloadMap, T extends JobType<PayloadMap>>(filters?: JobFilters, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1124
|
+
/** Get jobs by tag(s) with query mode. */
|
|
1125
|
+
getJobsByTags<PayloadMap, T extends JobType<PayloadMap>>(tags: string[], mode?: TagQueryMode, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1126
|
+
/**
|
|
1127
|
+
* Atomically claim a batch of ready jobs for the given worker.
|
|
1128
|
+
* Equivalent to SELECT … FOR UPDATE SKIP LOCKED in Postgres.
|
|
1129
|
+
*/
|
|
1130
|
+
getNextBatch<PayloadMap, T extends JobType<PayloadMap>>(workerId: string, batchSize?: number, jobType?: string | string[]): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1131
|
+
/** Mark a job as completed. */
|
|
1132
|
+
completeJob(jobId: number): Promise<void>;
|
|
1133
|
+
/** Mark a job as failed with error info and schedule retry. */
|
|
1134
|
+
failJob(jobId: number, error: Error, failureReason?: FailureReason): Promise<void>;
|
|
1135
|
+
/** Update locked_at to keep the job alive (heartbeat). */
|
|
1136
|
+
prolongJob(jobId: number): Promise<void>;
|
|
1137
|
+
/** Retry a failed/cancelled job immediately. */
|
|
1138
|
+
retryJob(jobId: number): Promise<void>;
|
|
1139
|
+
/** Cancel a pending job. */
|
|
1140
|
+
cancelJob(jobId: number): Promise<void>;
|
|
1141
|
+
/** Cancel all pending jobs matching optional filters. Returns count. */
|
|
1142
|
+
cancelAllUpcomingJobs(filters?: JobFilters): Promise<number>;
|
|
1143
|
+
/** Edit a single pending job. */
|
|
1144
|
+
editJob(jobId: number, updates: JobUpdates): Promise<void>;
|
|
1145
|
+
/** Edit all pending jobs matching filters. Returns count. */
|
|
1146
|
+
editAllPendingJobs(filters: JobFilters | undefined, updates: JobUpdates): Promise<number>;
|
|
1147
|
+
/** Delete completed jobs older than N days. Deletes in batches for scale safety. Returns count deleted. */
|
|
1148
|
+
cleanupOldJobs(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1149
|
+
/** Delete job events older than N days. Deletes in batches for scale safety. Returns count deleted. */
|
|
1150
|
+
cleanupOldJobEvents(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1151
|
+
/** Reclaim jobs stuck in 'processing' for too long. Returns count. */
|
|
1152
|
+
reclaimStuckJobs(maxProcessingTimeMinutes?: number): Promise<number>;
|
|
1153
|
+
/** Update the progress percentage (0-100) for a job. */
|
|
1154
|
+
updateProgress(jobId: number, progress: number): Promise<void>;
|
|
1155
|
+
/** Record a job event. Should not throw. */
|
|
1156
|
+
recordJobEvent(jobId: number, eventType: JobEventType, metadata?: any): Promise<void>;
|
|
1157
|
+
/** Get all events for a job, ordered by createdAt ASC. */
|
|
1158
|
+
getJobEvents(jobId: number): Promise<JobEvent[]>;
|
|
1159
|
+
/** Create a cron schedule and return its ID. */
|
|
1160
|
+
addCronSchedule(input: CronScheduleInput): Promise<number>;
|
|
1161
|
+
/** Get a cron schedule by ID, or null if not found. */
|
|
1162
|
+
getCronSchedule(id: number): Promise<CronScheduleRecord | null>;
|
|
1163
|
+
/** Get a cron schedule by its unique name, or null if not found. */
|
|
1164
|
+
getCronScheduleByName(name: string): Promise<CronScheduleRecord | null>;
|
|
1165
|
+
/** List cron schedules, optionally filtered by status. */
|
|
1166
|
+
listCronSchedules(status?: CronScheduleStatus): Promise<CronScheduleRecord[]>;
|
|
1167
|
+
/** Delete a cron schedule by ID. */
|
|
1168
|
+
removeCronSchedule(id: number): Promise<void>;
|
|
1169
|
+
/** Pause a cron schedule. */
|
|
1170
|
+
pauseCronSchedule(id: number): Promise<void>;
|
|
1171
|
+
/** Resume a cron schedule. */
|
|
1172
|
+
resumeCronSchedule(id: number): Promise<void>;
|
|
1173
|
+
/** Edit a cron schedule. */
|
|
1174
|
+
editCronSchedule(id: number, updates: EditCronScheduleOptions, nextRunAt?: Date | null): Promise<void>;
|
|
1175
|
+
/**
|
|
1176
|
+
* Atomically fetch all active cron schedules whose nextRunAt <= now.
|
|
1177
|
+
* In PostgreSQL this uses FOR UPDATE SKIP LOCKED to prevent duplicate enqueuing.
|
|
1178
|
+
*/
|
|
1179
|
+
getDueCronSchedules(): Promise<CronScheduleRecord[]>;
|
|
1180
|
+
/**
|
|
1181
|
+
* Update a cron schedule after a job has been enqueued.
|
|
1182
|
+
* Sets lastEnqueuedAt, lastJobId, and advances nextRunAt.
|
|
1183
|
+
*/
|
|
1184
|
+
updateCronScheduleAfterEnqueue(id: number, lastEnqueuedAt: Date, lastJobId: number, nextRunAt: Date | null): Promise<void>;
|
|
1185
|
+
/**
|
|
1186
|
+
* Transition a job from 'processing' to 'waiting' status.
|
|
1187
|
+
* Persists step data so the handler can resume from where it left off.
|
|
1188
|
+
*
|
|
1189
|
+
* @param jobId - The job to pause.
|
|
1190
|
+
* @param options - Wait configuration including optional waitUntil date, token ID, and step data.
|
|
1191
|
+
*/
|
|
1192
|
+
waitJob(jobId: number, options: {
|
|
1193
|
+
waitUntil?: Date;
|
|
1194
|
+
waitTokenId?: string;
|
|
1195
|
+
stepData: Record<string, any>;
|
|
1196
|
+
}): Promise<void>;
|
|
1197
|
+
/**
|
|
1198
|
+
* Persist step data for a job. Called after each `ctx.run()` step completes
|
|
1199
|
+
* to save intermediate progress. Best-effort: should not throw.
|
|
1200
|
+
*
|
|
1201
|
+
* @param jobId - The job to update.
|
|
1202
|
+
* @param stepData - The step data to persist.
|
|
385
1203
|
*/
|
|
386
|
-
|
|
1204
|
+
updateStepData(jobId: number, stepData: Record<string, any>): Promise<void>;
|
|
1205
|
+
/**
|
|
1206
|
+
* Create a waitpoint token that can pause a job until an external signal completes it.
|
|
1207
|
+
*
|
|
1208
|
+
* @param jobId - The job ID to associate with the token (null if created outside a handler).
|
|
1209
|
+
* @param options - Optional timeout string (e.g. '10m', '1h') and tags.
|
|
1210
|
+
* @returns The created waitpoint with its unique ID.
|
|
1211
|
+
*/
|
|
1212
|
+
createWaitpoint(jobId: number | null, options?: CreateTokenOptions): Promise<{
|
|
1213
|
+
id: string;
|
|
1214
|
+
}>;
|
|
1215
|
+
/**
|
|
1216
|
+
* Complete a waitpoint token, optionally providing output data.
|
|
1217
|
+
* Moves the associated job from 'waiting' back to 'pending' so it gets picked up.
|
|
1218
|
+
*
|
|
1219
|
+
* @param tokenId - The waitpoint token ID to complete.
|
|
1220
|
+
* @param data - Optional data to pass to the waiting handler.
|
|
1221
|
+
*/
|
|
1222
|
+
completeWaitpoint(tokenId: string, data?: any): Promise<void>;
|
|
1223
|
+
/**
|
|
1224
|
+
* Retrieve a waitpoint token by its ID.
|
|
1225
|
+
*
|
|
1226
|
+
* @param tokenId - The waitpoint token ID to look up.
|
|
1227
|
+
* @returns The waitpoint record, or null if not found.
|
|
1228
|
+
*/
|
|
1229
|
+
getWaitpoint(tokenId: string): Promise<WaitpointRecord | null>;
|
|
1230
|
+
/**
|
|
1231
|
+
* Expire timed-out waitpoint tokens and move their associated jobs back to 'pending'.
|
|
1232
|
+
* Should be called periodically (e.g., alongside reclaimStuckJobs).
|
|
1233
|
+
*
|
|
1234
|
+
* @returns The number of tokens that were expired.
|
|
1235
|
+
*/
|
|
1236
|
+
expireTimedOutWaitpoints(): Promise<number>;
|
|
1237
|
+
/** Set a pending reason for unpicked jobs of a given type. */
|
|
1238
|
+
setPendingReasonForUnpickedJobs(reason: string, jobType?: string | string[]): Promise<void>;
|
|
1239
|
+
}
|
|
1240
|
+
|
|
1241
|
+
declare class PostgresBackend implements QueueBackend {
|
|
1242
|
+
private pool;
|
|
1243
|
+
constructor(pool: Pool);
|
|
1244
|
+
/** Expose the raw pool for advanced usage. */
|
|
1245
|
+
getPool(): Pool;
|
|
1246
|
+
recordJobEvent(jobId: number, eventType: JobEventType, metadata?: any): Promise<void>;
|
|
1247
|
+
getJobEvents(jobId: number): Promise<JobEvent[]>;
|
|
1248
|
+
/**
|
|
1249
|
+
* Add a job and return its numeric ID.
|
|
1250
|
+
*
|
|
1251
|
+
* @param job - Job configuration.
|
|
1252
|
+
* @param options - Optional. Pass `{ db }` to run the INSERT on an external
|
|
1253
|
+
* client (e.g., inside a transaction) so the job is part of the caller's
|
|
1254
|
+
* transaction. The event INSERT also uses the same client.
|
|
1255
|
+
*/
|
|
1256
|
+
addJob<PayloadMap, T extends JobType<PayloadMap>>({ jobType, payload, maxAttempts, priority, runAt, timeoutMs, forceKillOnTimeout, tags, idempotencyKey, retryDelay, retryBackoff, retryDelayMax, }: JobOptions<PayloadMap, T>, options?: AddJobOptions): Promise<number>;
|
|
1257
|
+
/**
|
|
1258
|
+
* Insert multiple jobs in a single database round-trip.
|
|
1259
|
+
*
|
|
1260
|
+
* Uses a multi-row INSERT with ON CONFLICT handling for idempotency keys.
|
|
1261
|
+
* Returns IDs in the same order as the input array.
|
|
1262
|
+
*/
|
|
1263
|
+
addJobs<PayloadMap, T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions): Promise<number[]>;
|
|
1264
|
+
getJob<PayloadMap, T extends JobType<PayloadMap>>(id: number): Promise<JobRecord<PayloadMap, T> | null>;
|
|
1265
|
+
getJobsByStatus<PayloadMap, T extends JobType<PayloadMap>>(status: string, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1266
|
+
getAllJobs<PayloadMap, T extends JobType<PayloadMap>>(limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1267
|
+
getJobs<PayloadMap, T extends JobType<PayloadMap>>(filters?: JobFilters, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1268
|
+
getJobsByTags<PayloadMap, T extends JobType<PayloadMap>>(tags: string[], mode?: TagQueryMode, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1269
|
+
getNextBatch<PayloadMap, T extends JobType<PayloadMap>>(workerId: string, batchSize?: number, jobType?: string | string[]): Promise<JobRecord<PayloadMap, T>[]>;
|
|
1270
|
+
completeJob(jobId: number): Promise<void>;
|
|
1271
|
+
failJob(jobId: number, error: Error, failureReason?: FailureReason): Promise<void>;
|
|
1272
|
+
prolongJob(jobId: number): Promise<void>;
|
|
1273
|
+
updateProgress(jobId: number, progress: number): Promise<void>;
|
|
1274
|
+
retryJob(jobId: number): Promise<void>;
|
|
1275
|
+
cancelJob(jobId: number): Promise<void>;
|
|
1276
|
+
cancelAllUpcomingJobs(filters?: JobFilters): Promise<number>;
|
|
1277
|
+
editJob(jobId: number, updates: JobUpdates): Promise<void>;
|
|
1278
|
+
editAllPendingJobs(filters: JobFilters | undefined, updates: JobUpdates): Promise<number>;
|
|
1279
|
+
/**
|
|
1280
|
+
* Delete completed jobs older than the given number of days.
|
|
1281
|
+
* Deletes in batches of 1000 to avoid long-running transactions
|
|
1282
|
+
* and excessive WAL bloat at scale.
|
|
1283
|
+
*
|
|
1284
|
+
* @param daysToKeep - Number of days to retain completed jobs (default 30).
|
|
1285
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
1286
|
+
* @returns Total number of deleted jobs.
|
|
1287
|
+
*/
|
|
1288
|
+
cleanupOldJobs(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1289
|
+
/**
|
|
1290
|
+
* Delete job events older than the given number of days.
|
|
1291
|
+
* Deletes in batches of 1000 to avoid long-running transactions
|
|
1292
|
+
* and excessive WAL bloat at scale.
|
|
1293
|
+
*
|
|
1294
|
+
* @param daysToKeep - Number of days to retain events (default 30).
|
|
1295
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
1296
|
+
* @returns Total number of deleted events.
|
|
1297
|
+
*/
|
|
1298
|
+
cleanupOldJobEvents(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1299
|
+
reclaimStuckJobs(maxProcessingTimeMinutes?: number): Promise<number>;
|
|
1300
|
+
/**
|
|
1301
|
+
* Batch-insert multiple job events in a single query.
|
|
1302
|
+
* More efficient than individual recordJobEvent calls.
|
|
1303
|
+
*/
|
|
1304
|
+
private recordJobEventsBatch;
|
|
1305
|
+
/** Create a cron schedule and return its ID. */
|
|
1306
|
+
addCronSchedule(input: CronScheduleInput): Promise<number>;
|
|
1307
|
+
/** Get a cron schedule by ID. */
|
|
1308
|
+
getCronSchedule(id: number): Promise<CronScheduleRecord | null>;
|
|
1309
|
+
/** Get a cron schedule by its unique name. */
|
|
1310
|
+
getCronScheduleByName(name: string): Promise<CronScheduleRecord | null>;
|
|
1311
|
+
/** List cron schedules, optionally filtered by status. */
|
|
1312
|
+
listCronSchedules(status?: CronScheduleStatus): Promise<CronScheduleRecord[]>;
|
|
1313
|
+
/** Delete a cron schedule by ID. */
|
|
1314
|
+
removeCronSchedule(id: number): Promise<void>;
|
|
1315
|
+
/** Pause a cron schedule. */
|
|
1316
|
+
pauseCronSchedule(id: number): Promise<void>;
|
|
1317
|
+
/** Resume a paused cron schedule. */
|
|
1318
|
+
resumeCronSchedule(id: number): Promise<void>;
|
|
1319
|
+
/** Edit a cron schedule. */
|
|
1320
|
+
editCronSchedule(id: number, updates: EditCronScheduleOptions, nextRunAt?: Date | null): Promise<void>;
|
|
1321
|
+
/**
|
|
1322
|
+
* Atomically fetch all active cron schedules whose nextRunAt <= NOW().
|
|
1323
|
+
* Uses FOR UPDATE SKIP LOCKED to prevent duplicate enqueuing across workers.
|
|
1324
|
+
*/
|
|
1325
|
+
getDueCronSchedules(): Promise<CronScheduleRecord[]>;
|
|
1326
|
+
/**
|
|
1327
|
+
* Update a cron schedule after a job has been enqueued.
|
|
1328
|
+
* Sets lastEnqueuedAt, lastJobId, and advances nextRunAt.
|
|
1329
|
+
*/
|
|
1330
|
+
updateCronScheduleAfterEnqueue(id: number, lastEnqueuedAt: Date, lastJobId: number, nextRunAt: Date | null): Promise<void>;
|
|
1331
|
+
/**
|
|
1332
|
+
* Transition a job from 'processing' to 'waiting' status.
|
|
1333
|
+
* Persists step data so the handler can resume from where it left off.
|
|
1334
|
+
*
|
|
1335
|
+
* @param jobId - The job to pause.
|
|
1336
|
+
* @param options - Wait configuration including optional waitUntil date, token ID, and step data.
|
|
1337
|
+
*/
|
|
1338
|
+
waitJob(jobId: number, options: {
|
|
1339
|
+
waitUntil?: Date;
|
|
1340
|
+
waitTokenId?: string;
|
|
1341
|
+
stepData: Record<string, any>;
|
|
1342
|
+
}): Promise<void>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Persist step data for a job. Called after each ctx.run() step completes.
|
|
1345
|
+
* Best-effort: does not throw to avoid killing the running handler.
|
|
1346
|
+
*
|
|
1347
|
+
* @param jobId - The job to update.
|
|
1348
|
+
* @param stepData - The step data to persist.
|
|
1349
|
+
*/
|
|
1350
|
+
updateStepData(jobId: number, stepData: Record<string, any>): Promise<void>;
|
|
1351
|
+
/**
|
|
1352
|
+
* Create a waitpoint token in the database.
|
|
1353
|
+
*
|
|
1354
|
+
* @param jobId - The job ID to associate with the token (null if created outside a handler).
|
|
1355
|
+
* @param options - Optional timeout string (e.g. '10m', '1h') and tags.
|
|
1356
|
+
* @returns The created waitpoint with its unique ID.
|
|
1357
|
+
*/
|
|
1358
|
+
createWaitpoint(jobId: number | null, options?: CreateTokenOptions): Promise<{
|
|
1359
|
+
id: string;
|
|
1360
|
+
}>;
|
|
1361
|
+
/**
|
|
1362
|
+
* Complete a waitpoint token and move the associated job back to 'pending'.
|
|
1363
|
+
*
|
|
1364
|
+
* @param tokenId - The waitpoint token ID to complete.
|
|
1365
|
+
* @param data - Optional data to pass to the waiting handler.
|
|
1366
|
+
*/
|
|
1367
|
+
completeWaitpoint(tokenId: string, data?: any): Promise<void>;
|
|
1368
|
+
/**
|
|
1369
|
+
* Retrieve a waitpoint token by its ID.
|
|
1370
|
+
*
|
|
1371
|
+
* @param tokenId - The waitpoint token ID to look up.
|
|
1372
|
+
* @returns The waitpoint record, or null if not found.
|
|
1373
|
+
*/
|
|
1374
|
+
getWaitpoint(tokenId: string): Promise<WaitpointRecord | null>;
|
|
1375
|
+
/**
|
|
1376
|
+
* Expire timed-out waitpoint tokens and move their associated jobs back to 'pending'.
|
|
1377
|
+
*
|
|
1378
|
+
* @returns The number of tokens that were expired.
|
|
1379
|
+
*/
|
|
1380
|
+
expireTimedOutWaitpoints(): Promise<number>;
|
|
1381
|
+
setPendingReasonForUnpickedJobs(reason: string, jobType?: string | string[]): Promise<void>;
|
|
387
1382
|
}
|
|
388
1383
|
|
|
389
1384
|
/**
|
|
@@ -438,8 +1433,31 @@ declare function testHandlerSerialization<PayloadMap, T extends keyof PayloadMap
|
|
|
438
1433
|
}>;
|
|
439
1434
|
|
|
440
1435
|
/**
|
|
441
|
-
*
|
|
1436
|
+
* Calculate the next occurrence of a cron expression after a given date.
|
|
1437
|
+
*
|
|
1438
|
+
* @param cronExpression - A standard cron expression (5 fields, e.g. "0 * * * *").
|
|
1439
|
+
* @param timezone - IANA timezone string (default: "UTC").
|
|
1440
|
+
* @param after - The reference date to compute the next run from (default: now).
|
|
1441
|
+
* @param CronImpl - Cron class for dependency injection (default: croner's Cron).
|
|
1442
|
+
* @returns The next occurrence as a Date, or null if the expression will never fire again.
|
|
1443
|
+
*/
|
|
1444
|
+
declare function getNextCronOccurrence(cronExpression: string, timezone?: string, after?: Date, CronImpl?: typeof Cron): Date | null;
|
|
1445
|
+
/**
|
|
1446
|
+
* Validate whether a string is a syntactically correct cron expression.
|
|
1447
|
+
*
|
|
1448
|
+
* @param cronExpression - The cron expression to validate.
|
|
1449
|
+
* @param CronImpl - Cron class for dependency injection (default: croner's Cron).
|
|
1450
|
+
* @returns True if the expression is valid, false otherwise.
|
|
1451
|
+
*/
|
|
1452
|
+
declare function validateCronExpression(cronExpression: string, CronImpl?: typeof Cron): boolean;
|
|
1453
|
+
|
|
1454
|
+
/**
|
|
1455
|
+
* Initialize the job queue system.
|
|
1456
|
+
*
|
|
1457
|
+
* Defaults to PostgreSQL when `backend` is omitted.
|
|
1458
|
+
* For PostgreSQL, provide either `databaseConfig` or `pool` (bring your own).
|
|
1459
|
+
* For Redis, provide either `redisConfig` or `client` (bring your own).
|
|
442
1460
|
*/
|
|
443
1461
|
declare const initJobQueue: <PayloadMap = any>(config: JobQueueConfig) => JobQueue<PayloadMap>;
|
|
444
1462
|
|
|
445
|
-
export { type DatabaseSSLConfig, type EditJobOptions, FailureReason, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobRecord, type JobStatus, type JobType, type Processor, type ProcessorOptions, type TagQueryMode, initJobQueue, testHandlerSerialization, validateHandlerSerializable };
|
|
1463
|
+
export { type AddJobOptions, type CreateTokenOptions, type CronScheduleInput, type CronScheduleOptions, type CronScheduleRecord, type CronScheduleStatus, type DatabaseClient, type DatabaseSSLConfig, type EditCronScheduleOptions, type EditJobOptions, FailureReason, type JobContext, type JobEvent, JobEventType, type JobHandler, type JobHandlers, type JobOptions, type JobQueue, type JobQueueConfig, type JobQueueConfigLegacy, type JobRecord, type JobStatus, type JobType, type OnTimeoutCallback, PostgresBackend, type PostgresJobQueueConfig, type Processor, type ProcessorOptions, type QueueBackend, type RedisJobQueueConfig, type RedisTLSConfig, type Supervisor, type SupervisorOptions, type SupervisorRunResult, type TagQueryMode, type WaitDuration, WaitSignal, type WaitToken, type WaitTokenResult, type WaitpointRecord, type WaitpointStatus, getNextCronOccurrence, initJobQueue, testHandlerSerialization, validateCronExpression, validateHandlerSerializable };
|