@nicnocquee/dataqueue 1.26.0 → 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -533,6 +533,90 @@ export type JobQueueConfigLegacy = PostgresJobQueueConfig;
533
533
 
534
534
  export type TagQueryMode = 'exact' | 'all' | 'any' | 'none';
535
535
 
536
+ // ── Cron schedule types ──────────────────────────────────────────────
537
+
538
+ /**
539
+ * Status of a cron schedule.
540
+ */
541
+ export type CronScheduleStatus = 'active' | 'paused';
542
+
543
+ /**
544
+ * Options for creating a recurring cron schedule.
545
+ * Each schedule defines a recurring job that is automatically enqueued
546
+ * when its cron expression matches.
547
+ */
548
+ export interface CronScheduleOptions<
549
+ PayloadMap,
550
+ T extends JobType<PayloadMap>,
551
+ > {
552
+ /** Unique human-readable name for the schedule. */
553
+ scheduleName: string;
554
+ /** Standard cron expression (5 fields, e.g. "0 * * * *"). */
555
+ cronExpression: string;
556
+ /** Job type from the PayloadMap. */
557
+ jobType: T;
558
+ /** Payload for each job instance. */
559
+ payload: PayloadMap[T];
560
+ /** Maximum retry attempts for each job instance (default: 3). */
561
+ maxAttempts?: number;
562
+ /** Priority for each job instance (default: 0). */
563
+ priority?: number;
564
+ /** Timeout in milliseconds for each job instance. */
565
+ timeoutMs?: number;
566
+ /** Whether to force-kill the job on timeout (default: false). */
567
+ forceKillOnTimeout?: boolean;
568
+ /** Tags for each job instance. */
569
+ tags?: string[];
570
+ /** IANA timezone string for cron evaluation (default: "UTC"). */
571
+ timezone?: string;
572
+ /**
573
+ * Whether to allow overlapping job instances (default: false).
574
+ * When false, a new job will not be enqueued if the previous instance
575
+ * is still pending, processing, or waiting.
576
+ */
577
+ allowOverlap?: boolean;
578
+ }
579
+
580
+ /**
581
+ * A persisted cron schedule record.
582
+ */
583
+ export interface CronScheduleRecord {
584
+ id: number;
585
+ scheduleName: string;
586
+ cronExpression: string;
587
+ jobType: string;
588
+ payload: any;
589
+ maxAttempts: number;
590
+ priority: number;
591
+ timeoutMs: number | null;
592
+ forceKillOnTimeout: boolean;
593
+ tags: string[] | undefined;
594
+ timezone: string;
595
+ allowOverlap: boolean;
596
+ status: CronScheduleStatus;
597
+ lastEnqueuedAt: Date | null;
598
+ lastJobId: number | null;
599
+ nextRunAt: Date | null;
600
+ createdAt: Date;
601
+ updatedAt: Date;
602
+ }
603
+
604
+ /**
605
+ * Options for editing an existing cron schedule.
606
+ * All fields are optional; only provided fields are updated.
607
+ */
608
+ export interface EditCronScheduleOptions {
609
+ cronExpression?: string;
610
+ payload?: any;
611
+ maxAttempts?: number;
612
+ priority?: number;
613
+ timeoutMs?: number | null;
614
+ forceKillOnTimeout?: boolean;
615
+ tags?: string[] | null;
616
+ timezone?: string;
617
+ allowOverlap?: boolean;
618
+ }
619
+
536
620
  export interface JobQueue<PayloadMap> {
537
621
  /**
538
622
  * Add a job to the job queue.
@@ -733,6 +817,71 @@ export interface JobQueue<PayloadMap> {
733
817
  */
734
818
  expireTimedOutTokens: () => Promise<number>;
735
819
 
820
+ // ── Cron schedule operations ────────────────────────────────────────
821
+
822
+ /**
823
+ * Add a recurring cron schedule. The processor automatically enqueues
824
+ * due cron jobs before each batch, so no manual triggering is needed.
825
+ *
826
+ * @returns The ID of the created schedule.
827
+ * @throws If the cron expression is invalid or the schedule name is already taken.
828
+ */
829
+ addCronJob: <T extends JobType<PayloadMap>>(
830
+ options: CronScheduleOptions<PayloadMap, T>,
831
+ ) => Promise<number>;
832
+
833
+ /**
834
+ * Get a cron schedule by its ID.
835
+ */
836
+ getCronJob: (id: number) => Promise<CronScheduleRecord | null>;
837
+
838
+ /**
839
+ * Get a cron schedule by its unique name.
840
+ */
841
+ getCronJobByName: (name: string) => Promise<CronScheduleRecord | null>;
842
+
843
+ /**
844
+ * List all cron schedules, optionally filtered by status.
845
+ */
846
+ listCronJobs: (status?: CronScheduleStatus) => Promise<CronScheduleRecord[]>;
847
+
848
+ /**
849
+ * Remove a cron schedule by its ID. Does not cancel any already-enqueued jobs.
850
+ */
851
+ removeCronJob: (id: number) => Promise<void>;
852
+
853
+ /**
854
+ * Pause a cron schedule. Paused schedules are skipped by `enqueueDueCronJobs()`.
855
+ */
856
+ pauseCronJob: (id: number) => Promise<void>;
857
+
858
+ /**
859
+ * Resume a paused cron schedule.
860
+ */
861
+ resumeCronJob: (id: number) => Promise<void>;
862
+
863
+ /**
864
+ * Edit an existing cron schedule. Only provided fields are updated.
865
+ * If `cronExpression` or `timezone` changes, `nextRunAt` is recalculated.
866
+ */
867
+ editCronJob: (id: number, updates: EditCronScheduleOptions) => Promise<void>;
868
+
869
+ /**
870
+ * Check all active cron schedules and enqueue jobs for any whose
871
+ * `nextRunAt` has passed. When `allowOverlap` is false (the default),
872
+ * a new job is not enqueued if the previous instance is still
873
+ * pending, processing, or waiting.
874
+ *
875
+ * **Note:** The processor calls this automatically before each batch,
876
+ * so you typically do not need to call it yourself. It is exposed for
877
+ * manual use in tests or one-off scripts.
878
+ *
879
+ * @returns The number of jobs that were enqueued.
880
+ */
881
+ enqueueDueCronJobs: () => Promise<number>;
882
+
883
+ // ── Advanced access ───────────────────────────────────────────────────
884
+
736
885
  /**
737
886
  * Get the PostgreSQL database pool.
738
887
  * Throws if the backend is not PostgreSQL.
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) Nico Prananta 2024
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.