@thynker-labs/queue-bullmq 0.0.1
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/dist/index.d.ts +41 -0
- package/dist/index.js +72 -0
- package/package.json +33 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Queue, Worker } from 'bullmq';
|
|
2
|
+
import { JobQueue, Envelope, Kernel, Stores } from '@thynker-labs/core';
|
|
3
|
+
|
|
4
|
+
declare const DEFAULT_QUEUE_NAME = "thynker-jobs";
|
|
5
|
+
interface BullMQConfig {
|
|
6
|
+
/** Env var holding Redis URL (default REDIS_URL). */
|
|
7
|
+
redisUrlEnv?: string;
|
|
8
|
+
queueName?: string;
|
|
9
|
+
}
|
|
10
|
+
interface QueuedJobPayload {
|
|
11
|
+
envelope: Envelope;
|
|
12
|
+
meta?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
declare class BullMQJobQueue implements JobQueue {
|
|
15
|
+
private queue;
|
|
16
|
+
constructor(config: BullMQConfig);
|
|
17
|
+
enqueue(job: {
|
|
18
|
+
envelope: Envelope;
|
|
19
|
+
meta?: object;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
id: string;
|
|
22
|
+
}>;
|
|
23
|
+
getQueue(): Queue<QueuedJobPayload>;
|
|
24
|
+
close(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
interface BullMQWorkerOptions {
|
|
27
|
+
config: BullMQConfig;
|
|
28
|
+
kernel: Kernel;
|
|
29
|
+
stores?: Stores;
|
|
30
|
+
/** Called after a job completes (e.g. persist async chat result). */
|
|
31
|
+
onJobComplete?: (args: {
|
|
32
|
+
jobId: string;
|
|
33
|
+
envelope: Envelope;
|
|
34
|
+
meta?: Record<string, unknown>;
|
|
35
|
+
responseText?: string;
|
|
36
|
+
}) => Promise<void>;
|
|
37
|
+
}
|
|
38
|
+
declare function createBullMQWorker(options: BullMQWorkerOptions): Worker<QueuedJobPayload>;
|
|
39
|
+
declare function createBullMQJobQueue(config: BullMQConfig): BullMQJobQueue;
|
|
40
|
+
|
|
41
|
+
export { type BullMQConfig, BullMQJobQueue, type BullMQWorkerOptions, DEFAULT_QUEUE_NAME, type QueuedJobPayload, createBullMQJobQueue, createBullMQWorker };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { Queue, Worker } from "bullmq";
|
|
3
|
+
var DEFAULT_QUEUE_NAME = "thynker-jobs";
|
|
4
|
+
function resolveRedisUrl(config) {
|
|
5
|
+
const envName = config.redisUrlEnv ?? "REDIS_URL";
|
|
6
|
+
const url = process.env[envName];
|
|
7
|
+
if (!url) {
|
|
8
|
+
throw new Error(`Missing ${envName} \u2014 required for BullMQ queue`);
|
|
9
|
+
}
|
|
10
|
+
return url;
|
|
11
|
+
}
|
|
12
|
+
function connectionFromUrl(url) {
|
|
13
|
+
return { url, maxRetriesPerRequest: null };
|
|
14
|
+
}
|
|
15
|
+
var BullMQJobQueue = class {
|
|
16
|
+
queue;
|
|
17
|
+
constructor(config) {
|
|
18
|
+
const url = resolveRedisUrl(config);
|
|
19
|
+
this.queue = new Queue(config.queueName ?? DEFAULT_QUEUE_NAME, {
|
|
20
|
+
connection: connectionFromUrl(url)
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async enqueue(job) {
|
|
24
|
+
const jobId = typeof job.meta === "object" && job.meta && "jobId" in job.meta && typeof job.meta.jobId === "string" ? job.meta.jobId : void 0;
|
|
25
|
+
const record = await this.queue.add("envelope", job, {
|
|
26
|
+
jobId,
|
|
27
|
+
removeOnComplete: 100,
|
|
28
|
+
removeOnFail: 500
|
|
29
|
+
});
|
|
30
|
+
return { id: record.id ?? `bull-${Date.now()}` };
|
|
31
|
+
}
|
|
32
|
+
getQueue() {
|
|
33
|
+
return this.queue;
|
|
34
|
+
}
|
|
35
|
+
async close() {
|
|
36
|
+
await this.queue.close();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
function createBullMQWorker(options) {
|
|
40
|
+
const url = resolveRedisUrl(options.config);
|
|
41
|
+
const queueName = options.config.queueName ?? DEFAULT_QUEUE_NAME;
|
|
42
|
+
const worker = new Worker(
|
|
43
|
+
queueName,
|
|
44
|
+
async (job) => {
|
|
45
|
+
const { envelope, meta } = job.data;
|
|
46
|
+
const { responseText } = await options.kernel.handle(envelope);
|
|
47
|
+
if (options.onJobComplete) {
|
|
48
|
+
await options.onJobComplete({
|
|
49
|
+
jobId: job.id ?? "unknown",
|
|
50
|
+
envelope,
|
|
51
|
+
meta,
|
|
52
|
+
responseText
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return { responseText };
|
|
56
|
+
},
|
|
57
|
+
{ connection: connectionFromUrl(url) }
|
|
58
|
+
);
|
|
59
|
+
worker.on("failed", (job, err) => {
|
|
60
|
+
console.error(`[bullmq] job ${job?.id} failed:`, err.message);
|
|
61
|
+
});
|
|
62
|
+
return worker;
|
|
63
|
+
}
|
|
64
|
+
function createBullMQJobQueue(config) {
|
|
65
|
+
return new BullMQJobQueue(config);
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
BullMQJobQueue,
|
|
69
|
+
DEFAULT_QUEUE_NAME,
|
|
70
|
+
createBullMQJobQueue,
|
|
71
|
+
createBullMQWorker
|
|
72
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@thynker-labs/queue-bullmq",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "BullMQ JobQueue adapter and worker for deferred agent tasks",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"bullmq": "5.56.0",
|
|
19
|
+
"ioredis": "5.6.1",
|
|
20
|
+
"@thynker-labs/core": "0.0.1"
|
|
21
|
+
},
|
|
22
|
+
"engines": {
|
|
23
|
+
"node": ">=20"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"test": "vitest run"
|
|
32
|
+
}
|
|
33
|
+
}
|