@tsed/bullmq 7.38.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.
Files changed (118) hide show
  1. package/.barrelsby.json +5 -0
  2. package/README.md +180 -0
  3. package/coverage/clover.xml +180 -0
  4. package/coverage/coverage-final.json +5 -0
  5. package/coverage/coverage-summary.json +6 -0
  6. package/coverage/lcov-report/Job.ts.html +136 -0
  7. package/coverage/lcov-report/base.css +224 -0
  8. package/coverage/lcov-report/block-navigation.js +87 -0
  9. package/coverage/lcov-report/decorators/Job.ts.html +136 -0
  10. package/coverage/lcov-report/decorators/index.html +116 -0
  11. package/coverage/lcov-report/dispatchers/JobDispatcher.ts.html +148 -0
  12. package/coverage/lcov-report/dispatchers/index.html +116 -0
  13. package/coverage/lcov-report/favicon.png +0 -0
  14. package/coverage/lcov-report/index.html +161 -0
  15. package/coverage/lcov-report/prettify.css +1 -0
  16. package/coverage/lcov-report/prettify.js +2 -0
  17. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  18. package/coverage/lcov-report/sorter.js +196 -0
  19. package/coverage/lcov-report/src/BullMQModule.ts.html +361 -0
  20. package/coverage/lcov-report/src/config/config.ts.html +142 -0
  21. package/coverage/lcov-report/src/config/index.html +116 -0
  22. package/coverage/lcov-report/src/decorators/Job.ts.html +136 -0
  23. package/coverage/lcov-report/src/decorators/index.html +116 -0
  24. package/coverage/lcov-report/src/dispatchers/JobDispatcher.ts.html +151 -0
  25. package/coverage/lcov-report/src/dispatchers/index.html +116 -0
  26. package/coverage/lcov-report/src/index.html +116 -0
  27. package/coverage/lcov-report/src/processors/ProcessorFactory.ts.html +166 -0
  28. package/coverage/lcov-report/src/processors/index.html +116 -0
  29. package/coverage/lcov.info +245 -0
  30. package/jest.config.js +11 -0
  31. package/lib/cjs/BullMQModule.js +98 -0
  32. package/lib/cjs/BullMQModule.js.map +1 -0
  33. package/lib/cjs/config/config.js +3 -0
  34. package/lib/cjs/config/config.js.map +1 -0
  35. package/lib/cjs/contracts/JobMethods.js +3 -0
  36. package/lib/cjs/contracts/JobMethods.js.map +1 -0
  37. package/lib/cjs/contracts/JobStore.js +3 -0
  38. package/lib/cjs/contracts/JobStore.js.map +1 -0
  39. package/lib/cjs/contracts/index.js +9 -0
  40. package/lib/cjs/contracts/index.js.map +1 -0
  41. package/lib/cjs/decorators/Job.js +17 -0
  42. package/lib/cjs/decorators/Job.js.map +1 -0
  43. package/lib/cjs/decorators/JobController.js +17 -0
  44. package/lib/cjs/decorators/JobController.js.map +1 -0
  45. package/lib/cjs/decorators/index.js +8 -0
  46. package/lib/cjs/decorators/index.js.map +1 -0
  47. package/lib/cjs/dispatchers/JobDispatcher.js +27 -0
  48. package/lib/cjs/dispatchers/JobDispatcher.js.map +1 -0
  49. package/lib/cjs/dispatchers/index.js +8 -0
  50. package/lib/cjs/dispatchers/index.js.map +1 -0
  51. package/lib/cjs/index.js +13 -0
  52. package/lib/cjs/index.js.map +1 -0
  53. package/lib/cjs/package.json +3 -0
  54. package/lib/cjs/processors/ProcessorFactory.js +20 -0
  55. package/lib/cjs/processors/ProcessorFactory.js.map +1 -0
  56. package/lib/esm/BullMQModule.js +95 -0
  57. package/lib/esm/BullMQModule.js.map +1 -0
  58. package/lib/esm/config/config.js +2 -0
  59. package/lib/esm/config/config.js.map +1 -0
  60. package/lib/esm/contracts/JobMethods.js +2 -0
  61. package/lib/esm/contracts/JobMethods.js.map +1 -0
  62. package/lib/esm/contracts/JobStore.js +2 -0
  63. package/lib/esm/contracts/JobStore.js.map +1 -0
  64. package/lib/esm/contracts/index.js +6 -0
  65. package/lib/esm/contracts/index.js.map +1 -0
  66. package/lib/esm/decorators/JobController.js +13 -0
  67. package/lib/esm/decorators/JobController.js.map +1 -0
  68. package/lib/esm/decorators/index.js +5 -0
  69. package/lib/esm/decorators/index.js.map +1 -0
  70. package/lib/esm/dispatchers/JobDispatcher.js +24 -0
  71. package/lib/esm/dispatchers/JobDispatcher.js.map +1 -0
  72. package/lib/esm/dispatchers/index.js +5 -0
  73. package/lib/esm/dispatchers/index.js.map +1 -0
  74. package/lib/esm/index.js +10 -0
  75. package/lib/esm/index.js.map +1 -0
  76. package/lib/esm/package.json +3 -0
  77. package/lib/tsconfig.esm.tsbuildinfo +1 -0
  78. package/lib/tsconfig.tsbuildinfo +1 -0
  79. package/lib/types/BullMQModule.d.ts +14 -0
  80. package/lib/types/config/config.d.ts +15 -0
  81. package/lib/types/contracts/JobMethods.d.ts +3 -0
  82. package/lib/types/contracts/JobStore.d.ts +6 -0
  83. package/lib/types/contracts/index.d.ts +5 -0
  84. package/lib/types/decorators/Job.d.ts +2 -0
  85. package/lib/types/decorators/JobController.d.ts +2 -0
  86. package/lib/types/decorators/index.d.ts +4 -0
  87. package/lib/types/dispatchers/JobDispatcher.d.ts +9 -0
  88. package/lib/types/dispatchers/index.d.ts +4 -0
  89. package/lib/types/index.d.ts +9 -0
  90. package/lib/types/processors/ProcessorFactory.d.ts +7 -0
  91. package/package.json +51 -0
  92. package/src/BullMQModule.js +149 -0
  93. package/src/BullMQModule.spec.js +236 -0
  94. package/src/BullMQModule.spec.ts +184 -0
  95. package/src/BullMQModule.ts +93 -0
  96. package/src/config/config.js +2 -0
  97. package/src/config/config.ts +19 -0
  98. package/src/contracts/JobMethods.js +2 -0
  99. package/src/contracts/JobMethods.ts +3 -0
  100. package/src/contracts/JobStore.js +2 -0
  101. package/src/contracts/JobStore.ts +7 -0
  102. package/src/contracts/index.js +21 -0
  103. package/src/contracts/index.ts +6 -0
  104. package/src/decorators/Job.js +18 -0
  105. package/src/decorators/JobController.js +18 -0
  106. package/src/decorators/JobController.spec.ts +50 -0
  107. package/src/decorators/JobController.ts +17 -0
  108. package/src/decorators/index.js +20 -0
  109. package/src/decorators/index.ts +5 -0
  110. package/src/dispatchers/JobDispatcher.js +72 -0
  111. package/src/dispatchers/JobDispatcher.spec.js +98 -0
  112. package/src/dispatchers/JobDispatcher.spec.ts +52 -0
  113. package/src/dispatchers/JobDispatcher.ts +22 -0
  114. package/src/dispatchers/index.js +20 -0
  115. package/src/dispatchers/index.ts +5 -0
  116. package/src/index.ts +10 -0
  117. package/tsconfig.esm.json +39 -0
  118. package/tsconfig.json +39 -0
