{"version":3,"file":"worker.min.js","sources":["../src/transfer.js","../src/worker.js"],"sourcesContent":["/**\n * The helper class for transferring data from the worker to the main thread.\n *\n * @param {Object} message The object to deliver to the main thread.\n * @param {Object[]} transfer An array of transferable Objects to transfer ownership of.\n */\nfunction Transfer(message, transfer) {\n this.message = message;\n this.transfer = transfer;\n}\n\nmodule.exports = Transfer;\n","/**\n * worker must be started as a child process or a web worker.\n * It listens for RPC messages from the parent process.\n */\nvar Transfer = require('./transfer');\n\n/**\n * Special message sent by parent which causes the worker to terminate itself.\n * Not a \"message object\"; this string is the entire message.\n */\nvar TERMINATE_METHOD_ID = '__workerpool-terminate__';\n\n// var nodeOSPlatform = require('./environment').nodeOSPlatform;\n\n// create a worker API for sending and receiving messages which works both on\n// node.js and in the browser\nvar worker = {\n exit: function() {}\n};\nif (typeof self !== 'undefined' && typeof postMessage === 'function' && typeof addEventListener === 'function') {\n // worker in the browser\n worker.on = function (event, callback) {\n addEventListener(event, function (message) {\n callback(message.data);\n })\n };\n worker.send = function (message) {\n postMessage(message);\n };\n}\nelse if (typeof process !== 'undefined') {\n // node.js\n\n var WorkerThreads;\n try {\n WorkerThreads = require('worker_threads');\n } catch(error) {\n if (typeof error === 'object' && error !== null && error.code === 'MODULE_NOT_FOUND') {\n // no worker_threads, fallback to sub-process based workers\n } else {\n throw error;\n }\n }\n\n if (WorkerThreads &&\n /* if there is a parentPort, we are in a WorkerThread */\n WorkerThreads.parentPort !== null) {\n var parentPort = WorkerThreads.parentPort;\n worker.send = parentPort.postMessage.bind(parentPort);\n worker.on = parentPort.on.bind(parentPort);\n worker.exit = process.exit.bind(process);\n } else {\n worker.on = process.on.bind(process);\n // ignore transfer argument since it is not supported by process\n worker.send = function (message) {\n process.send(message);\n };\n // register disconnect handler only for subprocess worker to exit when parent is killed unexpectedly\n worker.on('disconnect', function () {\n process.exit(1);\n });\n worker.exit = process.exit.bind(process);\n }\n}\nelse {\n throw new Error('Script must be executed as a worker');\n}\n\nfunction convertError(error) {\n return Object.getOwnPropertyNames(error).reduce(function(product, name) {\n return Object.defineProperty(product, name, {\n\tvalue: error[name],\n\tenumerable: true\n });\n }, {});\n}\n\n/**\n * Test whether a value is a Promise via duck typing.\n * @param {*} value\n * @returns {boolean} Returns true when given value is an object\n * having functions `then` and `catch`.\n */\nfunction isPromise(value) {\n return value && (typeof value.then === 'function') && (typeof value.catch === 'function');\n}\n\n// functions available externally\nworker.methods = {};\n\n/**\n * Execute a function with provided arguments\n * @param {String} fn Stringified function\n * @param {Array} [args] Function arguments\n * @returns {*}\n */\nworker.methods.run = function run(fn, args) {\n var f = new Function('return (' + fn + ').apply(null, arguments);');\n return f.apply(f, args);\n};\n\n/**\n * Get a list with methods available on this worker\n * @return {String[]} methods\n */\nworker.methods.methods = function methods() {\n return Object.keys(worker.methods);\n};\n\n/**\n * Custom handler for when the worker is terminated.\n */\nworker.terminationHandler = undefined;\n\n/**\n * Cleanup and exit the worker.\n * @param {Number} code \n * @returns \n */\nworker.cleanupAndExit = function(code) {\n var _exit = function() {\n worker.exit(code);\n }\n\n if(!worker.terminationHandler) {\n return _exit();\n }\n\n var result = worker.terminationHandler(code);\n if (isPromise(result)) {\n result.then(_exit, _exit);\n } else {\n _exit();\n }\n}\n\nvar currentRequestId = null;\n\nworker.on('message', function (request) {\n if (request === TERMINATE_METHOD_ID) {\n return worker.cleanupAndExit(0);\n }\n try {\n var method = worker.methods[request.method];\n\n if (method) {\n currentRequestId = request.id;\n \n // execute the function\n var result = method.apply(method, request.params);\n\n if (isPromise(result)) {\n // promise returned, resolve this and then return\n result\n .then(function (result) {\n if (result instanceof Transfer) {\n worker.send({\n id: request.id,\n result: result.message,\n error: null\n }, result.transfer);\n } else {\n worker.send({\n id: request.id,\n result: result,\n error: null\n });\n }\n currentRequestId = null;\n })\n .catch(function (err) {\n worker.send({\n id: request.id,\n result: null,\n error: convertError(err)\n });\n currentRequestId = null;\n });\n }\n else {\n // immediate result\n if (result instanceof Transfer) {\n worker.send({\n id: request.id,\n result: result.message,\n error: null\n }, result.transfer);\n } else {\n worker.send({\n id: request.id,\n result: result,\n error: null\n });\n }\n\n currentRequestId = null;\n }\n }\n else {\n throw new Error('Unknown method \"' + request.method + '\"');\n }\n }\n catch (err) {\n worker.send({\n id: request.id,\n result: null,\n error: convertError(err)\n });\n }\n});\n\n/**\n * Register methods to the worker\n * @param {Object} [methods]\n * @param {import('./types.js').WorkerRegisterOptions} [options]\n */\nworker.register = function (methods, options) {\n\n if (methods) {\n for (var name in methods) {\n if (methods.hasOwnProperty(name)) {\n worker.methods[name] = methods[name];\n }\n }\n }\n\n if (options) {\n worker.terminationHandler = options.onTerminate;\n }\n\n worker.send('ready');\n};\n\nworker.emit = function (payload) {\n if (currentRequestId) {\n if (payload instanceof Transfer) {\n worker.send({\n id: currentRequestId,\n isEvent: true,\n payload: payload.message\n }, payload.transfer);\n return;\n }\n\n worker.send({\n id: currentRequestId,\n isEvent: true,\n payload\n });\n }\n};\n\nif (typeof exports !== 'undefined') {\n exports.add = worker.register;\n exports.emit = worker.emit;\n}\n"],"names":["transfer","message","this","Transfer","require$$0","worker","exit","self","postMessage","addEventListener","on","event","callback","data","send","process","Error","WorkerThreads","require","error","code","parentPort","bind","convertError","Object","getOwnPropertyNames","reduce","product","name","defineProperty","value","enumerable","isPromise","then","catch","methods","run","fn","args","f","Function","apply","keys","terminationHandler","undefined","cleanupAndExit","_exit","result","currentRequestId","request","method","id","params","err","register","options","hasOwnProperty","onTerminate","emit","payload","isEvent","exports","add"],"mappings":"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"}