@nicnocquee/dataqueue 1.25.0 → 1.26.0-beta.20260223202259
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/ai/build-docs-content.ts +96 -0
- package/ai/build-llms-full.ts +42 -0
- package/ai/docs-content.json +284 -0
- package/ai/rules/advanced.md +150 -0
- package/ai/rules/basic.md +159 -0
- package/ai/rules/react-dashboard.md +83 -0
- package/ai/skills/dataqueue-advanced/SKILL.md +370 -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 +3236 -1237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +697 -23
- package/dist/index.d.ts +697 -23
- package/dist/index.js +3235 -1238
- 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/1781200000004_create_cron_schedules_table.sql +33 -0
- package/migrations/1781200000005_add_retry_config_to_job_queue.sql +17 -0
- package/package.json +24 -21
- package/src/backend.ts +170 -5
- package/src/backends/postgres.ts +992 -63
- package/src/backends/redis-scripts.ts +358 -26
- package/src/backends/redis.test.ts +1532 -0
- package/src/backends/redis.ts +993 -35
- 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 +1 -1
- package/src/index.test.ts +1034 -11
- package/src/index.ts +267 -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.ts +104 -113
- package/src/queue.test.ts +465 -0
- package/src/queue.ts +34 -252
- package/src/supervisor.test.ts +340 -0
- package/src/supervisor.ts +177 -0
- package/src/types.ts +476 -12
- package/LICENSE +0 -21
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,33 @@
|
|
|
1
1
|
import * as pg from 'pg';
|
|
2
2
|
import { Pool } from 'pg';
|
|
3
|
+
import { Cron } from 'croner';
|
|
3
4
|
|
|
4
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
|
+
}
|
|
5
31
|
interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
6
32
|
jobType: T;
|
|
7
33
|
payload: PayloadMap[T];
|
|
@@ -74,6 +100,26 @@ interface JobOptions<PayloadMap, T extends JobType<PayloadMap>> {
|
|
|
74
100
|
* Once a key exists, it cannot be reused until the job is cleaned up (via `cleanupOldJobs`).
|
|
75
101
|
*/
|
|
76
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;
|
|
77
123
|
}
|
|
78
124
|
/**
|
|
79
125
|
* Options for editing a pending job.
|
|
@@ -186,6 +232,18 @@ interface JobRecord<PayloadMap, T extends JobType<PayloadMap>> {
|
|
|
186
232
|
* Updated by the handler via `ctx.setProgress(percent)`.
|
|
187
233
|
*/
|
|
188
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;
|
|
189
247
|
}
|
|
190
248
|
/**
|
|
191
249
|
* Callback registered via `onTimeout`. Invoked when the timeout fires, before the AbortSignal is triggered.
|
|
@@ -416,6 +474,88 @@ interface Processor {
|
|
|
416
474
|
*/
|
|
417
475
|
start: () => Promise<number>;
|
|
418
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
|
+
}
|
|
419
559
|
interface DatabaseSSLConfig {
|
|
420
560
|
/**
|
|
421
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.
|
|
@@ -437,10 +577,13 @@ interface DatabaseSSLConfig {
|
|
|
437
577
|
/**
|
|
438
578
|
* Configuration for PostgreSQL backend (default).
|
|
439
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.
|
|
440
583
|
*/
|
|
441
584
|
interface PostgresJobQueueConfig {
|
|
442
585
|
backend?: 'postgres';
|
|
443
|
-
databaseConfig
|
|
586
|
+
databaseConfig?: {
|
|
444
587
|
connectionString?: string;
|
|
445
588
|
host?: string;
|
|
446
589
|
port?: number;
|
|
@@ -448,7 +591,29 @@ interface PostgresJobQueueConfig {
|
|
|
448
591
|
user?: string;
|
|
449
592
|
password?: string;
|
|
450
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;
|
|
451
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;
|
|
452
617
|
verbose?: boolean;
|
|
453
618
|
}
|
|
454
619
|
/**
|
|
@@ -462,10 +627,13 @@ interface RedisTLSConfig {
|
|
|
462
627
|
}
|
|
463
628
|
/**
|
|
464
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.
|
|
465
633
|
*/
|
|
466
634
|
interface RedisJobQueueConfig {
|
|
467
635
|
backend: 'redis';
|
|
468
|
-
redisConfig
|
|
636
|
+
redisConfig?: {
|
|
469
637
|
/** Redis URL (e.g. redis://localhost:6379) */
|
|
470
638
|
url?: string;
|
|
471
639
|
host?: string;
|
|
@@ -480,6 +648,17 @@ interface RedisJobQueueConfig {
|
|
|
480
648
|
*/
|
|
481
649
|
keyPrefix?: string;
|
|
482
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;
|
|
483
662
|
verbose?: boolean;
|
|
484
663
|
}
|
|
485
664
|
/**
|
|
@@ -490,11 +669,172 @@ type JobQueueConfig = PostgresJobQueueConfig | RedisJobQueueConfig;
|
|
|
490
669
|
/** @deprecated Use JobQueueConfig instead. Alias kept for backward compat. */
|
|
491
670
|
type JobQueueConfigLegacy = PostgresJobQueueConfig;
|
|
492
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
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Payload types for each event emitted by the job queue.
|
|
761
|
+
*/
|
|
762
|
+
interface QueueEventMap {
|
|
763
|
+
/** Fired after a job is successfully added to the queue. */
|
|
764
|
+
'job:added': {
|
|
765
|
+
jobId: number;
|
|
766
|
+
jobType: string;
|
|
767
|
+
};
|
|
768
|
+
/** Fired when a processor claims a job and begins executing its handler. */
|
|
769
|
+
'job:processing': {
|
|
770
|
+
jobId: number;
|
|
771
|
+
jobType: string;
|
|
772
|
+
};
|
|
773
|
+
/** Fired when a job handler completes successfully. */
|
|
774
|
+
'job:completed': {
|
|
775
|
+
jobId: number;
|
|
776
|
+
jobType: string;
|
|
777
|
+
};
|
|
778
|
+
/** Fired when a job handler fails. `willRetry` indicates whether the job will be retried. */
|
|
779
|
+
'job:failed': {
|
|
780
|
+
jobId: number;
|
|
781
|
+
jobType: string;
|
|
782
|
+
error: Error;
|
|
783
|
+
willRetry: boolean;
|
|
784
|
+
};
|
|
785
|
+
/** Fired after a job is cancelled via `cancelJob()`. */
|
|
786
|
+
'job:cancelled': {
|
|
787
|
+
jobId: number;
|
|
788
|
+
};
|
|
789
|
+
/** Fired after a failed job is manually retried via `retryJob()`. */
|
|
790
|
+
'job:retried': {
|
|
791
|
+
jobId: number;
|
|
792
|
+
};
|
|
793
|
+
/** Fired when a job enters the `waiting` state (via `ctx.waitFor`, `ctx.waitUntil`, or `ctx.waitForToken`). */
|
|
794
|
+
'job:waiting': {
|
|
795
|
+
jobId: number;
|
|
796
|
+
jobType: string;
|
|
797
|
+
};
|
|
798
|
+
/** Fired when a job reports progress via `ctx.setProgress()`. */
|
|
799
|
+
'job:progress': {
|
|
800
|
+
jobId: number;
|
|
801
|
+
progress: number;
|
|
802
|
+
};
|
|
803
|
+
/** Fired on internal errors from the processor or supervisor. */
|
|
804
|
+
error: Error;
|
|
805
|
+
}
|
|
806
|
+
/** Union of all event names supported by the job queue. */
|
|
807
|
+
type QueueEventName = keyof QueueEventMap;
|
|
808
|
+
/**
|
|
809
|
+
* Callback type for `emit`. Used internally to pass the emitter
|
|
810
|
+
* from `initJobQueue` into the processor and supervisor.
|
|
811
|
+
*/
|
|
812
|
+
type QueueEmitFn = <K extends QueueEventName>(event: K, data: QueueEventMap[K]) => void;
|
|
493
813
|
interface JobQueue<PayloadMap> {
|
|
494
814
|
/**
|
|
495
815
|
* Add a job to the job queue.
|
|
816
|
+
*
|
|
817
|
+
* @param job - The job to enqueue.
|
|
818
|
+
* @param options - Optional. Pass `{ db }` with an external database client
|
|
819
|
+
* to insert the job within an existing transaction (PostgreSQL only).
|
|
496
820
|
*/
|
|
497
|
-
addJob: <T extends JobType<PayloadMap>>(job: JobOptions<PayloadMap, T
|
|
821
|
+
addJob: <T extends JobType<PayloadMap>>(job: JobOptions<PayloadMap, T>, options?: AddJobOptions) => Promise<number>;
|
|
822
|
+
/**
|
|
823
|
+
* Add multiple jobs to the queue in a single operation.
|
|
824
|
+
*
|
|
825
|
+
* More efficient than calling `addJob` in a loop because it batches the
|
|
826
|
+
* INSERT into a single database round-trip (PostgreSQL) or a single
|
|
827
|
+
* atomic Lua script (Redis).
|
|
828
|
+
*
|
|
829
|
+
* Returns an array of job IDs in the same order as the input array.
|
|
830
|
+
* Each job may independently have an `idempotencyKey`; duplicates
|
|
831
|
+
* resolve to the existing job's ID without creating a new row.
|
|
832
|
+
*
|
|
833
|
+
* @param jobs - Array of jobs to enqueue.
|
|
834
|
+
* @param options - Optional. Pass `{ db }` with an external database client
|
|
835
|
+
* to insert the jobs within an existing transaction (PostgreSQL only).
|
|
836
|
+
*/
|
|
837
|
+
addJobs: <T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions) => Promise<number[]>;
|
|
498
838
|
/**
|
|
499
839
|
* Get a job by its ID.
|
|
500
840
|
*/
|
|
@@ -550,12 +890,18 @@ interface JobQueue<PayloadMap> {
|
|
|
550
890
|
retryJob: (jobId: number) => Promise<void>;
|
|
551
891
|
/**
|
|
552
892
|
* Cleanup jobs that are older than the specified number of days.
|
|
893
|
+
* Deletes in batches for scale safety.
|
|
894
|
+
* @param daysToKeep - Number of days to retain completed jobs (default 30).
|
|
895
|
+
* @param batchSize - Number of rows to delete per batch (default 1000 for PostgreSQL, 200 for Redis).
|
|
553
896
|
*/
|
|
554
|
-
cleanupOldJobs: (daysToKeep?: number) => Promise<number>;
|
|
897
|
+
cleanupOldJobs: (daysToKeep?: number, batchSize?: number) => Promise<number>;
|
|
555
898
|
/**
|
|
556
899
|
* Cleanup job events that are older than the specified number of days.
|
|
900
|
+
* Deletes in batches for scale safety.
|
|
901
|
+
* @param daysToKeep - Number of days to retain events (default 30).
|
|
902
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
557
903
|
*/
|
|
558
|
-
cleanupOldJobEvents: (daysToKeep?: number) => Promise<number>;
|
|
904
|
+
cleanupOldJobEvents: (daysToKeep?: number, batchSize?: number) => Promise<number>;
|
|
559
905
|
/**
|
|
560
906
|
* Cancel a job given its ID.
|
|
561
907
|
* - This will set the job status to 'cancelled' and clear the locked_at and locked_by.
|
|
@@ -633,6 +979,12 @@ interface JobQueue<PayloadMap> {
|
|
|
633
979
|
* Create a job processor. Handlers must be provided per-processor.
|
|
634
980
|
*/
|
|
635
981
|
createProcessor: (handlers: JobHandlers<PayloadMap>, options?: ProcessorOptions) => Processor;
|
|
982
|
+
/**
|
|
983
|
+
* Create a background supervisor that automatically reclaims stuck jobs,
|
|
984
|
+
* cleans up old completed jobs/events, and expires timed-out waitpoint
|
|
985
|
+
* tokens on a configurable interval.
|
|
986
|
+
*/
|
|
987
|
+
createSupervisor: (options?: SupervisorOptions) => Supervisor;
|
|
636
988
|
/**
|
|
637
989
|
* Get the job events for a job.
|
|
638
990
|
*/
|
|
@@ -642,8 +994,6 @@ interface JobQueue<PayloadMap> {
|
|
|
642
994
|
* Tokens can be completed externally to resume a waiting job.
|
|
643
995
|
* Can be called outside of handlers (e.g., from an API route).
|
|
644
996
|
*
|
|
645
|
-
* **PostgreSQL backend only.** Throws if the backend is Redis.
|
|
646
|
-
*
|
|
647
997
|
* @param options - Optional token configuration (timeout, tags).
|
|
648
998
|
* @returns A token object with `id`.
|
|
649
999
|
*/
|
|
@@ -652,8 +1002,6 @@ interface JobQueue<PayloadMap> {
|
|
|
652
1002
|
* Complete a waitpoint token, resuming the associated waiting job.
|
|
653
1003
|
* Can be called from anywhere (API routes, external services, etc.).
|
|
654
1004
|
*
|
|
655
|
-
* **PostgreSQL backend only.** Throws if the backend is Redis.
|
|
656
|
-
*
|
|
657
1005
|
* @param tokenId - The ID of the token to complete.
|
|
658
1006
|
* @param data - Optional data to pass to the waiting handler.
|
|
659
1007
|
*/
|
|
@@ -661,8 +1009,6 @@ interface JobQueue<PayloadMap> {
|
|
|
661
1009
|
/**
|
|
662
1010
|
* Retrieve a waitpoint token by its ID.
|
|
663
1011
|
*
|
|
664
|
-
* **PostgreSQL backend only.** Throws if the backend is Redis.
|
|
665
|
-
*
|
|
666
1012
|
* @param tokenId - The ID of the token to retrieve.
|
|
667
1013
|
* @returns The token record, or null if not found.
|
|
668
1014
|
*/
|
|
@@ -671,11 +1017,89 @@ interface JobQueue<PayloadMap> {
|
|
|
671
1017
|
* Expire timed-out waitpoint tokens and resume their associated jobs.
|
|
672
1018
|
* Call this periodically (e.g., alongside `reclaimStuckJobs`).
|
|
673
1019
|
*
|
|
674
|
-
* **PostgreSQL backend only.** Throws if the backend is Redis.
|
|
675
|
-
*
|
|
676
1020
|
* @returns The number of tokens that were expired.
|
|
677
1021
|
*/
|
|
678
1022
|
expireTimedOutTokens: () => Promise<number>;
|
|
1023
|
+
/**
|
|
1024
|
+
* Add a recurring cron schedule. The processor automatically enqueues
|
|
1025
|
+
* due cron jobs before each batch, so no manual triggering is needed.
|
|
1026
|
+
*
|
|
1027
|
+
* @returns The ID of the created schedule.
|
|
1028
|
+
* @throws If the cron expression is invalid or the schedule name is already taken.
|
|
1029
|
+
*/
|
|
1030
|
+
addCronJob: <T extends JobType<PayloadMap>>(options: CronScheduleOptions<PayloadMap, T>) => Promise<number>;
|
|
1031
|
+
/**
|
|
1032
|
+
* Get a cron schedule by its ID.
|
|
1033
|
+
*/
|
|
1034
|
+
getCronJob: (id: number) => Promise<CronScheduleRecord | null>;
|
|
1035
|
+
/**
|
|
1036
|
+
* Get a cron schedule by its unique name.
|
|
1037
|
+
*/
|
|
1038
|
+
getCronJobByName: (name: string) => Promise<CronScheduleRecord | null>;
|
|
1039
|
+
/**
|
|
1040
|
+
* List all cron schedules, optionally filtered by status.
|
|
1041
|
+
*/
|
|
1042
|
+
listCronJobs: (status?: CronScheduleStatus) => Promise<CronScheduleRecord[]>;
|
|
1043
|
+
/**
|
|
1044
|
+
* Remove a cron schedule by its ID. Does not cancel any already-enqueued jobs.
|
|
1045
|
+
*/
|
|
1046
|
+
removeCronJob: (id: number) => Promise<void>;
|
|
1047
|
+
/**
|
|
1048
|
+
* Pause a cron schedule. Paused schedules are skipped by `enqueueDueCronJobs()`.
|
|
1049
|
+
*/
|
|
1050
|
+
pauseCronJob: (id: number) => Promise<void>;
|
|
1051
|
+
/**
|
|
1052
|
+
* Resume a paused cron schedule.
|
|
1053
|
+
*/
|
|
1054
|
+
resumeCronJob: (id: number) => Promise<void>;
|
|
1055
|
+
/**
|
|
1056
|
+
* Edit an existing cron schedule. Only provided fields are updated.
|
|
1057
|
+
* If `cronExpression` or `timezone` changes, `nextRunAt` is recalculated.
|
|
1058
|
+
*/
|
|
1059
|
+
editCronJob: (id: number, updates: EditCronScheduleOptions) => Promise<void>;
|
|
1060
|
+
/**
|
|
1061
|
+
* Check all active cron schedules and enqueue jobs for any whose
|
|
1062
|
+
* `nextRunAt` has passed. When `allowOverlap` is false (the default),
|
|
1063
|
+
* a new job is not enqueued if the previous instance is still
|
|
1064
|
+
* pending, processing, or waiting.
|
|
1065
|
+
*
|
|
1066
|
+
* **Note:** The processor calls this automatically before each batch,
|
|
1067
|
+
* so you typically do not need to call it yourself. It is exposed for
|
|
1068
|
+
* manual use in tests or one-off scripts.
|
|
1069
|
+
*
|
|
1070
|
+
* @returns The number of jobs that were enqueued.
|
|
1071
|
+
*/
|
|
1072
|
+
enqueueDueCronJobs: () => Promise<number>;
|
|
1073
|
+
/**
|
|
1074
|
+
* Register a listener for a queue event. The listener is called every
|
|
1075
|
+
* time the event fires. Works identically with both PostgreSQL and Redis.
|
|
1076
|
+
*
|
|
1077
|
+
* @param event - The event name (e.g. `'job:completed'`, `'error'`).
|
|
1078
|
+
* @param listener - Callback receiving the event payload.
|
|
1079
|
+
*/
|
|
1080
|
+
on: <K extends QueueEventName>(event: K, listener: (data: QueueEventMap[K]) => void) => void;
|
|
1081
|
+
/**
|
|
1082
|
+
* Register a one-time listener. The listener is automatically removed
|
|
1083
|
+
* after it fires once.
|
|
1084
|
+
*
|
|
1085
|
+
* @param event - The event name.
|
|
1086
|
+
* @param listener - Callback receiving the event payload.
|
|
1087
|
+
*/
|
|
1088
|
+
once: <K extends QueueEventName>(event: K, listener: (data: QueueEventMap[K]) => void) => void;
|
|
1089
|
+
/**
|
|
1090
|
+
* Remove a previously registered listener.
|
|
1091
|
+
*
|
|
1092
|
+
* @param event - The event name.
|
|
1093
|
+
* @param listener - The exact function reference passed to `on` or `once`.
|
|
1094
|
+
*/
|
|
1095
|
+
off: <K extends QueueEventName>(event: K, listener: (data: QueueEventMap[K]) => void) => void;
|
|
1096
|
+
/**
|
|
1097
|
+
* Remove all listeners for a specific event, or all listeners for
|
|
1098
|
+
* all events when called without arguments.
|
|
1099
|
+
*
|
|
1100
|
+
* @param event - Optional event name. If omitted, removes everything.
|
|
1101
|
+
*/
|
|
1102
|
+
removeAllListeners: (event?: QueueEventName) => void;
|
|
679
1103
|
/**
|
|
680
1104
|
* Get the PostgreSQL database pool.
|
|
681
1105
|
* Throws if the backend is not PostgreSQL.
|
|
@@ -722,6 +1146,30 @@ interface JobUpdates {
|
|
|
722
1146
|
runAt?: Date | null;
|
|
723
1147
|
timeoutMs?: number | null;
|
|
724
1148
|
tags?: string[] | null;
|
|
1149
|
+
retryDelay?: number | null;
|
|
1150
|
+
retryBackoff?: boolean | null;
|
|
1151
|
+
retryDelayMax?: number | null;
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Input shape for creating a cron schedule in the backend.
|
|
1155
|
+
* This is the backend-level version of CronScheduleOptions.
|
|
1156
|
+
*/
|
|
1157
|
+
interface CronScheduleInput {
|
|
1158
|
+
scheduleName: string;
|
|
1159
|
+
cronExpression: string;
|
|
1160
|
+
jobType: string;
|
|
1161
|
+
payload: any;
|
|
1162
|
+
maxAttempts: number;
|
|
1163
|
+
priority: number;
|
|
1164
|
+
timeoutMs: number | null;
|
|
1165
|
+
forceKillOnTimeout: boolean;
|
|
1166
|
+
tags: string[] | undefined;
|
|
1167
|
+
timezone: string;
|
|
1168
|
+
allowOverlap: boolean;
|
|
1169
|
+
nextRunAt: Date | null;
|
|
1170
|
+
retryDelay: number | null;
|
|
1171
|
+
retryBackoff: boolean | null;
|
|
1172
|
+
retryDelayMax: number | null;
|
|
725
1173
|
}
|
|
726
1174
|
/**
|
|
727
1175
|
* Abstract backend interface that both PostgreSQL and Redis implement.
|
|
@@ -729,8 +1177,26 @@ interface JobUpdates {
|
|
|
729
1177
|
* and public API are backend-agnostic.
|
|
730
1178
|
*/
|
|
731
1179
|
interface QueueBackend {
|
|
732
|
-
/**
|
|
733
|
-
|
|
1180
|
+
/**
|
|
1181
|
+
* Add a job and return its numeric ID.
|
|
1182
|
+
*
|
|
1183
|
+
* @param job - Job configuration.
|
|
1184
|
+
* @param options - Optional. Pass `{ db }` to run the INSERT on an external
|
|
1185
|
+
* client (e.g., inside a transaction). PostgreSQL only.
|
|
1186
|
+
*/
|
|
1187
|
+
addJob<PayloadMap, T extends JobType<PayloadMap>>(job: JobOptions<PayloadMap, T>, options?: AddJobOptions): Promise<number>;
|
|
1188
|
+
/**
|
|
1189
|
+
* Add multiple jobs in a single operation and return their IDs.
|
|
1190
|
+
*
|
|
1191
|
+
* IDs are returned in the same order as the input array.
|
|
1192
|
+
* Each job may independently have an `idempotencyKey`; duplicates
|
|
1193
|
+
* resolve to the existing job's ID without creating a new row.
|
|
1194
|
+
*
|
|
1195
|
+
* @param jobs - Array of job configurations.
|
|
1196
|
+
* @param options - Optional. Pass `{ db }` to run the INSERTs on an external
|
|
1197
|
+
* client (e.g., inside a transaction). PostgreSQL only.
|
|
1198
|
+
*/
|
|
1199
|
+
addJobs<PayloadMap, T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions): Promise<number[]>;
|
|
734
1200
|
/** Get a single job by ID, or null if not found. */
|
|
735
1201
|
getJob<PayloadMap, T extends JobType<PayloadMap>>(id: number): Promise<JobRecord<PayloadMap, T> | null>;
|
|
736
1202
|
/** Get jobs filtered by status, ordered by createdAt DESC. */
|
|
@@ -762,10 +1228,10 @@ interface QueueBackend {
|
|
|
762
1228
|
editJob(jobId: number, updates: JobUpdates): Promise<void>;
|
|
763
1229
|
/** Edit all pending jobs matching filters. Returns count. */
|
|
764
1230
|
editAllPendingJobs(filters: JobFilters | undefined, updates: JobUpdates): Promise<number>;
|
|
765
|
-
/** Delete completed jobs older than N days. Returns count deleted. */
|
|
766
|
-
cleanupOldJobs(daysToKeep?: number): Promise<number>;
|
|
767
|
-
/** Delete job events older than N days. Returns count deleted. */
|
|
768
|
-
cleanupOldJobEvents(daysToKeep?: number): Promise<number>;
|
|
1231
|
+
/** Delete completed jobs older than N days. Deletes in batches for scale safety. Returns count deleted. */
|
|
1232
|
+
cleanupOldJobs(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1233
|
+
/** Delete job events older than N days. Deletes in batches for scale safety. Returns count deleted. */
|
|
1234
|
+
cleanupOldJobEvents(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
769
1235
|
/** Reclaim jobs stuck in 'processing' for too long. Returns count. */
|
|
770
1236
|
reclaimStuckJobs(maxProcessingTimeMinutes?: number): Promise<number>;
|
|
771
1237
|
/** Update the progress percentage (0-100) for a job. */
|
|
@@ -774,6 +1240,84 @@ interface QueueBackend {
|
|
|
774
1240
|
recordJobEvent(jobId: number, eventType: JobEventType, metadata?: any): Promise<void>;
|
|
775
1241
|
/** Get all events for a job, ordered by createdAt ASC. */
|
|
776
1242
|
getJobEvents(jobId: number): Promise<JobEvent[]>;
|
|
1243
|
+
/** Create a cron schedule and return its ID. */
|
|
1244
|
+
addCronSchedule(input: CronScheduleInput): Promise<number>;
|
|
1245
|
+
/** Get a cron schedule by ID, or null if not found. */
|
|
1246
|
+
getCronSchedule(id: number): Promise<CronScheduleRecord | null>;
|
|
1247
|
+
/** Get a cron schedule by its unique name, or null if not found. */
|
|
1248
|
+
getCronScheduleByName(name: string): Promise<CronScheduleRecord | null>;
|
|
1249
|
+
/** List cron schedules, optionally filtered by status. */
|
|
1250
|
+
listCronSchedules(status?: CronScheduleStatus): Promise<CronScheduleRecord[]>;
|
|
1251
|
+
/** Delete a cron schedule by ID. */
|
|
1252
|
+
removeCronSchedule(id: number): Promise<void>;
|
|
1253
|
+
/** Pause a cron schedule. */
|
|
1254
|
+
pauseCronSchedule(id: number): Promise<void>;
|
|
1255
|
+
/** Resume a cron schedule. */
|
|
1256
|
+
resumeCronSchedule(id: number): Promise<void>;
|
|
1257
|
+
/** Edit a cron schedule. */
|
|
1258
|
+
editCronSchedule(id: number, updates: EditCronScheduleOptions, nextRunAt?: Date | null): Promise<void>;
|
|
1259
|
+
/**
|
|
1260
|
+
* Atomically fetch all active cron schedules whose nextRunAt <= now.
|
|
1261
|
+
* In PostgreSQL this uses FOR UPDATE SKIP LOCKED to prevent duplicate enqueuing.
|
|
1262
|
+
*/
|
|
1263
|
+
getDueCronSchedules(): Promise<CronScheduleRecord[]>;
|
|
1264
|
+
/**
|
|
1265
|
+
* Update a cron schedule after a job has been enqueued.
|
|
1266
|
+
* Sets lastEnqueuedAt, lastJobId, and advances nextRunAt.
|
|
1267
|
+
*/
|
|
1268
|
+
updateCronScheduleAfterEnqueue(id: number, lastEnqueuedAt: Date, lastJobId: number, nextRunAt: Date | null): Promise<void>;
|
|
1269
|
+
/**
|
|
1270
|
+
* Transition a job from 'processing' to 'waiting' status.
|
|
1271
|
+
* Persists step data so the handler can resume from where it left off.
|
|
1272
|
+
*
|
|
1273
|
+
* @param jobId - The job to pause.
|
|
1274
|
+
* @param options - Wait configuration including optional waitUntil date, token ID, and step data.
|
|
1275
|
+
*/
|
|
1276
|
+
waitJob(jobId: number, options: {
|
|
1277
|
+
waitUntil?: Date;
|
|
1278
|
+
waitTokenId?: string;
|
|
1279
|
+
stepData: Record<string, any>;
|
|
1280
|
+
}): Promise<void>;
|
|
1281
|
+
/**
|
|
1282
|
+
* Persist step data for a job. Called after each `ctx.run()` step completes
|
|
1283
|
+
* to save intermediate progress. Best-effort: should not throw.
|
|
1284
|
+
*
|
|
1285
|
+
* @param jobId - The job to update.
|
|
1286
|
+
* @param stepData - The step data to persist.
|
|
1287
|
+
*/
|
|
1288
|
+
updateStepData(jobId: number, stepData: Record<string, any>): Promise<void>;
|
|
1289
|
+
/**
|
|
1290
|
+
* Create a waitpoint token that can pause a job until an external signal completes it.
|
|
1291
|
+
*
|
|
1292
|
+
* @param jobId - The job ID to associate with the token (null if created outside a handler).
|
|
1293
|
+
* @param options - Optional timeout string (e.g. '10m', '1h') and tags.
|
|
1294
|
+
* @returns The created waitpoint with its unique ID.
|
|
1295
|
+
*/
|
|
1296
|
+
createWaitpoint(jobId: number | null, options?: CreateTokenOptions): Promise<{
|
|
1297
|
+
id: string;
|
|
1298
|
+
}>;
|
|
1299
|
+
/**
|
|
1300
|
+
* Complete a waitpoint token, optionally providing output data.
|
|
1301
|
+
* Moves the associated job from 'waiting' back to 'pending' so it gets picked up.
|
|
1302
|
+
*
|
|
1303
|
+
* @param tokenId - The waitpoint token ID to complete.
|
|
1304
|
+
* @param data - Optional data to pass to the waiting handler.
|
|
1305
|
+
*/
|
|
1306
|
+
completeWaitpoint(tokenId: string, data?: any): Promise<void>;
|
|
1307
|
+
/**
|
|
1308
|
+
* Retrieve a waitpoint token by its ID.
|
|
1309
|
+
*
|
|
1310
|
+
* @param tokenId - The waitpoint token ID to look up.
|
|
1311
|
+
* @returns The waitpoint record, or null if not found.
|
|
1312
|
+
*/
|
|
1313
|
+
getWaitpoint(tokenId: string): Promise<WaitpointRecord | null>;
|
|
1314
|
+
/**
|
|
1315
|
+
* Expire timed-out waitpoint tokens and move their associated jobs back to 'pending'.
|
|
1316
|
+
* Should be called periodically (e.g., alongside reclaimStuckJobs).
|
|
1317
|
+
*
|
|
1318
|
+
* @returns The number of tokens that were expired.
|
|
1319
|
+
*/
|
|
1320
|
+
expireTimedOutWaitpoints(): Promise<number>;
|
|
777
1321
|
/** Set a pending reason for unpicked jobs of a given type. */
|
|
778
1322
|
setPendingReasonForUnpickedJobs(reason: string, jobType?: string | string[]): Promise<void>;
|
|
779
1323
|
}
|
|
@@ -785,7 +1329,22 @@ declare class PostgresBackend implements QueueBackend {
|
|
|
785
1329
|
getPool(): Pool;
|
|
786
1330
|
recordJobEvent(jobId: number, eventType: JobEventType, metadata?: any): Promise<void>;
|
|
787
1331
|
getJobEvents(jobId: number): Promise<JobEvent[]>;
|
|
788
|
-
|
|
1332
|
+
/**
|
|
1333
|
+
* Add a job and return its numeric ID.
|
|
1334
|
+
*
|
|
1335
|
+
* @param job - Job configuration.
|
|
1336
|
+
* @param options - Optional. Pass `{ db }` to run the INSERT on an external
|
|
1337
|
+
* client (e.g., inside a transaction) so the job is part of the caller's
|
|
1338
|
+
* transaction. The event INSERT also uses the same client.
|
|
1339
|
+
*/
|
|
1340
|
+
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>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Insert multiple jobs in a single database round-trip.
|
|
1343
|
+
*
|
|
1344
|
+
* Uses a multi-row INSERT with ON CONFLICT handling for idempotency keys.
|
|
1345
|
+
* Returns IDs in the same order as the input array.
|
|
1346
|
+
*/
|
|
1347
|
+
addJobs<PayloadMap, T extends JobType<PayloadMap>>(jobs: JobOptions<PayloadMap, T>[], options?: AddJobOptions): Promise<number[]>;
|
|
789
1348
|
getJob<PayloadMap, T extends JobType<PayloadMap>>(id: number): Promise<JobRecord<PayloadMap, T> | null>;
|
|
790
1349
|
getJobsByStatus<PayloadMap, T extends JobType<PayloadMap>>(status: string, limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
791
1350
|
getAllJobs<PayloadMap, T extends JobType<PayloadMap>>(limit?: number, offset?: number): Promise<JobRecord<PayloadMap, T>[]>;
|
|
@@ -801,14 +1360,108 @@ declare class PostgresBackend implements QueueBackend {
|
|
|
801
1360
|
cancelAllUpcomingJobs(filters?: JobFilters): Promise<number>;
|
|
802
1361
|
editJob(jobId: number, updates: JobUpdates): Promise<void>;
|
|
803
1362
|
editAllPendingJobs(filters: JobFilters | undefined, updates: JobUpdates): Promise<number>;
|
|
804
|
-
|
|
805
|
-
|
|
1363
|
+
/**
|
|
1364
|
+
* Delete completed jobs older than the given number of days.
|
|
1365
|
+
* Deletes in batches of 1000 to avoid long-running transactions
|
|
1366
|
+
* and excessive WAL bloat at scale.
|
|
1367
|
+
*
|
|
1368
|
+
* @param daysToKeep - Number of days to retain completed jobs (default 30).
|
|
1369
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
1370
|
+
* @returns Total number of deleted jobs.
|
|
1371
|
+
*/
|
|
1372
|
+
cleanupOldJobs(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
1373
|
+
/**
|
|
1374
|
+
* Delete job events older than the given number of days.
|
|
1375
|
+
* Deletes in batches of 1000 to avoid long-running transactions
|
|
1376
|
+
* and excessive WAL bloat at scale.
|
|
1377
|
+
*
|
|
1378
|
+
* @param daysToKeep - Number of days to retain events (default 30).
|
|
1379
|
+
* @param batchSize - Number of rows to delete per batch (default 1000).
|
|
1380
|
+
* @returns Total number of deleted events.
|
|
1381
|
+
*/
|
|
1382
|
+
cleanupOldJobEvents(daysToKeep?: number, batchSize?: number): Promise<number>;
|
|
806
1383
|
reclaimStuckJobs(maxProcessingTimeMinutes?: number): Promise<number>;
|
|
807
1384
|
/**
|
|
808
1385
|
* Batch-insert multiple job events in a single query.
|
|
809
1386
|
* More efficient than individual recordJobEvent calls.
|
|
810
1387
|
*/
|
|
811
1388
|
private recordJobEventsBatch;
|
|
1389
|
+
/** Create a cron schedule and return its ID. */
|
|
1390
|
+
addCronSchedule(input: CronScheduleInput): Promise<number>;
|
|
1391
|
+
/** Get a cron schedule by ID. */
|
|
1392
|
+
getCronSchedule(id: number): Promise<CronScheduleRecord | null>;
|
|
1393
|
+
/** Get a cron schedule by its unique name. */
|
|
1394
|
+
getCronScheduleByName(name: string): Promise<CronScheduleRecord | null>;
|
|
1395
|
+
/** List cron schedules, optionally filtered by status. */
|
|
1396
|
+
listCronSchedules(status?: CronScheduleStatus): Promise<CronScheduleRecord[]>;
|
|
1397
|
+
/** Delete a cron schedule by ID. */
|
|
1398
|
+
removeCronSchedule(id: number): Promise<void>;
|
|
1399
|
+
/** Pause a cron schedule. */
|
|
1400
|
+
pauseCronSchedule(id: number): Promise<void>;
|
|
1401
|
+
/** Resume a paused cron schedule. */
|
|
1402
|
+
resumeCronSchedule(id: number): Promise<void>;
|
|
1403
|
+
/** Edit a cron schedule. */
|
|
1404
|
+
editCronSchedule(id: number, updates: EditCronScheduleOptions, nextRunAt?: Date | null): Promise<void>;
|
|
1405
|
+
/**
|
|
1406
|
+
* Atomically fetch all active cron schedules whose nextRunAt <= NOW().
|
|
1407
|
+
* Uses FOR UPDATE SKIP LOCKED to prevent duplicate enqueuing across workers.
|
|
1408
|
+
*/
|
|
1409
|
+
getDueCronSchedules(): Promise<CronScheduleRecord[]>;
|
|
1410
|
+
/**
|
|
1411
|
+
* Update a cron schedule after a job has been enqueued.
|
|
1412
|
+
* Sets lastEnqueuedAt, lastJobId, and advances nextRunAt.
|
|
1413
|
+
*/
|
|
1414
|
+
updateCronScheduleAfterEnqueue(id: number, lastEnqueuedAt: Date, lastJobId: number, nextRunAt: Date | null): Promise<void>;
|
|
1415
|
+
/**
|
|
1416
|
+
* Transition a job from 'processing' to 'waiting' status.
|
|
1417
|
+
* Persists step data so the handler can resume from where it left off.
|
|
1418
|
+
*
|
|
1419
|
+
* @param jobId - The job to pause.
|
|
1420
|
+
* @param options - Wait configuration including optional waitUntil date, token ID, and step data.
|
|
1421
|
+
*/
|
|
1422
|
+
waitJob(jobId: number, options: {
|
|
1423
|
+
waitUntil?: Date;
|
|
1424
|
+
waitTokenId?: string;
|
|
1425
|
+
stepData: Record<string, any>;
|
|
1426
|
+
}): Promise<void>;
|
|
1427
|
+
/**
|
|
1428
|
+
* Persist step data for a job. Called after each ctx.run() step completes.
|
|
1429
|
+
* Best-effort: does not throw to avoid killing the running handler.
|
|
1430
|
+
*
|
|
1431
|
+
* @param jobId - The job to update.
|
|
1432
|
+
* @param stepData - The step data to persist.
|
|
1433
|
+
*/
|
|
1434
|
+
updateStepData(jobId: number, stepData: Record<string, any>): Promise<void>;
|
|
1435
|
+
/**
|
|
1436
|
+
* Create a waitpoint token in the database.
|
|
1437
|
+
*
|
|
1438
|
+
* @param jobId - The job ID to associate with the token (null if created outside a handler).
|
|
1439
|
+
* @param options - Optional timeout string (e.g. '10m', '1h') and tags.
|
|
1440
|
+
* @returns The created waitpoint with its unique ID.
|
|
1441
|
+
*/
|
|
1442
|
+
createWaitpoint(jobId: number | null, options?: CreateTokenOptions): Promise<{
|
|
1443
|
+
id: string;
|
|
1444
|
+
}>;
|
|
1445
|
+
/**
|
|
1446
|
+
* Complete a waitpoint token and move the associated job back to 'pending'.
|
|
1447
|
+
*
|
|
1448
|
+
* @param tokenId - The waitpoint token ID to complete.
|
|
1449
|
+
* @param data - Optional data to pass to the waiting handler.
|
|
1450
|
+
*/
|
|
1451
|
+
completeWaitpoint(tokenId: string, data?: any): Promise<void>;
|
|
1452
|
+
/**
|
|
1453
|
+
* Retrieve a waitpoint token by its ID.
|
|
1454
|
+
*
|
|
1455
|
+
* @param tokenId - The waitpoint token ID to look up.
|
|
1456
|
+
* @returns The waitpoint record, or null if not found.
|
|
1457
|
+
*/
|
|
1458
|
+
getWaitpoint(tokenId: string): Promise<WaitpointRecord | null>;
|
|
1459
|
+
/**
|
|
1460
|
+
* Expire timed-out waitpoint tokens and move their associated jobs back to 'pending'.
|
|
1461
|
+
*
|
|
1462
|
+
* @returns The number of tokens that were expired.
|
|
1463
|
+
*/
|
|
1464
|
+
expireTimedOutWaitpoints(): Promise<number>;
|
|
812
1465
|
setPendingReasonForUnpickedJobs(reason: string, jobType?: string | string[]): Promise<void>;
|
|
813
1466
|
}
|
|
814
1467
|
|
|
@@ -863,11 +1516,32 @@ declare function testHandlerSerialization<PayloadMap, T extends keyof PayloadMap
|
|
|
863
1516
|
error?: string;
|
|
864
1517
|
}>;
|
|
865
1518
|
|
|
1519
|
+
/**
|
|
1520
|
+
* Calculate the next occurrence of a cron expression after a given date.
|
|
1521
|
+
*
|
|
1522
|
+
* @param cronExpression - A standard cron expression (5 fields, e.g. "0 * * * *").
|
|
1523
|
+
* @param timezone - IANA timezone string (default: "UTC").
|
|
1524
|
+
* @param after - The reference date to compute the next run from (default: now).
|
|
1525
|
+
* @param CronImpl - Cron class for dependency injection (default: croner's Cron).
|
|
1526
|
+
* @returns The next occurrence as a Date, or null if the expression will never fire again.
|
|
1527
|
+
*/
|
|
1528
|
+
declare function getNextCronOccurrence(cronExpression: string, timezone?: string, after?: Date, CronImpl?: typeof Cron): Date | null;
|
|
1529
|
+
/**
|
|
1530
|
+
* Validate whether a string is a syntactically correct cron expression.
|
|
1531
|
+
*
|
|
1532
|
+
* @param cronExpression - The cron expression to validate.
|
|
1533
|
+
* @param CronImpl - Cron class for dependency injection (default: croner's Cron).
|
|
1534
|
+
* @returns True if the expression is valid, false otherwise.
|
|
1535
|
+
*/
|
|
1536
|
+
declare function validateCronExpression(cronExpression: string, CronImpl?: typeof Cron): boolean;
|
|
1537
|
+
|
|
866
1538
|
/**
|
|
867
1539
|
* Initialize the job queue system.
|
|
868
1540
|
*
|
|
869
1541
|
* Defaults to PostgreSQL when `backend` is omitted.
|
|
1542
|
+
* For PostgreSQL, provide either `databaseConfig` or `pool` (bring your own).
|
|
1543
|
+
* For Redis, provide either `redisConfig` or `client` (bring your own).
|
|
870
1544
|
*/
|
|
871
1545
|
declare const initJobQueue: <PayloadMap = any>(config: JobQueueConfig) => JobQueue<PayloadMap>;
|
|
872
1546
|
|
|
873
|
-
export { type CreateTokenOptions, type DatabaseSSLConfig, 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 TagQueryMode, type WaitDuration, WaitSignal, type WaitToken, type WaitTokenResult, type WaitpointRecord, type WaitpointStatus, initJobQueue, testHandlerSerialization, validateHandlerSerializable };
|
|
1547
|
+
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 QueueEmitFn, type QueueEventMap, type QueueEventName, 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 };
|