worker-que 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,107 +1,37 @@
1
- # que-ts
1
+ # worker-que
2
2
 
3
- [![Test](https://github.com/Duke-Engineering/que-ts/actions/workflows/test.yml/badge.svg)](https://github.com/Duke-Engineering/que-ts/actions/workflows/test.yml)
4
- [![Coverage](https://github.com/Duke-Engineering/que-ts/actions/workflows/coverage.yml/badge.svg)](https://github.com/Duke-Engineering/que-ts/actions/workflows/coverage.yml)
5
- [![Security](https://github.com/Duke-Engineering/que-ts/actions/workflows/security.yml/badge.svg)](https://github.com/Duke-Engineering/que-ts/actions/workflows/security.yml)
6
- [![npm version](https://badge.fury.io/js/que-ts.svg)](https://badge.fury.io/js/que-ts)
3
+ > A production-ready TypeScript job queue library for PostgreSQL with real-time monitoring dashboard
7
4
 
8
- A TypeScript job queue library for PostgreSQL, compatible with Ruby Que and que-go implementations.
5
+ [![npm version](https://badge.fury.io/js/worker-que.svg)](https://www.npmjs.com/package/worker-que)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.2-blue.svg)](https://www.typescriptlang.org/)
8
+ [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D16.0.0-green.svg)](https://nodejs.org/)
9
9
 
10
10
  ## Features
11
11
 
12
- - **Cross-language compatibility**: Works with [Que (Ruby)](https://github.com/chanks/que) and [que-go](https://github.com/bgentry/que-go) job queues
13
- - **PostgreSQL advisory locks**: Reliable job processing with no duplicate execution
14
- - **TypeScript support**: Full type safety with comprehensive interfaces
15
- - **Retry logic**: Exponential backoff for failed jobs
16
- - **Multiple queues**: Support for named queues and priorities
17
- - **Transaction support**: Enqueue jobs within existing database transactions
18
- - **Web Dashboard**: Real-time monitoring and management UI (Express.js integration)
19
- - **SSL/TLS Support**: Secure connections with client certificates
20
-
21
- ## Installation
22
-
23
- ### From npm (when published)
24
- ```bash
25
- npm install que-ts
26
- ```
27
-
28
- ### From GitHub (development)
29
- ```bash
30
- npm install github:Duke-Engineering/que-ts#master
31
- ```
32
-
33
- **Note**: When installing from GitHub, the package will automatically build from TypeScript source using the `prepare` script.
34
-
35
- ### Troubleshooting GitHub Installation
36
-
37
- If you encounter "Cannot find module 'que-ts'" errors when installing from GitHub:
38
-
39
- 1. **Check the installation completed successfully**:
40
- ```bash
41
- cd node_modules/que-ts
42
- ls dist/ # Should show compiled JavaScript files
43
- ```
44
-
45
- 2. **Manual build if needed**:
46
- ```bash
47
- cd node_modules/que-ts
48
- npm run build
49
- ```
50
-
51
- 3. **Verify installation**:
52
- ```bash
53
- cd node_modules/que-ts
54
- node test-install.js
55
- ```
56
-
57
- 4. **Alternative: Use specific tag**:
58
- ```bash
59
- npm install github:Duke-Engineering/que-ts#v1.0.0
60
- ```
12
+ - **High Performance** - PostgreSQL-backed with advisory locks for reliable job processing
13
+ - 📊 **Real-time Dashboard** - Beautiful web UI for monitoring and managing jobs
14
+ - 🔐 **Enterprise Security** - SSL/TLS support with client certificates
15
+ - 🎯 **Priority Queues** - Multiple queues with configurable priorities
16
+ - 🔄 **Automatic Retries** - Exponential backoff for failed jobs
17
+ - 💾 **Transaction Support** - Enqueue jobs within database transactions
18
+ - 🌐 **Cross-Platform** - Compatible with Ruby Que and que-go
19
+ - 📝 **TypeScript Native** - Full type safety and IntelliSense support
61
20
 
62
21
  ## Quick Start
63
22
 
64
- ### Database Setup
65
-
66
- #### Option 1: Using Docker (Recommended for Development)
23
+ ### Installation
67
24
 
68
25
  ```bash
69
- # Start PostgreSQL with Docker
70
- npm run docker:up
71
-
72
- # Run tests
73
- npm test
74
-
75
- # Stop when done
76
- npm run docker:down
77
- ```
78
-
79
- For detailed Docker usage, see [DOCKER.md](DOCKER.md).
80
-
81
- #### Option 2: Manual Database Setup
82
-
83
- Create the required database table:
84
-
85
- ```sql
86
- CREATE TABLE que_jobs (
87
- priority smallint NOT NULL DEFAULT 100,
88
- run_at timestamptz NOT NULL DEFAULT now(),
89
- job_id bigserial NOT NULL,
90
- job_class text NOT NULL,
91
- args json NOT NULL DEFAULT '[]'::json,
92
- error_count integer NOT NULL DEFAULT 0,
93
- last_error text,
94
- queue text NOT NULL DEFAULT '',
95
- PRIMARY KEY (queue, priority, run_at, job_id)
96
- );
26
+ npm install worker-que pg express
97
27
  ```
98
28
 
99
29
  ### Basic Usage
100
30
 
101
31
  ```typescript
102
- import { Client, Worker } from 'que-ts';
32
+ import { Client, Worker } from 'worker-que';
103
33
 
104
- // Create a client
34
+ // Create client
105
35
  const client = new Client({
106
36
  host: 'localhost',
107
37
  port: 5432,
@@ -113,12 +43,7 @@ const client = new Client({
113
43
  // Enqueue jobs
114
44
  await client.enqueue('SendEmail', ['user@example.com', 'Welcome!']);
115
45
 
116
- await client.enqueue('ProcessPayment', [{ amount: 100, currency: 'USD' }], {
117
- priority: 10,
118
- runAt: new Date(Date.now() + 60000) // Run in 1 minute
119
- });
120
-
121
- // Create and start a worker
46
+ // Create worker
122
47
  const worker = new Worker({
123
48
  host: 'localhost',
124
49
  port: 5432,
@@ -127,48 +52,59 @@ const worker = new Worker({
127
52
  password: 'password'
128
53
  });
129
54
 
130
- // Register job handlers
55
+ // Register handlers
131
56
  worker.register('SendEmail', async (job) => {
132
57
  const [email, message] = job.args;
133
58
  console.log(`Sending email to ${email}: ${message}`);
134
- // Email sending logic here
135
- });
136
-
137
- worker.register('ProcessPayment', async (job) => {
138
- const paymentData = job.args[0];
139
- console.log(`Processing payment of ${paymentData.amount} ${paymentData.currency}`);
140
- // Payment processing logic here
59
+ // Your email logic here
141
60
  });
142
61
 
143
- // Start processing jobs
62
+ // Start processing
144
63
  await worker.work();
64
+ ```
145
65
 
146
- // Graceful shutdown
147
- process.on('SIGINT', async () => {
148
- await worker.shutdown();
149
- await client.close();
150
- });
66
+ ### Database Setup
67
+
68
+ Create the required table:
69
+
70
+ ```sql
71
+ CREATE TABLE que_jobs (
72
+ priority smallint NOT NULL DEFAULT 100,
73
+ run_at timestamptz NOT NULL DEFAULT now(),
74
+ job_id bigserial NOT NULL,
75
+ job_class text NOT NULL,
76
+ args json NOT NULL DEFAULT '[]'::json,
77
+ error_count integer NOT NULL DEFAULT 0,
78
+ last_error text,
79
+ queue text NOT NULL DEFAULT '',
80
+ PRIMARY KEY (queue, priority, run_at, job_id)
81
+ );
82
+ ```
83
+
84
+ Or use the included migration:
85
+
86
+ ```bash
87
+ psql -U postgres -d myapp -f node_modules/worker-que/migrations/schema.sql
151
88
  ```
152
89
 
153
90
  ## Web Dashboard
154
91
 
155
- que-ts includes a beautiful, real-time web dashboard for monitoring and managing your job queue.
92
+ Monitor and manage your jobs with the built-in web dashboard featuring **Microsoft Fluent Design** and **secure authentication**:
156
93
 
157
94
  ```typescript
158
95
  import express from 'express';
159
96
  import { Pool } from 'pg';
160
- import { createDashboard } from 'que-ts/dashboard';
97
+ import { createDashboard } from 'worker-que/dist/dashboard';
161
98
 
162
99
  const app = express();
163
100
  const pool = new Pool({ /* your config */ });
164
101
 
165
- // Mount dashboard at /admin/queue
102
+ // Built-in email/password authentication
166
103
  app.use('/admin/queue', createDashboard(pool, {
167
- title: 'My App Queue',
168
- refreshInterval: 3000,
169
- auth: (req, res, next) => {
170
- // Add your authentication logic
171
- return req.isAuthenticated();
104
+ title: 'My Job Queue',
105
+ auth: {
106
+ email: 'admin@example.com',
107
+ password: 'your-secure-password'
172
108
  }
173
109
  }));
174
110
 
@@ -177,238 +113,409 @@ app.listen(3000);
177
113
  ```
178
114
 
179
115
  **Dashboard Features:**
180
- - 📊 Real-time statistics (total, ready, scheduled, failed jobs)
181
- - 📈 Visual analytics (charts by queue and job class)
182
- - 🔍 Advanced filtering (status, queue, job class)
183
- - 🔄 Job management (retry failed jobs, delete jobs)
184
- - 🔐 Built-in authentication support
185
- - 📱 Responsive design
116
+ - 📊 Real-time job statistics with auto-refresh
117
+ - 📈 Visual analytics by queue and class
118
+ - 🔍 Filter and search jobs
119
+ - 🔄 Retry failed jobs
120
+ - 🗑️ Delete jobs
121
+ - 🔐 Built-in secure authentication with sessions
122
+ - 🎨 Modern Microsoft Fluent Design UI
123
+ - 📱 Fully responsive design
186
124
 
187
- For complete dashboard documentation, see [DASHBOARD.md](DASHBOARD.md).
125
+ [**→ Complete Dashboard Documentation**](./DASHBOARD.md)
188
126
 
189
- ## SSL Configuration
127
+ ## Core Concepts
190
128
 
191
- For detailed SSL configuration including AWS RDS, Google Cloud SQL, Azure, and certificate setup, see [SSL.md](SSL.md).
129
+ ### Jobs
192
130
 
193
- ## API Reference
131
+ Jobs are units of work stored in PostgreSQL:
194
132
 
195
- ### Client
133
+ ```typescript
134
+ await client.enqueue('ProcessPayment', [
135
+ { amount: 100, userId: 123 }
136
+ ], {
137
+ priority: 10, // Lower = higher priority
138
+ queue: 'critical', // Queue name
139
+ runAt: new Date() // Scheduled time
140
+ });
141
+ ```
196
142
 
197
- #### Constructor
143
+ ### Workers
144
+
145
+ Workers poll for jobs and execute registered handlers:
198
146
 
199
147
  ```typescript
200
- new Client(config?: ClientConfig)
201
- ```
148
+ const worker = new Worker({
149
+ host: 'localhost',
150
+ port: 5432,
151
+ database: 'myapp'
152
+ }, {
153
+ queue: 'critical', // Process specific queue
154
+ interval: 1000 // Poll every 1 second
155
+ });
202
156
 
203
- #### Methods
157
+ worker.register('ProcessPayment', async (job) => {
158
+ const [payment] = job.args;
159
+ // Process payment...
160
+ // Job automatically marked as done
161
+ });
204
162
 
205
- - `enqueue(jobClass: string, args?: any[], options?: EnqueueOptions): Promise<Job>`
206
- - `enqueueInTx(client: PoolClient, jobClass: string, args?: any[], options?: EnqueueOptions): Promise<Job>`
207
- - `lockJob(queue?: string): Promise<Job | null>`
208
- - `close(): Promise<void>`
163
+ await worker.work();
164
+ ```
209
165
 
210
- ### Worker
166
+ ### Error Handling
211
167
 
212
- #### Constructor
168
+ Failed jobs are automatically retried with exponential backoff:
169
+
170
+ - 1st retry: after 1 second
171
+ - 2nd retry: after 16 seconds
172
+ - 3rd retry: after 81 seconds
173
+ - 4th retry: after 256 seconds
213
174
 
214
175
  ```typescript
215
- new Worker(clientConfig?: ClientConfig, options?: WorkerOptions)
176
+ worker.register('RiskyJob', async (job) => {
177
+ try {
178
+ await riskyOperation();
179
+ } catch (error) {
180
+ throw error; // Job will be retried
181
+ }
182
+ });
216
183
  ```
217
184
 
218
- #### Methods
185
+ ## Advanced Features
219
186
 
220
- - `register(jobClass: string, workFunc: WorkFunction): void`
221
- - `work(): Promise<void>`
222
- - `workOne(): Promise<boolean>`
223
- - `shutdown(): Promise<void>`
187
+ ### Priority Queues
224
188
 
225
- ### Job
189
+ Organize jobs by priority and queue:
226
190
 
227
- #### Properties
191
+ ```typescript
192
+ // High priority
193
+ await client.enqueue('UrgentTask', [data], { priority: 1 });
194
+
195
+ // Critical queue
196
+ await client.enqueue('Payment', [data], {
197
+ priority: 1,
198
+ queue: 'critical'
199
+ });
200
+
201
+ // Background queue
202
+ await client.enqueue('Analytics', [data], {
203
+ priority: 500,
204
+ queue: 'background'
205
+ });
206
+ ```
228
207
 
229
- - `id: number`
230
- - `queue: string`
231
- - `priority: number`
232
- - `runAt: Date`
233
- - `jobClass: string`
234
- - `args: any[]`
235
- - `errorCount: number`
236
- - `lastError?: string`
208
+ ### Scheduled Jobs
237
209
 
238
- #### Methods
210
+ Schedule jobs for future execution:
239
211
 
240
- - `done(): Promise<void>`
241
- - `delete(): Promise<void>`
242
- - `error(errorMessage: string): Promise<void>`
212
+ ```typescript
213
+ // Run in 1 hour
214
+ const runAt = new Date(Date.now() + 3600000);
215
+ await client.enqueue('SendReminder', [data], { runAt });
216
+
217
+ // Daily at 9 AM
218
+ const tomorrow = new Date();
219
+ tomorrow.setDate(tomorrow.getDate() + 1);
220
+ tomorrow.setHours(9, 0, 0, 0);
221
+ await client.enqueue('DailyReport', [data], { runAt: tomorrow });
222
+ ```
243
223
 
244
- ## Configuration
224
+ ### Transaction Support
245
225
 
246
- ### ClientConfig
226
+ Enqueue jobs within database transactions:
247
227
 
248
228
  ```typescript
249
- interface ClientConfig {
250
- connectionString?: string;
251
- host?: string;
252
- port?: number;
253
- database?: string;
254
- user?: string;
255
- password?: string;
256
- ssl?: boolean | SSLConfig; // See SSL Configuration below
257
- maxConnections?: number;
229
+ import { Pool } from 'pg';
230
+
231
+ const pool = new Pool({ /* config */ });
232
+ const client = new Client({ /* config */ });
233
+
234
+ const pgClient = await pool.connect();
235
+ try {
236
+ await pgClient.query('BEGIN');
237
+
238
+ // Database operations
239
+ await pgClient.query('INSERT INTO orders ...');
240
+
241
+ // Enqueue job in same transaction
242
+ await client.enqueueInTx(pgClient, 'SendOrderEmail', [orderId]);
243
+
244
+ await pgClient.query('COMMIT');
245
+ } catch (error) {
246
+ await pgClient.query('ROLLBACK');
247
+ throw error;
248
+ } finally {
249
+ pgClient.release();
258
250
  }
259
251
  ```
260
252
 
261
- ### SSL Configuration
253
+ ### Multiple Workers
262
254
 
263
- que-ts supports SSL/TLS connections with client certificates:
255
+ Run specialized workers for different queues:
264
256
 
265
257
  ```typescript
266
- import { Client } from 'que-ts';
267
- import * as fs from 'fs';
258
+ // Critical queue worker (fast polling)
259
+ const criticalWorker = new Worker(dbConfig, {
260
+ queue: 'critical',
261
+ interval: 100
262
+ });
268
263
 
269
- // Basic SSL
270
- const client = new Client({
271
- host: 'your-database.com',
272
- port: 5432,
273
- database: 'mydb',
274
- user: 'myuser',
275
- password: 'mypassword',
276
- ssl: {
277
- rejectUnauthorized: true,
278
- }
264
+ // Background queue worker (slow polling)
265
+ const backgroundWorker = new Worker(dbConfig, {
266
+ queue: 'background',
267
+ interval: 5000
279
268
  });
280
269
 
281
- // SSL with client certificates
282
- const clientWithCerts = new Client({
283
- host: 'your-database.com',
284
- port: 5432,
285
- database: 'mydb',
286
- user: 'myuser',
287
- password: 'mypassword',
270
+ criticalWorker.work();
271
+ backgroundWorker.work();
272
+ ```
273
+
274
+ ### SSL/TLS Support
275
+
276
+ Secure database connections with client certificates:
277
+
278
+ ```typescript
279
+ import * as fs from 'fs';
280
+
281
+ const client = new Client({
282
+ host: 'db.example.com',
288
283
  ssl: {
289
284
  rejectUnauthorized: true,
290
285
  cert: fs.readFileSync('./certs/client-cert.pem'),
291
286
  key: fs.readFileSync('./certs/client-key.pem'),
292
- ca: fs.readFileSync('./certs/ca-cert.pem'),
293
- passphrase: 'optional-key-passphrase', // For encrypted keys
287
+ ca: fs.readFileSync('./certs/ca-cert.pem')
294
288
  }
295
289
  });
296
290
  ```
297
291
 
298
- For detailed SSL configuration including AWS RDS, Google Cloud SQL, Azure, and certificate setup, see [SSL.md](SSL.md).
292
+ [**→ Complete SSL Documentation**](./SSL.md)
293
+
294
+ ## API Reference
295
+
296
+ ### Client
297
+
298
+ #### `new Client(config: ClientConfig)`
299
299
 
300
- ### WorkerOptions
300
+ Creates a new client instance.
301
301
 
302
+ **Config Options:**
302
303
  ```typescript
303
- interface WorkerOptions {
304
- queue?: string; // Queue name to process (default: '')
305
- interval?: number; // Polling interval in ms (default: 5000)
304
+ {
305
+ host?: string;
306
+ port?: number;
307
+ database?: string;
308
+ user?: string;
309
+ password?: string;
310
+ ssl?: boolean | SSLConfig;
311
+ maxConnections?: number;
312
+ }
313
+ ```
314
+
315
+ #### `client.enqueue(jobClass, args?, options?): Promise<Job>`
316
+
317
+ Enqueues a new job.
318
+
319
+ **Parameters:**
320
+ - `jobClass` - Job type identifier
321
+ - `args` - Job arguments (JSON array)
322
+ - `options` - Priority, queue, runAt
323
+
324
+ **Returns:** Job instance with ID and metadata
325
+
326
+ #### `client.enqueueInTx(pgClient, jobClass, args?, options?): Promise<Job>`
327
+
328
+ Enqueues a job within a transaction.
329
+
330
+ #### `client.lockJob(queue?): Promise<Job | null>`
331
+
332
+ Locks and returns the next available job.
333
+
334
+ #### `client.close(): Promise<void>`
335
+
336
+ Closes all database connections.
337
+
338
+ ### Worker
339
+
340
+ #### `new Worker(config: ClientConfig, options?: WorkerOptions)`
341
+
342
+ Creates a new worker instance.
343
+
344
+ **Worker Options:**
345
+ ```typescript
346
+ {
347
+ queue?: string; // Queue to process (default: '')
348
+ interval?: number; // Poll interval in ms (default: 60000)
306
349
  maxAttempts?: number; // Max retry attempts (default: 5)
307
350
  }
308
351
  ```
309
352
 
310
- ### EnqueueOptions
353
+ #### `worker.register(jobClass, handler): void`
354
+
355
+ Registers a job handler function.
356
+
357
+ #### `worker.work(): Promise<void>`
358
+
359
+ Starts continuous job processing.
360
+
361
+ #### `worker.workOne(): Promise<boolean>`
362
+
363
+ Processes a single job. Returns true if job was processed.
364
+
365
+ #### `worker.shutdown(): Promise<void>`
366
+
367
+ Gracefully shuts down the worker.
368
+
369
+ ### Job
370
+
371
+ Job instances have these properties:
311
372
 
312
373
  ```typescript
313
- interface EnqueueOptions {
314
- priority?: number; // Job priority (lower = higher priority, default: 100)
315
- runAt?: Date; // When to run the job (default: now)
316
- queue?: string; // Queue name (default: '')
374
+ {
375
+ id: number;
376
+ queue: string;
377
+ priority: number;
378
+ runAt: Date;
379
+ jobClass: string;
380
+ args: any[];
381
+ errorCount: number;
382
+ lastError?: string;
317
383
  }
318
384
  ```
319
385
 
320
- ## Error Handling and Retries
386
+ And these methods:
321
387
 
322
- Failed jobs are automatically retried with exponential backoff:
388
+ - `job.done()` - Mark as completed
389
+ - `job.error(message)` - Mark as failed
390
+ - `job.delete()` - Remove from queue
323
391
 
324
- - 1st retry: after 1 second
325
- - 2nd retry: after 16 seconds
326
- - 3rd retry: after 81 seconds
327
- - 4th retry: after 256 seconds
328
- - etc.
392
+ ## Performance Tips
329
393
 
330
- Jobs that exceed the maximum number of retries remain in the queue for manual inspection.
394
+ ### Database Indexes
331
395
 
332
- ## Queues and Priorities
396
+ Add indexes for optimal performance:
333
397
 
334
- Jobs can be organized into named queues and assigned priorities:
398
+ ```sql
399
+ CREATE INDEX idx_que_jobs_run_at ON que_jobs(run_at);
400
+ CREATE INDEX idx_que_jobs_error_count ON que_jobs(error_count);
401
+ CREATE INDEX idx_que_jobs_queue ON que_jobs(queue);
402
+ CREATE INDEX idx_que_jobs_job_class ON que_jobs(job_class);
403
+ ```
404
+
405
+ ### Connection Pooling
406
+
407
+ Configure appropriate pool sizes:
335
408
 
336
409
  ```typescript
337
- // High priority job in 'critical' queue
338
- await client.enqueue('ProcessPayment', [paymentData], {
339
- queue: 'critical',
340
- priority: 1
410
+ const client = new Client({
411
+ maxConnections: 20 // Adjust based on load
341
412
  });
413
+ ```
342
414
 
343
- // Low priority job in 'background' queue
344
- await client.enqueue('SendNewsletter', [newsletterData], {
345
- queue: 'background',
346
- priority: 500
347
- });
415
+ ### Worker Tuning
416
+
417
+ Balance polling frequency with load:
348
418
 
349
- // Worker processing only critical queue
350
- const criticalWorker = new Worker(config, { queue: 'critical' });
419
+ ```typescript
420
+ // High-frequency (for critical jobs)
421
+ new Worker(config, { interval: 100 });
422
+
423
+ // Low-frequency (for background jobs)
424
+ new Worker(config, { interval: 30000 });
351
425
  ```
352
426
 
353
427
  ## Cross-Language Compatibility
354
428
 
355
- que-ts is designed to be fully compatible with:
356
-
357
- - **[Ruby Que](https://github.com/chanks/que)** - The original Ruby implementation
358
- - **[que-go](https://github.com/bgentry/que-go)** - Golang port (currently unmaintained)
429
+ worker-que is fully compatible with:
430
+ - [**Que (Ruby)**](https://github.com/chanks/que) - Original implementation
431
+ - [**que-go**](https://github.com/bgentry/que-go) - Go implementation
359
432
 
360
- You can enqueue jobs in one language and process them in another, or run workers in multiple languages simultaneously.
433
+ Jobs can be enqueued in one language and processed in another.
361
434
 
362
- ## Related Projects
435
+ ## Production Deployment
363
436
 
364
- ### Official Implementations
365
- - **[Que (Ruby)](https://github.com/chanks/que)** - The original and most mature implementation
366
- - **[que-go](https://github.com/bgentry/que-go)** - Go implementation (unmaintained, but stable)
367
- - **[que-ts](https://github.com/Duke-Engineering/que-ts)** - This TypeScript/Node.js implementation
437
+ ### Docker
368
438
 
369
- ## Development
439
+ ```dockerfile
440
+ FROM node:18-alpine
441
+ WORKDIR /app
442
+ COPY package*.json ./
443
+ RUN npm ci --only=production
444
+ COPY . .
445
+ ENV NODE_ENV=production
446
+ EXPOSE 3000
447
+ CMD ["node", "dist/server.js"]
448
+ ```
370
449
 
371
- ### Using Docker (Recommended)
450
+ ### Environment Variables
372
451
 
373
452
  ```bash
374
- # Install dependencies
375
- npm install
453
+ # Database
454
+ DB_HOST=postgres
455
+ DB_PORT=5432
456
+ DB_NAME=myapp
457
+ DB_USER=postgres
458
+ DB_PASSWORD=secret
459
+
460
+ # SSL
461
+ DB_SSL_ENABLED=true
462
+ DB_SSL_CERT=/path/to/client-cert.pem
463
+ DB_SSL_KEY=/path/to/client-key.pem
464
+ DB_SSL_CA=/path/to/ca-cert.pem
465
+
466
+ # Worker
467
+ WORKER_QUEUE=default
468
+ WORKER_INTERVAL=5000
469
+ WORKER_MAX_ATTEMPTS=5
470
+
471
+ # Dashboard
472
+ DASHBOARD_ENABLED=true
473
+ DASHBOARD_PORT=3000
474
+ DASHBOARD_AUTH_ENABLED=true
475
+ ```
376
476
 
377
- # Start PostgreSQL with Docker
378
- npm run docker:up
477
+ ### Graceful Shutdown
379
478
 
380
- # Run tests
381
- npm test
479
+ ```typescript
480
+ process.on('SIGTERM', async () => {
481
+ console.log('Shutting down...');
482
+ await worker.shutdown();
483
+ await client.close();
484
+ process.exit(0);
485
+ });
486
+ ```
382
487
 
383
- # Run tests in watch mode
384
- npm run test:watch
488
+ ## Documentation
385
489
 
386
- # Build
387
- npm run build
490
+ - [**Dashboard Guide**](./DASHBOARD.md) - Web UI setup and usage
491
+ - [**SSL Configuration**](./SSL.md) - Secure connections
492
+ - [**Docker Setup**](./DOCKER.md) - Container deployment
493
+ - [**Contributing**](./CONTRIBUTING.md) - Development guide
388
494
 
389
- # Lint
390
- npm run lint
495
+ ## Examples
391
496
 
392
- # Stop Docker containers
393
- npm run docker:down
394
- ```
497
+ Complete examples are available in the [`examples/`](./examples) directory:
395
498
 
396
- ### Docker Commands
499
+ - `basic-usage.ts` - Simple job queue
500
+ - `ssl-connection.ts` - SSL configurations
501
+ - `dashboard-server.ts` - Complete server with dashboard
397
502
 
398
- - `npm run docker:up` - Start PostgreSQL and Adminer
399
- - `npm run docker:down` - Stop containers
400
- - `npm run docker:logs` - View PostgreSQL logs
401
- - `npm run docker:clean` - Remove containers and volumes
402
- - `npm run test:docker` - Full test cycle with Docker
503
+ ## Support
403
504
 
404
- Access database admin at http://localhost:8080 (user: `que_user`, password: `que_password`)
505
+ - 📖 [Documentation](https://github.com/your-username/worker-que#readme)
506
+ - 🐛 [Issue Tracker](https://github.com/your-username/worker-que/issues)
507
+ - 💬 [Discussions](https://github.com/your-username/worker-que/discussions)
405
508
 
406
- See [DOCKER.md](DOCKER.md) for detailed Docker documentation.
509
+ ## License
407
510
 
408
- ### Manual Setup
511
+ [MIT](./LICENSE) © 2026
409
512
 
410
- If you prefer not to use Docker, ensure PostgreSQL is running and create the database schema manually using `migrations/schema.sql`.
513
+ ## Acknowledgments
411
514
 
412
- ## License
515
+ worker-que is inspired by and compatible with:
516
+ - [Que](https://github.com/chanks/que) by Chris Hanks
517
+ - [que-go](https://github.com/bgentry/que-go) by Blake Gentry
518
+
519
+ ---
413
520
 
414
- MIT
521
+ **Built with ❤️ using TypeScript and PostgreSQL**