worker-que 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,49 +52,56 @@ 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:
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
166
102
  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();
172
- }
103
+ title: 'My Job Queue',
104
+ auth: (req) => req.isAuthenticated() // Optional authentication
173
105
  }));
174
106
 
175
107
  app.listen(3000);
@@ -177,238 +109,407 @@ app.listen(3000);
177
109
  ```
178
110
 
179
111
  **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
112
+ - 📊 Real-time job statistics
113
+ - 📈 Visual analytics by queue and class
114
+ - 🔍 Filter and search jobs
115
+ - 🔄 Retry failed jobs
116
+ - 🗑️ Delete jobs
185
117
  - 📱 Responsive design
186
118
 
187
- For complete dashboard documentation, see [DASHBOARD.md](DASHBOARD.md).
119
+ [**→ Complete Dashboard Documentation**](./DASHBOARD.md)
188
120
 
189
- ## SSL Configuration
121
+ ## Core Concepts
190
122
 
191
- For detailed SSL configuration including AWS RDS, Google Cloud SQL, Azure, and certificate setup, see [SSL.md](SSL.md).
123
+ ### Jobs
192
124
 
193
- ## API Reference
125
+ Jobs are units of work stored in PostgreSQL:
194
126
 
195
- ### Client
127
+ ```typescript
128
+ await client.enqueue('ProcessPayment', [
129
+ { amount: 100, userId: 123 }
130
+ ], {
131
+ priority: 10, // Lower = higher priority
132
+ queue: 'critical', // Queue name
133
+ runAt: new Date() // Scheduled time
134
+ });
135
+ ```
136
+
137
+ ### Workers
196
138
 
197
- #### Constructor
139
+ Workers poll for jobs and execute registered handlers:
198
140
 
199
141
  ```typescript
200
- new Client(config?: ClientConfig)
201
- ```
142
+ const worker = new Worker({
143
+ host: 'localhost',
144
+ port: 5432,
145
+ database: 'myapp'
146
+ }, {
147
+ queue: 'critical', // Process specific queue
148
+ interval: 1000 // Poll every 1 second
149
+ });
202
150
 
203
- #### Methods
151
+ worker.register('ProcessPayment', async (job) => {
152
+ const [payment] = job.args;
153
+ // Process payment...
154
+ // Job automatically marked as done
155
+ });
204
156
 
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>`
157
+ await worker.work();
158
+ ```
209
159
 
210
- ### Worker
160
+ ### Error Handling
211
161
 
212
- #### Constructor
162
+ Failed jobs are automatically retried with exponential backoff:
163
+
164
+ - 1st retry: after 1 second
165
+ - 2nd retry: after 16 seconds
166
+ - 3rd retry: after 81 seconds
167
+ - 4th retry: after 256 seconds
213
168
 
214
169
  ```typescript
215
- new Worker(clientConfig?: ClientConfig, options?: WorkerOptions)
170
+ worker.register('RiskyJob', async (job) => {
171
+ try {
172
+ await riskyOperation();
173
+ } catch (error) {
174
+ throw error; // Job will be retried
175
+ }
176
+ });
216
177
  ```
217
178
 
218
- #### Methods
179
+ ## Advanced Features
219
180
 
220
- - `register(jobClass: string, workFunc: WorkFunction): void`
221
- - `work(): Promise<void>`
222
- - `workOne(): Promise<boolean>`
223
- - `shutdown(): Promise<void>`
181
+ ### Priority Queues
224
182
 
225
- ### Job
183
+ Organize jobs by priority and queue:
226
184
 
227
- #### Properties
185
+ ```typescript
186
+ // High priority
187
+ await client.enqueue('UrgentTask', [data], { priority: 1 });
228
188
 
229
- - `id: number`
230
- - `queue: string`
231
- - `priority: number`
232
- - `runAt: Date`
233
- - `jobClass: string`
234
- - `args: any[]`
235
- - `errorCount: number`
236
- - `lastError?: string`
189
+ // Critical queue
190
+ await client.enqueue('Payment', [data], {
191
+ priority: 1,
192
+ queue: 'critical'
193
+ });
237
194
 
