@opens/bullmq 1.0.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/README.md +66 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# BullMQWrapper
|
|
2
|
+
|
|
3
|
+
BullMQWrapper is a wrapper around BullMQ that simplifies creating and managing task queues using Redis. It provides an easy interface for queue creation, worker registration, and task publishing.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
### Creating a Task Queue
|
|
8
|
+
|
|
9
|
+
To create a queue, you can use `createTask`. You can specify the queue name, job options, and an optional worker to process jobs.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
|
|
13
|
+
import { bullmq } from '@opens/bullmq';
|
|
14
|
+
|
|
15
|
+
bullmq.createTask({
|
|
16
|
+
taskName: 'example-task',
|
|
17
|
+
concurrency: 5,
|
|
18
|
+
up: async (job) => {
|
|
19
|
+
console.log('Processing job:', job.id);
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Publishing a Task
|
|
25
|
+
|
|
26
|
+
Once the queue is created, you can add tasks to it using `publishTask`.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
await bullmq.publishTask({
|
|
30
|
+
taskName: 'example-task',
|
|
31
|
+
taskData: { key: 'value' },
|
|
32
|
+
taskOptions: { delay: 1000 },
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Creating a Worker
|
|
37
|
+
|
|
38
|
+
Workers process jobs in the queue. You can create a worker separately using `createWorker`.
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
bullmq.createWorker({
|
|
42
|
+
taskName: 'example-task',
|
|
43
|
+
concurrency: 3,
|
|
44
|
+
up: async (job) => {
|
|
45
|
+
console.log('Job executed:', job.data);
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Getting Task Count
|
|
51
|
+
|
|
52
|
+
To check the number of active queues, use `getTaskCount`.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
console.log('Number of task queues:', bullmq.getTaskCount());
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Error Handling
|
|
59
|
+
|
|
60
|
+
- If a task queue does not exist, `publishTask` returns `null`.
|
|
61
|
+
- If a worker fails, you can define a `down` function to handle failures.
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
This project is licensed under the MIT License.
|
|
66
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import BullMQ from 'bullmq';
|
|
2
|
+
import { Redis } from 'ioredis';
|
|
3
|
+
|
|
4
|
+
declare class BullMQWrapper {
|
|
5
|
+
private defaultConnection;
|
|
6
|
+
private bullMQ;
|
|
7
|
+
private taskQueues;
|
|
8
|
+
constructor(defaultConnection: Redis, bullMQ: typeof BullMQ);
|
|
9
|
+
createTask(params: {
|
|
10
|
+
taskName: string;
|
|
11
|
+
defaultOptions: BullMQ.DefaultJobOptions;
|
|
12
|
+
connection?: Redis;
|
|
13
|
+
up?: BullMQ.Processor;
|
|
14
|
+
down?: BullMQ.Processor;
|
|
15
|
+
concurrency?: number;
|
|
16
|
+
removeOnCompleteAge?: number;
|
|
17
|
+
removeOnCompleteCount?: number;
|
|
18
|
+
removeOnFailAge?: number;
|
|
19
|
+
removeOnFailCount?: number;
|
|
20
|
+
}): {
|
|
21
|
+
queue: BullMQ.Queue<any, any, string, any, any, string>;
|
|
22
|
+
worker?: undefined;
|
|
23
|
+
} | {
|
|
24
|
+
queue: BullMQ.Queue<any, any, string, any, any, string>;
|
|
25
|
+
worker: BullMQ.Worker<any, any, string>;
|
|
26
|
+
} | undefined;
|
|
27
|
+
createWorker(params: {
|
|
28
|
+
taskName: string;
|
|
29
|
+
up: BullMQ.Processor;
|
|
30
|
+
down?: BullMQ.Processor;
|
|
31
|
+
connection?: Redis;
|
|
32
|
+
concurrency: number;
|
|
33
|
+
removeOnCompleteAge?: number;
|
|
34
|
+
removeOnCompleteCount?: number;
|
|
35
|
+
removeOnFailAge?: number;
|
|
36
|
+
removeOnFailCount?: number;
|
|
37
|
+
onError?: Function;
|
|
38
|
+
}): {
|
|
39
|
+
worker: BullMQ.Worker<any, any, string>;
|
|
40
|
+
};
|
|
41
|
+
publishTask(params: {
|
|
42
|
+
taskName: string;
|
|
43
|
+
taskData: any;
|
|
44
|
+
taskOptions: BullMQ.JobsOptions;
|
|
45
|
+
}): Promise<BullMQ.JobJson | null>;
|
|
46
|
+
getTaskCount(): number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare const bullmq: BullMQWrapper;
|
|
50
|
+
|
|
51
|
+
export { bullmq };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
bullmq: () => bullmq
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/wrapper.ts
|
|
38
|
+
var BullMQWrapper = class {
|
|
39
|
+
constructor(defaultConnection, bullMQ) {
|
|
40
|
+
this.defaultConnection = defaultConnection;
|
|
41
|
+
this.bullMQ = bullMQ;
|
|
42
|
+
}
|
|
43
|
+
taskQueues = /* @__PURE__ */ new Map();
|
|
44
|
+
createTask(params) {
|
|
45
|
+
const { taskName, up, down, defaultOptions, connection, concurrency } = params;
|
|
46
|
+
if (this.taskQueues.has(taskName)) return;
|
|
47
|
+
const queue = new this.bullMQ.Queue(taskName, {
|
|
48
|
+
connection: this.defaultConnection ?? connection,
|
|
49
|
+
defaultJobOptions: defaultOptions
|
|
50
|
+
});
|
|
51
|
+
this.taskQueues.set(taskName, queue);
|
|
52
|
+
if (!up) return { queue };
|
|
53
|
+
const { worker } = this.createWorker({
|
|
54
|
+
up,
|
|
55
|
+
down,
|
|
56
|
+
concurrency: concurrency ?? 1,
|
|
57
|
+
...params
|
|
58
|
+
});
|
|
59
|
+
return { queue, worker };
|
|
60
|
+
}
|
|
61
|
+
createWorker(params) {
|
|
62
|
+
const {
|
|
63
|
+
taskName,
|
|
64
|
+
up,
|
|
65
|
+
down,
|
|
66
|
+
concurrency,
|
|
67
|
+
connection,
|
|
68
|
+
removeOnFailCount,
|
|
69
|
+
removeOnCompleteAge,
|
|
70
|
+
removeOnCompleteCount,
|
|
71
|
+
removeOnFailAge
|
|
72
|
+
} = params;
|
|
73
|
+
const registeredQueue = this.taskQueues.get(taskName);
|
|
74
|
+
if (!registeredQueue) throw new Error(`No task queue for [${taskName}] found`);
|
|
75
|
+
const worker = new this.bullMQ.Worker(
|
|
76
|
+
taskName,
|
|
77
|
+
async (job) => {
|
|
78
|
+
try {
|
|
79
|
+
await up(job);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (down) await down(job).catch(console.error);
|
|
82
|
+
throw error;
|
|
83
|
+
} finally {
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
concurrency,
|
|
88
|
+
connection: connection ?? this.defaultConnection,
|
|
89
|
+
removeOnComplete: {
|
|
90
|
+
age: removeOnCompleteAge ?? 0,
|
|
91
|
+
count: removeOnCompleteCount ?? 0
|
|
92
|
+
},
|
|
93
|
+
removeOnFail: {
|
|
94
|
+
age: removeOnFailAge ?? 0,
|
|
95
|
+
count: removeOnFailCount ?? 0
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
);
|
|
99
|
+
return { worker };
|
|
100
|
+
}
|
|
101
|
+
async publishTask(params) {
|
|
102
|
+
const queue = this.taskQueues.get(params.taskName);
|
|
103
|
+
if (!queue) return null;
|
|
104
|
+
const job = await queue.add("", params.taskData, params.taskOptions);
|
|
105
|
+
return job.asJSON();
|
|
106
|
+
}
|
|
107
|
+
getTaskCount() {
|
|
108
|
+
return this.taskQueues.size;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
// src/default-connection.ts
|
|
113
|
+
var import_ioredis = require("ioredis");
|
|
114
|
+
var DefaultConnection = class {
|
|
115
|
+
static getInstance() {
|
|
116
|
+
const host = process.env.REDIS_HOST;
|
|
117
|
+
const port = process.env.PORT;
|
|
118
|
+
if (!host) throw new Error("Environment variable ${REDIS_HOST} isnt set");
|
|
119
|
+
if (!port) throw new Error("Environment variable ${REDIS_PORT} isnt set");
|
|
120
|
+
return new import_ioredis.Redis({ host, port: parseInt(port), maxRetriesPerRequest: null });
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/index.ts
|
|
125
|
+
var import_bullmq = __toESM(require("bullmq"));
|
|
126
|
+
var bullmq = new BullMQWrapper(DefaultConnection.getInstance(), import_bullmq.default);
|
|
127
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
128
|
+
0 && (module.exports = {
|
|
129
|
+
bullmq
|
|
130
|
+
});
|
|
131
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/wrapper.ts","../src/default-connection.ts"],"sourcesContent":["import { BullMQWrapper } from './wrapper';\nimport { DefaultConnection } from './default-connection';\nimport BullMQ from 'bullmq';\nexport const bullmq = new BullMQWrapper(DefaultConnection.getInstance(), BullMQ);\n","import BullMQ from 'bullmq';\nimport { Redis } from 'ioredis';\n\nexport class BullMQWrapper {\n private taskQueues: Map<string, BullMQ.Queue> = new Map();\n\n constructor(private defaultConnection: Redis, private bullMQ: typeof BullMQ) {}\n\n public createTask(params: {\n taskName: string;\n defaultOptions: BullMQ.DefaultJobOptions;\n connection?: Redis;\n up?: BullMQ.Processor;\n down?: BullMQ.Processor;\n concurrency?: number;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n }) {\n const { taskName, up, down, defaultOptions, connection, concurrency } = params;\n if (this.taskQueues.has(taskName)) return;\n\n const queue = new this.bullMQ.Queue(taskName, {\n connection: this.defaultConnection ?? connection,\n defaultJobOptions: defaultOptions,\n });\n this.taskQueues.set(taskName, queue);\n\n if (!up) return { queue };\n\n const { worker } = this.createWorker({\n up,\n down,\n concurrency: concurrency ?? 1,\n ...params,\n });\n return { queue, worker };\n }\n\n public createWorker(params: {\n taskName: string;\n up: BullMQ.Processor;\n down?: BullMQ.Processor;\n connection?: Redis;\n concurrency: number;\n removeOnCompleteAge?: number;\n removeOnCompleteCount?: number;\n removeOnFailAge?: number;\n removeOnFailCount?: number;\n onError?: Function;\n }) {\n const {\n taskName,\n up,\n down,\n concurrency,\n connection,\n removeOnFailCount,\n removeOnCompleteAge,\n removeOnCompleteCount,\n removeOnFailAge,\n } = params;\n const registeredQueue = this.taskQueues.get(taskName);\n if (!registeredQueue) throw new Error(`No task queue for [${taskName}] found`);\n\n const worker = new this.bullMQ.Worker(\n taskName,\n async (job) => {\n try {\n await up(job);\n } catch (error) {\n if (down) await down(job).catch(console.error);\n throw error;\n } finally {\n }\n },\n {\n concurrency,\n connection: connection ?? this.defaultConnection,\n removeOnComplete: {\n age: removeOnCompleteAge ?? 0,\n count: removeOnCompleteCount ?? 0,\n },\n removeOnFail: {\n age: removeOnFailAge ?? 0,\n count: removeOnFailCount ?? 0,\n },\n },\n );\n\n return { worker };\n }\n\n public async publishTask(params: { taskName: string; taskData: any; taskOptions: BullMQ.JobsOptions }) {\n const queue = this.taskQueues.get(params.taskName);\n if (!queue) return null;\n const job = await queue.add('', params.taskData, params.taskOptions);\n return job.asJSON();\n }\n\n public getTaskCount() {\n return this.taskQueues.size;\n }\n}\n","import { Redis } from 'ioredis';\nexport class DefaultConnection {\n static getInstance() {\n const host = process.env.REDIS_HOST;\n const port = process.env.PORT;\n if (!host) throw new Error('Environment variable ${REDIS_HOST} isnt set');\n if (!port) throw new Error('Environment variable ${REDIS_PORT} isnt set');\n return new Redis({ host, port: parseInt(port), maxRetriesPerRequest: null });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,IAAM,gBAAN,MAAoB;AAAA,EAGzB,YAAoB,mBAAkC,QAAuB;AAAzD;AAAkC;AAAA,EAAwB;AAAA,EAFtE,aAAwC,oBAAI,IAAI;AAAA,EAIjD,WAAW,QAWf;AACD,UAAM,EAAE,UAAU,IAAI,MAAM,gBAAgB,YAAY,YAAY,IAAI;AACxE,QAAI,KAAK,WAAW,IAAI,QAAQ,EAAG;AAEnC,UAAM,QAAQ,IAAI,KAAK,OAAO,MAAM,UAAU;AAAA,MAC5C,YAAY,KAAK,qBAAqB;AAAA,MACtC,mBAAmB;AAAA,IACrB,CAAC;AACD,SAAK,WAAW,IAAI,UAAU,KAAK;AAEnC,QAAI,CAAC,GAAI,QAAO,EAAE,MAAM;AAExB,UAAM,EAAE,OAAO,IAAI,KAAK,aAAa;AAAA,MACnC;AAAA,MACA;AAAA,MACA,aAAa,eAAe;AAAA,MAC5B,GAAG;AAAA,IACL,CAAC;AACD,WAAO,EAAE,OAAO,OAAO;AAAA,EACzB;AAAA,EAEO,aAAa,QAWjB;AACD,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AACJ,UAAM,kBAAkB,KAAK,WAAW,IAAI,QAAQ;AACpD,QAAI,CAAC,gBAAiB,OAAM,IAAI,MAAM,sBAAsB,QAAQ,SAAS;AAE7E,UAAM,SAAS,IAAI,KAAK,OAAO;AAAA,MAC7B;AAAA,MACA,OAAO,QAAQ;AACb,YAAI;AACF,gBAAM,GAAG,GAAG;AAAA,QACd,SAAS,OAAO;AACd,cAAI,KAAM,OAAM,KAAK,GAAG,EAAE,MAAM,QAAQ,KAAK;AAC7C,gBAAM;AAAA,QACR,UAAE;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA,YAAY,cAAc,KAAK;AAAA,QAC/B,kBAAkB;AAAA,UAChB,KAAK,uBAAuB;AAAA,UAC5B,OAAO,yBAAyB;AAAA,QAClC;AAAA,QACA,cAAc;AAAA,UACZ,KAAK,mBAAmB;AAAA,UACxB,OAAO,qBAAqB;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,OAAO;AAAA,EAClB;AAAA,EAEA,MAAa,YAAY,QAA8E;AACrG,UAAM,QAAQ,KAAK,WAAW,IAAI,OAAO,QAAQ;AACjD,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,MAAM,MAAM,MAAM,IAAI,IAAI,OAAO,UAAU,OAAO,WAAW;AACnE,WAAO,IAAI,OAAO;AAAA,EACpB;AAAA,EAEO,eAAe;AACpB,WAAO,KAAK,WAAW;AAAA,EACzB;AACF;;;ACxGA,qBAAsB;AACf,IAAM,oBAAN,MAAwB;AAAA,EAC7B,OAAO,cAAc;AACnB,UAAM,OAAO,QAAQ,IAAI;AACzB,UAAM,OAAO,QAAQ,IAAI;AACzB,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,6CAA6C;AACxE,QAAI,CAAC,KAAM,OAAM,IAAI,MAAM,6CAA6C;AACxE,WAAO,IAAI,qBAAM,EAAE,MAAM,MAAM,SAAS,IAAI,GAAG,sBAAsB,KAAK,CAAC;AAAA,EAC7E;AACF;;;AFPA,oBAAmB;AACZ,IAAM,SAAS,IAAI,cAAc,kBAAkB,YAAY,GAAG,cAAAA,OAAM;","names":["BullMQ"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opens/bullmq",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A wrapper around bullmq",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup --dts",
|
|
13
|
+
"dev": "tsup --watch",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest"
|
|
16
|
+
},
|
|
17
|
+
"tsup": {
|
|
18
|
+
"entry": [
|
|
19
|
+
"src/index.ts"
|
|
20
|
+
],
|
|
21
|
+
"splitting": false,
|
|
22
|
+
"sourcemap": true,
|
|
23
|
+
"clean": true
|
|
24
|
+
},
|
|
25
|
+
"author": "Joao Victor Clementino",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"ioredis-mock": "^8.9.0",
|
|
29
|
+
"tsup": "^8.3.5",
|
|
30
|
+
"typescript": "^5.7.3",
|
|
31
|
+
"vitest": "^3.0.4"
|
|
32
|
+
},
|
|
33
|
+
"private": false,
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"bullmq": "^5.41.3",
|
|
39
|
+
"ioredis": "^5.5.0"
|
|
40
|
+
}
|
|
41
|
+
}
|