power-queues 2.1.13 → 2.1.14
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.cjs +36 -35
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +35 -24
- package/dist/index.js.map +1 -0
- package/package.json +16 -5
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
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
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
@@ -35,7 +25,6 @@ __export(index_exports, {
|
|
|
35
25
|
module.exports = __toCommonJS(index_exports);
|
|
36
26
|
|
|
37
27
|
// src/PowerQueues.ts
|
|
38
|
-
var import_p_limit = __toESM(require("p-limit"), 1);
|
|
39
28
|
var import_node_crypto = require("crypto");
|
|
40
29
|
var import_node_events = require("events");
|
|
41
30
|
var import_power_redis = require("power-redis");
|
|
@@ -275,30 +264,38 @@ var SelectStuck = `
|
|
|
275
264
|
`;
|
|
276
265
|
|
|
277
266
|
// src/PowerQueues.ts
|
|
267
|
+
var importDynamic = new Function("modulePath", "return import(modulePath)");
|
|
268
|
+
var pLimitCache;
|
|
269
|
+
async function getPLimit() {
|
|
270
|
+
pLimitCache ??= importDynamic("p-limit").then((mod) => mod.default);
|
|
271
|
+
return pLimitCache;
|
|
272
|
+
}
|
|
278
273
|
var PowerQueues = class extends import_power_redis.PowerRedis {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
274
|
+
abort = new AbortController();
|
|
275
|
+
redis;
|
|
276
|
+
scripts = {};
|
|
277
|
+
host = "host";
|
|
278
|
+
group = "gr1";
|
|
279
|
+
selectStuckCount = 256;
|
|
280
|
+
selectStuckTimeout = 2e4;
|
|
281
|
+
selectStuckMaxTimeout = 40;
|
|
282
|
+
selectCount = 1024;
|
|
283
|
+
selectTimeout = 100;
|
|
284
|
+
buildBatchCount = 1e3;
|
|
285
|
+
buildBatchMaxCount = 2e4;
|
|
286
|
+
retryCount = 1;
|
|
287
|
+
executeSync = false;
|
|
288
|
+
idemLockTimeout = 15e3;
|
|
289
|
+
idemDoneTimeout = 1e4;
|
|
290
|
+
logStatus = false;
|
|
291
|
+
logStatusTimeout = 12e4;
|
|
292
|
+
approveCount = 4e3;
|
|
293
|
+
removeOnExecuted = true;
|
|
294
|
+
concurrency = 256;
|
|
295
|
+
limit;
|
|
296
|
+
async initLimit() {
|
|
297
|
+
const pLimit = await getPLimit();
|
|
298
|
+
this.limit = pLimit(this.concurrency);
|
|
302
299
|
}
|
|
303
300
|
signal() {
|
|
304
301
|
return this.abort.signal;
|
|
@@ -308,7 +305,7 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
|
|
|
308
305
|
}
|
|
309
306
|
async runQueue(queueName, from = "0-0") {
|
|
310
307
|
(0, import_node_events.setMaxListeners)(0, this.abort.signal);
|
|
311
|
-
this.
|
|
308
|
+
await this.initLimit();
|
|
312
309
|
await this.createGroup(queueName, from);
|
|
313
310
|
await this.consumerLoop(queueName, from);
|
|
314
311
|
}
|
|
@@ -500,6 +497,9 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
|
|
|
500
497
|
}
|
|
501
498
|
let start = Date.now();
|
|
502
499
|
if (!this.executeSync && promises.length > 0) {
|
|
500
|
+
if (!this.limit) {
|
|
501
|
+
await this.initLimit();
|
|
502
|
+
}
|
|
503
503
|
await Promise.all(promises.map((item) => this.limit(() => item())));
|
|
504
504
|
}
|
|
505
505
|
await this.onBatchReady(queueName, result);
|
|
@@ -868,3 +868,4 @@ var PowerQueues = class extends import_power_redis.PowerRedis {
|
|
|
868
868
|
0 && (module.exports = {
|
|
869
869
|
PowerQueues
|
|
870
870
|
});
|
|
871
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/PowerQueues.ts","../src/scripts.ts"],"sourcesContent":["export * from './PowerQueues';\nexport type * from './types';","import { randomUUID } from 'node:crypto';\nimport { setMaxListeners } from 'node:events';\nimport type pLimitDefault from 'p-limit';\nimport type { IORedisLike } from 'power-redis';\nimport type {\n\tAddTasksOptions, \n\tTask,\n\tSavedScript,\n\tIdempotencyKeys,\n} from './types';\nimport { \n\tPowerRedis,\n\twait, \n} from 'power-redis';\nimport {\n\tXAddBulk,\n\tApprove,\n\tIdempotencyAllow,\n\tIdempotencyStart,\n\tIdempotencyDone,\n\tIdempotencyFree,\n\tSelectStuck,\n} from './scripts';\n\nclass Base {\n}\n\ntype PLimit = typeof pLimitDefault;\ntype Limit = ReturnType<PLimit>;\n\nconst importDynamic = new Function('modulePath', 'return import(modulePath)') as (modulePath: string) => Promise<{ default: PLimit }>;\nlet pLimitCache: Promise<PLimit> | undefined;\n\nasync function getPLimit(): Promise<PLimit> {\n\tpLimitCache ??= importDynamic('p-limit').then((mod) => mod.default);\n\n\treturn pLimitCache;\n}\n\nexport class PowerQueues extends PowerRedis {\n\tpublic abort = new AbortController();\n\tpublic redis!: IORedisLike;\n\tpublic readonly scripts: Record<string, SavedScript> = {};\n\tpublic readonly host: string = 'host';\n\tpublic readonly group: string = 'gr1';\n\tpublic readonly selectStuckCount: number = 256;\n\tpublic readonly selectStuckTimeout: number = 20000;\n\tpublic readonly selectStuckMaxTimeout: number = 40;\n\tpublic readonly selectCount: number = 1024;\n\tpublic readonly selectTimeout: number = 100;\n\tpublic readonly buildBatchCount: number = 1000;\n\tpublic readonly buildBatchMaxCount: number = 20000;\n\tpublic readonly retryCount: number = 1;\n\tpublic readonly executeSync: boolean = false;\n\tpublic readonly idemLockTimeout: number = 15000;\n\tpublic readonly idemDoneTimeout: number = 10000;\n\tpublic readonly logStatus: boolean = false;\n\tpublic readonly logStatusTimeout: number = 120000;\n\tpublic readonly approveCount: number = 4000;\n\tpublic readonly removeOnExecuted: boolean = true;\n\tpublic readonly concurrency: number = 256;\n\tprivate limit!: Limit;\n\n\tprivate async initLimit(): Promise<void> {\n\t\tconst pLimit = await getPLimit();\n\n\t\tthis.limit = pLimit(this.concurrency);\n\t}\n\n\tprivate signal() {\n\t\treturn this.abort.signal;\n\t}\n\n\tprivate consumer(): string {\n\t\treturn this.host +':'+ process.pid;\n\t}\n\n\tasync runQueue(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\tsetMaxListeners(0, this.abort.signal);\n\n\t\tawait this.initLimit();\n\n\t\tawait this.createGroup(queueName, from);\n\t\tawait this.consumerLoop(queueName, from);\n\t}\n\n\tasync createGroup(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\ttry {\n\t\t\tawait (this.redis as any).xgroup('CREATE', queueName, this.group, from, 'MKSTREAM');\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tconst msg = String(err?.message || '');\n\t\t\t\n\t\t\tif (!msg.includes('BUSYGROUP')) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync consumerLoop(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\tconst signal = this.signal();\n\n\t\twhile (!signal?.aborted) {\n\t\t\tlet tasks: any[] = [];\n\n\t\t\ttry {\n\t\t\t\ttasks = await this.select(queueName, from);\n\t\t\t}\n\t\t\tcatch {\n\t\t\t}\n\t\t\tif (!Array.isArray(tasks) || !(tasks.length > 0)) {\n\t\t\t\tawait wait(300);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this.approve(queueName, await this.execute(queueName, await this.beforeExecute(queueName, tasks)));\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tawait this.batchError(err, queueName, tasks);\n\n\t\t\t\ttry {\n\t\t\t\t\tawait this.approve(queueName, tasks.map((task) => ({\n\t\t\t\t\t\tid: task[0],\n\t\t\t\t\t\tcreatedAt: Number(task[2]),\n\t\t\t\t\t\tpayload: task[1],\n\t\t\t\t\t\tjob: task[3],\n\t\t\t\t\t\tidemKey: task[4],\n\t\t\t\t\t\tattempt: Number(task[5] || 0),\n\t\t\t\t\t})));\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t}\n\t\t\t\tawait wait(300);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async batchError(err: any, queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t\ttry {\n\t\t\tconst filtered: any = {};\n\n\t\t\ttasks.forEach((task, index) => {\n\t\t\t\tconst key = JSON.stringify([ task[5] || '0', task[2], task[3] ]);\n\n\t\t\t\tif (!filtered[key]) {\n\t\t\t\t\tfiltered[key] = [];\n\t\t\t\t}\n\t\t\t\tfiltered[key].push({ ...tasks[index][1], idemKey: tasks[index][4] });\n\t\t\t});\n\n\t\t\tfor (let key in filtered) {\n\t\t\t\tconst filteredTasks = filtered[key];\n\t\t\t\tconst keyP = JSON.parse(key);\n\t\t\t\tconst attempt = Number(keyP[0] || 0);\n\t\t\t\tconst job = String(keyP[2]);\n\n\t\t\t\tif (!(attempt >= (this.retryCount - 1))) {\n\t\t\t\t\tawait this.addTasks(queueName, filteredTasks, {\n\t\t\t\t\t\tjob,\n\t\t\t\t\t\tattempt: attempt + 1,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (this.logStatus) {\n\t\t\t\t\tconst statusKey = `${queueName}:${job}:`;\n\n\t\t\t\t\tawait this.setOne(statusKey +'err', Number(await this.getOne(statusKey +'err') || 0) + filteredTasks.length, this.logStatusTimeout);\n\t\t\t\t\tawait this.setOne(statusKey +'ready', Number(await this.getOne(statusKey +'ready') || 0) + filteredTasks.length, this.logStatusTimeout);\n\t\t\t\t\tawait this.addTasks(queueName +':dlq', filteredTasks, {\n\t\t\t\t\t\tjob,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (err: any) {\n\t\t}\n\t\ttry {\n\t\t\tawait this.onBatchError(err, queueName, tasks);\n\t\t}\n\t\tcatch (err: any) {\n\t\t}\n\t}\n\n\tprivate async approve(queueName: string, tasks: Task[]) {\n\t\tif (!Array.isArray(tasks) || !(tasks.length > 0)) {\n\t\t\treturn 0;\n\t\t}\n\t\tconst approveCount = Math.max(500, Math.min(4000, this.approveCount));\n\t\tlet total = 0,\n\t\t\ti = 0;\n\n\t\twhile (i < tasks.length) {\n\t\t\tconst room = Math.min(approveCount, tasks.length - i);\n\t\t\tconst part = tasks.slice(i, i + room).map((item) => String(item.id || ''));\n\t\t\tconst approved = await this.runScript('Approve', [ queueName ], [ this.group, this.removeOnExecuted ? '1' : '0', ...part ], Approve);\n\n\t\t\ttotal += Number(approved || 0);\n\t\t\ti += room;\n\t\t}\n\t\treturn total;\n\t}\n\n\tasync select(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\tlet selected = await this.selectS(queueName, from);\n\n\t\tif (!Array.isArray(selected) || !(selected.length > 0)) {\n\t\t\tselected = await this.selectF(queueName, from);\n\t\t}\n\t\treturn this.selectP(selected);\n\t}\n\n\tprivate async selectS(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\ttry {\n\t\t\tconst res = await this.runScript('SelectStuck', [ queueName ], [ this.group, this.consumer(), String(this.selectStuckTimeout), String(this.selectStuckCount), String(this.selectStuckMaxTimeout) ], SelectStuck);\n\n\t\t\treturn (Array.isArray(res) ? res : []) as any[];\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOGROUP')) {\n\t\t\t\tawait this.createGroup(queueName, from);\n\t\t\t}\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate async selectF(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\tlet rows = [];\n\n\t\ttry {\n\t\t\tconst res = await (this.redis as any).xreadgroup(\n\t\t\t\t'GROUP', this.group, this.consumer(),\n\t\t\t\t'BLOCK', Math.max(2, this.selectTimeout | 0),\n\t\t\t\t'COUNT', this.selectCount,\n\t\t\t\t'STREAMS', queueName, '>',\n\t\t\t);\n\n\t\t\trows = res?.[0]?.[1] ?? [];\n\n\t\t\tif (!Array.isArray(rows) || !(rows.length > 0)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOGROUP')) {\n\t\t\t\tawait this.createGroup(queueName, from);\n\t\t\t}\n\t\t}\n\t\treturn rows;\n\t}\n\n\tprivate selectP(raw: any): Array<[ string, any, number, string, string, number ]> {\n\t\tif (!Array.isArray(raw)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array\n\t\t\t.from(raw || [])\n\t\t\t.map((e) => {\n\t\t\t\tconst id = Buffer.isBuffer(e?.[0]) ? e[0].toString() : e?.[0];\n\t\t\t\tconst kvRaw = e?.[1] ?? [];\n\t\t\t\tconst kv = Array.isArray(kvRaw) ? kvRaw.map((x: any) => (Buffer.isBuffer(x) ? x.toString() : x)) : [];\n\t\n\t\t\t\treturn [ id as string, kv ] as [ string, any[] ];\n\t\t\t})\n\t\t\t.filter(([ id, kv ]) => typeof id === 'string' && id.length > 0 && Array.isArray(kv) && (kv.length & 1) === 0)\n\t\t\t.map(([ id, kv ]) => {\n\t\t\t\tconst { payload, createdAt, job, idemKey, attempt } = this.values(kv);\n\n\t\t\t\treturn [ id, this.payload(payload), createdAt, job, idemKey, Number(attempt) ];\n\t\t\t});\n\t}\n\n\tprivate values(value: any[]) {\n\t\tconst result: any = {};\n\n\t\tfor (let i = 0; i < value.length; i += 2) {\n\t\t\tresult[value[i]] = value[i + 1];\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate payload(data: any): any {\n\t\ttry {\n\t\t\treturn JSON.parse(data);\n\t\t}\n\t\tcatch (err) {\n\t\t}\n\t\treturn data;\n\t}\n\n\tprivate async execute(queueName: string, tasks: Array<[ string, any, number, string, string, number ]>): Promise<Task[]> {\n\t\tconst result: Task[] = [];\n\t\tlet contended = 0,\n\t\t\tpromises = [];\n\n\t\tfor (const [ id, payload, createdAt, job, idemKey, attempt ] of tasks) {\n\t\t\tif (!this.executeSync) {\n\t\t\t\tpromises.push(async () => {\n\t\t\t\t\tconst r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });\n\n\t\t\t\t\tif (r.id) {\n\t\t\t\t\t\tresult.push(r);\n\t\t\t\t\t}\n\t\t\t\t\telse if (r.contended) {\n\t\t\t\t\t\tcontended++;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconst r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });\n\n\t\t\t\tif (r.id) {\n\t\t\t\t\tresult.push(r);\n\t\t\t\t}\n\t\t\t\telse if (r.contended) {\n\t\t\t\t\tcontended++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet start = Date.now();\n\n\t\tif (!this.executeSync && promises.length > 0) {\n\t\t\tif (!this.limit) {\n\t\t\t\tawait this.initLimit();\n\t\t\t}\n\t\t\tawait Promise.all(promises.map((item) => this.limit(() => item())));\n\t\t}\n\t\tawait this.onBatchReady(queueName, result);\n\n\t\tif ((!Array.isArray(result) || !(result.length > 0)) && contended > (tasks.length >> 1)) {\n\t\t\tawait this.waitAbortable((15 + Math.floor(Math.random() * 35)) + Math.min(250, 15 * contended + Math.floor(Math.random() * 40)));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async executeProcess(queueName: string, task: Task): Promise<any> {\n\t\tconst keys = this.idempotencyKeys(queueName, String(task.idemKey));\n\t\tconst allow = await this.idempotencyAllow(keys);\n\n\t\tif (allow === 1) {\n\t\t\treturn { contended: true };\n\t\t}\n\t\telse if (allow === 0) {\n\t\t\tlet ttl = -2;\n\t\t\t\t\t\t\n\t\t\ttry {\n\t\t\t\tttl = await (this.redis as any).pttl(keys.startKey);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t\tawait this.waitAbortable(ttl);\n\t\t\treturn { contended: true };\n\t\t}\n\t\tif (!(await this.idempotencyStart(keys))) {\n\t\t\treturn { contended: true };\n\t\t}\n\t\tconst heartbeat = this.heartbeat(keys) || (() => {});\n\n\t\ttry {\n\t\t\tconst processed = await this.onExecute(queueName, task);\n\t\t\t\n\t\t\tawait this.idempotencyDone(keys);\n\t\t\treturn await this.success(queueName, processed);\n\t\t}\n\t\tcatch (err: any) {\n\t\t\ttry {\n\t\t\t\tawait this.idempotencyFree(keys);\n\t\t\t\treturn await this.error(err, queueName, task);\n\t\t\t}\n\t\t\tcatch (err2: any) {\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\theartbeat();\n\t\t}\n\t}\n\n\tprivate idempotencyKeys(queueName: string, key: string): IdempotencyKeys {\n\t\tconst prefix = `q:${queueName.replace(/[^\\w:\\-]/g, '_')}:`;\n\t\tconst keyP = key.replace(/[^\\w:\\-]/g, '_');\n\t\tconst doneKey = `${prefix}done:${keyP}`;\n\t\tconst lockKey = `${prefix}lock:${keyP}`;\n\t\tconst startKey = `${prefix}start:${keyP}`;\n\t\tconst token = `${this.consumer()}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;\n\n\t\treturn {\n\t\t\tprefix,\n\t\t\tdoneKey,\n\t\t\tlockKey,\n\t\t\tstartKey,\n\t\t\ttoken,\n\t\t};\n\t}\n\n\tprivate async idempotencyAllow(keys: IdempotencyKeys): Promise<0 | 1 | 2> {\n\t\tconst res = await this.runScript('IdempotencyAllow', [ keys.doneKey, keys.lockKey, keys.startKey ], [ String(this.idemLockTimeout), keys.token ], IdempotencyAllow);\n\n\t\treturn Number(res || 0) as 0 | 1 | 2;\n\t}\n\n\tprivate async idempotencyStart(keys: IdempotencyKeys): Promise<boolean> {\n\t\tconst res = await this.runScript('IdempotencyStart', [ keys.lockKey, keys.startKey ], [ keys.token, String(this.idemLockTimeout) ], IdempotencyStart);\n\n\t\treturn Number(res || 0) === 1;\n\t}\n\n\tprivate async idempotencyDone(keys: IdempotencyKeys): Promise<void> {\n\t\tawait this.runScript('IdempotencyDone', [ keys.doneKey, keys.lockKey, keys.startKey ], [ String(this.idemDoneTimeout), keys.token ], IdempotencyDone);\n\t}\n\n\tprivate async idempotencyFree(keys: IdempotencyKeys): Promise<void> {\n\t\tawait this.runScript('IdempotencyFree', [ keys.lockKey, keys.startKey ], [ keys.token ], IdempotencyFree);\n\t}\n\n\tprivate async success(queueName: string, task: Task) {\n\t\tif (this.logStatus) {\n\t\t\tconst statusKey = `${queueName}:${task.job}:`;\n\n\t\t\tawait this.incr(statusKey +'ok', this.logStatusTimeout);\n\t\t\tawait this.incr(statusKey +'ready', this.logStatusTimeout);\n\t\t}\n\t\treturn await this.onSuccess(queueName, task);\n\t}\n\n\tprivate async error(err: any, queueName: string, task: Task): Promise<Task> {\n\t\tconst taskP: any = { ...task };\n\n\t\tif (!(taskP.attempt >= (this.retryCount - 1))) {\n\t\t\tawait this.onRetry(err, queueName, taskP);\n\t\t\tawait this.addTasks(queueName, [{ ...taskP.payload, idemKey: taskP.idemKey, }], {\n\t\t\t\tcreatedAt: taskP.createdAt,\n\t\t\t\tjob: taskP.job,\n\t\t\t\tattempt: (taskP.attempt || 0) + 1,\n\t\t\t});\n\t\t}\n\t\telse if (this.logStatus) {\n\t\t\tconst dlqKey = queueName +':dlq';\n\t\t\tconst statusKey = `${queueName}:${taskP.job}:`;\n\n\t\t\tawait this.incr(statusKey +'err', this.logStatusTimeout);\n\t\t\tawait this.incr(statusKey +'ready', this.logStatusTimeout);\n\t\t\tawait this.addTasks(dlqKey, [{ ...taskP.payload, idemKey: taskP.idemKey, }], {\n\t\t\t\tcreatedAt: taskP.createdAt,\n\t\t\t\tjob: taskP.job,\n\t\t\t\tattempt: taskP.attempt,\n\t\t\t});\n\t\t}\n\t\treturn await this.onError(err, queueName, { ...taskP, attempt: (taskP.attempt || 0) + 1 });\n\t}\n\n\tprivate async waitAbortable(ttl: number) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst signal = this.signal();\n\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn resolve();\n\t\t\t}\n\t\t\tlet delay: number;\n\n\t\t\tif (ttl > 0) {\n\t\t\t\tconst base = Math.max(25, Math.min(ttl, 4000));\n\t\t\t\tconst jitter = Math.floor(Math.min(base, 200) * Math.random());\n\t\t\t\t\n\t\t\t\tdelay = base + jitter;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdelay = 5 + Math.floor(Math.random() * 15);\n\t\t\t}\n\t\t\tconst t = setTimeout(() => {\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.removeEventListener('abort', onAbort as any);\n\t\t\t\t}\n\t\t\t\tresolve();\n\t\t\t}, delay);\n\t\t\t(t as any).unref?.();\n\n\t\t\tfunction onAbort() { \n\t\t\t\tclearTimeout(t); \n\t\t\t\tresolve(); \n\t\t\t}\n\t\t\tsignal?.addEventListener?.('abort', onAbort, { once: true });\n\t\t});\n\t}\n\n\tprivate async sendHeartbeat(keys: IdempotencyKeys): Promise<boolean> {\n\t\ttry {\n\t\t\tconst r1 = await (this.redis as any).pexpire(keys.lockKey, this.idemLockTimeout);\n\t\t\tconst r2 = await (this.redis as any).pexpire(keys.startKey, this.idemLockTimeout);\n\t\t\tconst ok1 = Number(r1 || 0) === 1;\n\t\t\tconst ok2 = Number(r2 || 0) === 1;\n\n\t\t\treturn ok1 || ok2;\n\t\t}\n\t\tcatch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate heartbeat(keys: IdempotencyKeys) {\n\t\tif (this.idemLockTimeout <= 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst workerHeartbeatTimeoutMs = Math.max(1000, Math.floor(Math.max(5000, this.idemLockTimeout | 0) / 4));\n\t\tlet timer: any,\n\t\t\talive = true,\n\t\t\thbFails = 0;\n\n\t\tconst stop = () => {\n\t\t\talive = false;\n\t\t\t\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t};\n\t\tconst tick = async () => {\n\t\t\tif (!alive) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.signal()?.aborted) {\n\t\t\t\tstop();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst ok = await this.sendHeartbeat(keys);\n\t\t\t\t\n\t\t\t\thbFails = ok \n\t\t\t\t\t? 0 \n\t\t\t\t\t: (hbFails + 1);\n\t\t\t\t\n\t\t\t\tif (hbFails >= 3) {\n\t\t\t\t\tthrow new Error('Heartbeat lost.');\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch {\n\t\t\t\thbFails++;\n\t\t\t\t\n\t\t\t\tif (hbFails >= 6) {\n\t\t\t\t\tstop();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttimer = setTimeout(tick, workerHeartbeatTimeoutMs);\n\t\t\t(timer as any).unref?.();\n\t\t};\n\n\t\ttimer = setTimeout(tick, workerHeartbeatTimeoutMs);\n\t\t(timer as any).unref?.();\n\n\t\treturn () => stop();\n\t}\n\n\tprivate async runScript(name: string, keys: string[], args: (string|number)[], defaultCode?: string) {\n\t\tif (!this.scripts[name]) {\n\t\t\tif (!(typeof defaultCode === 'string' && defaultCode.length > 0)) {\n\t\t\t\tthrow new Error(`Undefined script \"${name}\". Save it before executing.`);\n\t\t\t}\n\t\t\tthis.saveScript(name, defaultCode);\n\t\t}\n\t\tif (!this.scripts[name].codeReady) {\n\t\t\tthis.scripts[name].codeReady = await this.loadScript(this.scripts[name].codeBody);\n\t\t}\n\t\ttry {\n\t\t\treturn await (this.redis as any).evalsha(this.scripts[name].codeReady!, keys.length, ...keys, ...args);\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOSCRIPT')) {\n\t\t\t\tthis.scripts[name].codeReady = await this.loadScript(this.scripts[name].codeBody);\n\n\t\t\t\treturn await (this.redis as any).evalsha(this.scripts[name].codeReady!, keys.length, ...keys, ...args);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync loadScripts(full: boolean = false): Promise<void> {\n\t\tconst scripts = full\n\t\t\t? [\n\t\t\t\t[ 'XAddBulk', XAddBulk ],\n\t\t\t\t[ 'Approve', Approve ],\n\t\t\t\t[ 'IdempotencyAllow', IdempotencyAllow ],\n\t\t\t\t[ 'IdempotencyStart', IdempotencyStart ],\n\t\t\t\t[ 'IdempotencyDone', IdempotencyDone ],\n\t\t\t\t[ 'IdempotencyFree', IdempotencyFree ],\n\t\t\t\t[ 'SelectStuck', SelectStuck ]\n\t\t\t]\n\t\t\t: [\n\t\t\t\t[ 'XAddBulk', XAddBulk ],\n\t\t\t];\n\n\t\tfor (const [ name, code ] of scripts) {\n\t\t\tawait this.loadScript(this.saveScript(name, code));\n\t\t}\n\t}\n\n\tprivate async loadScript(code: string): Promise<string> {\n\t\tfor (let i = 0; i < 3; i++) {\n\t\t\ttry {\n\t\t\t\treturn await (this.redis as any).script('LOAD', code);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tif (i === 2) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t\tawait new Promise((r) => setTimeout(r, 10 + Math.floor(Math.random() * 40)));\n\t\t\t}\n\t\t}\n\t\tthrow new Error('Load lua script failed.');\n\t}\n\n\tprivate saveScript(name: string, codeBody: string): string {\n\t\tif (!(typeof codeBody === 'string' && codeBody.length > 0)) {\n\t\t\tthrow new Error('Script body is empty.');\n\t\t}\n\t\tthis.scripts[name] = { codeBody };\n\n\t\treturn codeBody;\n\t}\n\n\tasync addTasks(queueName: string, data: any[], opts: AddTasksOptions = {}): Promise<string[]> {\n\t\tif (!Array.isArray(data) || !(data.length > 0)) {\n\t\t\tthrow new Error('Tasks is not filled.');\n\t\t}\n\t\tif (!(typeof queueName === 'string' && queueName.length > 0)) {\n\t\t\tthrow new Error('Queue name is required.');\n\t\t}\n\t\topts.job = opts.job ?? randomUUID();\n\n\t\tconst batches = this.buildBatches(data, opts);\n\t\tconst result: string[] = new Array(data.length);\n\t\tconst promises: Array<() => Promise<void>> = [];\n\t\tlet cursor = 0;\n\t\t\n\t\tfor (const batch of batches) {\n\t\t\tconst start = cursor;\n\t\t\tconst end = start + batch.length;\n\t\t\t\t\n\t\t\tcursor = end;\n\t\t\tpromises.push(async () => {\n\t\t\t\tconst payload = this.payloadBatch(batch, opts);\n\t\t\t\tconst partIds = await this.runScript('XAddBulk', [ queueName ], payload, XAddBulk);\n\n\t\t\t\tfor (let k = 0; k < partIds.length; k++) {\n\t\t\t\t\tresult[start + k] = partIds[k];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tconst runners = Array.from({ length: promises.length }, async () => {\n\t\t\twhile (promises.length) {\n\t\t\t\tconst promise = promises.shift();\n\n\t\t\t\tif (promise) {\n\t\t\t\t\tawait promise();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (opts.status) {\n\t\t\tawait (this.redis as any).set(`${queueName}:${opts.job}:total`, data.length);\n\t\t\tawait (this.redis as any).pexpire(`${queueName}:${opts.job}:total`, this.logStatusTimeout);\n\t\t}\n\t\tawait Promise.all(runners);\n\t\treturn result;\n\t}\n\n\tprivate buildBatches(tasks: Task[], opts: AddTasksOptions = {}): Task[][] {\n\t\tconst batches: Task[][] = [];\n\t\tlet batch: Task[] = [],\n\t\t\trealKeysLength = 8;\n\n\t\tfor (let task of tasks) {\n\t\t\tconst createdAt = opts?.createdAt || Date.now();\n\t\t\tconst { idemKey, ...taskP } = task;\n\t\t\tconst entry: Task = { \n\t\t\t\tpayload: JSON.stringify(taskP),\n\t\t\t\tattempt: Number(opts.attempt || 0),\n\t\t\t\tjob: opts.job ?? randomUUID(),\n\t\t\t\tidemKey: String(idemKey || randomUUID()),\n\t\t\t\tcreatedAt,\n\t\t\t};\n\t\t\tconst reqKeysLength = this.keysLength(entry);\n\t\t\t\n\t\t\tif (batch.length && (batch.length >= this.buildBatchCount || realKeysLength + reqKeysLength > this.buildBatchMaxCount)) {\n\t\t\t\tbatches.push(batch); \n\t\t\t\tbatch = []; \n\t\t\t\trealKeysLength = 0;\n\t\t\t}\n\t\t\tbatch.push(entry);\n\t\t\trealKeysLength += reqKeysLength;\n\t\t}\n\t\tif (batch.length) {\n\t\t\tbatches.push(batch);\n\t\t}\n\t\treturn batches;\n\t}\n\n\tprivate keysLength(task: Task): number {\n\t\treturn 2 + Object.keys(task as any).length * 2;\n\t}\n\n\tprivate payloadBatch(data: Task[], opts: AddTasksOptions): string[] {\n\t\tconst maxlen = Math.max(0, Math.floor(opts?.maxlen ?? 0));\n\t\tconst approx = opts?.exact ? 0 : (opts?.approx !== false ? 1 : 0);\n\t\tconst exact = opts?.exact ? 1 : 0;\n\t\tconst nomkstream = opts?.nomkstream ? 1 : 0;\n\t\tconst trimLimit = Math.max(0, Math.floor(opts?.trimLimit ?? 0));\n\t\tconst minidWindowMs = Math.max(0, Math.floor(opts?.minidWindowMs ?? 0));\n\t\tconst minidExact = opts?.minidExact ? 1 : 0;\n\t\tconst argv: string[] = [\n\t\t\tString(maxlen),\n\t\t\tString(approx),\n\t\t\tString(data.length),\n\t\t\tString(exact), \n\t\t\tString(nomkstream),\n\t\t\tString(trimLimit),\n\t\t\tString(minidWindowMs),\n\t\t\tString(minidExact),\n\t\t];\n\n\t\tfor (const item of data) {\n\t\t\tconst entry: any = item;\n\t\t\tconst id = entry.id ?? '*';\n\t\t\tlet flat: any = [];\n\n\t\t\tif ('payload' in entry) {\n\t\t\t\tfor (const [ k, v ] of Object.entries(entry)) {\n\t\t\t\t\tflat.push(k, v as any);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new Error('Task must have \"payload\" or \"flat\".');\n\t\t\t}\n\t\t\tconst pairs = flat.length / 2;\n\n\t\t\tif (pairs <= 0) {\n\t\t\t\tthrow new Error('Task \"flat\" must contain at least one field/value pair.');\n\t\t\t}\n\t\t\targv.push(String(id));\n\t\t\targv.push(String(pairs));\n\n\t\t\tfor (const token of flat) {\n\t\t\t\targv.push((token === null || token === undefined)\n\t\t\t\t\t? ''\n\t\t\t\t\t: (typeof token === 'string' && token.length > 0)\n\t\t\t\t\t\t? token\n\t\t\t\t\t\t: String(token));\n\t\t\t}\n\t\t}\n\t\treturn argv;\n\t}\n\n\tasync beforeExecute(queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t\treturn tasks;\n\t}\n\n\tasync onExecute(queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onBatchReady(queueName: string, tasks: Task[]) {\n\t}\n\n\tasync onSuccess(queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onError(err: any, queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onBatchError(err: any, queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t}\n\n\tasync onRetry(err: any, queueName: string, task: Task) {\n\t}\n}\n","\nexport const XAddBulk = `\n\tlocal UNPACK = table and table.unpack or unpack\n\n\tlocal stream = KEYS[1]\n\tlocal maxlen = tonumber(ARGV[1])\n\tlocal approxFlag = tonumber(ARGV[2]) == 1\n\tlocal n = tonumber(ARGV[3])\n\tlocal exactFlag = tonumber(ARGV[4]) == 1\n\tlocal nomkstream = tonumber(ARGV[5]) == 1\n\tlocal trimLimit = tonumber(ARGV[6])\n\tlocal minidWindowMs = tonumber(ARGV[7]) or 0\n\tlocal minidExact = tonumber(ARGV[8]) == 1\n\tlocal idx = 9\n\tlocal out = {}\n\n\tlocal common_opts = {}\n\tlocal co_len = 0\n\n\tif nomkstream then\n\t\tco_len = co_len + 1; common_opts[co_len] = 'NOMKSTREAM'\n\tend\n\n\tif minidWindowMs > 0 then\n\t\tlocal tm = redis.call('TIME')\n\t\tlocal now_ms = (tonumber(tm[1]) * 1000) + math.floor(tonumber(tm[2]) / 1000)\n\t\tlocal cutoff_ms = now_ms - minidWindowMs\n\t\tif cutoff_ms < 0 then cutoff_ms = 0 end\n\t\tlocal cutoff_id = tostring(cutoff_ms) .. '-0'\n\n\t\tco_len = co_len + 1; common_opts[co_len] = 'MINID'\n\t\tco_len = co_len + 1; common_opts[co_len] = (minidExact and '=' or '~')\n\t\tco_len = co_len + 1; common_opts[co_len] = cutoff_id\n\t\tif trimLimit and trimLimit > 0 then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = 'LIMIT'\n\t\t\tco_len = co_len + 1; common_opts[co_len] = trimLimit\n\t\tend\n\telseif maxlen and maxlen > 0 then\n\t\tco_len = co_len + 1; common_opts[co_len] = 'MAXLEN'\n\t\tif exactFlag then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = '='\n\t\telseif approxFlag then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = '~'\n\t\tend\n\t\tco_len = co_len + 1; common_opts[co_len] = maxlen\n\t\tif trimLimit and trimLimit > 0 then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = 'LIMIT'\n\t\t\tco_len = co_len + 1; common_opts[co_len] = trimLimit\n\t\tend\n\tend\n\n\tfor e = 1, n do\n\t\tlocal id = ARGV[idx]; idx = idx + 1\n\t\tlocal num_pairs = tonumber(ARGV[idx]); idx = idx + 1\n\n\t\tlocal a = {}\n\t\tlocal a_len = 0\n\n\t\tfor i = 1, co_len do a_len = a_len + 1; a[a_len] = common_opts[i] end\n\n\t\ta_len = a_len + 1; a[a_len] = id\n\n\t\tfor j = 1, (num_pairs * 2) do\n\t\t\ta_len = a_len + 1; a[a_len] = ARGV[idx]; idx = idx + 1\n\t\tend\n\n\t\tlocal addedId = redis.call('XADD', stream, UNPACK(a))\n\t\tout[#out+1] = addedId or ''\n\tend\n\n\treturn out\n`;\n\nexport const Approve = `\n\tlocal stream = KEYS[1]\n\tlocal group = ARGV[1]\n\tlocal delFlag = tonumber(ARGV[2]) == 1\n\n\tlocal acked = 0\n\tlocal nids = #ARGV - 2\n\tif nids > 0 then\n\t\tacked = tonumber(redis.call('XACK', stream, group, unpack(ARGV, 3))) or 0\n\t\tif delFlag and nids > 0 then\n\t\t\tlocal ok, deln = pcall(redis.call, 'XDEL', stream, unpack(ARGV, 3))\n\t\t\tif not ok then\n\t\t\t\tdeln = 0\n\t\t\t\tfor i = 3, #ARGV do\n\t\t\t\t\tdeln = deln + (tonumber(redis.call('XDEL', stream, ARGV[i])) or 0)\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\n\treturn acked\n`;\n\nexport const IdempotencyAllow = `\n\tlocal doneKey = KEYS[1]\n\tlocal lockKey = KEYS[2]\n\tlocal startKey = KEYS[3]\n\n\tif redis.call('EXISTS', doneKey) == 1 then\n\t\treturn 1\n\tend\n\n\tlocal ttl = tonumber(ARGV[1]) or 0\n\tif ttl <= 0 then return 0 end\n\n\tlocal ok = redis.call('SET', lockKey, ARGV[2], 'NX', 'PX', ttl)\n\tif ok then\n\t\tif startKey and startKey ~= '' then\n\t\t\tredis.call('SET', startKey, 1, 'PX', ttl)\n\t\tend\n\t\treturn 2\n\telse\n\t\treturn 0\n\tend\n`;\n\nexport const IdempotencyStart = `\n\tlocal lockKey = KEYS[1]\n\tlocal startKey = KEYS[2]\n\tif redis.call('GET', lockKey) == ARGV[1] then\n\t\tlocal ttl = tonumber(ARGV[2]) or 0\n\t\tif ttl > 0 then\n\t\t\tredis.call('SET', startKey, 1, 'PX', ttl)\n\t\t\tredis.call('PEXPIRE', lockKey, ttl)\n\t\telse\n\t\t\tredis.call('SET', startKey, 1)\n\t\tend\n\t\treturn 1\n\tend\n\treturn 0\n`;\n\nexport const IdempotencyDone = `\n\tlocal doneKey = KEYS[1]\n\tlocal lockKey = KEYS[2]\n\tlocal startKey = KEYS[3]\n\n\tredis.call('SET', doneKey, 1)\n\n\tlocal ttlMs = tonumber(ARGV[1]) or 0\n\tif ttlMs > 0 then\n\t\tredis.call('PEXPIRE', doneKey, ttlMs)\n\tend\n\n\tif redis.call('GET', lockKey) == ARGV[2] then\n\t\tredis.call('DEL', lockKey)\n\t\tif startKey then\n\t\t\tredis.call('DEL', startKey)\n\t\tend\n\tend\n\n\treturn 1\n`;\n\nexport const IdempotencyFree = `\n\tlocal lockKey = KEYS[1]\n\tlocal startKey = KEYS[2]\n\tif redis.call('GET', lockKey) == ARGV[1] then\n\t\tredis.call('DEL', lockKey)\n\t\tif startKey then redis.call('DEL', startKey) end\n\t\treturn 1\n\tend\n\treturn 0\n`;\n\nexport const SelectStuck = `\n\tlocal stream = KEYS[1]\n\tlocal group = ARGV[1]\n\tlocal consumer = ARGV[2]\n\tlocal pendingIdleMs = tonumber(ARGV[3])\n\tlocal count = tonumber(ARGV[4]) or 0\n\tif count < 1 then count = 1 end\n\n\tlocal timeBudgetMs = tonumber(ARGV[5]) or 15\n\tlocal t0 = redis.call('TIME')\n\tlocal start_ms = (tonumber(t0[1]) * 1000) + math.floor(tonumber(t0[2]) / 1000)\n\n\tlocal results = {}\n\tlocal collected = 0\n\tlocal start_id = '0-0'\n\tlocal iters = 0\n\tlocal max_iters = math.max(16, math.ceil(count / 100))\n\n\tlocal function time_exceeded()\n\t\tlocal t1 = redis.call('TIME')\n\t\tlocal now_ms = (tonumber(t1[1]) * 1000) + math.floor(tonumber(t1[2]) / 1000)\n\t\treturn (now_ms - start_ms) >= timeBudgetMs\n\tend\n\n\twhile (collected < count) and (iters < max_iters) do\n\t\tlocal to_claim = count - collected\n\t\tif to_claim < 1 then break end\n\n\t\tlocal claim = redis.call('XAUTOCLAIM', stream, group, consumer, pendingIdleMs, start_id, 'COUNT', to_claim)\n\t\titers = iters + 1\n\n\t\tlocal bucket = nil\n\t\tif claim then\n\t\t\tbucket = claim[2]\n\t\tend\n\t\tif bucket and #bucket > 0 then\n\t\t\tfor i = 1, #bucket do\n\t\t\t\tresults[#results+1] = bucket[i]\n\t\t\tend\n\t\t\tcollected = #results\n\t\tend\n\n\t\tlocal next_id = claim and claim[1] or start_id\n\t\tif next_id == start_id then\n\t\t\tlocal s, seq = string.match(start_id, '^(%d+)%-(%d+)$')\n\t\t\tif s and seq then\n\t\t\t\tstart_id = s .. '-' .. tostring(tonumber(seq) + 1)\n\t\t\telse\n\t\t\t\tstart_id = '0-1'\n\t\t\tend\n\t\telse\n\t\t\tstart_id = next_id\n\t\tend\n\n\t\tif time_exceeded() then\n\t\t\tbreak\n\t\tend\n\tend\n\n\tlocal left = count - collected\n\tif left > 0 then\n\t\tlocal xr = redis.call('XREADGROUP', 'GROUP', group, consumer, 'COUNT', left, 'STREAMS', stream, '>')\n\t\tif xr and xr[1] and xr[1][2] then\n\t\t\tlocal entries = xr[1][2]\n\t\t\tfor i = 1, #entries do\n\t\t\t\tresults[#results+1] = entries[i]\n\t\t\tend\n\t\tend\n\tend\n\n\treturn results\n`;\n"],"mappings":"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","names":["err"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -58,6 +58,7 @@ declare class PowerQueues extends PowerRedis {
|
|
|
58
58
|
readonly removeOnExecuted: boolean;
|
|
59
59
|
readonly concurrency: number;
|
|
60
60
|
private limit;
|
|
61
|
+
private initLimit;
|
|
61
62
|
private signal;
|
|
62
63
|
private consumer;
|
|
63
64
|
runQueue(queueName: string, from?: '$' | '0-0'): Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ declare class PowerQueues extends PowerRedis {
|
|
|
58
58
|
readonly removeOnExecuted: boolean;
|
|
59
59
|
readonly concurrency: number;
|
|
60
60
|
private limit;
|
|
61
|
+
private initLimit;
|
|
61
62
|
private signal;
|
|
62
63
|
private consumer;
|
|
63
64
|
runQueue(queueName: string, from?: '$' | '0-0'): Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/PowerQueues.ts
|
|
2
|
-
import pLimit from "p-limit";
|
|
3
2
|
import { randomUUID } from "crypto";
|
|
4
3
|
import { setMaxListeners } from "events";
|
|
5
4
|
import {
|
|
@@ -242,29 +241,37 @@ var SelectStuck = `
|
|
|
242
241
|
`;
|
|
243
242
|
|
|
244
243
|
// src/PowerQueues.ts
|
|
244
|
+
var importDynamic = new Function("modulePath", "return import(modulePath)");
|
|
245
|
+
var pLimitCache;
|
|
246
|
+
async function getPLimit() {
|
|
247
|
+
pLimitCache ??= importDynamic("p-limit").then((mod) => mod.default);
|
|
248
|
+
return pLimitCache;
|
|
249
|
+
}
|
|
245
250
|
var PowerQueues = class extends PowerRedis {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
251
|
+
abort = new AbortController();
|
|
252
|
+
redis;
|
|
253
|
+
scripts = {};
|
|
254
|
+
host = "host";
|
|
255
|
+
group = "gr1";
|
|
256
|
+
selectStuckCount = 256;
|
|
257
|
+
selectStuckTimeout = 2e4;
|
|
258
|
+
selectStuckMaxTimeout = 40;
|
|
259
|
+
selectCount = 1024;
|
|
260
|
+
selectTimeout = 100;
|
|
261
|
+
buildBatchCount = 1e3;
|
|
262
|
+
buildBatchMaxCount = 2e4;
|
|
263
|
+
retryCount = 1;
|
|
264
|
+
executeSync = false;
|
|
265
|
+
idemLockTimeout = 15e3;
|
|
266
|
+
idemDoneTimeout = 1e4;
|
|
267
|
+
logStatus = false;
|
|
268
|
+
logStatusTimeout = 12e4;
|
|
269
|
+
approveCount = 4e3;
|
|
270
|
+
removeOnExecuted = true;
|
|
271
|
+
concurrency = 256;
|
|
272
|
+
limit;
|
|
273
|
+
async initLimit() {
|
|
274
|
+
const pLimit = await getPLimit();
|
|
268
275
|
this.limit = pLimit(this.concurrency);
|
|
269
276
|
}
|
|
270
277
|
signal() {
|
|
@@ -275,7 +282,7 @@ var PowerQueues = class extends PowerRedis {
|
|
|
275
282
|
}
|
|
276
283
|
async runQueue(queueName, from = "0-0") {
|
|
277
284
|
setMaxListeners(0, this.abort.signal);
|
|
278
|
-
this.
|
|
285
|
+
await this.initLimit();
|
|
279
286
|
await this.createGroup(queueName, from);
|
|
280
287
|
await this.consumerLoop(queueName, from);
|
|
281
288
|
}
|
|
@@ -467,6 +474,9 @@ var PowerQueues = class extends PowerRedis {
|
|
|
467
474
|
}
|
|
468
475
|
let start = Date.now();
|
|
469
476
|
if (!this.executeSync && promises.length > 0) {
|
|
477
|
+
if (!this.limit) {
|
|
478
|
+
await this.initLimit();
|
|
479
|
+
}
|
|
470
480
|
await Promise.all(promises.map((item) => this.limit(() => item())));
|
|
471
481
|
}
|
|
472
482
|
await this.onBatchReady(queueName, result);
|
|
@@ -834,3 +844,4 @@ var PowerQueues = class extends PowerRedis {
|
|
|
834
844
|
export {
|
|
835
845
|
PowerQueues
|
|
836
846
|
};
|
|
847
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/PowerQueues.ts","../src/scripts.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport { setMaxListeners } from 'node:events';\nimport type pLimitDefault from 'p-limit';\nimport type { IORedisLike } from 'power-redis';\nimport type {\n\tAddTasksOptions, \n\tTask,\n\tSavedScript,\n\tIdempotencyKeys,\n} from './types';\nimport { \n\tPowerRedis,\n\twait, \n} from 'power-redis';\nimport {\n\tXAddBulk,\n\tApprove,\n\tIdempotencyAllow,\n\tIdempotencyStart,\n\tIdempotencyDone,\n\tIdempotencyFree,\n\tSelectStuck,\n} from './scripts';\n\nclass Base {\n}\n\ntype PLimit = typeof pLimitDefault;\ntype Limit = ReturnType<PLimit>;\n\nconst importDynamic = new Function('modulePath', 'return import(modulePath)') as (modulePath: string) => Promise<{ default: PLimit }>;\nlet pLimitCache: Promise<PLimit> | undefined;\n\nasync function getPLimit(): Promise<PLimit> {\n\tpLimitCache ??= importDynamic('p-limit').then((mod) => mod.default);\n\n\treturn pLimitCache;\n}\n\nexport class PowerQueues extends PowerRedis {\n\tpublic abort = new AbortController();\n\tpublic redis!: IORedisLike;\n\tpublic readonly scripts: Record<string, SavedScript> = {};\n\tpublic readonly host: string = 'host';\n\tpublic readonly group: string = 'gr1';\n\tpublic readonly selectStuckCount: number = 256;\n\tpublic readonly selectStuckTimeout: number = 20000;\n\tpublic readonly selectStuckMaxTimeout: number = 40;\n\tpublic readonly selectCount: number = 1024;\n\tpublic readonly selectTimeout: number = 100;\n\tpublic readonly buildBatchCount: number = 1000;\n\tpublic readonly buildBatchMaxCount: number = 20000;\n\tpublic readonly retryCount: number = 1;\n\tpublic readonly executeSync: boolean = false;\n\tpublic readonly idemLockTimeout: number = 15000;\n\tpublic readonly idemDoneTimeout: number = 10000;\n\tpublic readonly logStatus: boolean = false;\n\tpublic readonly logStatusTimeout: number = 120000;\n\tpublic readonly approveCount: number = 4000;\n\tpublic readonly removeOnExecuted: boolean = true;\n\tpublic readonly concurrency: number = 256;\n\tprivate limit!: Limit;\n\n\tprivate async initLimit(): Promise<void> {\n\t\tconst pLimit = await getPLimit();\n\n\t\tthis.limit = pLimit(this.concurrency);\n\t}\n\n\tprivate signal() {\n\t\treturn this.abort.signal;\n\t}\n\n\tprivate consumer(): string {\n\t\treturn this.host +':'+ process.pid;\n\t}\n\n\tasync runQueue(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\tsetMaxListeners(0, this.abort.signal);\n\n\t\tawait this.initLimit();\n\n\t\tawait this.createGroup(queueName, from);\n\t\tawait this.consumerLoop(queueName, from);\n\t}\n\n\tasync createGroup(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\ttry {\n\t\t\tawait (this.redis as any).xgroup('CREATE', queueName, this.group, from, 'MKSTREAM');\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tconst msg = String(err?.message || '');\n\t\t\t\n\t\t\tif (!msg.includes('BUSYGROUP')) {\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t}\n\t}\n\n\tasync consumerLoop(queueName: string, from: '$' | '0-0' = '0-0') {\n\t\tconst signal = this.signal();\n\n\t\twhile (!signal?.aborted) {\n\t\t\tlet tasks: any[] = [];\n\n\t\t\ttry {\n\t\t\t\ttasks = await this.select(queueName, from);\n\t\t\t}\n\t\t\tcatch {\n\t\t\t}\n\t\t\tif (!Array.isArray(tasks) || !(tasks.length > 0)) {\n\t\t\t\tawait wait(300);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this.approve(queueName, await this.execute(queueName, await this.beforeExecute(queueName, tasks)));\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t\tawait this.batchError(err, queueName, tasks);\n\n\t\t\t\ttry {\n\t\t\t\t\tawait this.approve(queueName, tasks.map((task) => ({\n\t\t\t\t\t\tid: task[0],\n\t\t\t\t\t\tcreatedAt: Number(task[2]),\n\t\t\t\t\t\tpayload: task[1],\n\t\t\t\t\t\tjob: task[3],\n\t\t\t\t\t\tidemKey: task[4],\n\t\t\t\t\t\tattempt: Number(task[5] || 0),\n\t\t\t\t\t})));\n\t\t\t\t}\n\t\t\t\tcatch {\n\t\t\t\t}\n\t\t\t\tawait wait(300);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async batchError(err: any, queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t\ttry {\n\t\t\tconst filtered: any = {};\n\n\t\t\ttasks.forEach((task, index) => {\n\t\t\t\tconst key = JSON.stringify([ task[5] || '0', task[2], task[3] ]);\n\n\t\t\t\tif (!filtered[key]) {\n\t\t\t\t\tfiltered[key] = [];\n\t\t\t\t}\n\t\t\t\tfiltered[key].push({ ...tasks[index][1], idemKey: tasks[index][4] });\n\t\t\t});\n\n\t\t\tfor (let key in filtered) {\n\t\t\t\tconst filteredTasks = filtered[key];\n\t\t\t\tconst keyP = JSON.parse(key);\n\t\t\t\tconst attempt = Number(keyP[0] || 0);\n\t\t\t\tconst job = String(keyP[2]);\n\n\t\t\t\tif (!(attempt >= (this.retryCount - 1))) {\n\t\t\t\t\tawait this.addTasks(queueName, filteredTasks, {\n\t\t\t\t\t\tjob,\n\t\t\t\t\t\tattempt: attempt + 1,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse if (this.logStatus) {\n\t\t\t\t\tconst statusKey = `${queueName}:${job}:`;\n\n\t\t\t\t\tawait this.setOne(statusKey +'err', Number(await this.getOne(statusKey +'err') || 0) + filteredTasks.length, this.logStatusTimeout);\n\t\t\t\t\tawait this.setOne(statusKey +'ready', Number(await this.getOne(statusKey +'ready') || 0) + filteredTasks.length, this.logStatusTimeout);\n\t\t\t\t\tawait this.addTasks(queueName +':dlq', filteredTasks, {\n\t\t\t\t\t\tjob,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (err: any) {\n\t\t}\n\t\ttry {\n\t\t\tawait this.onBatchError(err, queueName, tasks);\n\t\t}\n\t\tcatch (err: any) {\n\t\t}\n\t}\n\n\tprivate async approve(queueName: string, tasks: Task[]) {\n\t\tif (!Array.isArray(tasks) || !(tasks.length > 0)) {\n\t\t\treturn 0;\n\t\t}\n\t\tconst approveCount = Math.max(500, Math.min(4000, this.approveCount));\n\t\tlet total = 0,\n\t\t\ti = 0;\n\n\t\twhile (i < tasks.length) {\n\t\t\tconst room = Math.min(approveCount, tasks.length - i);\n\t\t\tconst part = tasks.slice(i, i + room).map((item) => String(item.id || ''));\n\t\t\tconst approved = await this.runScript('Approve', [ queueName ], [ this.group, this.removeOnExecuted ? '1' : '0', ...part ], Approve);\n\n\t\t\ttotal += Number(approved || 0);\n\t\t\ti += room;\n\t\t}\n\t\treturn total;\n\t}\n\n\tasync select(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\tlet selected = await this.selectS(queueName, from);\n\n\t\tif (!Array.isArray(selected) || !(selected.length > 0)) {\n\t\t\tselected = await this.selectF(queueName, from);\n\t\t}\n\t\treturn this.selectP(selected);\n\t}\n\n\tprivate async selectS(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\ttry {\n\t\t\tconst res = await this.runScript('SelectStuck', [ queueName ], [ this.group, this.consumer(), String(this.selectStuckTimeout), String(this.selectStuckCount), String(this.selectStuckMaxTimeout) ], SelectStuck);\n\n\t\t\treturn (Array.isArray(res) ? res : []) as any[];\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOGROUP')) {\n\t\t\t\tawait this.createGroup(queueName, from);\n\t\t\t}\n\t\t}\n\t\treturn [];\n\t}\n\n\tprivate async selectF(queueName: string, from: '$' | '0-0' = '0-0'): Promise<any[]> {\n\t\tlet rows = [];\n\n\t\ttry {\n\t\t\tconst res = await (this.redis as any).xreadgroup(\n\t\t\t\t'GROUP', this.group, this.consumer(),\n\t\t\t\t'BLOCK', Math.max(2, this.selectTimeout | 0),\n\t\t\t\t'COUNT', this.selectCount,\n\t\t\t\t'STREAMS', queueName, '>',\n\t\t\t);\n\n\t\t\trows = res?.[0]?.[1] ?? [];\n\n\t\t\tif (!Array.isArray(rows) || !(rows.length > 0)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOGROUP')) {\n\t\t\t\tawait this.createGroup(queueName, from);\n\t\t\t}\n\t\t}\n\t\treturn rows;\n\t}\n\n\tprivate selectP(raw: any): Array<[ string, any, number, string, string, number ]> {\n\t\tif (!Array.isArray(raw)) {\n\t\t\treturn [];\n\t\t}\n\t\treturn Array\n\t\t\t.from(raw || [])\n\t\t\t.map((e) => {\n\t\t\t\tconst id = Buffer.isBuffer(e?.[0]) ? e[0].toString() : e?.[0];\n\t\t\t\tconst kvRaw = e?.[1] ?? [];\n\t\t\t\tconst kv = Array.isArray(kvRaw) ? kvRaw.map((x: any) => (Buffer.isBuffer(x) ? x.toString() : x)) : [];\n\t\n\t\t\t\treturn [ id as string, kv ] as [ string, any[] ];\n\t\t\t})\n\t\t\t.filter(([ id, kv ]) => typeof id === 'string' && id.length > 0 && Array.isArray(kv) && (kv.length & 1) === 0)\n\t\t\t.map(([ id, kv ]) => {\n\t\t\t\tconst { payload, createdAt, job, idemKey, attempt } = this.values(kv);\n\n\t\t\t\treturn [ id, this.payload(payload), createdAt, job, idemKey, Number(attempt) ];\n\t\t\t});\n\t}\n\n\tprivate values(value: any[]) {\n\t\tconst result: any = {};\n\n\t\tfor (let i = 0; i < value.length; i += 2) {\n\t\t\tresult[value[i]] = value[i + 1];\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate payload(data: any): any {\n\t\ttry {\n\t\t\treturn JSON.parse(data);\n\t\t}\n\t\tcatch (err) {\n\t\t}\n\t\treturn data;\n\t}\n\n\tprivate async execute(queueName: string, tasks: Array<[ string, any, number, string, string, number ]>): Promise<Task[]> {\n\t\tconst result: Task[] = [];\n\t\tlet contended = 0,\n\t\t\tpromises = [];\n\n\t\tfor (const [ id, payload, createdAt, job, idemKey, attempt ] of tasks) {\n\t\t\tif (!this.executeSync) {\n\t\t\t\tpromises.push(async () => {\n\t\t\t\t\tconst r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });\n\n\t\t\t\t\tif (r.id) {\n\t\t\t\t\t\tresult.push(r);\n\t\t\t\t\t}\n\t\t\t\t\telse if (r.contended) {\n\t\t\t\t\t\tcontended++;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tconst r = await this.executeProcess(queueName, { id, payload, createdAt, job, idemKey, attempt });\n\n\t\t\t\tif (r.id) {\n\t\t\t\t\tresult.push(r);\n\t\t\t\t}\n\t\t\t\telse if (r.contended) {\n\t\t\t\t\tcontended++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tlet start = Date.now();\n\n\t\tif (!this.executeSync && promises.length > 0) {\n\t\t\tif (!this.limit) {\n\t\t\t\tawait this.initLimit();\n\t\t\t}\n\t\t\tawait Promise.all(promises.map((item) => this.limit(() => item())));\n\t\t}\n\t\tawait this.onBatchReady(queueName, result);\n\n\t\tif ((!Array.isArray(result) || !(result.length > 0)) && contended > (tasks.length >> 1)) {\n\t\t\tawait this.waitAbortable((15 + Math.floor(Math.random() * 35)) + Math.min(250, 15 * contended + Math.floor(Math.random() * 40)));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async executeProcess(queueName: string, task: Task): Promise<any> {\n\t\tconst keys = this.idempotencyKeys(queueName, String(task.idemKey));\n\t\tconst allow = await this.idempotencyAllow(keys);\n\n\t\tif (allow === 1) {\n\t\t\treturn { contended: true };\n\t\t}\n\t\telse if (allow === 0) {\n\t\t\tlet ttl = -2;\n\t\t\t\t\t\t\n\t\t\ttry {\n\t\t\t\tttl = await (this.redis as any).pttl(keys.startKey);\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t\tawait this.waitAbortable(ttl);\n\t\t\treturn { contended: true };\n\t\t}\n\t\tif (!(await this.idempotencyStart(keys))) {\n\t\t\treturn { contended: true };\n\t\t}\n\t\tconst heartbeat = this.heartbeat(keys) || (() => {});\n\n\t\ttry {\n\t\t\tconst processed = await this.onExecute(queueName, task);\n\t\t\t\n\t\t\tawait this.idempotencyDone(keys);\n\t\t\treturn await this.success(queueName, processed);\n\t\t}\n\t\tcatch (err: any) {\n\t\t\ttry {\n\t\t\t\tawait this.idempotencyFree(keys);\n\t\t\t\treturn await this.error(err, queueName, task);\n\t\t\t}\n\t\t\tcatch (err2: any) {\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\theartbeat();\n\t\t}\n\t}\n\n\tprivate idempotencyKeys(queueName: string, key: string): IdempotencyKeys {\n\t\tconst prefix = `q:${queueName.replace(/[^\\w:\\-]/g, '_')}:`;\n\t\tconst keyP = key.replace(/[^\\w:\\-]/g, '_');\n\t\tconst doneKey = `${prefix}done:${keyP}`;\n\t\tconst lockKey = `${prefix}lock:${keyP}`;\n\t\tconst startKey = `${prefix}start:${keyP}`;\n\t\tconst token = `${this.consumer()}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;\n\n\t\treturn {\n\t\t\tprefix,\n\t\t\tdoneKey,\n\t\t\tlockKey,\n\t\t\tstartKey,\n\t\t\ttoken,\n\t\t};\n\t}\n\n\tprivate async idempotencyAllow(keys: IdempotencyKeys): Promise<0 | 1 | 2> {\n\t\tconst res = await this.runScript('IdempotencyAllow', [ keys.doneKey, keys.lockKey, keys.startKey ], [ String(this.idemLockTimeout), keys.token ], IdempotencyAllow);\n\n\t\treturn Number(res || 0) as 0 | 1 | 2;\n\t}\n\n\tprivate async idempotencyStart(keys: IdempotencyKeys): Promise<boolean> {\n\t\tconst res = await this.runScript('IdempotencyStart', [ keys.lockKey, keys.startKey ], [ keys.token, String(this.idemLockTimeout) ], IdempotencyStart);\n\n\t\treturn Number(res || 0) === 1;\n\t}\n\n\tprivate async idempotencyDone(keys: IdempotencyKeys): Promise<void> {\n\t\tawait this.runScript('IdempotencyDone', [ keys.doneKey, keys.lockKey, keys.startKey ], [ String(this.idemDoneTimeout), keys.token ], IdempotencyDone);\n\t}\n\n\tprivate async idempotencyFree(keys: IdempotencyKeys): Promise<void> {\n\t\tawait this.runScript('IdempotencyFree', [ keys.lockKey, keys.startKey ], [ keys.token ], IdempotencyFree);\n\t}\n\n\tprivate async success(queueName: string, task: Task) {\n\t\tif (this.logStatus) {\n\t\t\tconst statusKey = `${queueName}:${task.job}:`;\n\n\t\t\tawait this.incr(statusKey +'ok', this.logStatusTimeout);\n\t\t\tawait this.incr(statusKey +'ready', this.logStatusTimeout);\n\t\t}\n\t\treturn await this.onSuccess(queueName, task);\n\t}\n\n\tprivate async error(err: any, queueName: string, task: Task): Promise<Task> {\n\t\tconst taskP: any = { ...task };\n\n\t\tif (!(taskP.attempt >= (this.retryCount - 1))) {\n\t\t\tawait this.onRetry(err, queueName, taskP);\n\t\t\tawait this.addTasks(queueName, [{ ...taskP.payload, idemKey: taskP.idemKey, }], {\n\t\t\t\tcreatedAt: taskP.createdAt,\n\t\t\t\tjob: taskP.job,\n\t\t\t\tattempt: (taskP.attempt || 0) + 1,\n\t\t\t});\n\t\t}\n\t\telse if (this.logStatus) {\n\t\t\tconst dlqKey = queueName +':dlq';\n\t\t\tconst statusKey = `${queueName}:${taskP.job}:`;\n\n\t\t\tawait this.incr(statusKey +'err', this.logStatusTimeout);\n\t\t\tawait this.incr(statusKey +'ready', this.logStatusTimeout);\n\t\t\tawait this.addTasks(dlqKey, [{ ...taskP.payload, idemKey: taskP.idemKey, }], {\n\t\t\t\tcreatedAt: taskP.createdAt,\n\t\t\t\tjob: taskP.job,\n\t\t\t\tattempt: taskP.attempt,\n\t\t\t});\n\t\t}\n\t\treturn await this.onError(err, queueName, { ...taskP, attempt: (taskP.attempt || 0) + 1 });\n\t}\n\n\tprivate async waitAbortable(ttl: number) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tconst signal = this.signal();\n\n\t\t\tif (signal?.aborted) {\n\t\t\t\treturn resolve();\n\t\t\t}\n\t\t\tlet delay: number;\n\n\t\t\tif (ttl > 0) {\n\t\t\t\tconst base = Math.max(25, Math.min(ttl, 4000));\n\t\t\t\tconst jitter = Math.floor(Math.min(base, 200) * Math.random());\n\t\t\t\t\n\t\t\t\tdelay = base + jitter;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdelay = 5 + Math.floor(Math.random() * 15);\n\t\t\t}\n\t\t\tconst t = setTimeout(() => {\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.removeEventListener('abort', onAbort as any);\n\t\t\t\t}\n\t\t\t\tresolve();\n\t\t\t}, delay);\n\t\t\t(t as any).unref?.();\n\n\t\t\tfunction onAbort() { \n\t\t\t\tclearTimeout(t); \n\t\t\t\tresolve(); \n\t\t\t}\n\t\t\tsignal?.addEventListener?.('abort', onAbort, { once: true });\n\t\t});\n\t}\n\n\tprivate async sendHeartbeat(keys: IdempotencyKeys): Promise<boolean> {\n\t\ttry {\n\t\t\tconst r1 = await (this.redis as any).pexpire(keys.lockKey, this.idemLockTimeout);\n\t\t\tconst r2 = await (this.redis as any).pexpire(keys.startKey, this.idemLockTimeout);\n\t\t\tconst ok1 = Number(r1 || 0) === 1;\n\t\t\tconst ok2 = Number(r2 || 0) === 1;\n\n\t\t\treturn ok1 || ok2;\n\t\t}\n\t\tcatch {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate heartbeat(keys: IdempotencyKeys) {\n\t\tif (this.idemLockTimeout <= 0) {\n\t\t\treturn;\n\t\t}\n\t\tconst workerHeartbeatTimeoutMs = Math.max(1000, Math.floor(Math.max(5000, this.idemLockTimeout | 0) / 4));\n\t\tlet timer: any,\n\t\t\talive = true,\n\t\t\thbFails = 0;\n\n\t\tconst stop = () => {\n\t\t\talive = false;\n\t\t\t\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t};\n\t\tconst tick = async () => {\n\t\t\tif (!alive) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.signal()?.aborted) {\n\t\t\t\tstop();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst ok = await this.sendHeartbeat(keys);\n\t\t\t\t\n\t\t\t\thbFails = ok \n\t\t\t\t\t? 0 \n\t\t\t\t\t: (hbFails + 1);\n\t\t\t\t\n\t\t\t\tif (hbFails >= 3) {\n\t\t\t\t\tthrow new Error('Heartbeat lost.');\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch {\n\t\t\t\thbFails++;\n\t\t\t\t\n\t\t\t\tif (hbFails >= 6) {\n\t\t\t\t\tstop();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\ttimer = setTimeout(tick, workerHeartbeatTimeoutMs);\n\t\t\t(timer as any).unref?.();\n\t\t};\n\n\t\ttimer = setTimeout(tick, workerHeartbeatTimeoutMs);\n\t\t(timer as any).unref?.();\n\n\t\treturn () => stop();\n\t}\n\n\tprivate async runScript(name: string, keys: string[], args: (string|number)[], defaultCode?: string) {\n\t\tif (!this.scripts[name]) {\n\t\t\tif (!(typeof defaultCode === 'string' && defaultCode.length > 0)) {\n\t\t\t\tthrow new Error(`Undefined script \"${name}\". Save it before executing.`);\n\t\t\t}\n\t\t\tthis.saveScript(name, defaultCode);\n\t\t}\n\t\tif (!this.scripts[name].codeReady) {\n\t\t\tthis.scripts[name].codeReady = await this.loadScript(this.scripts[name].codeBody);\n\t\t}\n\t\ttry {\n\t\t\treturn await (this.redis as any).evalsha(this.scripts[name].codeReady!, keys.length, ...keys, ...args);\n\t\t}\n\t\tcatch (err: any) {\n\t\t\tif (String(err?.message || '').includes('NOSCRIPT')) {\n\t\t\t\tthis.scripts[name].codeReady = await this.loadScript(this.scripts[name].codeBody);\n\n\t\t\t\treturn await (this.redis as any).evalsha(this.scripts[name].codeReady!, keys.length, ...keys, ...args);\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n\n\tasync loadScripts(full: boolean = false): Promise<void> {\n\t\tconst scripts = full\n\t\t\t? [\n\t\t\t\t[ 'XAddBulk', XAddBulk ],\n\t\t\t\t[ 'Approve', Approve ],\n\t\t\t\t[ 'IdempotencyAllow', IdempotencyAllow ],\n\t\t\t\t[ 'IdempotencyStart', IdempotencyStart ],\n\t\t\t\t[ 'IdempotencyDone', IdempotencyDone ],\n\t\t\t\t[ 'IdempotencyFree', IdempotencyFree ],\n\t\t\t\t[ 'SelectStuck', SelectStuck ]\n\t\t\t]\n\t\t\t: [\n\t\t\t\t[ 'XAddBulk', XAddBulk ],\n\t\t\t];\n\n\t\tfor (const [ name, code ] of scripts) {\n\t\t\tawait this.loadScript(this.saveScript(name, code));\n\t\t}\n\t}\n\n\tprivate async loadScript(code: string): Promise<string> {\n\t\tfor (let i = 0; i < 3; i++) {\n\t\t\ttry {\n\t\t\t\treturn await (this.redis as any).script('LOAD', code);\n\t\t\t}\n\t\t\tcatch (e) {\n\t\t\t\tif (i === 2) {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t\tawait new Promise((r) => setTimeout(r, 10 + Math.floor(Math.random() * 40)));\n\t\t\t}\n\t\t}\n\t\tthrow new Error('Load lua script failed.');\n\t}\n\n\tprivate saveScript(name: string, codeBody: string): string {\n\t\tif (!(typeof codeBody === 'string' && codeBody.length > 0)) {\n\t\t\tthrow new Error('Script body is empty.');\n\t\t}\n\t\tthis.scripts[name] = { codeBody };\n\n\t\treturn codeBody;\n\t}\n\n\tasync addTasks(queueName: string, data: any[], opts: AddTasksOptions = {}): Promise<string[]> {\n\t\tif (!Array.isArray(data) || !(data.length > 0)) {\n\t\t\tthrow new Error('Tasks is not filled.');\n\t\t}\n\t\tif (!(typeof queueName === 'string' && queueName.length > 0)) {\n\t\t\tthrow new Error('Queue name is required.');\n\t\t}\n\t\topts.job = opts.job ?? randomUUID();\n\n\t\tconst batches = this.buildBatches(data, opts);\n\t\tconst result: string[] = new Array(data.length);\n\t\tconst promises: Array<() => Promise<void>> = [];\n\t\tlet cursor = 0;\n\t\t\n\t\tfor (const batch of batches) {\n\t\t\tconst start = cursor;\n\t\t\tconst end = start + batch.length;\n\t\t\t\t\n\t\t\tcursor = end;\n\t\t\tpromises.push(async () => {\n\t\t\t\tconst payload = this.payloadBatch(batch, opts);\n\t\t\t\tconst partIds = await this.runScript('XAddBulk', [ queueName ], payload, XAddBulk);\n\n\t\t\t\tfor (let k = 0; k < partIds.length; k++) {\n\t\t\t\t\tresult[start + k] = partIds[k];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tconst runners = Array.from({ length: promises.length }, async () => {\n\t\t\twhile (promises.length) {\n\t\t\t\tconst promise = promises.shift();\n\n\t\t\t\tif (promise) {\n\t\t\t\t\tawait promise();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tif (opts.status) {\n\t\t\tawait (this.redis as any).set(`${queueName}:${opts.job}:total`, data.length);\n\t\t\tawait (this.redis as any).pexpire(`${queueName}:${opts.job}:total`, this.logStatusTimeout);\n\t\t}\n\t\tawait Promise.all(runners);\n\t\treturn result;\n\t}\n\n\tprivate buildBatches(tasks: Task[], opts: AddTasksOptions = {}): Task[][] {\n\t\tconst batches: Task[][] = [];\n\t\tlet batch: Task[] = [],\n\t\t\trealKeysLength = 8;\n\n\t\tfor (let task of tasks) {\n\t\t\tconst createdAt = opts?.createdAt || Date.now();\n\t\t\tconst { idemKey, ...taskP } = task;\n\t\t\tconst entry: Task = { \n\t\t\t\tpayload: JSON.stringify(taskP),\n\t\t\t\tattempt: Number(opts.attempt || 0),\n\t\t\t\tjob: opts.job ?? randomUUID(),\n\t\t\t\tidemKey: String(idemKey || randomUUID()),\n\t\t\t\tcreatedAt,\n\t\t\t};\n\t\t\tconst reqKeysLength = this.keysLength(entry);\n\t\t\t\n\t\t\tif (batch.length && (batch.length >= this.buildBatchCount || realKeysLength + reqKeysLength > this.buildBatchMaxCount)) {\n\t\t\t\tbatches.push(batch); \n\t\t\t\tbatch = []; \n\t\t\t\trealKeysLength = 0;\n\t\t\t}\n\t\t\tbatch.push(entry);\n\t\t\trealKeysLength += reqKeysLength;\n\t\t}\n\t\tif (batch.length) {\n\t\t\tbatches.push(batch);\n\t\t}\n\t\treturn batches;\n\t}\n\n\tprivate keysLength(task: Task): number {\n\t\treturn 2 + Object.keys(task as any).length * 2;\n\t}\n\n\tprivate payloadBatch(data: Task[], opts: AddTasksOptions): string[] {\n\t\tconst maxlen = Math.max(0, Math.floor(opts?.maxlen ?? 0));\n\t\tconst approx = opts?.exact ? 0 : (opts?.approx !== false ? 1 : 0);\n\t\tconst exact = opts?.exact ? 1 : 0;\n\t\tconst nomkstream = opts?.nomkstream ? 1 : 0;\n\t\tconst trimLimit = Math.max(0, Math.floor(opts?.trimLimit ?? 0));\n\t\tconst minidWindowMs = Math.max(0, Math.floor(opts?.minidWindowMs ?? 0));\n\t\tconst minidExact = opts?.minidExact ? 1 : 0;\n\t\tconst argv: string[] = [\n\t\t\tString(maxlen),\n\t\t\tString(approx),\n\t\t\tString(data.length),\n\t\t\tString(exact), \n\t\t\tString(nomkstream),\n\t\t\tString(trimLimit),\n\t\t\tString(minidWindowMs),\n\t\t\tString(minidExact),\n\t\t];\n\n\t\tfor (const item of data) {\n\t\t\tconst entry: any = item;\n\t\t\tconst id = entry.id ?? '*';\n\t\t\tlet flat: any = [];\n\n\t\t\tif ('payload' in entry) {\n\t\t\t\tfor (const [ k, v ] of Object.entries(entry)) {\n\t\t\t\t\tflat.push(k, v as any);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthrow new Error('Task must have \"payload\" or \"flat\".');\n\t\t\t}\n\t\t\tconst pairs = flat.length / 2;\n\n\t\t\tif (pairs <= 0) {\n\t\t\t\tthrow new Error('Task \"flat\" must contain at least one field/value pair.');\n\t\t\t}\n\t\t\targv.push(String(id));\n\t\t\targv.push(String(pairs));\n\n\t\t\tfor (const token of flat) {\n\t\t\t\targv.push((token === null || token === undefined)\n\t\t\t\t\t? ''\n\t\t\t\t\t: (typeof token === 'string' && token.length > 0)\n\t\t\t\t\t\t? token\n\t\t\t\t\t\t: String(token));\n\t\t\t}\n\t\t}\n\t\treturn argv;\n\t}\n\n\tasync beforeExecute(queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t\treturn tasks;\n\t}\n\n\tasync onExecute(queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onBatchReady(queueName: string, tasks: Task[]) {\n\t}\n\n\tasync onSuccess(queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onError(err: any, queueName: string, task: Task): Promise<Task> {\n\t\treturn task;\n\t}\n\n\tasync onBatchError(err: any, queueName: string, tasks: Array<[ string, any, number, string, string, number ]>) {\n\t}\n\n\tasync onRetry(err: any, queueName: string, task: Task) {\n\t}\n}\n","\nexport const XAddBulk = `\n\tlocal UNPACK = table and table.unpack or unpack\n\n\tlocal stream = KEYS[1]\n\tlocal maxlen = tonumber(ARGV[1])\n\tlocal approxFlag = tonumber(ARGV[2]) == 1\n\tlocal n = tonumber(ARGV[3])\n\tlocal exactFlag = tonumber(ARGV[4]) == 1\n\tlocal nomkstream = tonumber(ARGV[5]) == 1\n\tlocal trimLimit = tonumber(ARGV[6])\n\tlocal minidWindowMs = tonumber(ARGV[7]) or 0\n\tlocal minidExact = tonumber(ARGV[8]) == 1\n\tlocal idx = 9\n\tlocal out = {}\n\n\tlocal common_opts = {}\n\tlocal co_len = 0\n\n\tif nomkstream then\n\t\tco_len = co_len + 1; common_opts[co_len] = 'NOMKSTREAM'\n\tend\n\n\tif minidWindowMs > 0 then\n\t\tlocal tm = redis.call('TIME')\n\t\tlocal now_ms = (tonumber(tm[1]) * 1000) + math.floor(tonumber(tm[2]) / 1000)\n\t\tlocal cutoff_ms = now_ms - minidWindowMs\n\t\tif cutoff_ms < 0 then cutoff_ms = 0 end\n\t\tlocal cutoff_id = tostring(cutoff_ms) .. '-0'\n\n\t\tco_len = co_len + 1; common_opts[co_len] = 'MINID'\n\t\tco_len = co_len + 1; common_opts[co_len] = (minidExact and '=' or '~')\n\t\tco_len = co_len + 1; common_opts[co_len] = cutoff_id\n\t\tif trimLimit and trimLimit > 0 then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = 'LIMIT'\n\t\t\tco_len = co_len + 1; common_opts[co_len] = trimLimit\n\t\tend\n\telseif maxlen and maxlen > 0 then\n\t\tco_len = co_len + 1; common_opts[co_len] = 'MAXLEN'\n\t\tif exactFlag then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = '='\n\t\telseif approxFlag then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = '~'\n\t\tend\n\t\tco_len = co_len + 1; common_opts[co_len] = maxlen\n\t\tif trimLimit and trimLimit > 0 then\n\t\t\tco_len = co_len + 1; common_opts[co_len] = 'LIMIT'\n\t\t\tco_len = co_len + 1; common_opts[co_len] = trimLimit\n\t\tend\n\tend\n\n\tfor e = 1, n do\n\t\tlocal id = ARGV[idx]; idx = idx + 1\n\t\tlocal num_pairs = tonumber(ARGV[idx]); idx = idx + 1\n\n\t\tlocal a = {}\n\t\tlocal a_len = 0\n\n\t\tfor i = 1, co_len do a_len = a_len + 1; a[a_len] = common_opts[i] end\n\n\t\ta_len = a_len + 1; a[a_len] = id\n\n\t\tfor j = 1, (num_pairs * 2) do\n\t\t\ta_len = a_len + 1; a[a_len] = ARGV[idx]; idx = idx + 1\n\t\tend\n\n\t\tlocal addedId = redis.call('XADD', stream, UNPACK(a))\n\t\tout[#out+1] = addedId or ''\n\tend\n\n\treturn out\n`;\n\nexport const Approve = `\n\tlocal stream = KEYS[1]\n\tlocal group = ARGV[1]\n\tlocal delFlag = tonumber(ARGV[2]) == 1\n\n\tlocal acked = 0\n\tlocal nids = #ARGV - 2\n\tif nids > 0 then\n\t\tacked = tonumber(redis.call('XACK', stream, group, unpack(ARGV, 3))) or 0\n\t\tif delFlag and nids > 0 then\n\t\t\tlocal ok, deln = pcall(redis.call, 'XDEL', stream, unpack(ARGV, 3))\n\t\t\tif not ok then\n\t\t\t\tdeln = 0\n\t\t\t\tfor i = 3, #ARGV do\n\t\t\t\t\tdeln = deln + (tonumber(redis.call('XDEL', stream, ARGV[i])) or 0)\n\t\t\t\tend\n\t\t\tend\n\t\tend\n\tend\n\treturn acked\n`;\n\nexport const IdempotencyAllow = `\n\tlocal doneKey = KEYS[1]\n\tlocal lockKey = KEYS[2]\n\tlocal startKey = KEYS[3]\n\n\tif redis.call('EXISTS', doneKey) == 1 then\n\t\treturn 1\n\tend\n\n\tlocal ttl = tonumber(ARGV[1]) or 0\n\tif ttl <= 0 then return 0 end\n\n\tlocal ok = redis.call('SET', lockKey, ARGV[2], 'NX', 'PX', ttl)\n\tif ok then\n\t\tif startKey and startKey ~= '' then\n\t\t\tredis.call('SET', startKey, 1, 'PX', ttl)\n\t\tend\n\t\treturn 2\n\telse\n\t\treturn 0\n\tend\n`;\n\nexport const IdempotencyStart = `\n\tlocal lockKey = KEYS[1]\n\tlocal startKey = KEYS[2]\n\tif redis.call('GET', lockKey) == ARGV[1] then\n\t\tlocal ttl = tonumber(ARGV[2]) or 0\n\t\tif ttl > 0 then\n\t\t\tredis.call('SET', startKey, 1, 'PX', ttl)\n\t\t\tredis.call('PEXPIRE', lockKey, ttl)\n\t\telse\n\t\t\tredis.call('SET', startKey, 1)\n\t\tend\n\t\treturn 1\n\tend\n\treturn 0\n`;\n\nexport const IdempotencyDone = `\n\tlocal doneKey = KEYS[1]\n\tlocal lockKey = KEYS[2]\n\tlocal startKey = KEYS[3]\n\n\tredis.call('SET', doneKey, 1)\n\n\tlocal ttlMs = tonumber(ARGV[1]) or 0\n\tif ttlMs > 0 then\n\t\tredis.call('PEXPIRE', doneKey, ttlMs)\n\tend\n\n\tif redis.call('GET', lockKey) == ARGV[2] then\n\t\tredis.call('DEL', lockKey)\n\t\tif startKey then\n\t\t\tredis.call('DEL', startKey)\n\t\tend\n\tend\n\n\treturn 1\n`;\n\nexport const IdempotencyFree = `\n\tlocal lockKey = KEYS[1]\n\tlocal startKey = KEYS[2]\n\tif redis.call('GET', lockKey) == ARGV[1] then\n\t\tredis.call('DEL', lockKey)\n\t\tif startKey then redis.call('DEL', startKey) end\n\t\treturn 1\n\tend\n\treturn 0\n`;\n\nexport const SelectStuck = `\n\tlocal stream = KEYS[1]\n\tlocal group = ARGV[1]\n\tlocal consumer = ARGV[2]\n\tlocal pendingIdleMs = tonumber(ARGV[3])\n\tlocal count = tonumber(ARGV[4]) or 0\n\tif count < 1 then count = 1 end\n\n\tlocal timeBudgetMs = tonumber(ARGV[5]) or 15\n\tlocal t0 = redis.call('TIME')\n\tlocal start_ms = (tonumber(t0[1]) * 1000) + math.floor(tonumber(t0[2]) / 1000)\n\n\tlocal results = {}\n\tlocal collected = 0\n\tlocal start_id = '0-0'\n\tlocal iters = 0\n\tlocal max_iters = math.max(16, math.ceil(count / 100))\n\n\tlocal function time_exceeded()\n\t\tlocal t1 = redis.call('TIME')\n\t\tlocal now_ms = (tonumber(t1[1]) * 1000) + math.floor(tonumber(t1[2]) / 1000)\n\t\treturn (now_ms - start_ms) >= timeBudgetMs\n\tend\n\n\twhile (collected < count) and (iters < max_iters) do\n\t\tlocal to_claim = count - collected\n\t\tif to_claim < 1 then break end\n\n\t\tlocal claim = redis.call('XAUTOCLAIM', stream, group, consumer, pendingIdleMs, start_id, 'COUNT', to_claim)\n\t\titers = iters + 1\n\n\t\tlocal bucket = nil\n\t\tif claim then\n\t\t\tbucket = claim[2]\n\t\tend\n\t\tif bucket and #bucket > 0 then\n\t\t\tfor i = 1, #bucket do\n\t\t\t\tresults[#results+1] = bucket[i]\n\t\t\tend\n\t\t\tcollected = #results\n\t\tend\n\n\t\tlocal next_id = claim and claim[1] or start_id\n\t\tif next_id == start_id then\n\t\t\tlocal s, seq = string.match(start_id, '^(%d+)%-(%d+)$')\n\t\t\tif s and seq then\n\t\t\t\tstart_id = s .. '-' .. tostring(tonumber(seq) + 1)\n\t\t\telse\n\t\t\t\tstart_id = '0-1'\n\t\t\tend\n\t\telse\n\t\t\tstart_id = next_id\n\t\tend\n\n\t\tif time_exceeded() then\n\t\t\tbreak\n\t\tend\n\tend\n\n\tlocal left = count - collected\n\tif left > 0 then\n\t\tlocal xr = redis.call('XREADGROUP', 'GROUP', group, consumer, 'COUNT', left, 'STREAMS', stream, '>')\n\t\tif xr and xr[1] and xr[1][2] then\n\t\t\tlocal entries = xr[1][2]\n\t\t\tfor i = 1, #entries do\n\t\t\t\tresults[#results+1] = entries[i]\n\t\t\tend\n\t\tend\n\tend\n\n\treturn results\n`;\n"],"mappings":"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","names":["err"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "power-queues",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.14",
|
|
4
4
|
"description": "High-performance Redis Streams queue for Node.js with Lua-powered bulk XADD, idempotent workers, heartbeat locks, stuck-task recovery, retries, DLQ, and distributed processing.",
|
|
5
5
|
"author": "ihor-bielchenko",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
},
|
|
14
14
|
"homepage": "https://github.com/ihor-bielchenko/power-queues#readme",
|
|
15
15
|
"type": "module",
|
|
16
|
-
"main": "dist/index.cjs",
|
|
17
|
-
"module": "dist/index.js",
|
|
18
|
-
"types": "dist/index.d.ts",
|
|
16
|
+
"main": "./dist/index.cjs",
|
|
17
|
+
"module": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
19
|
"exports": {
|
|
20
20
|
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
21
22
|
"import": "./dist/index.js",
|
|
22
23
|
"require": "./dist/index.cjs",
|
|
23
24
|
"default": "./dist/index.js"
|
|
@@ -26,8 +27,12 @@
|
|
|
26
27
|
"files": [
|
|
27
28
|
"dist"
|
|
28
29
|
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "tsup",
|
|
32
|
+
"clean": "rimraf dist docs"
|
|
33
|
+
},
|
|
29
34
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
35
|
+
"node": ">=20"
|
|
31
36
|
},
|
|
32
37
|
"keywords": [
|
|
33
38
|
"redis",
|
|
@@ -83,6 +88,12 @@
|
|
|
83
88
|
"safe-redis",
|
|
84
89
|
"power-redis"
|
|
85
90
|
],
|
|
91
|
+
"devDependencies": {
|
|
92
|
+
"@types/node": "^24.8.1",
|
|
93
|
+
"rimraf": "^6.0.1",
|
|
94
|
+
"tsup": "^8.5.0",
|
|
95
|
+
"typescript": "^5.9.3"
|
|
96
|
+
},
|
|
86
97
|
"dependencies": {
|
|
87
98
|
"p-limit": "^7.3.0",
|
|
88
99
|
"power-redis": "^2.0.24"
|