58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
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());
|
|
}
|
|
}
|