@@ -0,0 +1,93 @@
1
+ import {BeforeInit, DIContext, runInContext} from "@tsed/common";
2
+ import {Constant, InjectorService, Module} from "@tsed/di";
3
+ import {getComputedType} from "@tsed/schema";
4
+ import {Job, Queue, Worker} from "bullmq";
5
+ import {v4} from "uuid";
6
+ import {BullMQConfig} from "./config/config";
7
+ import {JobMethods} from "./contracts";
8
+ import {JobDispatcher} from "./dispatchers";
9
+
10
+ @Module()
11
+ export class BullMQModule implements BeforeInit {
12
+ @Constant("bullmq")
13
+ private readonly bullmq: BullMQConfig;
14
+
15
+ constructor(private readonly injector: InjectorService, private readonly dispatcher: JobDispatcher) {}
16
+
17
+ $beforeInit() {
18
+ this.buildWorkers();
19
+ this.buildQueues();
20
+
21
+ this.injector.getMany<JobMethods>("bullmq:cron").map((job) => this.dispatcher.dispatch(getComputedType(job)));
22
+ }
23
+
24
+ private buildQueues() {
25
+ this.bullmq.queues.forEach((queue) => {
26
+ this.injector
27
+ .add(`bullmq.queue.${queue}`, {
28
+ type: "bullmq:queue",
29
+ useValue: new Queue(queue, {
30
+ connection: this.bullmq.connection,
31
+ defaultJobOptions: this.bullmq.defaultJobOptions
32
+ }),
33
+ hooks: {
34
+ $onDestroy: (queue) => queue.close()
35
+ }
36
+ })
37
+ .invoke<Queue>(`bullmq.queue.${queue}`);
38
+ });
39
+ }
40
+
41
+ private buildWorkers() {
42
+ (this.bullmq.workerQueues ?? this.bullmq.queues).forEach((queue) => {
43
+ this.injector
44
+ .add(`bullmq.worker.${queue}`, {
45
+ type: "bullmq:worker",
46
+ useValue: new Worker(queue, this.onProcess.bind(this), {
47
+ connection: this.bullmq.connection
48
+ }),
49
+ hooks: {
50
+ $onDestroy: (worker) => worker.close()
51
+ }
52
+ })
53
+ .invoke<Worker>(`bullmq.worker.${queue}`);
54
+ });
55
+ }
56
+
57
+ private getJob(name: string, queueName: string) {
58
+ return this.injector.get(`bullmq.job.${queueName}.${name}`);
59
+ }
60
+
61
+ private async onProcess(job: Job) {
62
+ const jobService = this.getJob(job.name, job.queueName);
63
+
64
+ if (!jobService) {
65
+ this.injector.logger.warn({
66
+ event: "BULLMQ_JOB_NOT_FOUND",
67
+ message: `Job ${job.name} ${job.queueName} not found`
68
+ });
69
+ return;
70
+ }
71
+
72
+ const $ctx = new DIContext({
73
+ injector: this.injector,
74
+ logger: this.injector.logger,
75
+ id: job.id || v4().split("-").join("")
76
+ });
77
+
78
+ $ctx.set("BULLMQ_JOB", job);
79
+
80
+ try {
81
+ return await runInContext($ctx, () => jobService.handle(job.data, job));
82
+ } catch (er) {
83
+ $ctx.logger.error({
84
+ event: "BULLMQ_JOB_ERROR",
85
+ message: er.message,
86
+ stack: er.stack
87
+ });
88
+ throw er;
89
+ } finally {
90
+ await $ctx.destroy();
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,19 @@
1
+ import {type ConnectionOptions, type DefaultJobOptions} from "bullmq";
2
+
3
+ export type BullMQConfig = {
4
+ queues: string[];
5
+ connection: ConnectionOptions;
6
+ defaultJobOptions?: DefaultJobOptions;
7
+ disableWorker?: boolean;
8
+ // optionally specify for which queues to start a worker for
9
+ // in case not all queues should be worked on
10
+ workerQueues?: string[];
11
+ };
12
+
13
+ declare global {
14
+ namespace TsED {
15
+ interface Configuration {
16
+ bullmq?: BullMQConfig;
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export interface JobMethods {
2
+ handle(payload: unknown): unknown;
3
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ import {JobsOptions} from "bullmq";
2
+
3
+ export type JobStore = {
4
+ name: string;
5
+ queue: string;
6
+ opts: JobsOptions;
7
+ };
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ /**
3
+ * @file Automatically generated by barrelsby.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./JobMethods"), exports);
21
+ __exportStar(require("./JobStore"), exports);
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from "./JobMethods";
6
+ export * from "./JobStore";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Job = void 0;
4
+ var core_1 = require("@tsed/core");
5
+ var di_1 = require("@tsed/di");
6
+ function Job(name, queue, opts) {
7
+ if (queue === void 0) { queue = "default"; }
8
+ if (opts === void 0) { opts = {}; }
9
+ return (0, core_1.useDecorators)((0, core_1.StoreMerge)("bullmq", {
10
+ name: name,
11
+ queue: queue,
12
+ opts: opts
13
+ }), (0, di_1.Injectable)({
14
+ provide: "bullmq.job.".concat(queue, ".").concat(name),
15
+ type: opts.repeat ? "bullmq:cron" : "bullmq:job"
16
+ }));
17
+ }
18
+ exports.Job = Job;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobController = void 0;
4
+ var core_1 = require("@tsed/core");
5
+ var di_1 = require("@tsed/di");
6
+ function JobController(name, queue, opts) {
7
+ if (queue === void 0) { queue = "default"; }
8
+ if (opts === void 0) { opts = {}; }
9
+ return (0, core_1.useDecorators)((0, core_1.StoreMerge)("bullmq", {
10
+ name: name,
11
+ queue: queue,
12
+ opts: opts
13
+ }), (0, di_1.Injectable)({
14
+ provide: "bullmq.job.".concat(queue, ".").concat(name),
15
+ type: opts.repeat ? "bullmq:cron" : "bullmq:job"
16
+ }));
17
+ }
18
+ exports.JobController = JobController;
@@ -0,0 +1,50 @@
1
+ import {JobController} from "./JobController";
2
+ import {Store} from "@tsed/core";
3
+
4
+ describe("JobController", () => {
5
+ it("should set the proper store data", () => {
6
+ @JobController("testjob")
7
+ class TestJob {}
8
+
9
+ const store = Store.from(TestJob).get("bullmq");
10
+
11
+ expect(store.name).toBe("testjob");
12
+ expect(store.queue).toBe("default");
13
+ expect(store.opts).toStrictEqual({});
14
+ });
15
+
16
+ it("should allow settings a custom queue", () => {
17
+ @JobController("testjob", "custom")
18
+ class CustomQueueJob {}
19
+
20
+ const store = Store.from(CustomQueueJob).get("bullmq");
21
+
22
+ expect(store.queue).toBe("custom");
23
+ });
24
+
25
+ it("should allow custom options to be set", () => {
26
+ @JobController("testjob", "default", {
27
+ backoff: 69,
28
+ attempts: 42
29
+ })
30
+ class CustomOptionsJob {}
31
+
32
+ const store = Store.from(CustomOptionsJob).get("bullmq");
33
+
34
+ expect(store.opts).toStrictEqual({
35
+ backoff: 69,
36
+ attempts: 42
37
+ });
38
+ });
39
+
40
+ it("should set type for cron jobs", () => {
41
+ @JobController("testjob", "default", {
42
+ repeat: {count: 42}
43
+ })
44
+ class CustomCronJob {}
45
+
46
+ const store = Store.from(CustomCronJob).get("bullmq");
47
+
48
+ expect(store);
49
+ });
50
+ });
@@ -0,0 +1,17 @@
1
+ import {StoreMerge, useDecorators} from "@tsed/core";
2
+ import {Injectable} from "@tsed/di";
3
+ import {JobsOptions} from "bullmq";
4
+
5
+ export function JobController(name: string, queue: string = "default", opts: JobsOptions = {}) {
6
+ return useDecorators(
7
+ StoreMerge("bullmq", {
8
+ name,
9
+ queue,
10
+ opts
11
+ }),
12
+ Injectable({
13
+ provide: `bullmq.job.${queue}.${name}`,
14
+ type: opts.repeat ? "bullmq:cron" : "bullmq:job"
15
+ })
16
+ );
17
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * @file Automatically generated by barrelsby.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./JobController"), exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from "./JobController";
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __generator = (this && this.__generator) || function (thisArg, body) {
18
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
19
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
20
+ function verb(n) { return function (v) { return step([n, v]); }; }
21
+ function step(op) {
22
+ if (f) throw new TypeError("Generator is already executing.");
23
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
24
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
25
+ if (y = 0, t) op = [op[0] & 2, t.value];
26
+ switch (op[0]) {
27
+ case 0: case 1: t = op; break;
28
+ case 4: _.label++; return { value: op[1], done: false };
29
+ case 5: _.label++; y = op[1]; op = [0]; continue;
30
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
31
+ default:
32
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
33
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
34
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
35
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
36
+ if (t[2]) _.ops.pop();
37
+ _.trys.pop(); continue;
38
+ }
39
+ op = body.call(thisArg, _);
40
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
41
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
42
+ }
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.JobDispatcher = void 0;
46
+ var di_1 = require("@tsed/di");
47
+ var core_1 = require("@tsed/core");
48
+ var JobDispatcher = /** @class */ (function () {
49
+ function JobDispatcher(injector) {
50
+ this.injector = injector;
51
+ }
52
+ // eslint-disable-next-line require-await
53
+ JobDispatcher.prototype.dispatch = function (job, payload) {
54
+ if (payload === void 0) { payload = {}; }
55
+ return __awaiter(this, void 0, void 0, function () {
56
+ var store, queue;
57
+ return __generator(this, function (_a) {
58
+ store = core_1.Store.from(job).get("bullmq");
59
+ queue = this.injector.getMany("bullmq:queue").find(function (queue) { return queue.name === store.queue; });
60
+ if (!queue) {
61
+ throw new Error("Queue(".concat(store.queue, ") not defined"));
62
+ }
63
+ return [2 /*return*/, queue.add(store.name, payload, store.opts)];
64
+ });
65
+ });
66
+ };
67
+ JobDispatcher = __decorate([
68
+ (0, di_1.Service)()
69
+ ], JobDispatcher);
70
+ return JobDispatcher;
71
+ }());
72
+ exports.JobDispatcher = JobDispatcher;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ var __generator = (this && this.__generator) || function (thisArg, body) {
18
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
19
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
20
+ function verb(n) { return function (v) { return step([n, v]); }; }
21
+ function step(op) {
22
+ if (f) throw new TypeError("Generator is already executing.");
23
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
24
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
25
+ if (y = 0, t) op = [op[0] & 2, t.value];
26
+ switch (op[0]) {
27
+ case 0: case 1: t = op; break;
28
+ case 4: _.label++; return { value: op[1], done: false };
29
+ case 5: _.label++; y = op[1]; op = [0]; continue;
30
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
31
+ default:
32
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
33
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
34
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
35
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
36
+ if (t[2]) _.ops.pop();
37
+ _.trys.pop(); continue;
38
+ }
39
+ op = body.call(thisArg, _);
40
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
41
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
42
+ }
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ var di_1 = require("@tsed/di");
46
+ var JobDispatcher_1 = require("./JobDispatcher");
47
+ var decorators_1 = require("../decorators");
48
+ var bullmq_1 = require("bullmq");
49
+ var ts_mockito_1 = require("ts-mockito");
50
+ var ExampleTestJob = /** @class */ (function () {
51
+ function ExampleTestJob() {
52
+ }
53
+ ExampleTestJob.prototype.handle = function (payload) { };
54
+ ExampleTestJob = __decorate([
55
+ (0, decorators_1.JobController)("example-job", "default", {
56
+ backoff: 69
57
+ })
58
+ ], ExampleTestJob);
59
+ return ExampleTestJob;
60
+ }());
61
+ var NotConfiguredQueueTestJob = /** @class */ (function () {
62
+ function NotConfiguredQueueTestJob() {
63
+ }
64
+ NotConfiguredQueueTestJob.prototype.handle = function () { };
65
+ NotConfiguredQueueTestJob = __decorate([
66
+ (0, decorators_1.JobController)("queue-not-configured", "not-configured")
67
+ ], NotConfiguredQueueTestJob);
68
+ return NotConfiguredQueueTestJob;
69
+ }());
70
+ describe("JobDispatcher", function () {
71
+ it("should throw an exception when a queue is not configured", function () {
72
+ var injector = (0, ts_mockito_1.mock)(di_1.InjectorService);
73
+ (0, ts_mockito_1.when)(injector.getMany("bullmq:queue")).thenReturn([]);
74
+ var dispatcher = new JobDispatcher_1.JobDispatcher((0, ts_mockito_1.instance)(injector));
75
+ expect(dispatcher.dispatch(NotConfiguredQueueTestJob)).rejects.toThrow(new Error("Queue(not-configured) not defined"));
76
+ (0, ts_mockito_1.verify)(injector.getMany("bullmq:queue")).once();
77
+ });
78
+ it("should dispatch job", function () { return __awaiter(void 0, void 0, void 0, function () {
79
+ var injector, queue, dispatcher;
80
+ return __generator(this, function (_a) {
81
+ switch (_a.label) {
82
+ case 0:
83
+ injector = (0, ts_mockito_1.mock)(di_1.InjectorService);
84
+ queue = (0, ts_mockito_1.mock)(bullmq_1.Queue);
85
+ (0, ts_mockito_1.when)(queue.name).thenReturn("default");
86
+ (0, ts_mockito_1.when)(injector.getMany("bullmq:queue")).thenReturn([(0, ts_mockito_1.instance)(queue)]);
87
+ dispatcher = new JobDispatcher_1.JobDispatcher((0, ts_mockito_1.instance)(injector));
88
+ return [4 /*yield*/, dispatcher.dispatch(ExampleTestJob, { msg: "hello test" })];
89
+ case 1:
90
+ _a.sent();
91
+ (0, ts_mockito_1.verify)(queue.add("example-job", (0, ts_mockito_1.objectContaining)({ msg: "hello test" }), (0, ts_mockito_1.objectContaining)({
92
+ backoff: 69
93
+ }))).once();
94
+ return [2 /*return*/];
95
+ }
96
+ });
97
+ }); });
98
+ });
@@ -0,0 +1,52 @@
1
+ import {InjectorService} from "@tsed/di";
2
+ import {JobDispatcher} from "./JobDispatcher";
3
+ import {JobMethods} from "../contracts";
4
+ import {JobController} from "../decorators";
5
+ import {Queue} from "bullmq";
6
+ import {instance, mock, verify, when, objectContaining} from "ts-mockito";
7
+
8
+ @JobController("example-job", "default", {
9
+ backoff: 69
10
+ })
11
+ class ExampleTestJob implements JobMethods {
12
+ handle(payload: {msg: string}) {}
13
+ }
14
+
15
+ @JobController("queue-not-configured", "not-configured")
16
+ class NotConfiguredQueueTestJob implements JobMethods {
17
+ handle() {}
18
+ }
19
+
20
+ describe("JobDispatcher", () => {
21
+ it("should throw an exception when a queue is not configured", () => {
22
+ const injector = mock(InjectorService);
23
+ when(injector.getMany("bullmq:queue")).thenReturn([]);
24
+
25
+ const dispatcher = new JobDispatcher(instance(injector));
26
+
27
+ expect(dispatcher.dispatch(NotConfiguredQueueTestJob)).rejects.toThrow(new Error("Queue(not-configured) not defined"));
28
+ verify(injector.getMany("bullmq:queue")).once();
29
+ });
30
+
31
+ it("should dispatch job", async () => {
32
+ const injector = mock(InjectorService);
33
+ const queue = mock(Queue);
34
+ when(queue.name).thenReturn("default");
35
+
36
+ when(injector.getMany("bullmq:queue")).thenReturn([instance(queue)]);
37
+
38
+ const dispatcher = new JobDispatcher(instance(injector));
39
+
40
+ await dispatcher.dispatch(ExampleTestJob, {msg: "hello test"});
41
+
42
+ verify(
43
+ queue.add(
44
+ "example-job",
45
+ objectContaining({msg: "hello test"}),
46
+ objectContaining({
47
+ backoff: 69
48
+ })
49
+ )
50
+ ).once();
51
+ });
52
+ });
@@ -0,0 +1,22 @@
1
+ import {InjectorService, Service} from "@tsed/di";
2
+ import {JobMethods, type JobStore} from "../contracts";
3
+ import {Store, Type} from "@tsed/core";
4
+ import {Job as BullMQJob, Queue} from "bullmq";
5
+
6
+ @Service()
7
+ export class JobDispatcher {
8
+ constructor(private readonly injector: InjectorService) {}
9
+
10
+ // eslint-disable-next-line require-await
11
+ public async dispatch<T extends JobMethods>(job: Type<JobMethods>, payload: Parameters<T["handle"]>[0] = {}): Promise<BullMQJob> {
12
+ const store = Store.from(job).get<JobStore>("bullmq");
13
+
14
+ const queue = this.injector.getMany<Queue>("bullmq:queue").find((queue) => queue.name === store.queue);
15
+
16
+ if (!queue) {
17
+ throw new Error(`Queue(${store.queue}) not defined`);
18
+ }
19
+
20
+ return queue.add(store.name, payload, store.opts);
21
+ }
22
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * @file Automatically generated by barrelsby.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ __exportStar(require("./JobDispatcher"), exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from "./JobDispatcher";
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file Automatically generated by barrelsby.
3
+ */
4
+
5
+ export * from "./BullMQModule";
6
+ export * from "./config/config";
7
+ export * from "./contracts/JobMethods";
8
+ export * from "./contracts/JobStore";
9
+ export * from "./decorators/JobController";
10
+ export * from "./dispatchers/JobDispatcher";
@@ -0,0 +1,39 @@
1
+ {
2
+ "extends": "@tsed/typescript/tsconfig.node.json",
3
+ "compilerOptions": {
4
+ "baseUrl": ".",
5
+ "module": "ES2020",
6
+ "rootDir": "src",
7
+ "outDir": "./lib/esm",
8
+ "declaration": true,
9
+ "declarationDir": "./lib/types",
10
+ "composite": true,
11
+ "noEmit": false
12
+ },
13
+ "include": ["src", "src/**/*.json"],
14
+ "exclude": [
15
+ "node_modules",
16
+ "test",
17
+ "lib",
18
+ "benchmark",
19
+ "coverage",
20
+ "spec",
21
+ "**/*.benchmark.ts",
22
+ "**/*.spec.ts",
23
+ "keys",
24
+ "jest.config.js",
25
+ "**/__mock__/**",
26
+ "webpack.config.js"
27
+ ],
28
+ "references": [
29
+ {
30
+ "path": "../../platform/common"
31
+ },
32
+ {
33
+ "path": "../../core"
34
+ },
35
+ {
36
+ "path": "../../di"
37
+ }
38
+ ]
39
+ }