class ExtractionWorker { private workerPool: Worker[] = []; private taskQueue: Array<{ bytes: Uint8Array; mimeType: string; resolve: (value: any) => void; reject: (error: any) => void; }> = []; constructor(workerCount?: number) { const count = workerCount ?? (typeof navigator !== "undefined" ? (navigator.hardwareConcurrency ?? 2) : 2); for (let i = 0; i < count; i++) { const worker = new Worker("extraction-worker.js"); worker.onmessage = (e) => this.handleWorkerMessage(worker, e.data); worker.onerror = (e) => this.handleWorkerError(worker, e); this.workerPool.push(worker); } } async extract(bytes: Uint8Array, mimeType: string) { return new Promise((resolve, reject) => { this.taskQueue.push({ bytes, mimeType, resolve, reject }); this.processTasks(); }); } private processTasks() { const availableWorker = this.workerPool[0]; const task = this.taskQueue.shift(); if (!task || !availableWorker) return; availableWorker.postMessage({ bytes: task.bytes, mimeType: task.mimeType }); this.workerPool.push(this.workerPool.shift()!); } private handleWorkerMessage(_worker: Worker, result: any) { const task = this.taskQueue.shift(); if (task) { task.resolve(result); this.processTasks(); } } private handleWorkerError(_worker: Worker, error: any) { const task = this.taskQueue.shift(); if (task) { task.reject(error); this.processTasks(); } } terminate() { this.workerPool.forEach((w) => w.terminate()); } }