workmatic 1.0.0 → 1.0.2

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.d.ts CHANGED
@@ -1,12 +1,368 @@
1
+ import * as http from 'http';
2
+ import * as better_sqlite3 from 'better-sqlite3';
3
+ import { Kysely, Generated } from 'kysely';
4
+
1
5
  /**
2
- * Workmatic - A persistent job queue for Node.js
6
+ * Job status types
7
+ */
8
+ type JobStatus = 'ready' | 'running' | 'done' | 'failed' | 'dead';
9
+ /**
10
+ * Database table schema for workmatic_jobs
11
+ */
12
+ interface WorkmaticJobsTable {
13
+ id: Generated<number>;
14
+ public_id: string;
15
+ queue: string;
16
+ payload: string;
17
+ status: JobStatus;
18
+ priority: number;
19
+ run_at: number;
20
+ attempts: number;
21
+ max_attempts: number;
22
+ lease_until: number;
23
+ created_at: number;
24
+ updated_at: number;
25
+ last_error: string | null;
26
+ }
27
+ /**
28
+ * Database table schema for workmatic_settings
29
+ */
30
+ interface WorkmaticSettingsTable {
31
+ queue: string;
32
+ paused: number;
33
+ updated_at: number;
34
+ }
35
+ /**
36
+ * Kysely database schema
37
+ */
38
+ interface WorkmaticDatabase {
39
+ workmatic_jobs: WorkmaticJobsTable;
40
+ workmatic_settings: WorkmaticSettingsTable;
41
+ }
42
+ /**
43
+ * Kysely database instance type
44
+ */
45
+ type WorkmaticDb = Kysely<WorkmaticDatabase>;
46
+ /**
47
+ * Job representation returned to users
48
+ */
49
+ interface Job<TPayload = unknown> {
50
+ /** Unique public identifier (nanoid) */
51
+ id: string;
52
+ /** Queue name */
53
+ queue: string;
54
+ /** Job payload */
55
+ payload: TPayload;
56
+ /** Current status */
57
+ status: JobStatus;
58
+ /** Priority (lower = higher priority) */
59
+ priority: number;
60
+ /** Number of attempts made */
61
+ attempts: number;
62
+ /** Maximum allowed attempts */
63
+ maxAttempts: number;
64
+ /** When the job was created (unix ms) */
65
+ createdAt: number;
66
+ /** Last error message if failed */
67
+ lastError: string | null;
68
+ }
69
+ /**
70
+ * Options for adding a job
71
+ */
72
+ interface AddJobOptions {
73
+ /** Job priority (lower = higher priority). Default: 0 */
74
+ priority?: number;
75
+ /** Delay before job becomes available (ms). Default: 0 */
76
+ delayMs?: number;
77
+ /** Maximum retry attempts. Default: 3 */
78
+ maxAttempts?: number;
79
+ }
80
+ /**
81
+ * Result of adding a job
82
+ */
83
+ interface AddJobResult {
84
+ ok: true;
85
+ id: string;
86
+ }
87
+ /**
88
+ * Options for creating a database
89
+ */
90
+ interface DatabaseOptions {
91
+ /** Existing better-sqlite3 Database instance */
92
+ db?: better_sqlite3.Database;
93
+ /** Path to SQLite database file (ignored if db is provided) */
94
+ filename?: string;
95
+ }
96
+ /**
97
+ * Options for creating a client
98
+ */
99
+ interface ClientOptions {
100
+ /** Kysely database instance */
101
+ db: WorkmaticDb;
102
+ /** Queue name. Default: 'default' */
103
+ queue?: string;
104
+ }
105
+ /**
106
+ * Backoff function type
107
+ */
108
+ type BackoffFunction = (attempts: number) => number;
109
+ /**
110
+ * Options for creating a worker
111
+ */
112
+ interface WorkerOptions {
113
+ /** Kysely database instance */
114
+ db: WorkmaticDb;
115
+ /** Queue name. Default: 'default' */
116
+ queue?: string;
117
+ /** Number of concurrent job processors. Default: 1 */
118
+ concurrency?: number;
119
+ /** Lease duration in ms. Default: 30000 */
120
+ leaseMs?: number;
121
+ /** Poll interval in ms when no jobs available. Default: 1000 */
122
+ pollMs?: number;
123
+ /** Job execution timeout in ms. Default: undefined (no timeout) */
124
+ timeoutMs?: number;
125
+ /** Backoff function for retries. Default: exponential */
126
+ backoff?: BackoffFunction;
127
+ }
128
+ /**
129
+ * Job processor function type
130
+ */
131
+ type JobProcessor<TPayload = unknown> = (job: Job<TPayload>) => Promise<void>;
132
+ /**
133
+ * Stats by status
134
+ */
135
+ interface JobStats {
136
+ ready: number;
137
+ running: number;
138
+ done: number;
139
+ failed: number;
140
+ dead: number;
141
+ total: number;
142
+ }
143
+ /**
144
+ * Client interface
145
+ */
146
+ interface WorkmaticClient {
147
+ /** Add a job to the queue */
148
+ add<TPayload = unknown>(payload: TPayload, options?: AddJobOptions): Promise<AddJobResult>;
149
+ /** Get job statistics */
150
+ stats(): Promise<JobStats>;
151
+ }
152
+ /**
153
+ * Worker interface
154
+ */
155
+ interface WorkmaticWorker {
156
+ /** Set the job processor function */
157
+ process<TPayload = unknown>(fn: JobProcessor<TPayload>): void;
158
+ /** Start processing jobs */
159
+ start(): void;
160
+ /** Stop processing jobs (drains current jobs) */
161
+ stop(): Promise<void>;
162
+ /** Pause processing (stops claiming new jobs) */
163
+ pause(): void;
164
+ /** Resume processing */
165
+ resume(): void;
166
+ /** Get job statistics */
167
+ stats(): Promise<JobStats>;
168
+ /** Check if worker is running */
169
+ readonly isRunning: boolean;
170
+ /** Check if worker is paused */
171
+ readonly isPaused: boolean;
172
+ /** Queue name */
173
+ readonly queue: string;
174
+ }
175
+ /**
176
+ * Options for creating a dashboard
177
+ */
178
+ interface DashboardOptions {
179
+ /** Kysely database instance */
180
+ db: WorkmaticDb;
181
+ /** HTTP server port. Default: 3000 */
182
+ port?: number;
183
+ /** Worker instances to control */
184
+ workers?: WorkmaticWorker[];
185
+ }
186
+ /**
187
+ * Options for creating dashboard middleware
188
+ */
189
+ interface DashboardMiddlewareOptions {
190
+ /** Kysely database instance */
191
+ db: WorkmaticDb;
192
+ /** Worker instances to control */
193
+ workers?: WorkmaticWorker[];
194
+ /** Base path for mounting (e.g., '/workmatic'). Default: '' */
195
+ basePath?: string;
196
+ }
197
+ /**
198
+ * Express-compatible request handler
199
+ */
200
+ type DashboardMiddleware = (req: http.IncomingMessage, res: http.ServerResponse, next?: () => void) => void;
201
+ /**
202
+ * Dashboard interface
203
+ */
204
+ interface WorkmaticDashboard {
205
+ /** Close the dashboard server */
206
+ close(): Promise<void>;
207
+ /** Server port */
208
+ readonly port: number;
209
+ }
210
+ /**
211
+ * Internal job representation from database
212
+ */
213
+ interface ClaimedJob {
214
+ id: number;
215
+ public_id: string;
216
+ queue: string;
217
+ payload: string;
218
+ attempts: number;
219
+ max_attempts: number;
220
+ }
221
+
222
+ /**
223
+ * Create and initialize the workmatic database
224
+ *
225
+ * @param options - Database options
226
+ * @returns Kysely database instance
227
+ *
228
+ * @example
229
+ * ```ts
230
+ * // Using a file path
231
+ * const db = createDatabase({ filename: './jobs.db' });
232
+ *
233
+ * // Using an existing better-sqlite3 instance
234
+ * import Database from 'better-sqlite3';
235
+ * const sqlite = new Database('./jobs.db');
236
+ * const db = createDatabase({ db: sqlite });
237
+ *
238
+ * // In-memory database (for testing)
239
+ * const db = createDatabase({ filename: ':memory:' });
240
+ * ```
241
+ */
242
+ declare function createDatabase(options?: DatabaseOptions): WorkmaticDb;
243
+
244
+ /**
245
+ * Create a job queue client for adding jobs
246
+ *
247
+ * @param options - Client options
248
+ * @returns Client instance
249
+ *
250
+ * @example
251
+ * ```ts
252
+ * const client = createClient({ db });
253
+ *
254
+ * // Add a simple job
255
+ * const result = await client.add({ email: 'user@example.com' });
256
+ * console.log(result.id); // Job public ID
257
+ *
258
+ * // Add a job with options
259
+ * await client.add(
260
+ * { userId: 123 },
261
+ * { priority: 1, delayMs: 5000, maxAttempts: 5 }
262
+ * );
263
+ *
264
+ * // Get queue statistics
265
+ * const stats = await client.stats();
266
+ * console.log(stats); // { ready: 5, running: 2, done: 100, ... }
267
+ * ```
268
+ */
269
+ declare function createClient(options: ClientOptions): WorkmaticClient;
270
+
271
+ /**
272
+ * Create a job queue worker for processing jobs
273
+ *
274
+ * @param options - Worker options
275
+ * @returns Worker instance
276
+ *
277
+ * @example
278
+ * ```ts
279
+ * const worker = createWorker({ db, concurrency: 4 });
280
+ *
281
+ * // Set the processor function
282
+ * worker.process(async (job) => {
283
+ * console.log('Processing job:', job.id);
284
+ * await sendEmail(job.payload.email);
285
+ * });
286
+ *
287
+ * // Start processing
288
+ * worker.start();
289
+ *
290
+ * // Later, gracefully stop
291
+ * await worker.stop();
292
+ * ```
293
+ */
294
+ declare function createWorker(options: WorkerOptions): WorkmaticWorker;
295
+
296
+ /**
297
+ * Create a dashboard HTTP server for monitoring and controlling the job queue
298
+ *
299
+ * @param options - Dashboard options
300
+ * @returns Dashboard instance
301
+ *
302
+ * @example
303
+ * ```ts
304
+ * const dashboard = createDashboard({
305
+ * db,
306
+ * port: 3000,
307
+ * workers: [worker1, worker2]
308
+ * });
309
+ *
310
+ * console.log(`Dashboard running at http://localhost:${dashboard.port}`);
311
+ *
312
+ * // Later, close the server
313
+ * await dashboard.close();
314
+ * ```
315
+ */
316
+ declare function createDashboard(options: DashboardOptions): WorkmaticDashboard;
317
+ /**
318
+ * Create an Express-compatible middleware for the dashboard
319
+ *
320
+ * @param options - Middleware options
321
+ * @returns Express middleware function
322
+ *
323
+ * @example
324
+ * ```ts
325
+ * import express from 'express';
326
+ * import { createDashboardMiddleware } from 'workmatic';
327
+ *
328
+ * const app = express();
329
+ *
330
+ * // Mount dashboard at /workmatic
331
+ * app.use(createDashboardMiddleware({
332
+ * db,
333
+ * basePath: '/workmatic',
334
+ * workers: [worker]
335
+ * }));
336
+ *
337
+ * app.listen(3000);
338
+ * // Dashboard available at http://localhost:3000/workmatic
339
+ * ```
340
+ */
341
+ declare function createDashboardMiddleware(options: DashboardMiddlewareOptions): DashboardMiddleware;
342
+
343
+ /**
344
+ * Default exponential backoff function
345
+ * Returns delay in milliseconds: 1000 * 2^attempts
346
+ *
347
+ * @param attempts - Number of failed attempts
348
+ * @returns Delay in milliseconds
349
+ *
350
+ * @example
351
+ * ```ts
352
+ * defaultBackoff(0) // 1000ms (1 second)
353
+ * defaultBackoff(1) // 2000ms (2 seconds)
354
+ * defaultBackoff(2) // 4000ms (4 seconds)
355
+ * defaultBackoff(3) // 8000ms (8 seconds)
356
+ * ```
357
+ */
358
+ declare const defaultBackoff: BackoffFunction;
359
+ /**
360
+ * Validate that a payload is JSON-serializable
3
361
  *
4
- * @packageDocumentation
362
+ * @param payload - The payload to validate
363
+ * @throws Error if payload cannot be serialized to JSON
364
+ * @returns The JSON string representation
5
365
  */
