worker-que 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/DASHBOARD-QUICKSTART.md +278 -0
  2. package/DASHBOARD.md +556 -0
  3. package/LICENSE +21 -0
  4. package/README.md +414 -0
  5. package/SSL-QUICK-REFERENCE.md +225 -0
  6. package/SSL.md +516 -0
  7. package/dist/client.d.ts +11 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +64 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/dashboard/index.d.ts +34 -0
  12. package/dist/dashboard/index.d.ts.map +1 -0
  13. package/dist/dashboard/index.js +164 -0
  14. package/dist/dashboard/index.js.map +1 -0
  15. package/dist/dashboard/service.d.ts +66 -0
  16. package/dist/dashboard/service.d.ts.map +1 -0
  17. package/dist/dashboard/service.js +201 -0
  18. package/dist/dashboard/service.js.map +1 -0
  19. package/dist/dashboard/views.d.ts +3 -0
  20. package/dist/dashboard/views.d.ts.map +1 -0
  21. package/dist/dashboard/views.js +786 -0
  22. package/dist/dashboard/views.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +29 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/job.d.ts +19 -0
  28. package/dist/job.d.ts.map +1 -0
  29. package/dist/job.js +36 -0
  30. package/dist/job.js.map +1 -0
  31. package/dist/sql.d.ts +8 -0
  32. package/dist/sql.d.ts.map +1 -0
  33. package/dist/sql.js +57 -0
  34. package/dist/sql.js.map +1 -0
  35. package/dist/types.d.ts +90 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +3 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/utils.d.ts +6 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +31 -0
  42. package/dist/utils.js.map +1 -0
  43. package/dist/worker.d.ts +19 -0
  44. package/dist/worker.d.ts.map +1 -0
  45. package/dist/worker.js +99 -0
  46. package/dist/worker.js.map +1 -0
  47. package/migrations/schema.sql +26 -0
  48. package/package.json +105 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"views.js","sourceRoot":"","sources":["../../src/dashboard/views.ts"],"names":[],"mappings":";;AAEA,4CA6wBC;AA7wBD,SAAgB,gBAAgB,CAAC,OAAmC;IAClE,OAAO;;;;;;aAMI,OAAO,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmXZ,OAAO,CAAC,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mCAuFQ,OAAO,CAAC,eAAe;;;;;;;;;;;;;;;;;;gDAkBV,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;gDAkBhB,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;gDAgBhB,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDA6Bf,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDAqKhB,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;iDAkBhB,OAAO,CAAC,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmD9D,CAAC,IAAI,EAAE,CAAC;AACX,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { Client } from './client';
