light-async-queue 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +385 -0
  3. package/dist/src/dlq/DeadLetterQueue.d.ts +34 -0
  4. package/dist/src/dlq/DeadLetterQueue.d.ts.map +1 -0
  5. package/dist/src/dlq/DeadLetterQueue.js +60 -0
  6. package/dist/src/dlq/DeadLetterQueue.js.map +1 -0
  7. package/dist/src/index.d.ts +14 -0
  8. package/dist/src/index.d.ts.map +1 -0
  9. package/dist/src/index.js +13 -0
  10. package/dist/src/index.js.map +1 -0
  11. package/dist/src/queue/Backoff.d.ts +24 -0
  12. package/dist/src/queue/Backoff.d.ts.map +1 -0
  13. package/dist/src/queue/Backoff.js +37 -0
  14. package/dist/src/queue/Backoff.js.map +1 -0
  15. package/dist/src/queue/Job.d.ts +44 -0
  16. package/dist/src/queue/Job.d.ts.map +1 -0
  17. package/dist/src/queue/Job.js +89 -0
  18. package/dist/src/queue/Job.js.map +1 -0
  19. package/dist/src/queue/Queue.d.ts +67 -0
  20. package/dist/src/queue/Queue.d.ts.map +1 -0
  21. package/dist/src/queue/Queue.js +261 -0
  22. package/dist/src/queue/Queue.js.map +1 -0
  23. package/dist/src/queue/Scheduler.d.ts +30 -0
  24. package/dist/src/queue/Scheduler.d.ts.map +1 -0
  25. package/dist/src/queue/Scheduler.js +62 -0
  26. package/dist/src/queue/Scheduler.js.map +1 -0
  27. package/dist/src/storage/FileStore.d.ts +55 -0
  28. package/dist/src/storage/FileStore.d.ts.map +1 -0
  29. package/dist/src/storage/FileStore.js +247 -0
  30. package/dist/src/storage/FileStore.js.map +1 -0
  31. package/dist/src/storage/MemoryStore.d.ts +21 -0
  32. package/dist/src/storage/MemoryStore.d.ts.map +1 -0
  33. package/dist/src/storage/MemoryStore.js +55 -0
  34. package/dist/src/storage/MemoryStore.js.map +1 -0
  35. package/dist/src/types.d.ts +126 -0
  36. package/dist/src/types.d.ts.map +1 -0
  37. package/dist/src/types.js +2 -0
  38. package/dist/src/types.js.map +1 -0
  39. package/dist/src/worker/Worker.d.ts +36 -0
  40. package/dist/src/worker/Worker.d.ts.map +1 -0
  41. package/dist/src/worker/Worker.js +170 -0
  42. package/dist/src/worker/Worker.js.map +1 -0
  43. package/dist/src/worker/childProcessor.d.ts +2 -0
  44. package/dist/src/worker/childProcessor.d.ts.map +1 -0
  45. package/dist/src/worker/childProcessor.js +70 -0
  46. package/dist/src/worker/childProcessor.js.map +1 -0
  47. package/package.json +71 -0