238
- #### Methods
195
+ // Background queue
196
+ await client.enqueue('Analytics', [data], {
197
+ priority: 500,
198
+ queue: 'background'
199
+ });
200
+ ```
239
201
 
240
- - `done(): Promise<void>`
241
- - `delete(): Promise<void>`
242
- - `error(errorMessage: string): Promise<void>`
202
+ ### Scheduled Jobs
243
203
 
244
- ## Configuration
204
+ Schedule jobs for future execution:
245
205
 
246
- ### ClientConfig
206
+ ```typescript
207
+ // Run in 1 hour
208
+ const runAt = new Date(Date.now() + 3600000);
209
+ await client.enqueue('SendReminder', [data], { runAt });
210
+
211
+ // Daily at 9 AM
212
+ const tomorrow = new Date();
213
+ tomorrow.setDate(tomorrow.getDate() + 1);
214
+ tomorrow.setHours(9, 0, 0, 0);
215
+ await client.enqueue('DailyReport', [data], { runAt: tomorrow });
216
+ ```
217
+
218
+ ### Transaction Support
219
+
220
+ Enqueue jobs within database transactions:
247
221
 
248
222
  ```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;
223
+ import { Pool } from 'pg';
224
+
225
+ const pool = new Pool({ /* config */ });
226
+ const client = new Client({ /* config */ });
227
+
228
+ const pgClient = await pool.connect();
229
+ try {
230
+ await pgClient.query('BEGIN');
231
+
232
+ // Database operations
233
+ await pgClient.query('INSERT INTO orders ...');
234
+
235
+ // Enqueue job in same transaction
236
+ await client.enqueueInTx(pgClient, 'SendOrderEmail', [orderId]);
237
+
238
+ await pgClient.query('COMMIT');
239
+ } catch (error) {
240
+ await pgClient.query('ROLLBACK');
241
+ throw error;
242
+ } finally {
243
+ pgClient.release();
258
244
  }
259
245
  ```
260
246
 
261
- ### SSL Configuration
247
+ ### Multiple Workers
262
248
 
263
- que-ts supports SSL/TLS connections with client certificates:
249
+ Run specialized workers for different queues:
264
250
 
265
251
  ```typescript
266
- import { Client } from 'que-ts';
267
- import * as fs from 'fs';
252
+ // Critical queue worker (fast polling)
253
+ const criticalWorker = new Worker(dbConfig, {
254
+ queue: 'critical',
255
+ interval: 100
256
+ });
268
257
 
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
- }
258
+ // Background queue worker (slow polling)
259
+ const backgroundWorker = new Worker(dbConfig, {
260
+ queue: 'background',
261
+ interval: 5000
279
262
  });
280
263
 
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',
264
+ criticalWorker.work();
265
+ backgroundWorker.work();
266
+ ```
267
+
268
+ ### SSL/TLS Support
269
+
270
+ Secure database connections with client certificates:
271
+
272
+ ```typescript
273
+ import * as fs from 'fs';
274
+
275
+ const client = new Client({
276
+ host: 'db.example.com',
288
277
  ssl: {
289
278
  rejectUnauthorized: true,
290
279
  cert: fs.readFileSync('./certs/client-cert.pem'),
291
280
  key: fs.readFileSync('./certs/client-key.pem'),
292
- ca: fs.readFileSync('./certs/ca-cert.pem'),
293
- passphrase: 'optional-key-passphrase', // For encrypted keys
281
+ ca: fs.readFileSync('./certs/ca-cert.pem')
294
282
  }
295
283
  });
296
284
  ```
297
285
 
298
- For detailed SSL configuration including AWS RDS, Google Cloud SQL, Azure, and certificate setup, see [SSL.md](SSL.md).
286
+ [**→ Complete SSL Documentation**](./SSL.md)
287
+
288
+ ## API Reference
289
+
290
+ ### Client
291
+
292
+ #### `new Client(config: ClientConfig)`
299
293
 
300
- ### WorkerOptions
294
+ Creates a new client instance.
301
295
 
296
+ **Config Options:**
302
297
  ```typescript
