Skip to content

Commit

Permalink
Updated to fix support for Windows Node.js
Browse files Browse the repository at this point in the history
  • Loading branch information
Balearica committed Oct 3, 2024
1 parent 3b4ab48 commit 5c4ae6e
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 56 deletions.
41 changes: 27 additions & 14 deletions js/generalWorkerMain.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,50 @@ 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;

const ready = new Promise((innerResolve, innerReject) => {
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.
Expand Down
34 changes: 21 additions & 13 deletions js/worker/generalWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand Down Expand Up @@ -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<import('@scribe.js/tesseract.js').Block>} */(res0.data.blocks);
Expand All @@ -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` });
};

/**
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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' });
34 changes: 23 additions & 11 deletions mupdf/mupdf-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,31 +27,35 @@ 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;
});

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)) {
Expand All @@ -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) => {
Expand Down
27 changes: 18 additions & 9 deletions mupdf/mupdf-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '';
Expand Down Expand Up @@ -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;
};

Expand Down Expand Up @@ -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);
}
8 changes: 1 addition & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

0 comments on commit 5c4ae6e

Please sign in to comment.