diff --git a/js/generalWorkerMain.js b/js/generalWorkerMain.js index 073cc6d..b1277fd 100644 --- a/js/generalWorkerMain.js +++ b/js/generalWorkerMain.js @@ -6,19 +6,23 @@ export async function initGeneralWorker() { // This method of creating workers works natively in the browser, Node.js, and Webpack 5. // Do not change without confirming compatibility with all three. const obj = {}; - let worker; - if (typeof process === 'undefined') { - worker = new Worker(new URL('./worker/generalWorker.js', import.meta.url), { type: 'module' }); - } else { - const WorkerNode = typeof process === 'undefined' ? Worker : (await import('web-worker')).default; - worker = new WorkerNode(new URL('./worker/generalWorker.js', import.meta.url), { type: 'module' }); - } + const Worker = typeof process === 'undefined' ? globalThis.Worker : (await import('worker_threads')).Worker; + const worker = new Worker(new URL('./worker/generalWorker.js', import.meta.url), { type: 'module' }); return new Promise((resolve, reject) => { - worker.onerror = (err) => { + + const errorHandler = (err) => { console.error(err); }; + if (typeof process === 'undefined') { + // @ts-ignore + worker.onerror = errorHandler; + } else { + // @ts-ignore + worker.on('error', errorHandler); + } + const workerPromises = {}; let promiseId = 0; @@ -26,17 +30,26 @@ export async function initGeneralWorker() { workerPromises['0'] = { resolve: innerResolve, reject: innerReject, func: 'ready' }; }); - worker.onmessage = async (event) => { - if (workerPromises[event.data.id]) { - if (event.data.status === 'reject') { - console.log(event.data.data); - workerPromises[event.data.id].reject(event.data.data); + + const messageHandler = async (data) => { + if (workerPromises[data.id]) { + if (data.status === 'reject') { + console.log(data.data); + workerPromises[data.id].reject(data.data); } else { - workerPromises[event.data.id].resolve(event.data.data); + workerPromises[data.id].resolve(data.data); } } }; + if (typeof process === 'undefined') { + // @ts-ignore + worker.onmessage = (event) => messageHandler(event.data); + } else { + // @ts-ignore + worker.on('message', messageHandler); + } + /** * Wraps a function to be called via worker messages. * @param {string} func The function name to call. diff --git a/js/worker/generalWorker.js b/js/worker/generalWorker.js index 92baf00..56e3d8c 100644 --- a/js/worker/generalWorker.js +++ b/js/worker/generalWorker.js @@ -15,7 +15,8 @@ import { } from './compareOCRModule.js'; import { optimizeFont } from './optimizeFontModule.js'; -// import Tesseract from "../../tess/tesseract.esm.min.js"; +const parentPort = typeof process === 'undefined' ? globalThis : (await import('worker_threads')).parentPort; +if (!parentPort) throw new Error('This file must be run in a worker'); const Tesseract = typeof process === 'undefined' ? (await import('../../tess/tesseract.esm.min.js')).default : await import('@scribe.js/tesseract.js'); @@ -296,7 +297,7 @@ export const recognizeAndConvert2 = async ({ const xB = { recognize: res1.data, convert: { legacy: null, lstm: resLSTM } }; - postMessage({ data: xB, id: `${id}b`, status: 'resolve' }); + parentPort.postMessage({ data: xB, id: `${id}b`, status: 'resolve' }); })(); } else if (!options.lstm && options.legacy) { const legacyBlocks = /** @type {Array} */(res0.data.blocks); @@ -312,10 +313,10 @@ export const recognizeAndConvert2 = async ({ const x = { recognize: res0.data, convert: { legacy: resLegacy, lstm: resLSTM } }; - postMessage({ data: x, id, status: 'resolve' }); + parentPort.postMessage({ data: x, id, status: 'resolve' }); // Both promises must resolve for the scheduler to move on, even if only one OCR engine is being run. - if (!options.legacy || !options.lstm) postMessage({ data: null, id: `${id}b` }); + if (!options.legacy || !options.lstm) parentPort.postMessage({ data: null, id: `${id}b` }); }; /** @@ -373,13 +374,11 @@ async function compareOCRPageImpWrap(args) { return await compareOCRPageImp(args); } -postMessage({ data: 'ready', id: 0, status: 'resolve' }); +const handleMessage = async (data) => { -// eslint-disable-next-line no-restricted-globals -addEventListener('message', async (e) => { - const func = e.data[0]; - const args = e.data[1]; - const id = e.data[2]; + const func = data[0]; + const args = data[1]; + const id = data[2]; if (func === 'recognizeAndConvert2') { recognizeAndConvert2(args, id); @@ -415,6 +414,15 @@ addEventListener('message', async (e) => { loadFontsWorker, updateFontContWorker, })[func](args) - .then((x) => postMessage({ data: x, id, status: 'resolve' })) - .catch((err) => postMessage({ data: err, id, status: 'reject' })); -}); + .then((x) => parentPort.postMessage({ data: x, id, status: 'resolve' })) + .catch((err) => parentPort.postMessage({ data: err, id, status: 'reject' })); +}; + +if (typeof process === 'undefined') { + onmessage = (event) => handleMessage(event.data); +} else { + parentPort.on('message', handleMessage); +} + + +parentPort.postMessage({ data: 'ready', id: 0, status: 'resolve' }); diff --git a/mupdf/mupdf-async.js b/mupdf/mupdf-async.js index ff69a5d..e0c5ffd 100644 --- a/mupdf/mupdf-async.js +++ b/mupdf/mupdf-async.js @@ -27,18 +27,21 @@ export async function initMuPDFWorker() { // This method of creating workers works natively in the browser, Node.js, and Webpack 5. // Do not change without confirming compatibility with all three. const mupdf = {}; - let worker; + const Worker = typeof process === 'undefined' ? globalThis.Worker : (await import('worker_threads')).Worker; + const worker = new Worker(new URL('./mupdf-worker.js', import.meta.url), { type: 'module' }); + + const errorHandler = (err) => { + console.error(err); + }; + if (typeof process === 'undefined') { - worker = new Worker(new URL('./mupdf-worker.js', import.meta.url), { type: 'module' }); + // @ts-ignore + worker.onerror = errorHandler; } else { - const WorkerNode = typeof process === 'undefined' ? Worker : (await import('web-worker')).default; - worker = new WorkerNode(new URL('./mupdf-worker.js', import.meta.url), { type: 'module' }); + // @ts-ignore + worker.on('error', errorHandler); } - worker.onerror = function (error) { - throw error; - }; - let readyResolve; const readyPromise = new Promise((resolve, reject) => { readyResolve = resolve; @@ -46,12 +49,13 @@ export async function initMuPDFWorker() { worker.promises = {}; worker.promiseId = 0; - worker.onmessage = async function (event) { - if (typeof event.data === 'string' && event.data === 'READY') { + + const messageHandler = async (data) => { + if (typeof data === 'string' && data === 'READY') { readyResolve(); return; } - const [type, id, result] = event.data; + const [type, id, result] = data; if (type === 'RESULT') { // worker.promises[id].resolve(result); if (['drawPageAsPNG'].includes(worker.promises[id].func)) { @@ -69,6 +73,14 @@ export async function initMuPDFWorker() { } }; + if (typeof process === 'undefined') { + // @ts-ignore + worker.onmessage = (event) => messageHandler(event.data); + } else { + // @ts-ignore + worker.on('message', messageHandler); + } + function wrap(func) { return function (...args) { return new Promise((resolve, reject) => { diff --git a/mupdf/mupdf-worker.js b/mupdf/mupdf-worker.js index 3704d3c..81031df 100644 --- a/mupdf/mupdf-worker.js +++ b/mupdf/mupdf-worker.js @@ -20,6 +20,9 @@ // Artifex Software, Inc., 1305 Grant Avenue - Suite 200, Novato, // CA 94945, U.S.A., +1(415)492-9861, for further information. +const parentPort = typeof process === 'undefined' ? globalThis : (await import('worker_threads')).parentPort; +if (!parentPort) throw new Error('This file must be run in a worker'); + // Copied from https://gist.github.com/jonleighton/958841 function arrayBufferToBase64(arrayBuffer) { let base64 = ''; @@ -127,7 +130,7 @@ Module.onRuntimeInitialized = function () { mupdf.outlineNext = Module.cwrap('outlineNext', 'number', ['number']); wasm_checkNativeText = Module.cwrap('checkNativeText', 'number', ['number', 'number']); mupdf.writeDocument = Module.cwrap('writeDocument', 'null', []); - postMessage('READY'); + parentPort.postMessage('READY'); ready = true; }; @@ -446,19 +449,25 @@ mupdf.search = function (doc, page, dpi, needle) { return JSON.parse(mupdf.searchJSON(doc, page, dpi, needle)); }; -addEventListener('message', (event) => { - const [func, args, id] = event.data; +const handleMessage = (data) => { + const [func, args, id] = data; if (!ready) { - postMessage(['ERROR', id, { name: 'NotReadyError', message: 'WASM module is not ready yet' }]); + parentPort.postMessage(['ERROR', id, { name: 'NotReadyError', message: 'WASM module is not ready yet' }]); return; } try { const result = mupdf[func](...args); - if (result instanceof ArrayBuffer) postMessage(['RESULT', id, result], [result]); + if (result instanceof ArrayBuffer) parentPort.postMessage(['RESULT', id, result], [result]); else if (result?.buffer instanceof ArrayBuffer) { - postMessage(['RESULT', id, result], [result.buffer]); - } else postMessage(['RESULT', id, result]); + parentPort.postMessage(['RESULT', id, result], [result.buffer]); + } else parentPort.postMessage(['RESULT', id, result]); } catch (error) { - postMessage(['ERROR', id, { name: error.name, message: error.message }]); + parentPort.postMessage(['ERROR', id, { name: error.name, message: error.message }]); } -}); +} + +if (typeof process === 'undefined') { + onmessage = (event) => handleMessage(event.data); +} else { + parentPort.on('message', handleMessage); +} diff --git a/package-lock.json b/package-lock.json index 5360cba..327395e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,7 @@ "@scribe.js/tesseract.js": "^5.1.1", "canvas": "^2.11.2", "commander": "^11.1.0", - "puppeteer": "^22.13.0", - "web-worker": "~1.2.0" + "puppeteer": "^22.13.0" }, "devDependencies": { "@playwright/test": "^1.40.1", @@ -9207,11 +9206,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/web-worker": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz", - "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==" - }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", diff --git a/package.json b/package.json index 65a36e1..d4d0bb4 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "canvas": "^2.11.2", "commander": "^11.1.0", "puppeteer": "^22.13.0", - "@scribe.js/tesseract.js": "^5.1.1", - "web-worker": "~1.2.0" + "@scribe.js/tesseract.js": "^5.1.1" } }