303
- interface WorkerOptions {
304
- queue?: string; // Queue name to process (default: '')
305
- interval?: number; // Polling interval in ms (default: 5000)
298
+ {
299
+ host?: string;
300
+ port?: number;
301
+ database?: string;
302
+ user?: string;
303
+ password?: string;
304
+ ssl?: boolean | SSLConfig;
305
+ maxConnections?: number;
306
+ }
307
+ ```
308
+
309
+ #### `client.enqueue(jobClass, args?, options?): Promise<Job>`
310
+
311
+ Enqueues a new job.
312
+
313
+ **Parameters:**
314
+ - `jobClass` - Job type identifier
315
+ - `args` - Job arguments (JSON array)
316
+ - `options` - Priority, queue, runAt
317
+
318
+ **Returns:** Job instance with ID and metadata
319
+
320
+ #### `client.enqueueInTx(pgClient, jobClass, args?, options?): Promise<Job>`
321
+
322
+ Enqueues a job within a transaction.
323
+
324
+ #### `client.lockJob(queue?): Promise<Job | null>`
325
+
326
+ Locks and returns the next available job.
327
+
328
+ #### `client.close(): Promise<void>`
329
+
330
+ Closes all database connections.
331
+
332
+ ### Worker
333
+
334
+ #### `new Worker(config: ClientConfig, options?: WorkerOptions)`
335
+
336
+ Creates a new worker instance.
337
+
338
+ **Worker Options:**
339
+ ```typescript
340
+ {
341
+ queue?: string; // Queue to process (default: '')
342
+ interval?: number; // Poll interval in ms (default: 60000)
306
343
  maxAttempts?: number; // Max retry attempts (default: 5)
307
344
  }
308
345
  ```
309
346
 
310
- ### EnqueueOptions
347
+ #### `worker.register(jobClass, handler): void`
348
+
349
+ Registers a job handler function.
350
+
351
+ #### `worker.work(): Promise<void>`
352
+
353
+ Starts continuous job processing.
354
+
355
+ #### `worker.workOne(): Promise<boolean>`
356
+
357
+ Processes a single job. Returns true if job was processed.
358
+
359
+ #### `worker.shutdown(): Promise<void>`
360
+
361
+ Gracefully shuts down the worker.
362
+
363
+ ### Job
364
+
365
+ Job instances have these properties:
311
366
 
312
367
  ```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: '')
368
+ {
369
+ id: number;
370
+ queue: string;
371
+ priority: number;
372
+ runAt: Date;
373
+ jobClass: string;
374
+ args: any[];
375
+ errorCount: number;
376
+ lastError?: string;
317
377
  }
318
378
  ```
319
379
 
320
- ## Error Handling and Retries
380
+ And these methods:
321
381
 
322
- Failed jobs are automatically retried with exponential backoff:
382
+ - `job.done()` - Mark as completed
383
+ - `job.error(message)` - Mark as failed
384
+ - `job.delete()` - Remove from queue
323
385
 
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.
386
+ ## Performance Tips
329
387
 
330
- Jobs that exceed the maximum number of retries remain in the queue for manual inspection.
388
+ ### Database Indexes
331
389
 
332
- ## Queues and Priorities
390
+ Add indexes for optimal performance:
333
391
 
334
- Jobs can be organized into named queues and assigned priorities:
392
+ ```sql
393
+ CREATE INDEX idx_que_jobs_run_at ON que_jobs(run_at);
394
+ CREATE INDEX idx_que_jobs_error_count ON que_jobs(error_count);
395
+ CREATE INDEX idx_que_jobs_queue ON que_jobs(queue);
396
+ CREATE INDEX idx_que_jobs_job_class ON que_jobs(job_class);
397
+ ```
398
+
399
+ ### Connection Pooling
400
+
401
+ Configure appropriate pool sizes:
335
402
 
336
403
  ```typescript
