@happyvertical/jobs 0.74.8

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 (46) hide show
  1. package/AGENT.md +33 -0
  2. package/LICENSE +7 -0
  3. package/dist/adapters/bull.d.ts +103 -0
  4. package/dist/adapters/bull.d.ts.map +1 -0
  5. package/dist/adapters/bull.js +349 -0
  6. package/dist/adapters/bull.js.map +1 -0
  7. package/dist/adapters/bullmq.d.ts +85 -0
  8. package/dist/adapters/bullmq.d.ts.map +1 -0
  9. package/dist/adapters/bullmq.js +391 -0
  10. package/dist/adapters/bullmq.js.map +1 -0
  11. package/dist/adapters/cloud-tasks.d.ts +110 -0
  12. package/dist/adapters/cloud-tasks.d.ts.map +1 -0
  13. package/dist/adapters/cloud-tasks.js +336 -0
  14. package/dist/adapters/cloud-tasks.js.map +1 -0
  15. package/dist/adapters/postgres.d.ts +55 -0
  16. package/dist/adapters/postgres.d.ts.map +1 -0
  17. package/dist/adapters/postgres.js +437 -0
  18. package/dist/adapters/postgres.js.map +1 -0
  19. package/dist/adapters/sqlite.d.ts +44 -0
  20. package/dist/adapters/sqlite.d.ts.map +1 -0
  21. package/dist/adapters/sqlite.js +323 -0
  22. package/dist/adapters/sqlite.js.map +1 -0
  23. package/dist/adapters/sqs.d.ts +112 -0
  24. package/dist/adapters/sqs.d.ts.map +1 -0
  25. package/dist/adapters/sqs.js +411 -0
  26. package/dist/adapters/sqs.js.map +1 -0
  27. package/dist/base-store.d.ts +69 -0
  28. package/dist/base-store.d.ts.map +1 -0
  29. package/dist/chunks/base-store-DlNksWvQ.js +324 -0
  30. package/dist/chunks/base-store-DlNksWvQ.js.map +1 -0
  31. package/dist/cli/claude-context.d.ts +3 -0
  32. package/dist/cli/claude-context.d.ts.map +1 -0
  33. package/dist/cli/claude-context.js +21 -0
  34. package/dist/cli/claude-context.js.map +1 -0
  35. package/dist/index.d.ts +16 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +252 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/retry.d.ts +84 -0
  40. package/dist/retry.d.ts.map +1 -0
  41. package/dist/types.d.ts +311 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/worker.d.ts +74 -0
  44. package/dist/worker.d.ts.map +1 -0
  45. package/metadata.json +34 -0
  46. package/package.json +114 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/worker.ts"],"sourcesContent":["import { EventEmitter } from 'node:events';\nimport { createId } from '@happyvertical/utils';\nimport { fromConfig } from './retry.js';\nimport type {\n Worker as IWorker,\n Job,\n JobHandler,\n JobStore,\n WorkerConfig,\n} from './types.js';\n\n/**\n * Worker events\n */\nexport interface WorkerEvents {\n 'job:started': (job: Job) => void;\n 'job:completed': (job: Job, result: unknown) => void;\n 'job:failed': (job: Job, error: Error) => void;\n 'job:retrying': (job: Job, error: Error, delay: number) => void;\n 'worker:started': () => void;\n 'worker:stopped': () => void;\n 'worker:error': (error: Error) => void;\n}\n\n/**\n * Default worker configuration\n */\nconst DEFAULT_CONFIG: Required<WorkerConfig> = {\n id: '',\n concurrency: 5,\n queues: ['default'],\n pollInterval: 1000,\n heartbeatInterval: 30000,\n shutdownTimeout: 30000,\n};\n\n/**\n * Job worker that processes jobs from a store\n */\nexport class JobWorker extends EventEmitter implements IWorker {\n readonly id: string;\n private readonly store: JobStore;\n private readonly handler: JobHandler;\n private readonly config: Required<WorkerConfig>;\n private running = false;\n private activeJobs = new Map<string, Job>();\n private pollTimer: NodeJS.Timeout | null = null;\n private heartbeatTimer: NodeJS.Timeout | null = null;\n private shutdownPromise: Promise<void> | null = null;\n\n constructor(store: JobStore, handler: JobHandler, config: WorkerConfig = {}) {\n super();\n this.store = store;\n this.handler = handler;\n this.config = {\n ...DEFAULT_CONFIG,\n ...config,\n id: config.id || `worker_${createId().slice(0, 8)}`,\n };\n this.id = this.config.id;\n }\n\n /**\n * Start processing jobs\n */\n async start(): Promise<void> {\n if (this.running) return;\n\n this.running = true;\n\n // Subscribe to store events for push-based notifications\n this.store.subscribe(async (event) => {\n if (event.type === 'job.ready' && this.running) {\n // Immediately try to dequeue when a job becomes ready\n await this.poll();\n }\n });\n\n // Start polling loop\n this.startPolling();\n\n // Start heartbeat loop\n this.startHeartbeat();\n\n this.emit('worker:started');\n }\n\n /**\n * Stop processing jobs (graceful shutdown)\n */\n async stop(): Promise<void> {\n if (!this.running) return;\n if (this.shutdownPromise) return this.shutdownPromise;\n\n this.running = false;\n\n // Stop timers\n if (this.pollTimer) {\n clearTimeout(this.pollTimer);\n this.pollTimer = null;\n }\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n\n // Wait for active jobs to complete (with timeout)\n this.shutdownPromise = this.waitForActiveJobs();\n\n try {\n await this.shutdownPromise;\n } finally {\n this.shutdownPromise = null;\n this.emit('worker:stopped');\n }\n }\n\n /**\n * Check if worker is running\n */\n isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Get count of active jobs\n */\n activeJobCount(): number {\n return this.activeJobs.size;\n }\n\n /**\n * Start the polling loop\n */\n private startPolling(): void {\n const scheduleNextPoll = () => {\n if (!this.running) return;\n\n if (!this.store.waitForUpdate) {\n this.pollTimer = setTimeout(poll, this.config.pollInterval);\n return;\n }\n\n this.pollTimer = setTimeout(() => {\n void waitThenPoll();\n }, 0);\n };\n\n const waitThenPoll = async () => {\n try {\n await this.store.waitForUpdate?.(this.config.pollInterval);\n } catch (error) {\n this.emit('worker:error', error as Error);\n }\n\n if (this.running) {\n await poll();\n }\n };\n\n const poll = async () => {\n if (!this.running) return;\n\n try {\n await this.poll();\n } catch (error) {\n this.emit('worker:error', error as Error);\n }\n\n // Schedule next poll\n scheduleNextPoll();\n };\n\n // Start immediately\n poll();\n }\n\n /**\n * Poll for and process jobs\n */\n private async poll(): Promise<void> {\n // Calculate how many jobs we can take\n const available = this.config.concurrency - this.activeJobs.size;\n if (available <= 0) return;\n\n // Dequeue jobs\n const jobs = await this.store.dequeue(\n this.config.queues,\n available,\n this.id,\n );\n\n // Process each job concurrently\n for (const job of jobs) {\n this.processJob(job);\n }\n }\n\n /**\n * Process a single job\n */\n private async processJob(job: Job): Promise<void> {\n this.activeJobs.set(job.id, job);\n this.emit('job:started', job);\n\n let timeoutId: NodeJS.Timeout | null = null;\n\n try {\n // Set up timeout with cleanup capability\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutId = setTimeout(() => {\n reject(new Error(`Job timeout after ${job.timeout}ms`));\n }, job.timeout);\n });\n\n // Execute handler with timeout\n const result = await Promise.race([this.handler(job), timeoutPromise]);\n\n // Job completed successfully\n await this.store.update(job.id, {\n status: 'completed',\n completedAt: new Date(),\n resultPointer: result.resultPointer ?? null,\n });\n\n this.emit('job:completed', job, result.result);\n } catch (error) {\n await this.handleJobError(job, error as Error);\n } finally {\n // Clean up timeout timer to prevent memory leak\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n this.activeJobs.delete(job.id);\n }\n }\n\n /**\n * Handle job execution error\n */\n private async handleJobError(job: Job, error: Error): Promise<void> {\n const strategy = fromConfig(job.retryStrategy);\n const decision = strategy.shouldRetry(job.attempts, error);\n\n if (decision.shouldRetry && job.attempts < job.maxAttempts) {\n // Schedule retry\n const nextRunAt = new Date(Date.now() + decision.delay);\n\n await this.store.update(job.id, {\n status: 'pending',\n lastError: error.message,\n runAt: nextRunAt,\n workerId: null,\n workerHeartbeat: null,\n });\n\n this.emit('job:retrying', job, error, decision.delay);\n } else {\n // Job failed permanently\n await this.store.update(job.id, {\n status: 'failed',\n completedAt: new Date(),\n lastError: error.message,\n });\n\n this.emit('job:failed', job, error);\n }\n }\n\n /**\n * Start heartbeat loop to keep jobs alive\n */\n private startHeartbeat(): void {\n this.heartbeatTimer = setInterval(async () => {\n for (const [jobId] of this.activeJobs) {\n try {\n await this.store.heartbeat(jobId, this.id);\n } catch (error) {\n // Log heartbeat errors but don't interrupt job processing\n console.warn(`Heartbeat failed for job ${jobId}:`, error);\n }\n }\n }, this.config.heartbeatInterval);\n }\n\n /**\n * Wait for active jobs to complete with timeout\n */\n private async waitForActiveJobs(): Promise<void> {\n if (this.activeJobs.size === 0) return;\n\n return new Promise((resolve) => {\n const checkInterval = setInterval(() => {\n if (this.activeJobs.size === 0) {\n clearInterval(checkInterval);\n clearTimeout(timeout);\n resolve();\n }\n }, 100);\n\n const timeout = setTimeout(() => {\n clearInterval(checkInterval);\n console.warn(\n `Shutdown timeout: ${this.activeJobs.size} jobs still active`,\n );\n resolve();\n }, this.config.shutdownTimeout);\n });\n }\n}\n\n/**\n * Create a job worker\n */\nexport function createWorker(\n store: JobStore,\n handler: JobHandler,\n config?: WorkerConfig,\n): JobWorker {\n return new JobWorker(store, handler, config);\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ import { RetryDecision, RetryStrategy, RetryStrategyConfig } from './types.js';
2
+ /**
3
+ * Options for exponential backoff retry strategy
4
+ */
5
+ export interface ExponentialBackoffOptions {
6
+ /** Initial delay in milliseconds (default: 1000) */
7
+ initialDelay?: number;
8
+ /** Maximum delay in milliseconds (default: 300000 = 5 minutes) */
9
+ maxDelay?: number;
10
+ /** Multiplier for each attempt (default: 2) */
11
+ multiplier?: number;
12
+ /** Add random jitter to prevent thundering herd (default: true) */
13
+ jitter?: boolean;
14
+ /** Maximum attempts (optional, can also be set on job) */
15
+ maxAttempts?: number;
16
+ }
17
+ /**
18
+ * Options for linear retry strategy
19
+ */
20
+ export interface LinearBackoffOptions {
21
+ /** Fixed delay between retries in milliseconds (default: 5000) */
22
+ delay?: number;
23
+ /** Maximum attempts (optional) */
24
+ maxAttempts?: number;
25
+ }
26
+ /**
27
+ * Custom retry decision function
28
+ */
29
+ export type CustomRetryFn = (attempt: number, error: Error) => RetryDecision;
30
+ /**
31
+ * Create an exponential backoff retry strategy
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * const strategy = exponential({
36
+ * initialDelay: 1000,
37
+ * maxDelay: 300000,
38
+ * multiplier: 2,
39
+ * jitter: true,
40
+ * });
41
+ * ```
42
+ */
43
+ export declare function exponential(options?: ExponentialBackoffOptions): RetryStrategy;
44
+ /**
45
+ * Create a linear retry strategy with fixed delay
46
+ *
47
+ * @example
48
+ * ```typescript
49
+ * const strategy = linear({ delay: 5000 });
50
+ * ```
51
+ */
52
+ export declare function linear(options?: LinearBackoffOptions): RetryStrategy;
53
+ /**
54
+ * Create a custom retry strategy
55
+ *
56
+ * @example
57
+ * ```typescript
58
+ * const strategy = custom((attempt, error) => {
59
+ * if (error.message.includes('RATE_LIMITED')) {
60
+ * return { shouldRetry: true, delay: 60000 };
61
+ * }
62
+ * return { shouldRetry: attempt < 3, delay: attempt * 1000 };
63
+ * });
64
+ * ```
65
+ */
66
+ export declare function custom(fn: CustomRetryFn): RetryStrategy;
67
+ /**
68
+ * Create a no-retry strategy
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const strategy = noRetry();
73
+ * ```
74
+ */
75
+ export declare function noRetry(): RetryStrategy;
76
+ /**
77
+ * Reconstruct a retry strategy from its config
78
+ */
79
+ export declare function fromConfig(config: RetryStrategyConfig): RetryStrategy;
80
+ /**
81
+ * Default retry strategy
82
+ */
83
+ export declare const DEFAULT_RETRY_STRATEGY: RetryStrategy;
84
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0DD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAmCD;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,aAAa,CAAC;AAiD7E;;;;;;;;;;;;GAYG;AACH,wBAAgB,WAAW,CACzB,OAAO,CAAC,EAAE,yBAAyB,GAClC,aAAa,CAEf;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAEpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,MAAM,CAAC,EAAE,EAAE,aAAa,GAAG,aAAa,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAEvC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAkBrE;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,eAKjC,CAAC"}
@@ -0,0 +1,311 @@
1
+ /**
2
+ * Job status enum
3
+ */
4
+ export type JobStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
5
+ /**
6
+ * Timeout behavior when a job exceeds its timeout
7
+ */
8
+ export type TimeoutBehavior = 'fail' | 'kill' | 'warn';
9
+ /**
10
+ * Priority levels for jobs
11
+ */
12
+ export type JobPriority = 'low' | 'normal' | 'high' | 'critical';
13
+ /**
14
+ * Retry strategy configuration
15
+ */
16
+ export interface RetryStrategyConfig {
17
+ type: 'exponential' | 'linear' | 'custom';
18
+ config: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * Result of a retry strategy calculation
22
+ */
23
+ export interface RetryDecision {
24
+ shouldRetry: boolean;
25
+ delay: number;
26
+ }
27
+ /**
28
+ * Retry strategy interface
29
+ */
30
+ export interface RetryStrategy {
31
+ /**
32
+ * Determine whether to retry and how long to wait
33
+ * @param attempt Current attempt number (1-based)
34
+ * @param error The error that caused the failure
35
+ */
36
+ shouldRetry(attempt: number, error: Error): RetryDecision;
37
+ /**
38
+ * Serialize the strategy for storage
39
+ */
40
+ toConfig(): RetryStrategyConfig;
41
+ }
42
+ /**
43
+ * Job payload - what work to execute
44
+ */
45
+ export interface JobPayload {
46
+ /** The type of object (e.g., 'Document', 'Agent') */
47
+ objectType: string;
48
+ /** Instance ID (null for singleton/static methods) */
49
+ objectId: string | null;
50
+ /** Method name to execute */
51
+ method: string;
52
+ /** Arguments to pass to the method */
53
+ args: Record<string, unknown>;
54
+ }
55
+ /**
56
+ * Core job interface
57
+ */
58
+ export interface Job {
59
+ /** Unique job identifier */
60
+ id: string;
61
+ /** Queue name this job belongs to */
62
+ queue: string;
63
+ /** The work to execute */
64
+ payload: JobPayload;
65
+ /** Current job status */
66
+ status: JobStatus;
67
+ /** Priority (higher = more important) */
68
+ priority: number;
69
+ /** Number of execution attempts */
70
+ attempts: number;
71
+ /** Maximum attempts before giving up */
72
+ maxAttempts: number;
73
+ /** When to run the job (for delayed jobs) */
74
+ runAt: Date;
75
+ /** When the job started executing */
76
+ startedAt: Date | null;
77
+ /** When the job completed/failed */
78
+ completedAt: Date | null;
79
+ /** Timeout in milliseconds */
80
+ timeout: number;
81
+ /** What to do when timeout is exceeded */
82
+ timeoutBehavior: TimeoutBehavior;
83
+ /** Last error message if failed */
84
+ lastError: string | null;
85
+ /** URI pointer to result storage */
86
+ resultPointer: string | null;
87
+ /** Retry strategy configuration */
88
+ retryStrategy: RetryStrategyConfig;
89
+ /** Worker ID currently processing this job */
90
+ workerId: string | null;
91
+ /** Last heartbeat from worker */
92
+ workerHeartbeat: Date | null;
93
+ /** When the job was created */
94
+ createdAt: Date;
95
+ /** When the job was last updated */
96
+ updatedAt: Date;
97
+ }
98
+ /**
99
+ * Options for creating a new job
100
+ */
101
+ export interface JobCreateOptions {
102
+ /** Queue name (default: 'default') */
103
+ queue?: string;
104
+ /** Job payload */
105
+ payload: JobPayload;
106
+ /** Priority level or number */
107
+ priority?: JobPriority | number;
108
+ /** When to run (default: now) */
109
+ runAt?: Date;
110
+ /** Maximum attempts (default: 3) */
111
+ maxAttempts?: number;
112
+ /** Timeout in ms (default: 300000) */
113
+ timeout?: number;
114
+ /** Timeout behavior (default: 'fail') */
115
+ timeoutBehavior?: TimeoutBehavior;
116
+ /** Retry strategy */
117
+ retryStrategy?: RetryStrategy | RetryStrategyConfig;
118
+ }
119
+ /**
120
+ * Filter options for listing jobs
121
+ */
122
+ export interface JobFilter {
123
+ /** Filter by queue */
124
+ queue?: string;
125
+ /** Filter by status */
126
+ status?: JobStatus | JobStatus[];
127
+ /** Filter by object type */
128
+ objectType?: string;
129
+ /** Filter by method */
130
+ method?: string;
131
+ /** Jobs created after this date */
132
+ createdAfter?: Date;
133
+ /** Jobs created before this date */
134
+ createdBefore?: Date;
135
+ /** Maximum number of jobs to return */
136
+ limit?: number;
137
+ /** Offset for pagination */
138
+ offset?: number;
139
+ /** Order by field */
140
+ orderBy?: 'createdAt' | 'runAt' | 'priority' | 'attempts';
141
+ /** Order direction */
142
+ orderDir?: 'asc' | 'desc';
143
+ }
144
+ /**
145
+ * Options for job cleanup
146
+ */
147
+ export interface CleanupOptions {
148
+ /** Delete completed jobs older than this */
149
+ completedBefore?: Date;
150
+ /** Delete failed jobs older than this */
151
+ failedBefore?: Date;
152
+ /** Delete cancelled jobs older than this */
153
+ cancelledBefore?: Date;
154
+ /** Maximum jobs to delete in one operation */
155
+ limit?: number;
156
+ }
157
+ /**
158
+ * Job event types
159
+ */
160
+ export type JobEventType = 'job.created' | 'job.ready' | 'job.started' | 'job.completed' | 'job.failed' | 'job.cancelled' | 'job.retrying';
161
+ /**
162
+ * Job event payload
163
+ */
164
+ export interface JobEvent {
165
+ type: JobEventType;
166
+ job: Job;
167
+ timestamp: Date;
168
+ /** Error details for failed events */
169
+ error?: string;
170
+ /** Result pointer for completed events */
171
+ resultPointer?: string;
172
+ }
173
+ /**
174
+ * Job event listener callback
175
+ */
176
+ export type JobEventListener = (event: JobEvent) => void | Promise<void>;
177
+ /**
178
+ * Unsubscribe function returned by subscribe
179
+ */
180
+ export type Unsubscribe = () => void;
181
+ /**
182
+ * Job handle returned from enqueue operations
183
+ */
184
+ export interface JobHandle {
185
+ /** Job ID */
186
+ id: string;
187
+ /** Get current job status */
188
+ status(): Promise<JobStatus>;
189
+ /** Get full job details */
190
+ get(): Promise<Job | null>;
191
+ /** Wait for job completion */
192
+ wait(options?: {
193
+ timeout?: number;
194
+ }): Promise<unknown>;
195
+ /** Cancel the job */
196
+ cancel(): Promise<void>;
197
+ }
198
+ /**
199
+ * Abstract job store interface that adapters implement
200
+ */
201
+ export interface JobStore {
202
+ /**
203
+ * Initialize the store (create tables, etc.)
204
+ */
205
+ initialize(): Promise<void>;
206
+ /**
207
+ * Enqueue a new job
208
+ */
209
+ enqueue(options: JobCreateOptions): Promise<Job>;
210
+ /**
211
+ * Dequeue jobs ready for processing
212
+ * @param queues Queue names to dequeue from (in priority order)
213
+ * @param limit Maximum jobs to dequeue
214
+ * @param workerId Worker ID claiming the jobs
215
+ */
216
+ dequeue(queues: string[], limit: number, workerId: string): Promise<Job[]>;
217
+ /**
218
+ * Update a job
219
+ */
220
+ update(id: string, updates: Partial<Job>): Promise<Job>;
221
+ /**
222
+ * Get a job by ID
223
+ */
224
+ get(id: string): Promise<Job | null>;
225
+ /**
226
+ * List jobs with filtering
227
+ */
228
+ list(filter: JobFilter): Promise<Job[]>;
229
+ /**
230
+ * Cancel a job
231
+ */
232
+ cancel(id: string): Promise<void>;
233
+ /**
234
+ * Clean up old jobs
235
+ */
236
+ cleanup(options: CleanupOptions): Promise<number>;
237
+ /**
238
+ * Subscribe to job events
239
+ */
240
+ subscribe(listener: JobEventListener): Unsubscribe;
241
+ /**
242
+ * Wait for a store-level update signal, if the adapter supports one.
243
+ * Adapters without push notifications may omit this and rely on polling.
244
+ */
245
+ waitForUpdate?(timeoutMs?: number): Promise<boolean>;
246
+ /**
247
+ * Update worker heartbeat for a job
248
+ */
249
+ heartbeat(jobId: string, workerId: string): Promise<void>;
250
+ /**
251
+ * Get queue statistics
252
+ */
253
+ stats(queue?: string): Promise<QueueStats>;
254
+ /**
255
+ * Close the store and release resources
256
+ */
257
+ close(): Promise<void>;
258
+ }
259
+ /**
260
+ * Queue statistics
261
+ */
262
+ export interface QueueStats {
263
+ pending: number;
264
+ running: number;
265
+ completed: number;
266
+ failed: number;
267
+ cancelled: number;
268
+ avgDuration: number | null;
269
+ }
270
+ /**
271
+ * Worker configuration
272
+ */
273
+ export interface WorkerConfig {
274
+ /** Unique worker ID */
275
+ id?: string;
276
+ /** Number of concurrent jobs */
277
+ concurrency?: number;
278
+ /** Queues to process (in priority order) */
279
+ queues?: string[];
280
+ /** Poll interval for non-push stores (ms) */
281
+ pollInterval?: number;
282
+ /** Heartbeat interval (ms) */
283
+ heartbeatInterval?: number;
284
+ /** Shutdown timeout (ms) */
285
+ shutdownTimeout?: number;
286
+ }
287
+ /**
288
+ * Job handler function
289
+ */
290
+ export type JobHandler = (job: Job) => Promise<{
291
+ result?: unknown;
292
+ resultPointer?: string;
293
+ }>;
294
+ /**
295
+ * Worker interface
296
+ */
297
+ export interface Worker {
298
+ /** Worker ID */
299
+ id: string;
300
+ /** Start processing jobs */
301
+ start(): Promise<void>;
302
+ /** Stop processing jobs (graceful shutdown) */
303
+ stop(): Promise<void>;
304
+ /** Check if worker is running */
305
+ isRunning(): boolean;
306
+ /** Register event listener */
307
+ on(event: string, listener: (...args: unknown[]) => void): void;
308
+ /** Remove event listener */
309
+ off(event: string, listener: (...args: unknown[]) => void): void;
310
+ }
311
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { Worker as IWorker, Job, JobHandler, JobStore, WorkerConfig } from './types.js';
3
+ /**
4
+ * Worker events
5
+ */
6
+ export interface WorkerEvents {
7
+ 'job:started': (job: Job) => void;
8
+ 'job:completed': (job: Job, result: unknown) => void;
9
+ 'job:failed': (job: Job, error: Error) => void;
10
+ 'job:retrying': (job: Job, error: Error, delay: number) => void;
11
+ 'worker:started': () => void;
12
+ 'worker:stopped': () => void;
13
+ 'worker:error': (error: Error) => void;
14
+ }
15
+ /**
16
+ * Job worker that processes jobs from a store
17
+ */
18
+ export declare class JobWorker extends EventEmitter implements IWorker {
19
+ readonly id: string;
20
+ private readonly store;
21
+ private readonly handler;
22
+ private readonly config;
23
+ private running;
24
+ private activeJobs;
25
+ private pollTimer;
26
+ private heartbeatTimer;
27
+ private shutdownPromise;
28
+ constructor(store: JobStore, handler: JobHandler, config?: WorkerConfig);
29
+ /**
30
+ * Start processing jobs
31
+ */
32
+ start(): Promise<void>;
33
+ /**
34
+ * Stop processing jobs (graceful shutdown)
35
+ */
36
+ stop(): Promise<void>;
37
+ /**
38
+ * Check if worker is running
39
+ */
40
+ isRunning(): boolean;
41
+ /**
42
+ * Get count of active jobs
43
+ */
44
+ activeJobCount(): number;
45
+ /**
46
+ * Start the polling loop
47
+ */
48
+ private startPolling;
49
+ /**
50
+ * Poll for and process jobs
51
+ */
52
+ private poll;
53
+ /**
54
+ * Process a single job
55
+ */
56
+ private processJob;
57
+ /**
58
+ * Handle job execution error
59
+ */
60
+ private handleJobError;
61
+ /**
62
+ * Start heartbeat loop to keep jobs alive
63
+ */
64
+ private startHeartbeat;
65
+ /**
66
+ * Wait for active jobs to complete with timeout
67
+ */
68
+ private waitForActiveJobs;
69
+ }
70
+ /**
71
+ * Create a job worker
72
+ */
73
+ export declare function createWorker(store: JobStore, handler: JobHandler, config?: WorkerConfig): JobWorker;
74
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EACV,MAAM,IAAI,OAAO,EACjB,GAAG,EACH,UAAU,EACV,QAAQ,EACR,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;IAClC,eAAe,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/C,cAAc,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,cAAc,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACxC;AAcD;;GAEG;AACH,qBAAa,SAAU,SAAQ,YAAa,YAAW,OAAO;IAC5D,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAW;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAyB;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,eAAe,CAA8B;gBAEzC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAE,YAAiB;IAY3E;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3B;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,OAAO,CAAC,YAAY;IA2CpB;;OAEG;YACW,IAAI;IAkBlB;;OAEG;YACW,UAAU;IAoCxB;;OAEG;YACW,cAAc;IA6B5B;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;OAEG;YACW,iBAAiB;CAqBhC;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,UAAU,EACnB,MAAM,CAAC,EAAE,YAAY,GACpB,SAAS,CAEX"}
package/metadata.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@happyvertical/jobs",
3
+ "path": "packages/jobs",
4
+ "position": {
5
+ "index": 16,
6
+ "count": 30
7
+ },
8
+ "description": "Job queue abstraction with multiple backend adapters (SQLite, PostgreSQL, Bull, SQS)",
9
+ "provides": [
10
+ "Job queue abstraction with multiple backend adapters (SQLite, PostgreSQL, Bull, SQS)"
11
+ ],
12
+ "implements": [],
13
+ "requires": {
14
+ "workspace": [
15
+ "@happyvertical/sql",
16
+ "@happyvertical/utils"
17
+ ],
18
+ "externalHappyVertical": [],
19
+ "external": [
20
+ "@aws-sdk/client-sqs",
21
+ "@google-cloud/tasks",
22
+ "bull",
23
+ "bullmq"
24
+ ]
25
+ },
26
+ "dependents": [],
27
+ "stability": {
28
+ "level": "stable",
29
+ "reason": "Primary package surface is described as implemented and production-oriented."
30
+ },
31
+ "keywords": [
32
+ "jobs"
33
+ ]
34
+ }
package/package.json ADDED
@@ -0,0 +1,114 @@
1
+ {
2
+ "name": "@happyvertical/jobs",
3
+ "version": "0.74.8",
4
+ "description": "Job queue abstraction with multiple backend adapters (SQLite, PostgreSQL, Bull, SQS)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md",
11
+ "LICENSE",
12
+ "AGENT.md",
13
+ "metadata.json"
14
+ ],
15
+ "bin": {
16
+ "have-jobs-context": "./dist/cli/claude-context.js"
17
+ },
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org",
20
+ "access": "public"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/happyvertical/sdk.git",
25
+ "directory": "packages/jobs"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/happyvertical/sdk/issues"
29
+ },
30
+ "homepage": "https://github.com/happyvertical/sdk/tree/main/packages/jobs#readme",
31
+ "exports": {
32
+ ".": {
33
+ "import": "./dist/index.js",
34
+ "types": "./dist/index.d.ts"
35
+ },
36
+ "./sqlite": {
37
+ "import": "./dist/adapters/sqlite.js",
38
+ "types": "./dist/adapters/sqlite.d.ts"
39
+ },
40
+ "./postgres": {
41
+ "import": "./dist/adapters/postgres.js",
42
+ "types": "./dist/adapters/postgres.d.ts"
43
+ },
44
+ "./bull": {
45
+ "import": "./dist/adapters/bull.js",
46
+ "types": "./dist/adapters/bull.d.ts"
47
+ },
48
+ "./bullmq": {
49
+ "import": "./dist/adapters/bullmq.js",
50
+ "types": "./dist/adapters/bullmq.d.ts"
51
+ },
52
+ "./sqs": {
53
+ "import": "./dist/adapters/sqs.js",
54
+ "types": "./dist/adapters/sqs.d.ts"
55
+ },
56
+ "./cloud-tasks": {
57
+ "import": "./dist/adapters/cloud-tasks.js",
58
+ "types": "./dist/adapters/cloud-tasks.d.ts"
59
+ }
60
+ },
61
+ "keywords": [
62
+ "jobs",
63
+ "queue",
64
+ "background",
65
+ "worker",
66
+ "task"
67
+ ],
68
+ "author": "willgriffin@gmail.com",
69
+ "license": "ISC",
70
+ "dependencies": {
71
+ "@happyvertical/sql": "0.74.8",
72
+ "@happyvertical/utils": "0.74.8"
73
+ },
74
+ "devDependencies": {
75
+ "@aws-sdk/client-sqs": "^3.1034.0",
76
+ "@google-cloud/tasks": "^6.2.1",
77
+ "@types/bull": "^4.10.4",
78
+ "@types/node": "25.0.10",
79
+ "bull": "^4.16.5",
80
+ "bullmq": "^5.76.0",
81
+ "typescript": "^5.9.3",
82
+ "vite": "7.3.2",
83
+ "vite-plugin-dts": "4.5.4",
84
+ "vitest": "^4.1.5"
85
+ },
86
+ "peerDependencies": {
87
+ "@aws-sdk/client-sqs": ">=3.1034.0",
88
+ "@google-cloud/tasks": ">=4.1.0",
89
+ "bull": ">=4.16.5",
90
+ "bullmq": ">=5.76.0"
91
+ },
92
+ "peerDependenciesMeta": {
93
+ "bull": {
94
+ "optional": true
95
+ },
96
+ "bullmq": {
97
+ "optional": true
98
+ },
99
+ "@aws-sdk/client-sqs": {
100
+ "optional": true
101
+ },
102
+ "@google-cloud/tasks": {
103
+ "optional": true
104
+ }
105
+ },
106
+ "scripts": {
107
+ "test": "npx vitest run",
108
+ "test:watch": "npx vitest",
109
+ "build": "vite build",
110
+ "build:watch": "vite build --watch",
111
+ "clean": "rm -rf dist *.tsbuildinfo",
112
+ "dev": "npm run build:watch & npm run test:watch"
113
+ }
114
+ }