@blokjs/trigger-worker 0.2.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/CHANGELOG.md +22 -0
- package/dist/WorkerTrigger.d.ts +197 -0
- package/dist/WorkerTrigger.js +311 -0
- package/dist/adapters/BullMQAdapter.d.ts +71 -0
- package/dist/adapters/BullMQAdapter.js +259 -0
- package/dist/adapters/InMemoryAdapter.d.ts +48 -0
- package/dist/adapters/InMemoryAdapter.js +224 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.js +64 -0
- package/package.json +45 -0
- package/src/WorkerTrigger.test.ts +510 -0
- package/src/WorkerTrigger.ts +501 -0
- package/src/adapters/BullMQAdapter.ts +296 -0
- package/src/adapters/InMemoryAdapter.ts +276 -0
- package/src/index.ts +67 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* BullMQAdapter - Worker adapter using BullMQ (Redis-backed)
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Redis-backed persistent job queues
|
|
7
|
+
* - Configurable concurrency per queue
|
|
8
|
+
* - Job priority support
|
|
9
|
+
* - Delayed job scheduling
|
|
10
|
+
* - Automatic retries with configurable backoff
|
|
11
|
+
* - Queue statistics
|
|
12
|
+
*
|
|
13
|
+
* Requires: bullmq and ioredis as peer dependencies
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const adapter = new BullMQAdapter({
|
|
18
|
+
* host: "localhost",
|
|
19
|
+
* port: 6379,
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.BullMQAdapter = void 0;
|
|
58
|
+
/**
|
|
59
|
+
* BullMQ Worker Adapter
|
|
60
|
+
*
|
|
61
|
+
* Uses BullMQ for robust, Redis-backed job processing with support for
|
|
62
|
+
* priority queues, delayed jobs, retries, and dead letter handling.
|
|
63
|
+
*/
|
|
64
|
+
class BullMQAdapter {
|
|
65
|
+
provider = "bullmq";
|
|
66
|
+
connection = null;
|
|
67
|
+
workers = new Map();
|
|
68
|
+
queues = new Map();
|
|
69
|
+
connected = false;
|
|
70
|
+
config;
|
|
71
|
+
constructor(config) {
|
|
72
|
+
this.config = {
|
|
73
|
+
host: config?.host || process.env.REDIS_HOST || "localhost",
|
|
74
|
+
port: config?.port ?? Number.parseInt(process.env.REDIS_PORT || "6379", 10),
|
|
75
|
+
password: config?.password || process.env.REDIS_PASSWORD,
|
|
76
|
+
db: config?.db ?? Number.parseInt(process.env.REDIS_DB || "0", 10),
|
|
77
|
+
prefix: config?.prefix || "blok-worker",
|
|
78
|
+
maxStalledCount: config?.maxStalledCount ?? 2,
|
|
79
|
+
stalledInterval: config?.stalledInterval ?? 5000,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async connect() {
|
|
83
|
+
if (this.connected)
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
const { default: IORedis } = await Promise.resolve().then(() => __importStar(require("ioredis")));
|
|
87
|
+
this.connection = new IORedis({
|
|
88
|
+
host: this.config.host,
|
|
89
|
+
port: this.config.port,
|
|
90
|
+
password: this.config.password,
|
|
91
|
+
db: this.config.db,
|
|
92
|
+
maxRetriesPerRequest: null, // Required for BullMQ
|
|
93
|
+
});
|
|
94
|
+
// Verify connection
|
|
95
|
+
await this.connection.ping();
|
|
96
|
+
this.connected = true;
|
|
97
|
+
console.log(`[BullMQAdapter] Connected to Redis at ${this.config.host}:${this.config.port}`);
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
throw new Error(`Failed to connect to Redis: ${error.message}. Ensure ioredis and bullmq are installed: npm install ioredis bullmq`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async disconnect() {
|
|
104
|
+
if (!this.connected)
|
|
105
|
+
return;
|
|
106
|
+
try {
|
|
107
|
+
// Close all workers
|
|
108
|
+
for (const [, worker] of this.workers) {
|
|
109
|
+
await worker.close();
|
|
110
|
+
}
|
|
111
|
+
this.workers.clear();
|
|
112
|
+
// Close all queues
|
|
113
|
+
for (const [, queue] of this.queues) {
|
|
114
|
+
await queue.close();
|
|
115
|
+
}
|
|
116
|
+
this.queues.clear();
|
|
117
|
+
// Close Redis connection
|
|
118
|
+
if (this.connection) {
|
|
119
|
+
await this.connection.quit();
|
|
120
|
+
}
|
|
121
|
+
this.connected = false;
|
|
122
|
+
console.log("[BullMQAdapter] Disconnected from Redis");
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
console.error(`[BullMQAdapter] Disconnect error: ${error.message}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async process(config, handler) {
|
|
129
|
+
if (!this.connected) {
|
|
130
|
+
throw new Error("Not connected. Call connect() first.");
|
|
131
|
+
}
|
|
132
|
+
try {
|
|
133
|
+
// Dynamic import to avoid hard dependency on bullmq
|
|
134
|
+
const bullmq = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
135
|
+
const BullWorker = bullmq.Worker;
|
|
136
|
+
const BullQueue = bullmq.Queue;
|
|
137
|
+
// Build worker options
|
|
138
|
+
const workerOpts = {
|
|
139
|
+
connection: this.connection,
|
|
140
|
+
concurrency: config.concurrency ?? 1,
|
|
141
|
+
prefix: this.config.prefix,
|
|
142
|
+
stalledInterval: this.config.stalledInterval ?? 5000,
|
|
143
|
+
maxStalledCount: this.config.maxStalledCount ?? 2,
|
|
144
|
+
};
|
|
145
|
+
const worker = new BullWorker(config.queue,
|
|
146
|
+
// BullMQ processor callback
|
|
147
|
+
((bullJob) => {
|
|
148
|
+
const job = bullJob;
|
|
149
|
+
const workerJob = {
|
|
150
|
+
id: job.id || `job-${Date.now()}`,
|
|
151
|
+
data: job.data,
|
|
152
|
+
headers: job.data?._headers || {},
|
|
153
|
+
queue: config.queue,
|
|
154
|
+
priority: job.opts?.priority ?? config.priority ?? 0,
|
|
155
|
+
attempts: job.attemptsMade,
|
|
156
|
+
maxRetries: config.retries ?? 3,
|
|
157
|
+
createdAt: new Date(job.timestamp),
|
|
158
|
+
delay: job.opts?.delay,
|
|
159
|
+
timeout: config.timeout,
|
|
160
|
+
raw: job,
|
|
161
|
+
complete: async () => {
|
|
162
|
+
// BullMQ auto-completes when processor resolves
|
|
163
|
+
},
|
|
164
|
+
fail: async (error, requeue) => {
|
|
165
|
+
if (!requeue) {
|
|
166
|
+
await job.moveToFailed(error, job.token || "", true);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
throw error; // BullMQ will auto-retry
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
return handler(workerJob);
|
|
174
|
+
}), workerOpts);
|
|
175
|
+
this.workers.set(config.queue, worker);
|
|
176
|
+
// Ensure queue object exists for job dispatching
|
|
177
|
+
if (!this.queues.has(config.queue)) {
|
|
178
|
+
const queue = new BullQueue(config.queue, {
|
|
179
|
+
connection: this.connection,
|
|
180
|
+
prefix: this.config.prefix,
|
|
181
|
+
});
|
|
182
|
+
this.queues.set(config.queue, queue);
|
|
183
|
+
}
|
|
184
|
+
console.log(`[BullMQAdapter] Processing queue: ${config.queue} (concurrency=${config.concurrency ?? 1})`);
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
throw new Error(`Failed to start processing: ${error.message}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async addJob(queue, data, opts) {
|
|
191
|
+
if (!this.connected) {
|
|
192
|
+
throw new Error("Not connected. Call connect() first.");
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
// Ensure queue exists
|
|
196
|
+
if (!this.queues.has(queue)) {
|
|
197
|
+
const { Queue } = await Promise.resolve().then(() => __importStar(require("bullmq")));
|
|
198
|
+
const q = new Queue(queue, {
|
|
199
|
+
connection: this.connection,
|
|
200
|
+
prefix: this.config.prefix,
|
|
201
|
+
});
|
|
202
|
+
this.queues.set(queue, q);
|
|
203
|
+
}
|
|
204
|
+
const q = this.queues.get(queue);
|
|
205
|
+
const job = await q.add("process", data, {
|
|
206
|
+
priority: opts?.priority,
|
|
207
|
+
delay: opts?.delay,
|
|
208
|
+
attempts: (opts?.retries ?? 3) + 1,
|
|
209
|
+
jobId: opts?.jobId,
|
|
210
|
+
backoff: {
|
|
211
|
+
type: "exponential",
|
|
212
|
+
delay: 1000,
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
return job.id;
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
throw new Error(`Failed to add job: ${error.message}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
async stopProcessing(queue) {
|
|
222
|
+
const worker = this.workers.get(queue);
|
|
223
|
+
if (worker) {
|
|
224
|
+
await worker.close();
|
|
225
|
+
this.workers.delete(queue);
|
|
226
|
+
console.log(`[BullMQAdapter] Stopped processing queue: ${queue}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
isConnected() {
|
|
230
|
+
return this.connected;
|
|
231
|
+
}
|
|
232
|
+
async healthCheck() {
|
|
233
|
+
if (!this.connected || !this.connection)
|
|
234
|
+
return false;
|
|
235
|
+
try {
|
|
236
|
+
await this.connection.ping();
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async getQueueStats(queue) {
|
|
244
|
+
if (!this.queues.has(queue)) {
|
|
245
|
+
return { waiting: 0, active: 0, completed: 0, failed: 0, delayed: 0 };
|
|
246
|
+
}
|
|
247
|
+
const q = this.queues.get(queue);
|
|
248
|
+
const [waiting, active, completed, failed, delayed] = await Promise.all([
|
|
249
|
+
q.getWaitingCount(),
|
|
250
|
+
q.getActiveCount(),
|
|
251
|
+
q.getCompletedCount(),
|
|
252
|
+
q.getFailedCount(),
|
|
253
|
+
q.getDelayedCount(),
|
|
254
|
+
]);
|
|
255
|
+
return { waiting, active, completed, failed, delayed };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
exports.BullMQAdapter = BullMQAdapter;
|
|
259
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnVsbE1RQWRhcHRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9CdWxsTVFBZGFwdGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBCSDs7Ozs7R0FLRztBQUNILE1BQWEsYUFBYTtJQUNoQixRQUFRLEdBQUcsUUFBaUIsQ0FBQztJQUM5QixVQUFVLEdBQVksSUFBSSxDQUFDO0lBQzNCLE9BQU8sR0FBeUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUMxQyxNQUFNLEdBQXlCLElBQUksR0FBRyxFQUFFLENBQUM7SUFDekMsU0FBUyxHQUFHLEtBQUssQ0FBQztJQUNULE1BQU0sQ0FBZTtJQUV0QyxZQUFZLE1BQThCO1FBQ3pDLElBQUksQ0FBQyxNQUFNLEdBQUc7WUFDYixJQUFJLEVBQUUsTUFBTSxFQUFFLElBQUksSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxXQUFXO1lBQzNELElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQztZQUMzRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWM7WUFDeEQsRUFBRSxFQUFFLE1BQU0sRUFBRSxFQUFFLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsSUFBSSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ2xFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxJQUFJLGFBQWE7WUFDdkMsZUFBZSxFQUFFLE1BQU0sRUFBRSxlQUFlLElBQUksQ0FBQztZQUM3QyxlQUFlLEVBQUUsTUFBTSxFQUFFLGVBQWUsSUFBSSxJQUFJ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LEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUN2RSxDQUFDO1FBRUQsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQU05QixDQUFDO1FBRUYsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7WUFDdkUsQ0FBQyxDQUFDLGVBQWUsRUFBRTtZQUNuQixDQUFDLENBQUMsY0FBYyxFQUFFO1lBQ2xCLENBQUMsQ0FBQyxpQkFBaUIsRUFBRTtZQUNyQixDQUFDLENBQUMsY0FBYyxFQUFFO1lBQ2xCLENBQUMsQ0FBQyxlQUFlLEVBQUU7U0FDbkIsQ0FBQyxDQUFDO1FBRUgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN4RCxDQUFDO0NBQ0Q7QUFuUEQsc0NBbVBDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCdWxsTVFBZGFwdGVyIC0gV29ya2VyIGFkYXB0ZXIgdXNpbmcgQnVsbE1RIChSZWRpcy1iYWNrZWQpXG4gKlxuICogRmVhdHVyZXM6XG4gKiAtIFJlZGlzLWJhY2tlZCBwZXJzaXN0ZW50IGpvYiBxdWV1ZXNcbiAqIC0gQ29uZmlndXJhYmxlIGNvbmN1cnJlbmN5IHBlciBxdWV1ZVxuICogLSBKb2IgcHJpb3JpdHkgc3VwcG9ydFxuICogLSBEZWxheWVkIGpvYiBzY2hlZHVsaW5nXG4gKiAtIEF1dG9tYXRpYyByZXRyaWVzIHdpdGggY29uZmlndXJhYmxlIGJhY2tvZmZcbiAqIC0gUXVldWUgc3RhdGlzdGljc1xuICpcbiAqIFJlcXVpcmVzOiBidWxsbXEgYW5kIGlvcmVkaXMgYXMgcGVlciBkZXBlbmRlbmNpZXNcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYWRhcHRlciA9IG5ldyBCdWxsTVFBZGFwdGVyKHtcbiAqICAgaG9zdDogXCJsb2NhbGhvc3RcIixcbiAqICAgcG9ydDogNjM3OSxcbiAqIH0pO1xuICogYGBgXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBXb3JrZXJBZGFwdGVyLCBXb3JrZXJKb2IsIFdvcmtlclF1ZXVlU3RhdHMgfSBmcm9tIFwiLi4vV29ya2VyVHJpZ2dlclwiO1xuXG5pbXBvcnQgdHlwZSB7IFdvcmtlclRyaWdnZXJPcHRzIH0gZnJvbSBcIkBibG9rL2hlbHBlclwiO1xuXG4vKipcbiAqIEJ1bGxNUSBhZGFwdGVyIGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBCdWxsTVFDb25maWcge1xuXHQvKiogUmVkaXMgaG9zdCAoZGVmYXVsdDogZnJvbSBSRURJU19IT1NUIGVudiBvciBcImxvY2FsaG9zdFwiKSAqL1xuXHRob3N0OiBzdHJpbmc7XG5cdC8qKiBSZWRpcyBwb3J0IChkZWZhdWx0OiBmcm9tIFJFRElTX1BPUlQgZW52IG9yIDYzNzkpICovXG5cdHBvcnQ6IG51bWJlcjtcblx0LyoqIFJlZGlzIHBhc3N3b3JkIChkZWZhdWx0OiBmcm9tIFJFRElTX1BBU1NXT1JEIGVudikgKi9cblx0cGFzc3dvcmQ/OiBzdHJpbmc7XG5cdC8qKiBSZWRpcyBkYXRhYmFzZSAoZGVmYXVsdDogZnJvbSBSRURJU19EQiBlbnYgb3IgMCkgKi9cblx0ZGI/OiBudW1iZXI7XG5cdC8qKiBLZXkgcHJlZml4IGZvciBhbGwgQnVsbE1RIGtleXMgKi9cblx0cHJlZml4Pzogc3RyaW5nO1xuXHQvKiogTWF4IHN0YWxsZWQgY291bnQgYmVmb3JlIGpvYiBmYWlscyAqL1xuXHRtYXhTdGFsbGVkQ291bnQ/OiBudW1iZXI7XG5cdC8qKiBTdGFsbGVkIGludGVydmFsIGluIG1zICovXG5cdHN0YWxsZWRJbnRlcnZhbD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBCdWxsTVEgV29ya2VyIEFkYXB0ZXJcbiAqXG4gKiBVc2VzIEJ1bGxNUSBmb3Igcm9idXN0LCBSZWRpcy1iYWNrZWQgam9iIHByb2Nlc3Npbmcgd2l0aCBzdXBwb3J0IGZvclxuICogcHJpb3JpdHkgcXVldWVzLCBkZWxheWVkIGpvYnMsIHJldHJpZXMsIGFuZCBkZWFkIGxldHRlciBoYW5kbGluZy5cbiAqL1xuZXhwb3J0IGNsYXNzIEJ1bGxNUUFkYXB0ZXIgaW1wbGVtZW50cyBXb3JrZXJBZGFwdGVyIHtcblx0cmVhZG9ubHkgcHJvdmlkZXIgPSBcImJ1bGxtcVwiIGFzIGNvbnN0O1xuXHRwcml2YXRlIGNvbm5lY3Rpb246IHVua25vd24gPSBudWxsO1xuXHRwcml2YXRlIHdvcmtlcnM6IE1hcDxzdHJpbmcsIHVua25vd24+ID0gbmV3IE1hcCgpO1xuXHRwcml2YXRlIHF1ZXVlczogTWFwPHN0cmluZywgdW5rbm93bj4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgY29ubmVjdGVkID0gZmFsc2U7XG5cdHByaXZhdGUgcmVhZG9ubHkgY29uZmlnOiBCdWxsTVFDb25maWc7XG5cblx0Y29uc3RydWN0b3IoY29uZmlnPzogUGFydGlhbDxCdWxsTVFDb25maWc+KSB7XG5cdFx0dGhpcy5jb25maWcgPSB7XG5cdFx0XHRob3N0OiBjb25maWc/Lmhvc3QgfHwgcHJvY2Vzcy5lbnYuUkVESVNfSE9TVCB8fCBcImxvY2FsaG9zdFwiLFxuXHRcdFx0cG9ydDogY29uZmlnPy5wb3J0ID8/IE51bWJlci5wYXJzZUludChwcm9jZXNzLmVudi5SRURJU19QT1JUIHx8IFwiNjM3OVwiLCAxMCksXG5cdFx0XHRwYXNzd29yZDogY29uZmlnPy5wYXNzd29yZCB8fCBwcm9jZXNzLmVudi5SRURJU19QQVNTV09SRCxcblx0XHRcdGRiOiBjb25maWc/LmRiID8/IE51bWJlci5wYXJzZUludChwcm9jZXNzLmVudi5SRURJU19EQiB8fCBcIjBcIiwgMTApLFxuXHRcdFx0cHJlZml4OiBjb25maWc/LnByZWZpeCB8fCBcImJsb2std29ya2VyXCIsXG5cdFx0XHRtYXhTdGFsbGVkQ291bnQ6IGNvbmZpZz8ubWF4U3RhbGxlZENvdW50ID8/IDIsXG5cdFx0XHRzdGFsbGVkSW50ZXJ2YWw6IGNvbmZpZz8uc3RhbGxlZEludGVydmFsID8/IDUwMDAsXG5cdFx0fTtcblx0fVxuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm47XG5cblx0XHR0cnkge1xuXHRcdFx0Y29uc3QgeyBkZWZhdWx0OiBJT1JlZGlzIH0gPSBhd2FpdCBpbXBvcnQoXCJpb3JlZGlzXCIpO1xuXHRcdFx0dGhpcy5jb25uZWN0aW9uID0gbmV3IElPUmVkaXMoe1xuXHRcdFx0XHRob3N0OiB0aGlzLmNvbmZpZy5ob3N0LFxuXHRcdFx0XHRwb3J0OiB0aGlzLmNvbmZpZy5wb3J0LFxuXHRcdFx0XHRwYXNzd29yZDogdGhpcy5jb25maWcucGFzc3dvcmQsXG5cdFx0XHRcdGRiOiB0aGlzLmNvbmZpZy5kYixcblx0XHRcdFx0bWF4UmV0cmllc1BlclJlcXVlc3Q6IG51bGwsIC8vIFJlcXVpcmVkIGZvciBCdWxsTVFcblx0XHRcdH0pO1xuXG5cdFx0XHQvLyBWZXJpZnkgY29ubmVjdGlvblxuXHRcdFx0YXdhaXQgKHRoaXMuY29ubmVjdGlvbiBhcyB7IHBpbmc6ICgpID0+IFByb21pc2U8c3RyaW5nPiB9KS5waW5nKCk7XG5cdFx0XHR0aGlzLmNvbm5lY3RlZCA9IHRydWU7XG5cdFx0XHRjb25zb2xlLmxvZyhgW0J1bGxNUUFkYXB0ZXJdIENvbm5lY3RlZCB0byBSZWRpcyBhdCAke3RoaXMuY29uZmlnLmhvc3R9OiR7dGhpcy5jb25maWcucG9ydH1gKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRgRmFpbGVkIHRvIGNvbm5lY3QgdG8gUmVkaXM6ICR7KGVycm9yIGFzIEVycm9yKS5tZXNzYWdlfS4gRW5zdXJlIGlvcmVkaXMgYW5kIGJ1bGxtcSBhcmUgaW5zdGFsbGVkOiBucG0gaW5zdGFsbCBpb3JlZGlzIGJ1bGxtcWAsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdGFzeW5jIGRpc2Nvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0aWYgKCF0aGlzLmNvbm5lY3RlZCkgcmV0dXJuO1xuXG5cdFx0dHJ5IHtcblx0XHRcdC8vIENsb3NlIGFsbCB3b3JrZXJzXG5cdFx0XHRmb3IgKGNvbnN0IFssIHdvcmtlcl0gb2YgdGhpcy53b3JrZXJzKSB7XG5cdFx0XHRcdGF3YWl0ICh3b3JrZXIgYXMgeyBjbG9zZTogKCkgPT4gUHJvbWlzZTx2b2lkPiB9KS5jbG9zZSgpO1xuXHRcdFx0fVxuXHRcdFx0dGhpcy53b3JrZXJzLmNsZWFyKCk7XG5cblx0XHRcdC8vIENsb3NlIGFsbCBxdWV1ZXNcblx0XHRcdGZvciAoY29uc3QgWywgcXVldWVdIG9mIHRoaXMucXVldWVzKSB7XG5cdFx0XHRcdGF3YWl0IChxdWV1ZSBhcyB7IGNsb3NlOiAoKSA9PiBQcm9taXNlPHZvaWQ+IH0pLmNsb3NlKCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnF1ZXVlcy5jbGVhcigpO1xuXG5cdFx0XHQvLyBDbG9zZSBSZWRpcyBjb25uZWN0aW9uXG5cdFx0XHRpZiAodGhpcy5jb25uZWN0aW9uKSB7XG5cdFx0XHRcdGF3YWl0ICh0aGlzLmNvbm5lY3Rpb24gYXMgeyBxdWl0OiAoKSA9PiBQcm9taXNlPHN0cmluZz4gfSkucXVpdCgpO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHRcdFx0Y29uc29sZS5sb2coXCJbQnVsbE1RQWRhcHRlcl0gRGlzY29ubmVjdGVkIGZyb20gUmVkaXNcIik7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoYFtCdWxsTVFBZGFwdGVyXSBEaXNjb25uZWN0IGVycm9yOiAkeyhlcnJvciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBwcm9jZXNzKGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHMsIGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIk5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0Ly8gRHluYW1pYyBpbXBvcnQgdG8gYXZvaWQgaGFyZCBkZXBlbmRlbmN5IG9uIGJ1bGxtcVxuXHRcdFx0Y29uc3QgYnVsbG1xID0gYXdhaXQgaW1wb3J0KFwiYnVsbG1xXCIpO1xuXHRcdFx0Y29uc3QgQnVsbFdvcmtlciA9IGJ1bGxtcS5Xb3JrZXI7XG5cdFx0XHRjb25zdCBCdWxsUXVldWUgPSBidWxsbXEuUXVldWU7XG5cblx0XHRcdC8vIEJ1aWxkIHdvcmtlciBvcHRpb25zXG5cdFx0XHRjb25zdCB3b3JrZXJPcHRzID0ge1xuXHRcdFx0XHRjb25uZWN0aW9uOiB0aGlzLmNvbm5lY3Rpb24sXG5cdFx0XHRcdGNvbmN1cnJlbmN5OiBjb25maWcuY29uY3VycmVuY3kgPz8gMSxcblx0XHRcdFx0cHJlZml4OiB0aGlzLmNvbmZpZy5wcmVmaXgsXG5cdFx0XHRcdHN0YWxsZWRJbnRlcnZhbDogdGhpcy5jb25maWcuc3RhbGxlZEludGVydmFsID8/IDUwMDAsXG5cdFx0XHRcdG1heFN0YWxsZWRDb3VudDogdGhpcy5jb25maWcubWF4U3RhbGxlZENvdW50ID8/IDIsXG5cdFx0XHR9O1xuXG5cdFx0XHRjb25zdCB3b3JrZXIgPSBuZXcgQnVsbFdvcmtlcihcblx0XHRcdFx0Y29uZmlnLnF1ZXVlLFxuXHRcdFx0XHQvLyBCdWxsTVEgcHJvY2Vzc29yIGNhbGxiYWNrXG5cdFx0XHRcdCgoYnVsbEpvYjogdW5rbm93bikgPT4ge1xuXHRcdFx0XHRcdGNvbnN0IGpvYiA9IGJ1bGxKb2IgYXMge1xuXHRcdFx0XHRcdFx0aWQ/OiBzdHJpbmc7XG5cdFx0XHRcdFx0XHRkYXRhOiB1bmtub3duO1xuXHRcdFx0XHRcdFx0b3B0cz86IHsgcHJpb3JpdHk/OiBudW1iZXI7IGRlbGF5PzogbnVtYmVyIH07XG5cdFx0XHRcdFx0XHRhdHRlbXB0c01hZGU6IG51bWJlcjtcblx0XHRcdFx0XHRcdHRpbWVzdGFtcDogbnVtYmVyO1xuXHRcdFx0XHRcdFx0dG9rZW4/OiBzdHJpbmc7XG5cdFx0XHRcdFx0XHRtb3ZlVG9GYWlsZWQ6IChlcnI6IEVycm9yLCB0b2tlbjogc3RyaW5nLCBmZXRjaE5leHQ6IGJvb2xlYW4pID0+IFByb21pc2U8dm9pZD47XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0XHRjb25zdCB3b3JrZXJKb2I6IFdvcmtlckpvYiA9IHtcblx0XHRcdFx0XHRcdGlkOiBqb2IuaWQgfHwgYGpvYi0ke0RhdGUubm93KCl9YCxcblx0XHRcdFx0XHRcdGRhdGE6IGpvYi5kYXRhLFxuXHRcdFx0XHRcdFx0aGVhZGVyczogKChqb2IuZGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik/Ll9oZWFkZXJzIGFzIFJlY29yZDxzdHJpbmcsIHN0cmluZz4pIHx8IHt9LFxuXHRcdFx0XHRcdFx0cXVldWU6IGNvbmZpZy5xdWV1ZSxcblx0XHRcdFx0XHRcdHByaW9yaXR5OiBqb2Iub3B0cz8ucHJpb3JpdHkgPz8gY29uZmlnLnByaW9yaXR5ID8/IDAsXG5cdFx0XHRcdFx0XHRhdHRlbXB0czogam9iLmF0dGVtcHRzTWFkZSxcblx0XHRcdFx0XHRcdG1heFJldHJpZXM6IGNvbmZpZy5yZXRyaWVzID8/IDMsXG5cdFx0XHRcdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKGpvYi50aW1lc3RhbXApLFxuXHRcdFx0XHRcdFx0ZGVsYXk6IGpvYi5vcHRzPy5kZWxheSxcblx0XHRcdFx0XHRcdHRpbWVvdXQ6IGNvbmZpZy50aW1lb3V0LFxuXHRcdFx0XHRcdFx0cmF3OiBqb2IsXG5cdFx0XHRcdFx0XHRjb21wbGV0ZTogYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHQvLyBCdWxsTVEgYXV0by1jb21wbGV0ZXMgd2hlbiBwcm9jZXNzb3IgcmVzb2x2ZXNcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRmYWlsOiBhc3luYyAoZXJyb3I6IEVycm9yLCByZXF1ZXVlPzogYm9vbGVhbikgPT4ge1xuXHRcdFx0XHRcdFx0XHRpZiAoIXJlcXVldWUpIHtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCBqb2IubW92ZVRvRmFpbGVkKGVycm9yLCBqb2IudG9rZW4gfHwgXCJcIiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgZXJyb3I7IC8vIEJ1bGxNUSB3aWxsIGF1dG8tcmV0cnlcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdHJldHVybiBoYW5kbGVyKHdvcmtlckpvYik7XG5cdFx0XHRcdH0pIGFzIG5ldmVyLFxuXHRcdFx0XHR3b3JrZXJPcHRzIGFzIG5ldmVyLFxuXHRcdFx0KTtcblxuXHRcdFx0dGhpcy53b3JrZXJzLnNldChjb25maWcucXVldWUsIHdvcmtlcik7XG5cblx0XHRcdC8vIEVuc3VyZSBxdWV1ZSBvYmplY3QgZXhpc3RzIGZvciBqb2IgZGlzcGF0Y2hpbmdcblx0XHRcdGlmICghdGhpcy5xdWV1ZXMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdFx0Y29uc3QgcXVldWUgPSBuZXcgQnVsbFF1ZXVlKGNvbmZpZy5xdWV1ZSwge1xuXHRcdFx0XHRcdGNvbm5lY3Rpb246IHRoaXMuY29ubmVjdGlvbiBhcyB7IGhvc3Q6IHN0cmluZzsgcG9ydDogbnVtYmVyIH0sXG5cdFx0XHRcdFx0cHJlZml4OiB0aGlzLmNvbmZpZy5wcmVmaXgsXG5cdFx0XHRcdH0gYXMgbmV2ZXIpO1xuXHRcdFx0XHR0aGlzLnF1ZXVlcy5zZXQoY29uZmlnLnF1ZXVlLCBxdWV1ZSk7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnNvbGUubG9nKGBbQnVsbE1RQWRhcHRlcl0gUHJvY2Vzc2luZyBxdWV1ZTogJHtjb25maWcucXVldWV9IChjb25jdXJyZW5jeT0ke2NvbmZpZy5jb25jdXJyZW5jeSA/PyAxfSlgKTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gc3RhcnQgcHJvY2Vzc2luZzogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgYWRkSm9iKFxuXHRcdHF1ZXVlOiBzdHJpbmcsXG5cdFx0ZGF0YTogdW5rbm93bixcblx0XHRvcHRzPzoge1xuXHRcdFx0cHJpb3JpdHk/OiBudW1iZXI7XG5cdFx0XHRkZWxheT86IG51bWJlcjtcblx0XHRcdHJldHJpZXM/OiBudW1iZXI7XG5cdFx0XHR0aW1lb3V0PzogbnVtYmVyO1xuXHRcdFx0am9iSWQ/OiBzdHJpbmc7XG5cdFx0fSxcblx0KTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0dHJ5IHtcblx0XHRcdC8vIEVuc3VyZSBxdWV1ZSBleGlzdHNcblx0XHRcdGlmICghdGhpcy5xdWV1ZXMuaGFzKHF1ZXVlKSkge1xuXHRcdFx0XHRjb25zdCB7IFF1ZXVlIH0gPSBhd2FpdCBpbXBvcnQoXCJidWxsbXFcIik7XG5cdFx0XHRcdGNvbnN0IHEgPSBuZXcgUXVldWUocXVldWUsIHtcblx0XHRcdFx0XHRjb25uZWN0aW9uOiB0aGlzLmNvbm5lY3Rpb24gYXMgeyBob3N0OiBzdHJpbmc7IHBvcnQ6IG51bWJlciB9LFxuXHRcdFx0XHRcdHByZWZpeDogdGhpcy5jb25maWcucHJlZml4LFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0dGhpcy5xdWV1ZXMuc2V0KHF1ZXVlLCBxKTtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcSA9IHRoaXMucXVldWVzLmdldChxdWV1ZSkgYXMge1xuXHRcdFx0XHRhZGQ6IChuYW1lOiBzdHJpbmcsIGRhdGE6IHVua25vd24sIG9wdHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KSA9PiBQcm9taXNlPHsgaWQ6IHN0cmluZyB9Pjtcblx0XHRcdH07XG5cblx0XHRcdGNvbnN0IGpvYiA9IGF3YWl0IHEuYWRkKFwicHJvY2Vzc1wiLCBkYXRhLCB7XG5cdFx0XHRcdHByaW9yaXR5OiBvcHRzPy5wcmlvcml0eSxcblx0XHRcdFx0ZGVsYXk6IG9wdHM/LmRlbGF5LFxuXHRcdFx0XHRhdHRlbXB0czogKG9wdHM/LnJldHJpZXMgPz8gMykgKyAxLFxuXHRcdFx0XHRqb2JJZDogb3B0cz8uam9iSWQsXG5cdFx0XHRcdGJhY2tvZmY6IHtcblx0XHRcdFx0XHR0eXBlOiBcImV4cG9uZW50aWFsXCIsXG5cdFx0XHRcdFx0ZGVsYXk6IDEwMDAsXG5cdFx0XHRcdH0sXG5cdFx0XHR9KTtcblxuXHRcdFx0cmV0dXJuIGpvYi5pZDtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYWRkIGpvYjogJHsoZXJyb3IgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG5cdFx0fVxuXHR9XG5cblx0YXN5bmMgc3RvcFByb2Nlc3NpbmcocXVldWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHdvcmtlciA9IHRoaXMud29ya2Vycy5nZXQocXVldWUpO1xuXHRcdGlmICh3b3JrZXIpIHtcblx0XHRcdGF3YWl0ICh3b3JrZXIgYXMgeyBjbG9zZTogKCkgPT4gUHJvbWlzZTx2b2lkPiB9KS5jbG9zZSgpO1xuXHRcdFx0dGhpcy53b3JrZXJzLmRlbGV0ZShxdWV1ZSk7XG5cdFx0XHRjb25zb2xlLmxvZyhgW0J1bGxNUUFkYXB0ZXJdIFN0b3BwZWQgcHJvY2Vzc2luZyBxdWV1ZTogJHtxdWV1ZX1gKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkIHx8ICF0aGlzLmNvbm5lY3Rpb24pIHJldHVybiBmYWxzZTtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgKHRoaXMuY29ubmVjdGlvbiBhcyB7IHBpbmc6ICgpID0+IFByb21pc2U8c3RyaW5nPiB9KS5waW5nKCk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRpZiAoIXRoaXMucXVldWVzLmhhcyhxdWV1ZSkpIHtcblx0XHRcdHJldHVybiB7IHdhaXRpbmc6IDAsIGFjdGl2ZTogMCwgY29tcGxldGVkOiAwLCBmYWlsZWQ6IDAsIGRlbGF5ZWQ6IDAgfTtcblx0XHR9XG5cblx0XHRjb25zdCBxID0gdGhpcy5xdWV1ZXMuZ2V0KHF1ZXVlKSBhcyB7XG5cdFx0XHRnZXRXYWl0aW5nQ291bnQ6ICgpID0+IFByb21pc2U8bnVtYmVyPjtcblx0XHRcdGdldEFjdGl2ZUNvdW50OiAoKSA9PiBQcm9taXNlPG51bWJlcj47XG5cdFx0XHRnZXRDb21wbGV0ZWRDb3VudDogKCkgPT4gUHJvbWlzZTxudW1iZXI+O1xuXHRcdFx0Z2V0RmFpbGVkQ291bnQ6ICgpID0+IFByb21pc2U8bnVtYmVyPjtcblx0XHRcdGdldERlbGF5ZWRDb3VudDogKCkgPT4gUHJvbWlzZTxudW1iZXI+O1xuXHRcdH07XG5cblx0XHRjb25zdCBbd2FpdGluZywgYWN0aXZlLCBjb21wbGV0ZWQsIGZhaWxlZCwgZGVsYXllZF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG5cdFx0XHRxLmdldFdhaXRpbmdDb3VudCgpLFxuXHRcdFx0cS5nZXRBY3RpdmVDb3VudCgpLFxuXHRcdFx0cS5nZXRDb21wbGV0ZWRDb3VudCgpLFxuXHRcdFx0cS5nZXRGYWlsZWRDb3VudCgpLFxuXHRcdFx0cS5nZXREZWxheWVkQ291bnQoKSxcblx0XHRdKTtcblxuXHRcdHJldHVybiB7IHdhaXRpbmcsIGFjdGl2ZSwgY29tcGxldGVkLCBmYWlsZWQsIGRlbGF5ZWQgfTtcblx0fVxufVxuIl19
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* InMemoryAdapter - Worker adapter using in-process queues
|
|
3
|
+
*
|
|
4
|
+
* Ideal for:
|
|
5
|
+
* - Development and testing
|
|
6
|
+
* - Simple background job processing
|
|
7
|
+
* - Single-instance deployments
|
|
8
|
+
*
|
|
9
|
+
* Limitations:
|
|
10
|
+
* - Jobs are lost on process restart
|
|
11
|
+
* - No distributed processing
|
|
12
|
+
* - No persistence
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const adapter = new InMemoryAdapter();
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
import type { WorkerTriggerOpts } from "@blok/helper";
|
|
20
|
+
import type { WorkerAdapter, WorkerJob, WorkerQueueStats } from "../WorkerTrigger";
|
|
21
|
+
/**
|
|
22
|
+
* InMemoryAdapter - Simple in-process worker queue
|
|
23
|
+
*/
|
|
24
|
+
export declare class InMemoryAdapter implements WorkerAdapter {
|
|
25
|
+
readonly provider: "in-memory";
|
|
26
|
+
private connected;
|
|
27
|
+
private jobs;
|
|
28
|
+
private processors;
|
|
29
|
+
private stats;
|
|
30
|
+
connect(): Promise<void>;
|
|
31
|
+
disconnect(): Promise<void>;
|
|
32
|
+
process(config: WorkerTriggerOpts, handler: (job: WorkerJob) => Promise<void>): Promise<void>;
|
|
33
|
+
addJob(queue: string, data: unknown, opts?: {
|
|
34
|
+
priority?: number;
|
|
35
|
+
delay?: number;
|
|
36
|
+
retries?: number;
|
|
37
|
+
timeout?: number;
|
|
38
|
+
jobId?: string;
|
|
39
|
+
}): Promise<string>;
|
|
40
|
+
stopProcessing(queue: string): Promise<void>;
|
|
41
|
+
isConnected(): boolean;
|
|
42
|
+
healthCheck(): Promise<boolean>;
|
|
43
|
+
getQueueStats(queue: string): Promise<WorkerQueueStats>;
|
|
44
|
+
/**
|
|
45
|
+
* Process the next available job from a queue
|
|
46
|
+
*/
|
|
47
|
+
private processNext;
|
|
48
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* InMemoryAdapter - Worker adapter using in-process queues
|
|
4
|
+
*
|
|
5
|
+
* Ideal for:
|
|
6
|
+
* - Development and testing
|
|
7
|
+
* - Simple background job processing
|
|
8
|
+
* - Single-instance deployments
|
|
9
|
+
*
|
|
10
|
+
* Limitations:
|
|
11
|
+
* - Jobs are lost on process restart
|
|
12
|
+
* - No distributed processing
|
|
13
|
+
* - No persistence
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const adapter = new InMemoryAdapter();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.InMemoryAdapter = void 0;
|
|
22
|
+
const uuid_1 = require("uuid");
|
|
23
|
+
/**
|
|
24
|
+
* InMemoryAdapter - Simple in-process worker queue
|
|
25
|
+
*/
|
|
26
|
+
class InMemoryAdapter {
|
|
27
|
+
provider = "in-memory";
|
|
28
|
+
connected = false;
|
|
29
|
+
jobs = new Map();
|
|
30
|
+
processors = new Map();
|
|
31
|
+
stats = new Map();
|
|
32
|
+
async connect() {
|
|
33
|
+
this.connected = true;
|
|
34
|
+
}
|
|
35
|
+
async disconnect() {
|
|
36
|
+
// Stop all processors
|
|
37
|
+
for (const [queue, processor] of this.processors) {
|
|
38
|
+
processor.running = false;
|
|
39
|
+
if (processor.timer) {
|
|
40
|
+
clearInterval(processor.timer);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
this.processors.clear();
|
|
44
|
+
this.jobs.clear();
|
|
45
|
+
this.stats.clear();
|
|
46
|
+
this.connected = false;
|
|
47
|
+
}
|
|
48
|
+
async process(config, handler) {
|
|
49
|
+
if (!this.connected) {
|
|
50
|
+
throw new Error("Not connected. Call connect() first.");
|
|
51
|
+
}
|
|
52
|
+
if (!this.jobs.has(config.queue)) {
|
|
53
|
+
this.jobs.set(config.queue, []);
|
|
54
|
+
}
|
|
55
|
+
if (!this.stats.has(config.queue)) {
|
|
56
|
+
this.stats.set(config.queue, { completed: 0, failed: 0 });
|
|
57
|
+
}
|
|
58
|
+
const processor = {
|
|
59
|
+
config,
|
|
60
|
+
handler,
|
|
61
|
+
active: 0,
|
|
62
|
+
running: true,
|
|
63
|
+
};
|
|
64
|
+
this.processors.set(config.queue, processor);
|
|
65
|
+
// Start polling for jobs
|
|
66
|
+
processor.timer = setInterval(() => {
|
|
67
|
+
this.processNext(config.queue).catch((err) => {
|
|
68
|
+
console.error(`[InMemoryAdapter] Error processing ${config.queue}: ${err.message}`);
|
|
69
|
+
});
|
|
70
|
+
}, 50); // Poll every 50ms
|
|
71
|
+
}
|
|
72
|
+
async addJob(queue, data, opts) {
|
|
73
|
+
if (!this.connected) {
|
|
74
|
+
throw new Error("Not connected. Call connect() first.");
|
|
75
|
+
}
|
|
76
|
+
if (!this.jobs.has(queue)) {
|
|
77
|
+
this.jobs.set(queue, []);
|
|
78
|
+
}
|
|
79
|
+
if (!this.stats.has(queue)) {
|
|
80
|
+
this.stats.set(queue, { completed: 0, failed: 0 });
|
|
81
|
+
}
|
|
82
|
+
const job = {
|
|
83
|
+
id: opts?.jobId || (0, uuid_1.v4)(),
|
|
84
|
+
data,
|
|
85
|
+
queue,
|
|
86
|
+
priority: opts?.priority ?? 0,
|
|
87
|
+
attempts: 0,
|
|
88
|
+
maxRetries: opts?.retries ?? 3,
|
|
89
|
+
createdAt: new Date(),
|
|
90
|
+
delay: opts?.delay ?? 0,
|
|
91
|
+
timeout: opts?.timeout ?? 0,
|
|
92
|
+
status: opts?.delay && opts.delay > 0 ? "delayed" : "waiting",
|
|
93
|
+
};
|
|
94
|
+
if (job.status === "delayed") {
|
|
95
|
+
job.scheduledAt = new Date(Date.now() + job.delay);
|
|
96
|
+
}
|
|
97
|
+
const jobs = this.jobs.get(queue);
|
|
98
|
+
// Insert sorted by priority (higher first)
|
|
99
|
+
const insertIdx = jobs.findIndex((j) => j.status === "waiting" && j.priority < job.priority);
|
|
100
|
+
if (insertIdx >= 0) {
|
|
101
|
+
jobs.splice(insertIdx, 0, job);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
jobs.push(job);
|
|
105
|
+
}
|
|
106
|
+
return job.id;
|
|
107
|
+
}
|
|
108
|
+
async stopProcessing(queue) {
|
|
109
|
+
const processor = this.processors.get(queue);
|
|
110
|
+
if (processor) {
|
|
111
|
+
processor.running = false;
|
|
112
|
+
if (processor.timer) {
|
|
113
|
+
clearInterval(processor.timer);
|
|
114
|
+
}
|
|
115
|
+
this.processors.delete(queue);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
isConnected() {
|
|
119
|
+
return this.connected;
|
|
120
|
+
}
|
|
121
|
+
async healthCheck() {
|
|
122
|
+
return this.connected;
|
|
123
|
+
}
|
|
124
|
+
async getQueueStats(queue) {
|
|
125
|
+
const jobs = this.jobs.get(queue) || [];
|
|
126
|
+
const queueStats = this.stats.get(queue) || { completed: 0, failed: 0 };
|
|
127
|
+
return {
|
|
128
|
+
waiting: jobs.filter((j) => j.status === "waiting").length,
|
|
129
|
+
active: jobs.filter((j) => j.status === "active").length,
|
|
130
|
+
completed: queueStats.completed,
|
|
131
|
+
failed: queueStats.failed,
|
|
132
|
+
delayed: jobs.filter((j) => j.status === "delayed").length,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Process the next available job from a queue
|
|
137
|
+
*/
|
|
138
|
+
async processNext(queue) {
|
|
139
|
+
const processor = this.processors.get(queue);
|
|
140
|
+
if (!processor || !processor.running)
|
|
141
|
+
return;
|
|
142
|
+
const concurrency = processor.config.concurrency ?? 1;
|
|
143
|
+
if (processor.active >= concurrency)
|
|
144
|
+
return;
|
|
145
|
+
const jobs = this.jobs.get(queue);
|
|
146
|
+
if (!jobs || jobs.length === 0)
|
|
147
|
+
return;
|
|
148
|
+
// Check for delayed jobs that are ready
|
|
149
|
+
const now = Date.now();
|
|
150
|
+
for (const job of jobs) {
|
|
151
|
+
if (job.status === "delayed" && job.scheduledAt && job.scheduledAt.getTime() <= now) {
|
|
152
|
+
job.status = "waiting";
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Find next waiting job
|
|
156
|
+
const jobIdx = jobs.findIndex((j) => j.status === "waiting");
|
|
157
|
+
if (jobIdx < 0)
|
|
158
|
+
return;
|
|
159
|
+
const internalJob = jobs[jobIdx];
|
|
160
|
+
internalJob.status = "active";
|
|
161
|
+
processor.active++;
|
|
162
|
+
const workerJob = {
|
|
163
|
+
id: internalJob.id,
|
|
164
|
+
data: internalJob.data,
|
|
165
|
+
headers: {},
|
|
166
|
+
queue: internalJob.queue,
|
|
167
|
+
priority: internalJob.priority,
|
|
168
|
+
attempts: internalJob.attempts,
|
|
169
|
+
maxRetries: internalJob.maxRetries,
|
|
170
|
+
createdAt: internalJob.createdAt,
|
|
171
|
+
delay: internalJob.delay,
|
|
172
|
+
timeout: internalJob.timeout,
|
|
173
|
+
raw: internalJob,
|
|
174
|
+
complete: async () => {
|
|
175
|
+
internalJob.status = "completed";
|
|
176
|
+
const idx = jobs.indexOf(internalJob);
|
|
177
|
+
if (idx >= 0)
|
|
178
|
+
jobs.splice(idx, 1);
|
|
179
|
+
const s = this.stats.get(queue);
|
|
180
|
+
if (s)
|
|
181
|
+
s.completed++;
|
|
182
|
+
},
|
|
183
|
+
fail: async (error, requeue) => {
|
|
184
|
+
internalJob.attempts++;
|
|
185
|
+
internalJob.error = error;
|
|
186
|
+
if (requeue && internalJob.attempts < internalJob.maxRetries) {
|
|
187
|
+
// Requeue with backoff
|
|
188
|
+
const backoff = Math.min(1000 * Math.pow(2, internalJob.attempts), 30000);
|
|
189
|
+
internalJob.status = "delayed";
|
|
190
|
+
internalJob.scheduledAt = new Date(Date.now() + backoff);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
internalJob.status = "failed";
|
|
194
|
+
const idx = jobs.indexOf(internalJob);
|
|
195
|
+
if (idx >= 0)
|
|
196
|
+
jobs.splice(idx, 1);
|
|
197
|
+
const s = this.stats.get(queue);
|
|
198
|
+
if (s)
|
|
199
|
+
s.failed++;
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
try {
|
|
204
|
+
await processor.handler(workerJob);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
// Handler threw - treat as failure
|
|
208
|
+
if (internalJob.status === "active") {
|
|
209
|
+
internalJob.status = "failed";
|
|
210
|
+
const idx = jobs.indexOf(internalJob);
|
|
211
|
+
if (idx >= 0)
|
|
212
|
+
jobs.splice(idx, 1);
|
|
213
|
+
const s = this.stats.get(queue);
|
|
214
|
+
if (s)
|
|
215
|
+
s.failed++;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
finally {
|
|
219
|
+
processor.active--;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
exports.InMemoryAdapter = InMemoryAdapter;
|
|
224
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5NZW1vcnlBZGFwdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXJzL0luTWVtb3J5QWRhcHRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHOzs7QUFHSCwrQkFBa0M7QUFnQ2xDOztHQUVHO0FBQ0gsTUFBYSxlQUFlO0lBQ2xCLFFBQVEsR0FBRyxXQUFvQixDQUFDO0lBQ2pDLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDbEIsSUFBSSxHQUErQixJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQzdDLFVBQVUsR0FBZ0MsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNwRCxLQUFLLEdBQXVELElBQUksR0FBRyxFQUFFLENBQUM7SUFFOUUsS0FBSyxDQUFDLE9BQU87UUFDWixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN2QixDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVU7UUFDZixzQkFBc0I7UUFDdEIsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsRCxTQUFTLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUMxQixJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDckIsYUFBYSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQyxDQUFDO1FBQ0YsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQXlCLEVBQUUsT0FBMEM7UUFDbEYsSUFBSSxDQUFDLElB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NE5DIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBJbk1lbW9yeUFkYXB0ZXIgLSBXb3JrZXIgYWRhcHRlciB1c2luZyBpbi1wcm9jZXNzIHF1ZXVlc1xuICpcbiAqIElkZWFsIGZvcjpcbiAqIC0gRGV2ZWxvcG1lbnQgYW5kIHRlc3RpbmdcbiAqIC0gU2ltcGxlIGJhY2tncm91bmQgam9iIHByb2Nlc3NpbmdcbiAqIC0gU2luZ2xlLWluc3RhbmNlIGRlcGxveW1lbnRzXG4gKlxuICogTGltaXRhdGlvbnM6XG4gKiAtIEpvYnMgYXJlIGxvc3Qgb24gcHJvY2VzcyByZXN0YXJ0XG4gKiAtIE5vIGRpc3RyaWJ1dGVkIHByb2Nlc3NpbmdcbiAqIC0gTm8gcGVyc2lzdGVuY2VcbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHlwZXNjcmlwdFxuICogY29uc3QgYWRhcHRlciA9IG5ldyBJbk1lbW9yeUFkYXB0ZXIoKTtcbiAqIGBgYFxuICovXG5cbmltcG9ydCB0eXBlIHsgV29ya2VyVHJpZ2dlck9wdHMgfSBmcm9tIFwiQGJsb2svaGVscGVyXCI7XG5pbXBvcnQgeyB2NCBhcyB1dWlkIH0gZnJvbSBcInV1aWRcIjtcbmltcG9ydCB0eXBlIHsgV29ya2VyQWRhcHRlciwgV29ya2VySm9iLCBXb3JrZXJRdWV1ZVN0YXRzIH0gZnJvbSBcIi4uL1dvcmtlclRyaWdnZXJcIjtcblxuLyoqXG4gKiBJbnRlcm5hbCBqb2IgcmVwcmVzZW50YXRpb25cbiAqL1xuaW50ZXJmYWNlIEludGVybmFsSm9iIHtcblx0aWQ6IHN0cmluZztcblx0ZGF0YTogdW5rbm93bjtcblx0cXVldWU6IHN0cmluZztcblx0cHJpb3JpdHk6IG51bWJlcjtcblx0YXR0ZW1wdHM6IG51bWJlcjtcblx0bWF4UmV0cmllczogbnVtYmVyO1xuXHRjcmVhdGVkQXQ6IERhdGU7XG5cdGRlbGF5OiBudW1iZXI7XG5cdHRpbWVvdXQ6IG51bWJlcjtcblx0c3RhdHVzOiBcIndhaXRpbmdcIiB8IFwiYWN0aXZlXCIgfCBcImNvbXBsZXRlZFwiIHwgXCJmYWlsZWRcIiB8IFwiZGVsYXllZFwiO1xuXHRzY2hlZHVsZWRBdD86IERhdGU7XG5cdGVycm9yPzogRXJyb3I7XG59XG5cbi8qKlxuICogUXVldWUgcHJvY2Vzc29yIGVudHJ5XG4gKi9cbmludGVyZmFjZSBRdWV1ZVByb2Nlc3NvciB7XG5cdGNvbmZpZzogV29ya2VyVHJpZ2dlck9wdHM7XG5cdGhhbmRsZXI6IChqb2I6IFdvcmtlckpvYikgPT4gUHJvbWlzZTx2b2lkPjtcblx0YWN0aXZlOiBudW1iZXI7XG5cdHJ1bm5pbmc6IGJvb2xlYW47XG5cdHRpbWVyPzogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+O1xufVxuXG4vKipcbiAqIEluTWVtb3J5QWRhcHRlciAtIFNpbXBsZSBpbi1wcm9jZXNzIHdvcmtlciBxdWV1ZVxuICovXG5leHBvcnQgY2xhc3MgSW5NZW1vcnlBZGFwdGVyIGltcGxlbWVudHMgV29ya2VyQWRhcHRlciB7XG5cdHJlYWRvbmx5IHByb3ZpZGVyID0gXCJpbi1tZW1vcnlcIiBhcyBjb25zdDtcblx0cHJpdmF0ZSBjb25uZWN0ZWQgPSBmYWxzZTtcblx0cHJpdmF0ZSBqb2JzOiBNYXA8c3RyaW5nLCBJbnRlcm5hbEpvYltdPiA9IG5ldyBNYXAoKTtcblx0cHJpdmF0ZSBwcm9jZXNzb3JzOiBNYXA8c3RyaW5nLCBRdWV1ZVByb2Nlc3Nvcj4gPSBuZXcgTWFwKCk7XG5cdHByaXZhdGUgc3RhdHM6IE1hcDxzdHJpbmcsIHsgY29tcGxldGVkOiBudW1iZXI7IGZhaWxlZDogbnVtYmVyIH0+ID0gbmV3IE1hcCgpO1xuXG5cdGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0dGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuXHR9XG5cblx0YXN5bmMgZGlzY29ubmVjdCgpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHQvLyBTdG9wIGFsbCBwcm9jZXNzb3JzXG5cdFx0Zm9yIChjb25zdCBbcXVldWUsIHByb2Nlc3Nvcl0gb2YgdGhpcy5wcm9jZXNzb3JzKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHRoaXMucHJvY2Vzc29ycy5jbGVhcigpO1xuXHRcdHRoaXMuam9icy5jbGVhcigpO1xuXHRcdHRoaXMuc3RhdHMuY2xlYXIoKTtcblx0XHR0aGlzLmNvbm5lY3RlZCA9IGZhbHNlO1xuXHR9XG5cblx0YXN5bmMgcHJvY2Vzcyhjb25maWc6IFdvcmtlclRyaWdnZXJPcHRzLCBoYW5kbGVyOiAoam9iOiBXb3JrZXJKb2IpID0+IFByb21pc2U8dm9pZD4pOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoIXRoaXMuY29ubmVjdGVkKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoXCJOb3QgY29ubmVjdGVkLiBDYWxsIGNvbm5lY3QoKSBmaXJzdC5cIik7XG5cdFx0fVxuXG5cdFx0aWYgKCF0aGlzLmpvYnMuaGFzKGNvbmZpZy5xdWV1ZSkpIHtcblx0XHRcdHRoaXMuam9icy5zZXQoY29uZmlnLnF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMoY29uZmlnLnF1ZXVlKSkge1xuXHRcdFx0dGhpcy5zdGF0cy5zZXQoY29uZmlnLnF1ZXVlLCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH0pO1xuXHRcdH1cblxuXHRcdGNvbnN0IHByb2Nlc3NvcjogUXVldWVQcm9jZXNzb3IgPSB7XG5cdFx0XHRjb25maWcsXG5cdFx0XHRoYW5kbGVyLFxuXHRcdFx0YWN0aXZlOiAwLFxuXHRcdFx0cnVubmluZzogdHJ1ZSxcblx0XHR9O1xuXG5cdFx0dGhpcy5wcm9jZXNzb3JzLnNldChjb25maWcucXVldWUsIHByb2Nlc3Nvcik7XG5cblx0XHQvLyBTdGFydCBwb2xsaW5nIGZvciBqb2JzXG5cdFx0cHJvY2Vzc29yLnRpbWVyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuXHRcdFx0dGhpcy5wcm9jZXNzTmV4dChjb25maWcucXVldWUpLmNhdGNoKChlcnIpID0+IHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihgW0luTWVtb3J5QWRhcHRlcl0gRXJyb3IgcHJvY2Vzc2luZyAke2NvbmZpZy5xdWV1ZX06ICR7KGVyciBhcyBFcnJvcikubWVzc2FnZX1gKTtcblx0XHRcdH0pO1xuXHRcdH0sIDUwKTsgLy8gUG9sbCBldmVyeSA1MG1zXG5cdH1cblxuXHRhc3luYyBhZGRKb2IoXG5cdFx0cXVldWU6IHN0cmluZyxcblx0XHRkYXRhOiB1bmtub3duLFxuXHRcdG9wdHM/OiB7XG5cdFx0XHRwcmlvcml0eT86IG51bWJlcjtcblx0XHRcdGRlbGF5PzogbnVtYmVyO1xuXHRcdFx0cmV0cmllcz86IG51bWJlcjtcblx0XHRcdHRpbWVvdXQ/OiBudW1iZXI7XG5cdFx0XHRqb2JJZD86IHN0cmluZztcblx0XHR9LFxuXHQpOiBQcm9taXNlPHN0cmluZz4ge1xuXHRcdGlmICghdGhpcy5jb25uZWN0ZWQpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcihcIk5vdCBjb25uZWN0ZWQuIENhbGwgY29ubmVjdCgpIGZpcnN0LlwiKTtcblx0XHR9XG5cblx0XHRpZiAoIXRoaXMuam9icy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLmpvYnMuc2V0KHF1ZXVlLCBbXSk7XG5cdFx0fVxuXHRcdGlmICghdGhpcy5zdGF0cy5oYXMocXVldWUpKSB7XG5cdFx0XHR0aGlzLnN0YXRzLnNldChxdWV1ZSwgeyBjb21wbGV0ZWQ6IDAsIGZhaWxlZDogMCB9KTtcblx0XHR9XG5cblx0XHRjb25zdCBqb2I6IEludGVybmFsSm9iID0ge1xuXHRcdFx0aWQ6IG9wdHM/LmpvYklkIHx8IHV1aWQoKSxcblx0XHRcdGRhdGEsXG5cdFx0XHRxdWV1ZSxcblx0XHRcdHByaW9yaXR5OiBvcHRzPy5wcmlvcml0eSA/PyAwLFxuXHRcdFx0YXR0ZW1wdHM6IDAsXG5cdFx0XHRtYXhSZXRyaWVzOiBvcHRzPy5yZXRyaWVzID8/IDMsXG5cdFx0XHRjcmVhdGVkQXQ6IG5ldyBEYXRlKCksXG5cdFx0XHRkZWxheTogb3B0cz8uZGVsYXkgPz8gMCxcblx0XHRcdHRpbWVvdXQ6IG9wdHM/LnRpbWVvdXQgPz8gMCxcblx0XHRcdHN0YXR1czogb3B0cz8uZGVsYXkgJiYgb3B0cy5kZWxheSA+IDAgPyBcImRlbGF5ZWRcIiA6IFwid2FpdGluZ1wiLFxuXHRcdH07XG5cblx0XHRpZiAoam9iLnN0YXR1cyA9PT0gXCJkZWxheWVkXCIpIHtcblx0XHRcdGpvYi5zY2hlZHVsZWRBdCA9IG5ldyBEYXRlKERhdGUubm93KCkgKyBqb2IuZGVsYXkpO1xuXHRcdH1cblxuXHRcdGNvbnN0IGpvYnMgPSB0aGlzLmpvYnMuZ2V0KHF1ZXVlKSE7XG5cblx0XHQvLyBJbnNlcnQgc29ydGVkIGJ5IHByaW9yaXR5IChoaWdoZXIgZmlyc3QpXG5cdFx0Y29uc3QgaW5zZXJ0SWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIiAmJiBqLnByaW9yaXR5IDwgam9iLnByaW9yaXR5KTtcblx0XHRpZiAoaW5zZXJ0SWR4ID49IDApIHtcblx0XHRcdGpvYnMuc3BsaWNlKGluc2VydElkeCwgMCwgam9iKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0am9icy5wdXNoKGpvYik7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGpvYi5pZDtcblx0fVxuXG5cdGFzeW5jIHN0b3BQcm9jZXNzaW5nKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBwcm9jZXNzb3IgPSB0aGlzLnByb2Nlc3NvcnMuZ2V0KHF1ZXVlKTtcblx0XHRpZiAocHJvY2Vzc29yKSB7XG5cdFx0XHRwcm9jZXNzb3IucnVubmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKHByb2Nlc3Nvci50aW1lcikge1xuXHRcdFx0XHRjbGVhckludGVydmFsKHByb2Nlc3Nvci50aW1lcik7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnByb2Nlc3NvcnMuZGVsZXRlKHF1ZXVlKTtcblx0XHR9XG5cdH1cblxuXHRpc0Nvbm5lY3RlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBoZWFsdGhDaGVjaygpOiBQcm9taXNlPGJvb2xlYW4+IHtcblx0XHRyZXR1cm4gdGhpcy5jb25uZWN0ZWQ7XG5cdH1cblxuXHRhc3luYyBnZXRRdWV1ZVN0YXRzKHF1ZXVlOiBzdHJpbmcpOiBQcm9taXNlPFdvcmtlclF1ZXVlU3RhdHM+IHtcblx0XHRjb25zdCBqb2JzID0gdGhpcy5qb2JzLmdldChxdWV1ZSkgfHwgW107XG5cdFx0Y29uc3QgcXVldWVTdGF0cyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKSB8fCB7IGNvbXBsZXRlZDogMCwgZmFpbGVkOiAwIH07XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0d2FpdGluZzogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIikubGVuZ3RoLFxuXHRcdFx0YWN0aXZlOiBqb2JzLmZpbHRlcigoaikgPT4gai5zdGF0dXMgPT09IFwiYWN0aXZlXCIpLmxlbmd0aCxcblx0XHRcdGNvbXBsZXRlZDogcXVldWVTdGF0cy5jb21wbGV0ZWQsXG5cdFx0XHRmYWlsZWQ6IHF1ZXVlU3RhdHMuZmFpbGVkLFxuXHRcdFx0ZGVsYXllZDogam9icy5maWx0ZXIoKGopID0+IGouc3RhdHVzID09PSBcImRlbGF5ZWRcIikubGVuZ3RoLFxuXHRcdH07XG5cdH1cblxuXHQvKipcblx0ICogUHJvY2VzcyB0aGUgbmV4dCBhdmFpbGFibGUgam9iIGZyb20gYSBxdWV1ZVxuXHQgKi9cblx0cHJpdmF0ZSBhc3luYyBwcm9jZXNzTmV4dChxdWV1ZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3QgcHJvY2Vzc29yID0gdGhpcy5wcm9jZXNzb3JzLmdldChxdWV1ZSk7XG5cdFx0aWYgKCFwcm9jZXNzb3IgfHwgIXByb2Nlc3Nvci5ydW5uaW5nKSByZXR1cm47XG5cblx0XHRjb25zdCBjb25jdXJyZW5jeSA9IHByb2Nlc3Nvci5jb25maWcuY29uY3VycmVuY3kgPz8gMTtcblx0XHRpZiAocHJvY2Vzc29yLmFjdGl2ZSA+PSBjb25jdXJyZW5jeSkgcmV0dXJuO1xuXG5cdFx0Y29uc3Qgam9icyA9IHRoaXMuam9icy5nZXQocXVldWUpO1xuXHRcdGlmICgham9icyB8fCBqb2JzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGRlbGF5ZWQgam9icyB0aGF0IGFyZSByZWFkeVxuXHRcdGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cdFx0Zm9yIChjb25zdCBqb2Igb2Ygam9icykge1xuXHRcdFx0aWYgKGpvYi5zdGF0dXMgPT09IFwiZGVsYXllZFwiICYmIGpvYi5zY2hlZHVsZWRBdCAmJiBqb2Iuc2NoZWR1bGVkQXQuZ2V0VGltZSgpIDw9IG5vdykge1xuXHRcdFx0XHRqb2Iuc3RhdHVzID0gXCJ3YWl0aW5nXCI7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmluZCBuZXh0IHdhaXRpbmcgam9iXG5cdFx0Y29uc3Qgam9iSWR4ID0gam9icy5maW5kSW5kZXgoKGopID0+IGouc3RhdHVzID09PSBcIndhaXRpbmdcIik7XG5cdFx0aWYgKGpvYklkeCA8IDApIHJldHVybjtcblxuXHRcdGNvbnN0IGludGVybmFsSm9iID0gam9ic1tqb2JJZHhdO1xuXHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiYWN0aXZlXCI7XG5cdFx0cHJvY2Vzc29yLmFjdGl2ZSsrO1xuXG5cdFx0Y29uc3Qgd29ya2VySm9iOiBXb3JrZXJKb2IgPSB7XG5cdFx0XHRpZDogaW50ZXJuYWxKb2IuaWQsXG5cdFx0XHRkYXRhOiBpbnRlcm5hbEpvYi5kYXRhLFxuXHRcdFx0aGVhZGVyczoge30sXG5cdFx0XHRxdWV1ZTogaW50ZXJuYWxKb2IucXVldWUsXG5cdFx0XHRwcmlvcml0eTogaW50ZXJuYWxKb2IucHJpb3JpdHksXG5cdFx0XHRhdHRlbXB0czogaW50ZXJuYWxKb2IuYXR0ZW1wdHMsXG5cdFx0XHRtYXhSZXRyaWVzOiBpbnRlcm5hbEpvYi5tYXhSZXRyaWVzLFxuXHRcdFx0Y3JlYXRlZEF0OiBpbnRlcm5hbEpvYi5jcmVhdGVkQXQsXG5cdFx0XHRkZWxheTogaW50ZXJuYWxKb2IuZGVsYXksXG5cdFx0XHR0aW1lb3V0OiBpbnRlcm5hbEpvYi50aW1lb3V0LFxuXHRcdFx0cmF3OiBpbnRlcm5hbEpvYixcblx0XHRcdGNvbXBsZXRlOiBhc3luYyAoKSA9PiB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiY29tcGxldGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuY29tcGxldGVkKys7XG5cdFx0XHR9LFxuXHRcdFx0ZmFpbDogYXN5bmMgKGVycm9yOiBFcnJvciwgcmVxdWV1ZT86IGJvb2xlYW4pID0+IHtcblx0XHRcdFx0aW50ZXJuYWxKb2IuYXR0ZW1wdHMrKztcblx0XHRcdFx0aW50ZXJuYWxKb2IuZXJyb3IgPSBlcnJvcjtcblxuXHRcdFx0XHRpZiAocmVxdWV1ZSAmJiBpbnRlcm5hbEpvYi5hdHRlbXB0cyA8IGludGVybmFsSm9iLm1heFJldHJpZXMpIHtcblx0XHRcdFx0XHQvLyBSZXF1ZXVlIHdpdGggYmFja29mZlxuXHRcdFx0XHRcdGNvbnN0IGJhY2tvZmYgPSBNYXRoLm1pbigxMDAwICogTWF0aC5wb3coMiwgaW50ZXJuYWxKb2IuYXR0ZW1wdHMpLCAzMDAwMCk7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJkZWxheWVkXCI7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc2NoZWR1bGVkQXQgPSBuZXcgRGF0ZShEYXRlLm5vdygpICsgYmFja29mZik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aW50ZXJuYWxKb2Iuc3RhdHVzID0gXCJmYWlsZWRcIjtcblx0XHRcdFx0XHRjb25zdCBpZHggPSBqb2JzLmluZGV4T2YoaW50ZXJuYWxKb2IpO1xuXHRcdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0XHRjb25zdCBzID0gdGhpcy5zdGF0cy5nZXQocXVldWUpO1xuXHRcdFx0XHRcdGlmIChzKSBzLmZhaWxlZCsrO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdH07XG5cblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgcHJvY2Vzc29yLmhhbmRsZXIod29ya2VySm9iKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdC8vIEhhbmRsZXIgdGhyZXcgLSB0cmVhdCBhcyBmYWlsdXJlXG5cdFx0XHRpZiAoaW50ZXJuYWxKb2Iuc3RhdHVzID09PSBcImFjdGl2ZVwiKSB7XG5cdFx0XHRcdGludGVybmFsSm9iLnN0YXR1cyA9IFwiZmFpbGVkXCI7XG5cdFx0XHRcdGNvbnN0IGlkeCA9IGpvYnMuaW5kZXhPZihpbnRlcm5hbEpvYik7XG5cdFx0XHRcdGlmIChpZHggPj0gMCkgam9icy5zcGxpY2UoaWR4LCAxKTtcblx0XHRcdFx0Y29uc3QgcyA9IHRoaXMuc3RhdHMuZ2V0KHF1ZXVlKTtcblx0XHRcdFx0aWYgKHMpIHMuZmFpbGVkKys7XG5cdFx0XHR9XG5cdFx0fSBmaW5hbGx5IHtcblx0XHRcdHByb2Nlc3Nvci5hY3RpdmUtLTtcblx0XHR9XG5cdH1cbn1cbiJdfQ==
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @blok/trigger-worker
|
|
3
|
+
*
|
|
4
|
+
* Worker-based trigger for Blok workflows.
|
|
5
|
+
* Supports background job processing with:
|
|
6
|
+
* - Configurable concurrency per queue
|
|
7
|
+
* - Automatic retries with exponential backoff
|
|
8
|
+
* - Job timeouts
|
|
9
|
+
* - Priority-based job ordering
|
|
10
|
+
* - Delayed job scheduling
|
|
11
|
+
* - Queue statistics and monitoring
|
|
12
|
+
*
|
|
13
|
+
* Adapters:
|
|
14
|
+
* - BullMQ (Redis-backed, production)
|
|
15
|
+
* - InMemory (development/testing)
|
|
16
|
+
*
|
|
17
|
+
* @example BullMQ
|
|
18
|
+
* ```typescript
|
|
19
|
+
* import { WorkerTrigger, BullMQAdapter } from "@blok/trigger-worker";
|
|
20
|
+
*
|
|
21
|
+
* class MyWorkerTrigger extends WorkerTrigger {
|
|
22
|
+
* protected adapter = new BullMQAdapter({
|
|
23
|
+
* host: "localhost",
|
|
24
|
+
* port: 6379,
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* protected nodes = myNodes;
|
|
28
|
+
* protected workflows = myWorkflows;
|
|
29
|
+
* }
|
|
30
|
+
*
|
|
31
|
+
* const trigger = new MyWorkerTrigger();
|
|
32
|
+
* await trigger.listen();
|
|
33
|
+
*
|
|
34
|
+
* // Dispatch a job
|
|
35
|
+
* await trigger.dispatch("background-jobs", { userId: "123" }, {
|
|
36
|
+
* priority: 10,
|
|
37
|
+
* retries: 3,
|
|
38
|
+
* delay: 5000, // delay 5 seconds
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @example InMemory (development)
|
|
43
|
+
* ```typescript
|
|
44
|
+
* import { WorkerTrigger, InMemoryAdapter } from "@blok/trigger-worker";
|
|
45
|
+
*
|
|
46
|
+
* class DevWorkerTrigger extends WorkerTrigger {
|
|
47
|
+
* protected adapter = new InMemoryAdapter();
|
|
48
|
+
* protected nodes = myNodes;
|
|
49
|
+
* protected workflows = myWorkflows;
|
|
50
|
+
* }
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export { WorkerTrigger, type WorkerAdapter, type WorkerJob, type WorkerQueueStats, } from "./WorkerTrigger";
|
|
54
|
+
export { BullMQAdapter, type BullMQConfig } from "./adapters/BullMQAdapter";
|
|
55
|
+
export { InMemoryAdapter } from "./adapters/InMemoryAdapter";
|
|
56
|
+
export type { WorkerTriggerOpts } from "@blok/helper";
|