337
- // High priority job in 'critical' queue
338
- await client.enqueue('ProcessPayment', [paymentData], {
339
- queue: 'critical',
340
- priority: 1
404
+ const client = new Client({
405
+ maxConnections: 20 // Adjust based on load
341
406
  });
407
+ ```
342
408
 
343
- // Low priority job in 'background' queue
344
- await client.enqueue('SendNewsletter', [newsletterData], {
345
- queue: 'background',
346
- priority: 500
347
- });
409
+ ### Worker Tuning
410
+
411
+ Balance polling frequency with load:
348
412
 
349
- // Worker processing only critical queue
350
- const criticalWorker = new Worker(config, { queue: 'critical' });
413
+ ```typescript
414
+ // High-frequency (for critical jobs)
415
+ new Worker(config, { interval: 100 });
416
+
417
+ // Low-frequency (for background jobs)
418
+ new Worker(config, { interval: 30000 });
351
419
  ```
352
420
 
353
421
  ## Cross-Language Compatibility
354
422
 
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)
423
+ worker-que is fully compatible with:
424
+ - [**Que (Ruby)**](https://github.com/chanks/que) - Original implementation
425
+ - [**que-go**](https://github.com/bgentry/que-go) - Go implementation
359
426
 
360
- You can enqueue jobs in one language and process them in another, or run workers in multiple languages simultaneously.
427
+ Jobs can be enqueued in one language and processed in another.
361
428
 
362
- ## Related Projects
429
+ ## Production Deployment
363
430
 
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
431
+ ### Docker
368
432
 
369
- ## Development
433
+ ```dockerfile
434
+ FROM node:18-alpine
435
+ WORKDIR /app
436
+ COPY package*.json ./
437
+ RUN npm ci --only=production
438
+ COPY . .
439
+ ENV NODE_ENV=production
440
+ EXPOSE 3000
441
+ CMD ["node", "dist/server.js"]
442
+ ```
370
443
 
371
- ### Using Docker (Recommended)
444
+ ### Environment Variables
372
445
 
373
446
  ```bash
374
- # Install dependencies
375
- npm install
447
+ # Database
448
+ DB_HOST=postgres
449
+ DB_PORT=5432
450
+ DB_NAME=myapp
451
+ DB_USER=postgres
452
+ DB_PASSWORD=secret
453
+
454
+ # SSL
455
+ DB_SSL_ENABLED=true
456
+ DB_SSL_CERT=/path/to/client-cert.pem
457
+ DB_SSL_KEY=/path/to/client-key.pem
458
+ DB_SSL_CA=/path/to/ca-cert.pem
459
+
460
+ # Worker
461
+ WORKER_QUEUE=default
462
+ WORKER_INTERVAL=5000
463
+ WORKER_MAX_ATTEMPTS=5
464
+
465
+ # Dashboard
466
+ DASHBOARD_ENABLED=true
467
+ DASHBOARD_PORT=3000
468
+ DASHBOARD_AUTH_ENABLED=true
469
+ ```
376
470
 
377
- # Start PostgreSQL with Docker
378
- npm run docker:up
471
+ ### Graceful Shutdown
379
472
 
380
- # Run tests
381
- npm test
473
+ ```typescript
474
+ process.on('SIGTERM', async () => {
475
+ console.log('Shutting down...');
476
+ await worker.shutdown();
477
+ await client.close();
478
+ process.exit(0);
479
+ });
480
+ ```
382
481
 
383
- # Run tests in watch mode
384
- npm run test:watch
482
+ ## Documentation
385
483
 
386
- # Build
387
- npm run build
484
+ - [**Dashboard Guide**](./DASHBOARD.md) - Web UI setup and usage
485
+ - [**SSL Configuration**](./SSL.md) - Secure connections
486
+ - [**Docker Setup**](./DOCKER.md) - Container deployment
487
+ - [**Contributing**](./CONTRIBUTING.md) - Development guide
388
488
 
389
- # Lint
390
- npm run lint
489
+ ## Examples
391
490
 
392
- # Stop Docker containers
393
- npm run docker:down
394
- ```
491
+ Complete examples are available in the [`examples/`](./examples) directory:
395
492
 
396
- ### Docker Commands
493
+ - `basic-usage.ts` - Simple job queue
494
+ - `ssl-connection.ts` - SSL configurations
495
+ - `dashboard-server.ts` - Complete server with dashboard
397
496
 
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
497
+ ## Support
403
498
 
404
- Access database admin at http://localhost:8080 (user: `que_user`, password: `que_password`)
499
+ - 📖 [Documentation](https://github.com/your-username/worker-que#readme)
500
+ - 🐛 [Issue Tracker](https://github.com/your-username/worker-que/issues)
501
+ - 💬 [Discussions](https://github.com/your-username/worker-que/discussions)
405
502
 
406
- See [DOCKER.md](DOCKER.md) for detailed Docker documentation.
503
+ ## License
407
504
 
408
- ### Manual Setup
505
+ [MIT](./LICENSE) © 2026
409
506
 
410
- If you prefer not to use Docker, ensure PostgreSQL is running and create the database schema manually using `migrations/schema.sql`.
507
+ ## Acknowledgments
411
508
 
412
- ## License
509
+ worker-que is inspired by and compatible with:
510
+ - [Que](https://github.com/chanks/que) by Chris Hanks
511
+ - [que-go](https://github.com/bgentry/que-go) by Blake Gentry
512
+
513
+ ---
413
514
 
414
- MIT
515
+ **Built with ❤️ using TypeScript and PostgreSQL**