const resolvePaths = require('./utils/resolvePaths'); const circularize = require('./utils/circularize'); const createJob = require('./createJob'); const { log } = require('./utils/log'); const getId = require('./utils/getId'); const { defaultOEM } = require('./constants/config'); const { defaultOptions, spawnWorker, terminateWorker, onMessage, loadImage, send, } = require('./worker/node'); let workerCounter = 0; module.exports = (_options = {}) => { const id = getId('Worker', workerCounter); const { logger, errorHandler, ...options } = resolvePaths({ ...defaultOptions, ..._options, }); const resolves = {}; const rejects = {}; let worker = spawnWorker(options); workerCounter += 1; const setResolve = (action, res) => { resolves[action] = res; }; const setReject = (action, rej) => { rejects[action] = rej; }; const startJob = ({ id: jobId, action, payload }) => ( new Promise((resolve, reject) => { log(`[${id}]: Start ${jobId}, action=${action}`); setResolve(action, resolve); setReject(action, reject); send(worker, { workerId: id, jobId, action, payload, }); }) ); const load = jobId => ( startJob(createJob({ id: jobId, action: 'load', payload: { options }, })) ); const writeText = (path, text, jobId) => ( startJob(createJob({ id: jobId, action: 'FS', payload: { method: 'writeFile', args: [path, text] }, })) ); const readText = (path, jobId) => ( startJob(createJob({ id: jobId, action: 'FS', payload: { method: 'readFile', args: [path, { encoding: 'utf8' }] }, })) ); const removeFile = (path, jobId) => ( startJob(createJob({ id: jobId, action: 'FS', payload: { method: 'unlink', args: [path] }, })) ); const FS = (method, args, jobId) => ( startJob(createJob({ id: jobId, action: 'FS', payload: { method, args }, })) ); const loadLanguage = (langs = 'eng', jobId) => ( startJob(createJob({ id: jobId, action: 'loadLanguage', payload: { langs, options }, })) ); const initialize = (langs = 'eng', oem = defaultOEM, jobId) => ( startJob(createJob({ id: jobId, action: 'initialize', payload: { langs, oem }, })) ); const setParameters = (params = {}, jobId) => ( startJob(createJob({ id: jobId, action: 'setParameters', payload: { params }, })) ); const recognize = async (image, opts = {}, jobId) => ( startJob(createJob({ id: jobId, action: 'recognize', payload: { image: await loadImage(image), options: opts }, })) ); const getPDF = (title = 'Tesseract OCR Result', textonly = false, jobId) => ( startJob(createJob({ id: jobId, action: 'getPDF', payload: { title, textonly }, })) ); const detect = async (image, jobId) => ( startJob(createJob({ id: jobId, action: 'detect', payload: { image: await loadImage(image) }, })) ); const terminate = async () => { if (worker !== null) { /* await startJob(createJob({ id: jobId, action: 'terminate', })); */ terminateWorker(worker); worker = null; } return Promise.resolve(); }; onMessage(worker, ({ workerId, jobId, status, action, data, }) => { if (status === 'resolve') { log(`[${workerId}]: Complete ${jobId}`); let d = data; if (action === 'recognize') { d = circularize(data); } else if (action === 'getPDF') { d = Array.from({ ...data, length: Object.keys(data).length }); } resolves[action]({ jobId, data: d }); } else if (status === 'reject') { rejects[action](data); if (errorHandler) { errorHandler(data); } else { throw Error(data); } } else if (status === 'progress') { logger(data); } }); return { id, worker, setResolve, setReject, load, writeText, readText, removeFile, FS, loadLanguage, initialize, setParameters, recognize, getPDF, detect, terminate, }; };