{"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":"oVAWA,IAAAA,EALA,SAAkBC,EAASD,GACzBE,KAAKD,QAAUA,EACfC,KAAKF,SAAWA,CAClB,qBCLA,IAAIG,EAAWC,EAYXC,EAAS,CACXC,KAAM,WAAa,GAErB,GAAoB,oBAATC,MAA+C,mBAAhBC,aAA0D,mBAArBC,iBAE7EJ,EAAOK,GAAK,SAAUC,EAAOC,GAC3BH,iBAAiBE,GAAO,SAAUV,GAChCW,EAASX,EAAQY,KACvB,KAEER,EAAOS,KAAO,SAAUb,GACtBO,YAAYP,QAGX,IAAuB,oBAAZc,QAmCd,MAAM,IAAIC,MAAM,uCAhChB,IAAIC,EACJ,IACEA,EAAgBC,QAAQ,iBACzB,CAAC,MAAMC,GACN,GAAqB,iBAAVA,GAAgC,OAAVA,GAAiC,qBAAfA,EAAMC,KAGvD,MAAMD,CAET,CAED,GAAIF,GAE2B,OAA7BA,EAAcI,WAAqB,CACnC,IAAIA,EAAcJ,EAAcI,WAChChB,EAAOS,KAAOO,EAAWb,YAAYc,KAAKD,GAC1ChB,EAAOK,GAAKW,EAAWX,GAAGY,KAAKD,GAC/BhB,EAAOC,KAAOS,QAAQT,KAAKgB,KAAKP,QACpC,MACIV,EAAOK,GAAKK,QAAQL,GAAGY,KAAKP,SAE5BV,EAAOS,KAAO,SAAUb,GACtBc,QAAQD,KAAKb,IAGfI,EAAOK,GAAG,cAAc,WACtBK,QAAQT,KAAK,EACnB,IACID,EAAOC,KAAOS,QAAQT,KAAKgB,KAAKP,QAKpC,CAEA,SAASQ,EAAaJ,GACpB,OAAOK,OAAOC,oBAAoBN,GAAOO,QAAO,SAASC,EAASC,GAChE,OAAOJ,OAAOK,eAAeF,EAASC,EAAM,CAC/CE,MAAOX,EAAMS,GACbG,YAAY,GAEV,GAAE,CAAE,EACP,CAQA,SAASC,EAAUF,GACjB,OAAOA,GAAgC,mBAAfA,EAAMG,MAAgD,mBAAhBH,EAAMI,KACtE,CAGA7B,EAAO8B,QAAU,GAQjB9B,EAAO8B,QAAQC,IAAM,SAAaC,EAAIC,GACpC,IAAIC,EAAI,IAAIC,SAAS,WAAaH,EAAK,6BACvC,OAAOE,EAAEE,MAAMF,EAAGD,IAOpBjC,EAAO8B,QAAQA,QAAU,WACvB,OAAOX,OAAOkB,KAAKrC,EAAO8B,UAM5B9B,EAAOsC,wBAAqBC,EAO5BvC,EAAOwC,eAAiB,SAASzB,GAC/B,IAAI0B,EAAQ,WACVzC,EAAOC,KAAKc,IAGd,IAAIf,EAAOsC,mBACT,OAAOG,IAGT,IAAIC,EAAS1C,EAAOsC,mBAAmBvB,GACnCY,EAAUe,GACZA,EAAOd,KAAKa,EAAOA,GAEnBA,KAIJ,IAAIE,EAAmB,KAEvB3C,EAAOK,GAAG,WAAW,SAAUuC,GAC7B,GAjIwB,6BAiIpBA,EACF,OAAO5C,EAAOwC,eAAe,GAE/B,IACE,IAAIK,EAAS7C,EAAO8B,QAAQc,EAAQC,QAEpC,IAAIA,EAsDF,MAAM,IAAIlC,MAAM,mBAAqBiC,EAAQC,OAAS,KArDtDF,EAAmBC,EAAQE,GAG3B,IAAIJ,EAASG,EAAOT,MAAMS,EAAQD,EAAQG,QAEtCpB,EAAUe,GAEZA,EACKd,MAAK,SAAUc,GACVA,aAAkB5C,EACpBE,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQA,EAAO9C,QACfkB,MAAO,MACN4B,EAAO/C,UAEVK,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQA,EACR5B,MAAO,OAGX6B,EAAmB,IACjC,IACad,OAAM,SAAUmB,GACfhD,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQ,KACR5B,MAAOI,EAAa8B,KAEtBL,EAAmB,IACjC,KAIYD,aAAkB5C,EACpBE,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQA,EAAO9C,QACfkB,MAAO,MACN4B,EAAO/C,UAEVK,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQA,EACR5B,MAAO,OAIX6B,EAAmB,KAMxB,CACD,MAAOK,GACLhD,EAAOS,KAAK,CACVqC,GAAIF,EAAQE,GACZJ,OAAQ,KACR5B,MAAOI,EAAa8B,IAEvB,CACH,IAOAhD,EAAOiD,SAAW,SAAUnB,EAASoB,GAEnC,GAAIpB,EACF,IAAK,IAAIP,KAAQO,EACXA,EAAQqB,eAAe5B,KACzBvB,EAAO8B,QAAQP,GAAQO,EAAQP,IAKjC2B,IACFlD,EAAOsC,mBAAqBY,EAAQE,aAGtCpD,EAAOS,KAAK,UAGdT,EAAOqD,KAAO,SAAUC,GACtB,GAAIX,EAAkB,CACpB,GAAIW,aAAmBxD,EAMrB,YALAE,EAAOS,KAAK,CACVqC,GAAIH,EACJY,SAAS,EACTD,QAASA,EAAQ1D,SAChB0D,EAAQ3D,UAIbK,EAAOS,KAAK,CACVqC,GAAIH,EACJY,SAAS,EACTD,WAEH,GAIDE,EAAcC,IAAAzD,EAAOiD,SACrBO,EAAeH,KAAArD,EAAOqD"}