6
- export { createDatabase } from './database.js';
7
- export { createClient } from './client.js';
8
- export { createWorker } from './worker.js';
9
- export { createDashboard, createDashboardMiddleware } from './dashboard.js';
10
- export { defaultBackoff, validatePayload } from './utils.js';
11
- export type { Job, JobStatus, JobStats, ClaimedJob, AddJobOptions, AddJobResult, DatabaseOptions, ClientOptions, WorkerOptions, DashboardOptions, DashboardMiddlewareOptions, BackoffFunction, JobProcessor, WorkmaticClient, WorkmaticWorker, WorkmaticDashboard, DashboardMiddleware, WorkmaticDb, WorkmaticDatabase, WorkmaticJobsTable, } from './types.js';
12
- //# sourceMappingURL=index.d.ts.map
366
+ declare function validatePayload(payload: unknown): string;
367
+
368
+ export { type AddJobOptions, type AddJobResult, type BackoffFunction, type ClaimedJob, type ClientOptions, type DashboardMiddleware, type DashboardMiddlewareOptions, type DashboardOptions, type DatabaseOptions, type Job, type JobProcessor, type JobStats, type JobStatus, type WorkerOptions, type WorkmaticClient, type WorkmaticDashboard, type WorkmaticDatabase, type WorkmaticDb, type WorkmaticJobsTable, type WorkmaticWorker, createClient, createDashboard, createDashboardMiddleware, createDatabase, createWorker, defaultBackoff, validatePayload };