@tsed/bullmq 8.43.1 → 8.43.3

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.
@@ -2,6 +2,7 @@ import { Store } from "@tsed/core";
2
2
  import { inject, injectable } from "@tsed/di";
3
3
  import { BULLMQ } from "../constants/constants.js";
4
4
  import { getJobToken } from "../utils/getJobToken.js";
5
+ import { getJobSchedulerId } from "../utils/getJobSchedulerId.js";
5
6
  import { getQueueToken } from "../utils/getQueueToken.js";
6
7
  export class JobDispatcher {
7
8
  async dispatch(job, payload, options = {}) {
@@ -10,10 +11,29 @@ export class JobDispatcher {
10
11
  if (!queue) {
11
12
  throw new Error(`Queue(${queueName}) not defined`);
12
13
  }
13
- return queue.add(jobName, payload, {
14
+ const { repeat, ...opts } = {
14
15
  ...defaultJobOptions,
15
16
  ...options
16
- });
17
+ };
18
+ if (repeat) {
19
+ const { jobId, ...template } = opts;
20
+ // a repeat given at dispatch time gets its own scheduler, so several schedules of the same job can coexist
21
+ const schedulerId = jobId || (options.repeat ? getJobSchedulerId(jobName, repeat) : jobName);
22
+ await this.removeLegacyRepeatable(queue, jobName, repeat, jobId);
23
+ // bullmq v6 removed the `repeat` option from Queue.add(): repeating jobs are handled by a job scheduler
24
+ return queue.upsertJobScheduler(schedulerId, repeat, { name: jobName, data: payload, opts: template });
25
+ }
26
+ return queue.add(jobName, payload, opts);
27
+ }
28
+ /**
29
+ * Repeatable jobs registered by `Queue.add(name, data, {repeat})` (bullmq < 6) aren't replaced by a job scheduler:
30
+ * they must be removed, otherwise the job is produced twice.
31
+ */
32
+ async removeLegacyRepeatable(queue, jobName, repeat, jobId) {
33
+ const legacyQueue = queue;
34
+ if (typeof legacyQueue.removeRepeatable === "function") {
35
+ await legacyQueue.removeRepeatable(jobName, repeat, jobId);
36
+ }
17
37
  }
18
38
  async resolveDispatchArgs(job, payload) {
19
39
  let queueName;
package/lib/esm/index.js CHANGED
@@ -17,6 +17,7 @@ export * from "./dispatchers/JobDispatcher.js";
17
17
  export * from "./dispatchers/JobDispatcherOptions.js";
18
18
  export * from "./utils/createQueueProvider.js";
19
19
  export * from "./utils/createWorkerProvider.js";
20
+ export * from "./utils/getJobSchedulerId.js";
20
21
  export * from "./utils/getJobToken.js";
21
22
  export * from "./utils/getQueueToken.js";
22
23
  export * from "./utils/getWorkerToken.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Build a stable job scheduler id from the job name and its repeat settings.
3
+ */
4
+ export function getJobSchedulerId(jobName, repeat) {
5
+ const endDate = repeat.endDate === undefined ? undefined : new Date(repeat.endDate).getTime();
6
+ return [jobName, repeat.pattern ?? repeat.every, repeat.tz, endDate].filter((value) => value !== undefined).join(":");
7
+ }
@@ -1,6 +1,15 @@
1
- import { JobsOptions } from "bullmq";
1
+ import type { JobsOptions, RepeatOptions } from "bullmq";
2
+ /**
3
+ * Job options accepted by `@JobController` and `JobDispatcher`.
4
+ *
5
+ * `repeat` is kept as a Ts.ED option: bullmq v6 removed it from `Queue.add()`,
6
+ * so repeating jobs are registered through `Queue.upsertJobScheduler()`.
7
+ */
8
+ export type JobOptions = Omit<JobsOptions, "repeat"> & {
9
+ repeat?: Omit<RepeatOptions, "key">;
10
+ };
2
11
  export interface JobStore {
3
12
  name: string;
4
13
  queue: string;
5
- opts: JobsOptions;
14
+ opts: JobOptions;
6
15
  }
@@ -1,3 +1,3 @@
1
- import { JobsOptions } from "bullmq";
2
- export declare function JobController(name: string, queue?: string, opts?: JobsOptions): any;
1
+ import type { JobOptions } from "../contracts/JobStore.js";
2
+ export declare function JobController(name: string, queue?: string, opts?: JobOptions): any;
3
3
  export declare function FallbackJobController(queue?: string): any;
@@ -1,11 +1,16 @@
1
- import { Job as BullMQJob, JobsOptions } from "bullmq";
2
- import { JobMethods } from "../contracts/index.js";
1
+ import { Job as BullMQJob } from "bullmq";
2
+ import { JobMethods, type JobOptions } from "../contracts/index.js";
3
3
  import { Type } from "@tsed/core";
4
4
  import type { JobDispatcherOptions } from "./JobDispatcherOptions.js";
5
5
  export declare class JobDispatcher {
6
- dispatch<T extends JobMethods>(job: Type<T>, payload?: Parameters<T["handle"]>[0], options?: JobsOptions): Promise<BullMQJob>;
7
- dispatch<P = unknown>(job: JobDispatcherOptions, payload?: P, options?: JobsOptions): Promise<BullMQJob>;
8
- dispatch<P = unknown>(job: string, payload?: P, options?: JobsOptions): Promise<BullMQJob>;
6
+ dispatch<T extends JobMethods>(job: Type<T>, payload?: Parameters<T["handle"]>[0], options?: JobOptions): Promise<BullMQJob>;
7
+ dispatch<P = unknown>(job: JobDispatcherOptions, payload?: P, options?: JobOptions): Promise<BullMQJob>;
8
+ dispatch<P = unknown>(job: string, payload?: P, options?: JobOptions): Promise<BullMQJob>;
9
+ /**
10
+ * Repeatable jobs registered by `Queue.add(name, data, {repeat})` (bullmq < 6) aren't replaced by a job scheduler:
11
+ * they must be removed, otherwise the job is produced twice.
12
+ */
13
+ private removeLegacyRepeatable;
9
14
  private resolveDispatchArgs;
10
15
  private retrieveJobOptionsFromClassBasedJob;
11
16
  }
@@ -17,6 +17,7 @@ export * from "./dispatchers/JobDispatcher.js";
17
17
  export * from "./dispatchers/JobDispatcherOptions.js";
18
18
  export * from "./utils/createQueueProvider.js";
19
19
  export * from "./utils/createWorkerProvider.js";
20
+ export * from "./utils/getJobSchedulerId.js";
20
21
  export * from "./utils/getJobToken.js";
21
22
  export * from "./utils/getQueueToken.js";
22
23
  export * from "./utils/getWorkerToken.js";
@@ -1,2 +1,2 @@
1
1
  import { Queue, QueueOptions } from "bullmq";
2
- export declare function createQueueProvider(queue: string, opts: QueueOptions): Queue<any, any, string>;
2
+ export declare function createQueueProvider(queue: string, opts: QueueOptions): Queue<any, any, string, any, any, string, import("bullmq").RedisQueueBackend>;
@@ -1,2 +1,2 @@
1
1
  import { Job, Worker, WorkerOptions } from "bullmq";
2
- export declare function createWorkerProvider(worker: string, process: (job: Job) => any, opts: WorkerOptions): Worker<any, any, string>;
2
+ export declare function createWorkerProvider(worker: string, process: (job: Job) => any, opts: WorkerOptions): Worker<any, any, string, import("bullmq").RedisQueueBackend, import("bullmq").JobProgress>;
@@ -0,0 +1,5 @@
1
+ import type { RepeatOptions } from "bullmq";
2
+ /**
3
+ * Build a stable job scheduler id from the job name and its repeat settings.
4
+ */
5
+ export declare function getJobSchedulerId(jobName: string, repeat: Omit<RepeatOptions, "key">): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsed/bullmq",
3
- "version": "8.43.1",
3
+ "version": "8.43.3",
4
4
  "description": "BullMQ integration for Ts.ED",
5
5
  "keywords": [
6
6
  "BullMQ",
@@ -30,19 +30,19 @@
30
30
  "tslib": ">=2.7.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@tsed/barrels": "8.43.1",
34
- "@tsed/core": "8.43.1",
35
- "@tsed/di": "8.43.1",
36
- "@tsed/platform-http": "8.43.1",
37
- "@tsed/schema": "8.43.1",
38
- "@tsed/typescript": "8.43.1",
39
- "bullmq": "^4.12.3 || ^5.1.1",
33
+ "@tsed/barrels": "8.43.3",
34
+ "@tsed/core": "8.43.3",
35
+ "@tsed/di": "8.43.3",
36
+ "@tsed/platform-http": "8.43.3",
37
+ "@tsed/schema": "8.43.3",
38
+ "@tsed/typescript": "8.43.3",
39
+ "bullmq": "^6.3.8",
40
40
  "ts-mockito": "^2.6.1",
41
41
  "typescript": "6.0.2",
42
42
  "vitest": "4.1.4"
43
43
  },
44
44
  "peerDependencies": {
45
- "bullmq": "^4.12.3 || ^5.1.1"
45
+ "bullmq": ">=5.16.0"
46
46
  },
47
47
  "repository": "https://github.com/tsedio/tsed",
48
48
  "bugs": {