@@ -0,0 +1,247 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { createWriteStream } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ /**
5
+ * File-based storage implementation with crash recovery
6
+ * Uses append-only log for durability
7
+ */
8
+ export class FileStore {
9
+ filePath;
10
+ deadLetterPath;
11
+ jobs;
12
+ deadLetterJobs;
13
+ writeStream;
14
+ dlqWriteStream;
15
+ constructor(filePath) {
16
+ this.filePath = filePath;
17
+ this.deadLetterPath = filePath.replace(/\.log$/, '') + '-dead-letter.log';
18
+ this.jobs = new Map();
19
+ this.deadLetterJobs = new Map();
20
+ this.writeStream = null;
21
+ this.dlqWriteStream = null;
22
+ }
23
+ /**
24
+ * Initialize storage and perform crash recovery
25
+ */
26
+ async initialize() {
27
+ // Ensure directory exists
28
+ await this.ensureDirectory(this.filePath);
29
+ await this.ensureDirectory(this.deadLetterPath);
30
+ // Load existing jobs from file
31
+ await this.loadJobsFromFile();
32
+ // Perform crash recovery
33
+ await this.performCrashRecovery();
34
+ // Open write streams for appending
35
+ this.writeStream = createWriteStream(this.filePath, { flags: 'a' });
36
+ this.dlqWriteStream = createWriteStream(this.deadLetterPath, { flags: 'a' });
37
+ }
38
+ /**
39
+ * Ensure parent directory exists
40
+ */
41
+ async ensureDirectory(filePath) {
42
+ const dir = dirname(filePath);
43
+ try {
44
+ await fs.mkdir(dir, { recursive: true });
45
+ }
46
+ catch {
47
+ // Directory might already exist
48
+ }
49
+ }
50
+ /**
51
+ * Load jobs from log file
52
+ */
53
+ async loadJobsFromFile() {
54
+ try {
55
+ const content = await fs.readFile(this.filePath, 'utf-8');
56
+ const lines = content.trim().split('\n').filter(line => line.length > 0);
57
+ for (const line of lines) {
58
+ try {
59
+ const job = JSON.parse(line);
60
+ this.jobs.set(job.id, job);
61
+ }
62
+ catch (parseError) {
63
+ console.error('Failed to parse job line:', line, parseError);
64
+ }
65
+ }
66
+ }
67
+ catch (error) {
68
+ // File doesn't exist yet - this is fine for first run
69
+ if (error.code !== 'ENOENT') {
70
+ throw error;
71
+ }
72
+ }
73
+ // Load dead letter jobs
74
+ try {
75
+ const content = await fs.readFile(this.deadLetterPath, 'utf-8');
76
+ const lines = content.trim().split('\n').filter(line => line.length > 0);
77
+ for (const line of lines) {
78
+ try {
79
+ const job = JSON.parse(line);
80
+ this.deadLetterJobs.set(job.id, job);
81
+ }
82
+ catch (parseError) {
83
+ console.error('Failed to parse DLQ job line:', line, parseError);
84
+ }
85
+ }
86
+ }
87
+ catch (error) {
88
+ // File doesn't exist yet - this is fine
89
+ if (error.code !== 'ENOENT') {
90
+ throw error;
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Perform crash recovery:
96
+ * - Any job with status "processing" is marked as "pending"
97
+ * - Increment attempts by 1
98
+ * - Set nextRunAt to now
99
+ */
100
+ async performCrashRecovery() {
101
+ const now = Date.now();
102
+ let recoveredCount = 0;
103
+ for (const [id, job] of this.jobs.entries()) {
104
+ if (job.status === 'processing') {
105
+ // Job was being processed when system crashed
106
+ job.status = 'pending';
107
+ job.attempts += 1;
108
+ job.nextRunAt = now;
109
+ job.updatedAt = now;
110
+ this.jobs.set(id, job);
111
+ recoveredCount++;
112
+ }
113
+ }
114
+ if (recoveredCount > 0) {
115
+ console.log(`[FileStore] Crash recovery: ${recoveredCount} jobs recovered`);
116
+ // Rewrite the entire file with recovered state
117
+ await this.rewriteJobFile();
118
+ }
119
+ }
120
+ /**
121
+ * Rewrite the entire job file (used after crash recovery)
122
+ */
123
+ async rewriteJobFile() {
124
+ const lines = Array.from(this.jobs.values())
125
+ .map(job => JSON.stringify(job))
126
+ .join('\n');
127
+ if (lines.length > 0) {
128
+ await fs.writeFile(this.filePath, lines + '\n', 'utf-8');
129
+ }
130
+ }
131
+ /**
132
+ * Append a job to the log file atomically
133
+ */
134
+ async appendToLog(job) {
135
+ return new Promise((resolve, reject) => {
136
+ if (!this.writeStream) {
137
+ reject(new Error('Write stream not initialized'));
138
+ return;
139
+ }
140
+ const line = JSON.stringify(job) + '\n';
141
+ this.writeStream.write(line, (error) => {
142
+ if (error) {
143
+ reject(error);
144
+ }
145
+ else {
146
+ resolve();
147
+ }
148
+ });
149
+ });
150
+ }
151
+ /**
152
+ * Append a job to the dead letter queue log
153
+ */
154
+ async appendToDLQ(job) {
155
+ return new Promise((resolve, reject) => {
156
+ if (!this.dlqWriteStream) {
157
+ reject(new Error('DLQ write stream not initialized'));
158
+ return;
159
+ }
160
+ const line = JSON.stringify(job) + '\n';
161
+ this.dlqWriteStream.write(line, (error) => {
162
+ if (error) {
163
+ reject(error);
164
+ }
165
+ else {
166
+ resolve();
167
+ }
168
+ });
169
+ });
170
+ }
171
+ async addJob(job) {
172
+ this.jobs.set(job.id, { ...job });
173
+ await this.appendToLog(job);
174
+ }
175
+ async updateJob(job) {
176
+ if (!this.jobs.has(job.id)) {
177
+ throw new Error(`Job ${job.id} not found`);
178
+ }
179
+ this.jobs.set(job.id, { ...job });
180
+ await this.appendToLog(job);
181
+ }
182
+ async getPendingJobs(now) {
183
+ const pendingJobs = [];
184
+ for (const job of this.jobs.values()) {
185
+ if (job.status === 'pending' && job.nextRunAt <= now) {
186
+ pendingJobs.push({ ...job });
187
+ }
188
+ }
189
+ // Sort by nextRunAt (oldest first)
190
+ return pendingJobs.sort((a, b) => a.nextRunAt - b.nextRunAt);
191
+ }
192
+ async getJob(id) {
193
+ const job = this.jobs.get(id);
194
+ return job ? { ...job } : null;
195
+ }
196
+ async getAllJobs() {
197
+ return Array.from(this.jobs.values()).map(job => ({ ...job }));
198
+ }
199
+ async moveToDeadLetter(job) {
200
+ this.deadLetterJobs.set(job.id, { ...job });
201
+ this.jobs.delete(job.id);
202
+ await this.appendToDLQ(job);
203
+ // Rewrite main job file to remove the failed job
204
+ await this.rewriteJobFile();
205
+ }
206
+ async getFailedJobs() {
207
+ return Array.from(this.deadLetterJobs.values()).map(job => ({ ...job }));
208
+ }
209
+ async removeFromDeadLetter(jobId) {
210
+ this.deadLetterJobs.delete(jobId);
211
+ // Rewrite DLQ file
212
+ const lines = Array.from(this.deadLetterJobs.values())
213
+ .map(job => JSON.stringify(job))
214
+ .join('\n');
215
+ if (lines.length > 0) {
216
+ await fs.writeFile(this.deadLetterPath, lines + '\n', 'utf-8');
217
+ }
218
+ else {
219
+ // If no jobs left, write empty file
220
+ await fs.writeFile(this.deadLetterPath, '', 'utf-8');
221
+ }
222
+ }
223
+ async close() {
224
+ return new Promise((resolve) => {
225
+ let closed = 0;
226
+ const checkComplete = () => {
227
+ closed++;
228
+ if (closed === 2) {
229
+ resolve();
230
+ }
231
+ };
232
+ if (this.writeStream) {
233
+ this.writeStream.end(checkComplete);
234
+ }
235
+ else {
236
+ checkComplete();
237
+ }
238
+ if (this.dlqWriteStream) {
239
+ this.dlqWriteStream.end(checkComplete);
240
+ }
241
+ else {
242
+ checkComplete();
243
+ }
244
+ });
245
+ }
246
+ }
247
+ //# sourceMappingURL=FileStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileStore.js","sourceRoot":"","sources":["../../../src/storage/FileStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { StorageInterface, JobData } from '../types.js';
2
+ /**
3
+ * In-memory storage implementation
4
+ * Suitable for development and testing
5
+ */
6
+ export declare class MemoryStore implements StorageInterface {
7
+ private jobs;
8
+ private deadLetterJobs;
9
+ constructor();
10
+ initialize(): Promise<void>;
11
+ addJob(job: JobData): Promise<void>;
12
+ updateJob(job: JobData): Promise<void>;
13
+ getPendingJobs(now: number): Promise<JobData[]>;
14
+ getJob(id: string): Promise<JobData | null>;
15
+ getAllJobs(): Promise<JobData[]>;
16
+ moveToDeadLetter(job: JobData): Promise<void>;
17
+ getFailedJobs(): Promise<JobData[]>;
18
+ removeFromDeadLetter(jobId: string): Promise<void>;
19
+ close(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=MemoryStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStore.d.ts","sourceRoot":"","sources":["../../../src/storage/MemoryStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD;;;GAGG;AACH,qBAAa,WAAY,YAAW,gBAAgB;IAClD,OAAO,CAAC,IAAI,CAAuB;IACnC,OAAO,CAAC,cAAc,CAAuB;;IAOvC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAInC,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAa/C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK3C,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAIhC,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAInC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * In-memory storage implementation
3
+ * Suitable for development and testing
4
+ */
5
+ export class MemoryStore {
6
+ jobs;
7
+ deadLetterJobs;
8
+ constructor() {
9
+ this.jobs = new Map();
10
+ this.deadLetterJobs = new Map();
11
+ }
12
+ async initialize() {
13
+ // No initialization needed for memory store
14
+ }
15
+ async addJob(job) {
16
+ this.jobs.set(job.id, { ...job });
17
+ }
18
+ async updateJob(job) {
19
+ if (!this.jobs.has(job.id)) {
20
+ throw new Error(`Job ${job.id} not found`);
21
+ }
22
+ this.jobs.set(job.id, { ...job });
23
+ }
24
+ async getPendingJobs(now) {
25
+ const pendingJobs = [];
26
+ for (const job of this.jobs.values()) {
27
+ if (job.status === 'pending' && job.nextRunAt <= now) {
28
+ pendingJobs.push({ ...job });
29
+ }
30
+ }
31
+ // Sort by nextRunAt (oldest first)
32
+ return pendingJobs.sort((a, b) => a.nextRunAt - b.nextRunAt);
33
+ }
34
+ async getJob(id) {
35
+ const job = this.jobs.get(id);
36
+ return job ? { ...job } : null;
37
+ }
38
+ async getAllJobs() {
39
+ return Array.from(this.jobs.values()).map(job => ({ ...job }));
40
+ }
41
+ async moveToDeadLetter(job) {
42
+ this.deadLetterJobs.set(job.id, { ...job });
43
+ this.jobs.delete(job.id);
44
+ }
45
+ async getFailedJobs() {
46
+ return Array.from(this.deadLetterJobs.values()).map(job => ({ ...job }));
47
+ }
48
+ async removeFromDeadLetter(jobId) {
49
+ this.deadLetterJobs.delete(jobId);
50
+ }
51
+ async close() {
52
+ // No cleanup needed for memory store
53
+ }
54
+ }
55
+ //# sourceMappingURL=MemoryStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStore.js","sourceRoot":"","sources":["../../../src/storage/MemoryStore.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,WAAW;IACd,IAAI,CAAuB;IAC3B,cAAc,CAAuB;IAE7C;QACE,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACtB,IAAI,CAAC,cAAc,GAAG,IAAI,GAAG,EAAE,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,4CAA4C;IAC9C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAY;QACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAY;QAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,EAAE,YAAY,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,GAAW;QAC9B,MAAM,WAAW,GAAc,EAAE,CAAC;QAElC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,SAAS,IAAI,GAAG,EAAE,CAAC;gBACrD,WAAW,CAAC,IAAI,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9B,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,UAAU;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,GAAY;QACjC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,aAAa;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAa;QACtC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACT,qCAAqC;IACvC,CAAC;CACF"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Job status enum
3
+ */
4
+ export type JobStatus = 'pending' | 'processing' | 'completed' | 'failed';
5
+ /**
6
+ * Backoff strategy configuration
7
+ */
8
+ export interface BackoffConfig {
9
+ type: 'exponential' | 'fixed';
10
+ delay: number;
11
+ }
12
+ /**
13
+ * Retry configuration
14
+ */
15
+ export interface RetryConfig {
16
+ maxAttempts: number;
17
+ backoff: BackoffConfig;
18
+ }
19
+ /**
20
+ * Core job data structure
21
+ */
22
+ export interface JobData {
23
+ id: string;
24
+ payload: unknown;
25
+ attempts: number;
26
+ maxAttempts: number;
27
+ status: JobStatus;
28
+ nextRunAt: number;
29
+ createdAt: number;
30
+ updatedAt: number;
31
+ }
32
+ /**
33
+ * Queue configuration options
34
+ */
35
+ export interface QueueConfig {
36
+ storage: 'memory' | 'file';
37
+ filePath?: string;
38
+ concurrency: number;
39
+ retry: RetryConfig;
40
+ }
41
+ /**
42
+ * Job processor function type
43
+ */
44
+ export type JobProcessor<T = unknown> = (job: JobData) => Promise<T>;
45
+ /**
46
+ * Storage interface that all storage implementations must follow
47
+ */
48
+ export interface StorageInterface {
49
+ /**
50
+ * Initialize the storage (load from disk, etc.)
51
+ */
52
+ initialize(): Promise<void>;
53
+ /**
54
+ * Add a new job to storage
55
+ */
56
+ addJob(job: JobData): Promise<void>;
57
+ /**
58
+ * Update an existing job
59
+ */
60
+ updateJob(job: JobData): Promise<void>;
61
+ /**
62
+ * Get all pending jobs that are ready to run
63
+ */
64
+ getPendingJobs(now: number): Promise<JobData[]>;
65
+ /**
66
+ * Get a specific job by ID
67
+ */
68
+ getJob(id: string): Promise<JobData | null>;
69
+ /**
70
+ * Get all jobs (for debugging/monitoring)
71
+ */
72
+ getAllJobs(): Promise<JobData[]>;
73
+ /**
74
+ * Move a job to dead letter queue
75
+ */
76
+ moveToDeadLetter(job: JobData): Promise<void>;
77
+ /**
78
+ * Get all failed jobs from DLQ
79
+ */
80
+ getFailedJobs(): Promise<JobData[]>;
81
+ /**
82
+ * Remove a job from DLQ (for reprocessing)
83
+ */
84
+ removeFromDeadLetter(jobId: string): Promise<void>;
85
+ /**
86
+ * Close/cleanup storage
87
+ */
88
+ close(): Promise<void>;
89
+ }
90
+ /**
91
+ * Worker result - success case
92
+ */
93
+ export interface WorkerSuccess {
94
+ success: true;
95
+ result: unknown;
96
+ }
97
+ /**
98
+ * Worker result - failure case
99
+ */
100
+ export interface WorkerFailure {
101
+ success: false;
102
+ error: string;
103
+ }
104
+ /**
105
+ * Worker result type
106
+ */
107
+ export type WorkerResult = WorkerSuccess | WorkerFailure;
108
+ /**
109
+ * Message sent to child worker process
110
+ */
111
+ export type WorkerMessage = {
112
+ type: 'execute';
113
+ job: JobData;
114
+ } | {
115
+ type: 'setProcessor';
116
+ code: string;
117
+ };
118
+ /**
119
+ * Response from child worker process
120
+ */
121
+ export interface WorkerResponse {
122
+ type: 'result';
123
+ jobId: string;
124
+ result: WorkerResult;
125
+ }
126
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhD;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE5C;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEjC;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C;;OAEG;IACH,aAAa,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEpC;;OAEG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,OAAO,CAAC;CACd,GACD;IACE,IAAI,EAAE,cAAc,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEN;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,CAAC;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,36 @@
1
+ import { JobData, JobProcessor } from '../types.js';
2
+ /**
3
+ * Worker manager that handles job execution in isolated child processes
4
+ */
5
+ export declare class Worker {
6
+ private processor;
7
+ private childProcess;
8
+ private isReady;
9
+ private currentJobId;
10
+ constructor(processor: JobProcessor);
11
+ /**
12
+ * Initialize the worker by forking a child process
13
+ */
14
+ initialize(): Promise<void>;
15
+ /**
16
+ * Send the processor function to the child process
17
+ */
18
+ private sendProcessorToChild;
19
+ /**
20
+ * Execute a job in the child process
21
+ */
22
+ execute(job: JobData): Promise<{
23
+ success: boolean;
24
+ result?: unknown;
25
+ error?: string;
26
+ }>;
27
+ /**
28
+ * Check if worker is currently processing a job
29
+ */
30
+ isBusy(): boolean;
31
+ /**
32
+ * Terminate the worker
33
+ */
34
+ terminate(): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=Worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Worker.d.ts","sourceRoot":"","sources":["../../../src/worker/Worker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,YAAY,EAAkB,MAAM,aAAa,CAAC;AAOpE;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,YAAY,CAAgB;gBAExB,SAAS,EAAE,YAAY;IAOnC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA6CjC;;OAEG;YACW,oBAAoB;IAuBlC;;OAEG;IACG,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IA+D5F;;OAEG;IACH,MAAM,IAAI,OAAO;IAIjB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;CA0BjC"}