2
+ export { Worker } from './worker';
3
+ export { JobInstance } from './job';
4
+ export * from './types';
5
+ export { calculateRetryDelay, formatJobArgs, parseJobArgs } from './utils';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.parseJobArgs = exports.formatJobArgs = exports.calculateRetryDelay = exports.JobInstance = exports.Worker = exports.Client = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_1.Client; } });
20
+ var worker_1 = require("./worker");
21
+ Object.defineProperty(exports, "Worker", { enumerable: true, get: function () { return worker_1.Worker; } });
22
+ var job_1 = require("./job");
23
+ Object.defineProperty(exports, "JobInstance", { enumerable: true, get: function () { return job_1.JobInstance; } });
24
+ __exportStar(require("./types"), exports);
25
+ var utils_1 = require("./utils");
26
+ Object.defineProperty(exports, "calculateRetryDelay", { enumerable: true, get: function () { return utils_1.calculateRetryDelay; } });
27
+ Object.defineProperty(exports, "formatJobArgs", { enumerable: true, get: function () { return utils_1.formatJobArgs; } });
28
+ Object.defineProperty(exports, "parseJobArgs", { enumerable: true, get: function () { return utils_1.parseJobArgs; } });
29
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,6BAAoC;AAA3B,kGAAA,WAAW,OAAA;AACpB,0CAAwB;AACxB,iCAA2E;AAAlE,4GAAA,mBAAmB,OAAA;AAAE,sGAAA,aAAa,OAAA;AAAE,qGAAA,YAAY,OAAA"}
package/dist/job.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import { Pool } from 'pg';
2
+ import { Job, JobRow } from './types';
3
+ export declare class JobInstance implements Job {
4
+ readonly id: number;
5
+ readonly queue: string;
6
+ readonly priority: number;
7
+ readonly runAt: Date;
8
+ readonly jobClass: string;
9
+ readonly args: any[];
10
+ readonly errorCount: number;
11
+ readonly lastError?: string;
12
+ private pool;
13
+ constructor(row: JobRow, pool: Pool);
14
+ delete(): Promise<void>;
15
+ done(): Promise<void>;
16
+ error(errorMessage: string): Promise<void>;
17
+ private unlock;
18
+ }
19
+ //# sourceMappingURL=job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAItC,qBAAa,WAAY,YAAW,GAAG;IACrC,SAAgB,EAAE,EAAE,MAAM,CAAC;IAC3B,SAAgB,KAAK,EAAE,MAAM,CAAC;IAC9B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,KAAK,EAAE,IAAI,CAAC;IAC5B,SAAgB,QAAQ,EAAE,MAAM,CAAC;IACjC,SAAgB,IAAI,EAAE,GAAG,EAAE,CAAC;IAC5B,SAAgB,UAAU,EAAE,MAAM,CAAC;IACnC,SAAgB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnC,OAAO,CAAC,IAAI,CAAO;gBAEP,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI;IAY7B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAKvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAQlC,MAAM;CAGrB"}
package/dist/job.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JobInstance = void 0;
4
+ const sql_1 = require("./sql");
5
+ const utils_1 = require("./utils");
6
+ class JobInstance {
7
+ constructor(row, pool) {
8
+ this.id = parseInt(row.job_id, 10);
9
+ this.queue = row.queue;
10
+ this.priority = row.priority;
11
+ this.runAt = row.run_at;
12
+ this.jobClass = row.job_class;
13
+ this.args = (0, utils_1.parseJobArgs)(row.args);
14
+ this.errorCount = row.error_count;
15
+ this.lastError = row.last_error || undefined;
16
+ this.pool = pool;
17
+ }
18
+ async delete() {
19
+ await this.pool.query(sql_1.SQL_QUERIES.DELETE_JOB, [this.id]);
20
+ await this.unlock();
21
+ }
22
+ async done() {
23
+ await this.delete();
24
+ }
25
+ async error(errorMessage) {
26
+ const retryDelay = (0, utils_1.calculateRetryDelay)(this.errorCount + 1);
27
+ const updateQuery = sql_1.SQL_QUERIES.UPDATE_JOB_ERROR.replace('%d', retryDelay.toString());
28
+ await this.pool.query(updateQuery, [this.id, errorMessage]);
29
+ await this.unlock();
30
+ }
31
+ async unlock() {
32
+ await this.pool.query(sql_1.SQL_QUERIES.UNLOCK_JOB, [this.id]);
33
+ }
34
+ }
35
+ exports.JobInstance = JobInstance;
36
+ //# sourceMappingURL=job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job.js","sourceRoot":"","sources":["../src/job.ts"],"names":[],"mappings":";;;AAEA,+BAAoC;AACpC,mCAA4D;AAE5D,MAAa,WAAW;IAYtB,YAAY,GAAW,EAAE,IAAU;QACjC,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,SAAS,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAA,oBAAY,EAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,UAAU,IAAI,SAAS,CAAC;QAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAW,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,YAAoB;QAC9B,MAAM,UAAU,GAAG,IAAA,2BAAmB,EAAC,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,iBAAW,CAAC,gBAAgB,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC;QAEtF,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,MAAM;QAClB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,iBAAW,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF;AA5CD,kCA4CC"}
package/dist/sql.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export declare const SQL_QUERIES: {
2
+ readonly ENQUEUE_JOB: "\n INSERT INTO que_jobs (job_class, args, priority, run_at, queue)\n VALUES ($1, $2, $3, $4, $5)\n RETURNING job_id, priority, run_at, job_class, args, error_count, last_error, queue\n ";
3
+ readonly LOCK_JOB: "\n WITH RECURSIVE jobs AS (\n SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked\n FROM (\n SELECT j\n FROM que_jobs AS j\n WHERE queue = $1 AND run_at <= now() AND error_count < 5\n ORDER BY priority, run_at, job_id\n LIMIT 1\n ) AS t1\n UNION ALL (\n SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked\n FROM (\n SELECT (\n SELECT j\n FROM que_jobs AS j\n WHERE queue = $1 AND run_at <= now() AND error_count < 5\n AND (priority, run_at, job_id) > (jobs.priority, jobs.run_at, jobs.job_id)\n ORDER BY priority, run_at, job_id\n LIMIT 1\n ) AS j\n FROM jobs\n WHERE jobs.job_id IS NOT NULL\n LIMIT 1\n ) AS t1\n )\n )\n SELECT job_id, priority, run_at, job_class, args, error_count, last_error, queue\n FROM jobs\n WHERE locked\n LIMIT 1\n ";
4
+ readonly DELETE_JOB: "\n DELETE FROM que_jobs\n WHERE job_id = $1\n ";
5
+ readonly UPDATE_JOB_ERROR: "\n UPDATE que_jobs\n SET error_count = error_count + 1,\n last_error = $2,\n run_at = now() + interval '%d seconds'\n WHERE job_id = $1\n ";
6
+ readonly UNLOCK_JOB: "\n SELECT pg_advisory_unlock($1)\n ";
7
+ };
8
+ //# sourceMappingURL=sql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW;;;;;;CAwDd,CAAC"}
package/dist/sql.js ADDED
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SQL_QUERIES = void 0;
4
+ exports.SQL_QUERIES = {
5
+ ENQUEUE_JOB: `
6
+ INSERT INTO que_jobs (job_class, args, priority, run_at, queue)
7
+ VALUES ($1, $2, $3, $4, $5)
8
+ RETURNING job_id, priority, run_at, job_class, args, error_count, last_error, queue
9
+ `,
10
+ LOCK_JOB: `
11
+ WITH RECURSIVE jobs AS (
12
+ SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked
13
+ FROM (
14
+ SELECT j
15
+ FROM que_jobs AS j
16
+ WHERE queue = $1 AND run_at <= now() AND error_count < 5
17
+ ORDER BY priority, run_at, job_id
18
+ LIMIT 1
19
+ ) AS t1
20
+ UNION ALL (
21
+ SELECT (j).*, pg_try_advisory_lock((j).job_id) AS locked
22
+ FROM (
23
+ SELECT (
24
+ SELECT j
25
+ FROM que_jobs AS j
26
+ WHERE queue = $1 AND run_at <= now() AND error_count < 5
27
+ AND (priority, run_at, job_id) > (jobs.priority, jobs.run_at, jobs.job_id)
28
+ ORDER BY priority, run_at, job_id
29
+ LIMIT 1
30
+ ) AS j
31
+ FROM jobs
32
+ WHERE jobs.job_id IS NOT NULL
33
+ LIMIT 1
34
+ ) AS t1
35
+ )
36
+ )
37
+ SELECT job_id, priority, run_at, job_class, args, error_count, last_error, queue
38
+ FROM jobs
39
+ WHERE locked
40
+ LIMIT 1
41
+ `,
42
+ DELETE_JOB: `
43
+ DELETE FROM que_jobs
44
+ WHERE job_id = $1
45
+ `,
46
+ UPDATE_JOB_ERROR: `
47
+ UPDATE que_jobs
48
+ SET error_count = error_count + 1,
49
+ last_error = $2,
50
+ run_at = now() + interval '%d seconds'
51
+ WHERE job_id = $1
52
+ `,
53
+ UNLOCK_JOB: `
54
+ SELECT pg_advisory_unlock($1)
55
+ `
56
+ };
57
+ //# sourceMappingURL=sql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql.js","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG;IACzB,WAAW,EAAE;;;;GAIZ;IAED,QAAQ,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BT;IAED,UAAU,EAAE;;;GAGX;IAED,gBAAgB,EAAE;;;;;;GAMjB;IAED,UAAU,EAAE;;GAEX;CACO,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { ConnectionOptions } from "tls";
2
+ export type JSONValue = string | number | boolean | null | JSONObject | JSONArray;
3
+ export interface JSONObject {
4
+ [key: string]: JSONValue;
5
+ }
6
+ export interface JSONArray extends Array<JSONValue> {
7
+ }
8
+ export interface Job {
9
+ id: number;
10
+ queue: string;
11
+ priority: number;
12
+ runAt: Date;
13
+ jobClass: string;
14
+ args: JSONArray;
15
+ errorCount: number;
16
+ lastError?: string;
17
+ delete(): Promise<void>;
18
+ done(): Promise<void>;
19
+ error(errorMessage: string): Promise<void>;
20
+ }
21
+ export interface EnqueueOptions {
22
+ priority?: number;
23
+ runAt?: Date;
24
+ queue?: string;
25
+ }
26
+ export interface WorkFunction {
27
+ (job: Job): Promise<void>;
28
+ }
29
+ export interface WorkMap {
30
+ [jobClass: string]: WorkFunction;
31
+ }
32
+ /**
33
+ * SSL configuration options for PostgreSQL connection
34
+ */
35
+ export interface SSLConfig extends ConnectionOptions {
36
+ /**
37
+ * Reject unauthorized certificates (default: true for security)
38
+ * Set to false only in development/testing environments
39
+ */
40
+ rejectUnauthorized?: boolean;
41
+ /**
42
+ * Path to client certificate file (.crt or .pem)
43
+ */
44
+ cert?: string | Buffer;
45
+ /**
46
+ * Path to client private key file (.key)
47
+ */
48
+ key?: string | Buffer;
49
+ /**
50
+ * Path to CA certificate file to verify server certificate
51
+ */
52
+ ca?: string | Buffer | Array<string | Buffer>;
53
+ /**
54
+ * Passphrase for the private key if encrypted
55
+ */
56
+ passphrase?: string;
57
+ }
58
+ export interface ClientConfig {
59
+ connectionString?: string;
60
+ host?: string;
61
+ port?: number;
62
+ database?: string;
63
+ user?: string;
64
+ password?: string;
65
+ /**
66
+ * SSL configuration:
67
+ * - false: No SSL
68
+ * - true: SSL with default settings (rejectUnauthorized: true)
69
+ * - SSLConfig object: Custom SSL configuration with certificates
70
+ */
71
+ ssl?: boolean | SSLConfig;
72
+ dialectOptions?: object;
73
+ maxConnections?: number;
74
+ }
75
+ export interface WorkerOptions {
76
+ queue?: string;
77
+ interval?: number;
78
+ maxAttempts?: number;
79
+ }
80
+ export interface JobRow {
81
+ priority: number;
82
+ run_at: Date;
83
+ job_id: string;
84
+ job_class: string;
85
+ args: JSONArray;
86
+ error_count: number;
87
+ last_error?: string | null;
88
+ queue: string;
89
+ }
90
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,KAAK,CAAC;AAGxC,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,SAAS,CAAC;CAAG;AAEtD,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,IAAI,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,MAAM,WAAW,OAAO;IACtB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,iBAAiB;IAClD;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAC9C;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,SAAS,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import { JSONArray } from './types';
2
+ export declare function intPow(base: number, exponent: number): number;
3
+ export declare function calculateRetryDelay(errorCount: number): number;
4
+ export declare function formatJobArgs(args: JSONArray): string;
5
+ export declare function parseJobArgs(args: JSONArray): JSONArray;
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAa,MAAM,SAAS,CAAC;AAE/C,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM,CAErD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAQvD"}
package/dist/utils.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.intPow = intPow;
4
+ exports.calculateRetryDelay = calculateRetryDelay;
5
+ exports.formatJobArgs = formatJobArgs;
6
+ exports.parseJobArgs = parseJobArgs;
7
+ function intPow(base, exponent) {
8
+ if (exponent < 0) {
9
+ return 0;
10
+ }
11
+ let result = 1;
12
+ for (let i = 0; i < exponent; i++) {
13
+ result *= base;
14
+ }
15
+ return result;
16
+ }
17
+ function calculateRetryDelay(errorCount) {
18
+ return intPow(errorCount, 4);
19
+ }
20
+ function formatJobArgs(args) {
21
+ return JSON.stringify(args);
22
+ }
23
+ function parseJobArgs(args) {
24
+ // PostgreSQL JSON column is already parsed by the pg driver
25
+ // Just validate it's an array and return it
26
+ if (!Array.isArray(args)) {
27
+ throw new Error(`Expected job arguments to be an array, received: ${typeof args}`);
28
+ }
29
+ return args;
30
+ }
31
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":";;AAEA,wBAWC;AAED,kDAEC;AAED,sCAEC;AAED,oCAQC;AA7BD,SAAgB,MAAM,CAAC,IAAY,EAAE,QAAgB;IACnD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;QACjB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,IAAI,IAAI,CAAC;IACjB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,mBAAmB,CAAC,UAAkB;IACpD,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAgB,aAAa,CAAC,IAAe;IAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAgB,YAAY,CAAC,IAAe;IAC1C,4DAA4D;IAC5D,4CAA4C;IAC5C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,oDAAoD,OAAO,IAAI,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { WorkFunction, WorkerOptions, ClientConfig } from './types';
2
+ export declare class Worker {
3
+ private client;
4
+ private workMap;
5
+ private queue;
6
+ private interval;
7
+ private running;
8
+ private shutdownPromise;
9
+ private timeoutId;
10
+ private timeoutResolve;
11
+ constructor(clientConfig?: ClientConfig, options?: WorkerOptions);
12
+ register(jobClass: string, workFunc: WorkFunction): void;
13
+ work(): Promise<void>;
14
+ workOne(): Promise<boolean>;
15
+ shutdown(): Promise<void>;
16
+ private workLoop;
17
+ private processJob;
18
+ }
19
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAO,YAAY,EAAW,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAElF,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,cAAc,CAA6B;gBAEvC,YAAY,GAAE,YAAiB,EAAE,OAAO,GAAE,aAAkB;IAMxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAIlD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAUrB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAW3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBjB,QAAQ;YA8BR,UAAU;CAgBzB"}
package/dist/worker.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Worker = void 0;
4
+ const client_1 = require("./client");
5
+ class Worker {
6
+ constructor(clientConfig = {}, options = {}) {
7
+ this.workMap = {};
8
+ this.running = false;
9
+ this.shutdownPromise = null;
10
+ this.timeoutId = null;
11
+ this.timeoutResolve = null;
12
+ this.client = new client_1.Client(clientConfig);
13
+ this.queue = options.queue || '';
14
+ this.interval = options.interval || 60 * 1000;
15
+ }
16
+ register(jobClass, workFunc) {
17
+ this.workMap[jobClass] = workFunc;
18
+ }
19
+ async work() {
20
+ if (this.running) {
21
+ throw new Error('Worker is already running');
22
+ }
23
+ this.running = true;
24
+ this.shutdownPromise = this.workLoop();
25
+ return this.shutdownPromise;
26
+ }
27
+ async workOne() {
28
+ const job = await this.client.lockJob(this.queue);
29
+ if (!job) {
30
+ return false;
31
+ }
32
+ await this.processJob(job);
33
+ return true;
34
+ }
35
+ async shutdown() {
36
+ if (!this.running) {
37
+ return;
38
+ }
39
+ this.running = false;
40
+ if (this.timeoutId) {
41
+ clearTimeout(this.timeoutId);
42
+ this.timeoutId = null;
43
+ }
44
+ // Resolve any pending timeout promises
45
+ if (this.timeoutResolve) {
46
+ this.timeoutResolve();
47
+ this.timeoutResolve = null;
48
+ }
49
+ if (this.shutdownPromise) {
50
+ await this.shutdownPromise;
51
+ }
52
+ await this.client.close();
53
+ }
54
+ async workLoop() {
55
+ while (this.running) {
56
+ try {
57
+ const processed = await this.workOne();
58
+ if (!processed && this.running) {
59
+ await new Promise((resolve) => {
60
+ this.timeoutResolve = resolve;
61
+ this.timeoutId = setTimeout(() => {
62
+ this.timeoutResolve = null;
63
+ resolve();
64
+ }, this.interval);
65
+ });
66
+ }
67
+ }
68
+ catch (error) {
69
+ console.error('Worker error:', error);
70
+ if (this.running) {
71
+ await new Promise((resolve) => {
72
+ this.timeoutResolve = resolve;
73
+ this.timeoutId = setTimeout(() => {
74
+ this.timeoutResolve = null;
75
+ resolve();
76
+ }, this.interval);
77
+ });
78
+ }
79
+ }
80
+ }
81
+ }
82
+ async processJob(job) {
83
+ const workFunc = this.workMap[job.jobClass];
84
+ if (!workFunc) {
85
+ await job.error(`No work function registered for job class: ${job.jobClass}`);
86
+ return;
87
+ }
88
+ try {
89
+ await workFunc(job);
90
+ await job.done();
91
+ }
92
+ catch (error) {
93
+ const errorMessage = error instanceof Error ? error.message : String(error);
94
+ await job.error(errorMessage);
95
+ }
96
+ }
97
+ }
98
+ exports.Worker = Worker;
99
+ //# sourceMappingURL=worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ -- Que job queue table compatible with Ruby Que and que-go
2
+ CREATE TABLE que_jobs (
3
+ priority smallint NOT NULL DEFAULT 100,
4
+ run_at timestamptz NOT NULL DEFAULT now(),
5
+ job_id bigserial NOT NULL,
6
+ job_class text NOT NULL,
7
+ args json NOT NULL DEFAULT '[]'::json,
8
+ error_count integer NOT NULL DEFAULT 0,
9
+ last_error text,
10
+ queue text NOT NULL DEFAULT '',
11
+
12
+ -- Composite primary key for efficient job ordering and retrieval
13
+ PRIMARY KEY (queue, priority, run_at, job_id)
14
+ );
15
+
16
+ -- Index for efficient job polling
17
+ CREATE INDEX CONCURRENTLY que_poll_idx ON que_jobs (queue, priority, run_at, job_id) WHERE error_count < 5;
18
+
19
+ -- Function to get current time (useful for compatibility)
20
+ CREATE OR REPLACE FUNCTION que_current_time()
21
+ RETURNS timestamptz
22
+ LANGUAGE SQL
23
+ STABLE
24
+ AS $$
25
+ SELECT now();
26
+ $$;
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "worker-que",
3
+ "version": "1.0.0",
4
+ "description": "A TypeScript job queue library for PostgreSQL with real-time web dashboard, SSL support, and cross-language compatibility",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "require": "./dist/index.js",
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./dashboard": {
14
+ "require": "./dist/dashboard/index.js",
15
+ "import": "./dist/dashboard/index.js",
16
+ "types": "./dist/dashboard/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist/",
21
+ "migrations/",
22
+ "README.md",
23
+ "LICENSE",
24
+ "DASHBOARD.md",
25
+ "DASHBOARD-QUICKSTART.md",
26
+ "SSL.md",
27
+ "SSL-QUICK-REFERENCE.md"
28
+ ],
29
+ "scripts": {
30
+ "build": "tsc",
31
+ "prepare": "npm run build",
32
+ "dev": "tsc --watch",
33
+ "test": "jest --testTimeout=5000",
34
+ "test:watch": "jest --watch",
35
+ "test:coverage": "jest --coverage",
36
+ "test:debug": "jest --detectOpenHandles --testTimeout=5000",
37
+ "test:docker": "npm run docker:up && npm run test && npm run docker:down",
38
+ "lint": "eslint src/**/*.ts",
39
+ "lint:fix": "eslint src/**/*.ts --fix",
40
+ "prepublishOnly": "npm run lint && npm run build",
41
+ "clean": "rm -rf dist",
42
+ "docker:up": "docker-compose up -d",
43
+ "docker:down": "docker-compose down",
44
+ "docker:logs": "docker-compose logs -f postgres",
45
+ "docker:clean": "docker-compose down -v --remove-orphans",
46
+ "docker:reset": "npm run docker:clean && npm run docker:up"
47
+ },
48
+ "keywords": [
49
+ "job-queue",
50
+ "worker-queue",
51
+ "postgresql",
52
+ "postgres",
53
+ "typescript",
54
+ "background-jobs",
55
+ "job-processing",
56
+ "task-queue",
57
+ "async-jobs",
58
+ "que",
59
+ "worker",
60
+ "dashboard",
61
+ "queue-monitoring",
62
+ "express",
63
+ "ssl",
64
+ "tls",
65
+ "advisory-locks"
66
+ ],
67
+ "author": "",
68
+ "license": "MIT",
69
+ "devDependencies": {
70
+ "@types/express": "^4.17.21",
71
+ "@types/jest": "^29.5.5",
72
+ "@types/node": "^20.6.2",
73
+ "@types/pg": "^8.10.2",
74
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
75
+ "@typescript-eslint/parser": "^6.21.0",
76
+ "dotenv": "^17.2.1",
77
+ "eslint": "^8.57.1",
78
+ "express": "^4.18.2",
79
+ "jest": "^29.7.0",
80
+ "ts-jest": "^29.1.1"
81
+ },
82
+ "dependencies": {
83
+ "pg": "^8.11.3",
84
+ "typescript": "^5.2.2"
85
+ },
86
+ "peerDependencies": {
87
+ "express": "^4.18.0"
88
+ },
89
+ "peerDependenciesMeta": {
90
+ "express": {
91
+ "optional": true
92
+ }
93
+ },
94
+ "engines": {
95
+ "node": ">=16.0.0"
96
+ },
97
+ "repository": {
98
+ "type": "git",
99
+ "url": "https://github.com/Zongo-Technologies/expert-garbanzo.git"
100
+ },
101
+ "bugs": {
102
+ "url": "https://github.com/Zongo-Technologies/expert-garbanzo/issues"
103
+ },
104
+ "homepage": "https://github.com/Zongo-Technologies/expert-garbanzo#readme"
105
+ }