From bd7685b6904e03e7858f392f414933665410515c Mon Sep 17 00:00:00 2001 From: yuanpengfei03 Date: Wed, 9 Feb 2022 18:23:31 +0800 Subject: [PATCH 1/3] feature(async): support async func in action and manual to close child worker --- dist/sww.min.js | 2 +- dist/sww.min.js.map | 2 +- src/createDisposableWorker.js | 10 ++- src/run.js | 6 +- src/tests/integration/config/sworker.js | 25 +++++- src/tests/integration/config/tests.js | 108 +++++++++++++++--------- src/utils.js | 27 +++++- 7 files changed, 128 insertions(+), 52 deletions(-) diff --git a/dist/sww.min.js b/dist/sww.min.js index 55d68ee6..b3b62b67 100644 --- a/dist/sww.min.js +++ b/dist/sww.min.js @@ -1,2 +1,2 @@ -"use strict";function postAll(){var r=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];if(isValid(e)(["arraysArray","postParamsArray","stringsArray"])){if(0===e.length)return Promise.all(this.actions.map(function(e){var n=e.message;return r.postMessage(n)}));if(e.every(function(r){return"string"==typeof r}))return Promise.all(e.map(function(e){return r.postMessage(e)}));if(e.every(function(r){return"object"===(void 0===r?"undefined":_typeof(r))&&!Array.isArray(r)}))return Promise.all(e.map(function(e){var n=e.message,t=e.args;return r.postMessage(n,t)}));if(e.every(function(r){return Array.isArray(r)})&&e.length===this.actions.length)return Promise.all(e.map(function(e,n){return r.postMessage(r.actions[n].message,e)}))}return console.error(argumentError(makeOptionsFor(e))),null}var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},isValidObjectWith=function(r){return function(e){return!!e&&!Array.isArray(e)&&r.every(function(r){return e.hasOwnProperty(r)})}},isValidAction=function(r){return isValidObjectWith(["message","func"])(r)&&"function"==typeof r.func&&"string"==typeof r.message},isValidActionsArray=function(r){return r.every(isValidAction)},isValidPostParams=function(r){return isValidObjectWith(["message","args"])(r)&&Array.isArray(r.args)&&"string"==typeof r.message},isValidPostParamsArray=function(r){return r.every(isValidPostParams)},isValidObjectsArray=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return r.every(isValidObjectWith(e))}},testArray={actionsArray:function(r){return isValidActionsArray(r)},arraysArray:function(r){return r.every(function(r){return Array.isArray(r)})},objectsArray:function(r){return isValidObjectsArray(r)()},postParamsArray:function(r){return isValidPostParamsArray(r)},stringsArray:function(r){return r.every(function(r){return"string"==typeof r})}},isValidArg=function(r){return function(e){return"null"===e?null===r:"undefined"===e?void 0===r:"action"===e?isValidAction(r):Array.isArray(r)?!("array"!==e&&!testArray[e])&&("array"===e||testArray[e](r)):!!r&&(void 0===r?"undefined":_typeof(r))===e.toString()}},isValid=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return Array.isArray(e)?e.some(function(e){return isValidArg(r)(e)}):!!isValidArg(r)(e)}},argumentError=function(r){var e=r.expected,n=void 0===e?"":e,t=r.received,o=r.extraInfo,i=void 0===o?"":o;try{return new TypeError("You should provide "+n+"\n"+i+"\nReceived: "+JSON.stringify(t))}catch(r){if("Converting circular structure to JSON"===r.message)return new TypeError("You should provide "+n+"\n"+i+"\nReceived a circular structure: "+t);throw r}},makeResponse=function(r){return"\n self.onmessage = event => {\n const args = event.data.message.args\n if (args) {\n self.postMessage(("+r+").apply(null, args))\n return close()\n }\n self.postMessage(("+r+")())\n return close()\n }\n"},createDisposableWorker=function(r){var e=window.URL||window.webkitURL,n=new Blob([r],{type:"application/javascript"}),t=e.createObjectURL(n),o=new Worker(t);return o.post=function(r){return new Promise(function(n,i){o.onmessage=function(r){e.revokeObjectURL(t),n(r.data)},o.onerror=function(r){console.error("Error: Line "+r.lineno+" in "+r.filename+": "+r.message),i(r)},o.postMessage({message:r})})},o},run=function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments[1],n=isValid(r)("function"),t=isValid(e)(["array","undefined"]);if(n&&t){return createDisposableWorker(makeResponse(r)).post({args:e})}return n||console.error(argumentError({expected:"a function",received:r})),t||console.error(argumentError({expected:"an array",received:e})),null},warnWork=function(r){return console.warn("WARN! "+r+" is not a registered action for this worker"),r+" is not a registered action for this worker"},post=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments[1],t=isValid(e)("string"),o=isValid(n)(["array","undefined"]);if(t&&o){var i=r.filter(function(r){var n=r.message;return JSON.stringify(n)===JSON.stringify(e)}).map(function(r){return r.func}).pop();return i?n?run(i,n):run(i):run(warnWork,[JSON.stringify(e)])}return t||console.error(argumentError({expected:"a string",received:e})),o||console.error(argumentError({expected:"an array",received:n})),null}},makeOptionsFor=function(r){return{expected:"an array of arrays, an array of objects, or an array of strings",received:r,extraInfo:"If an array of arrays, it must have the same length as the actions registered for this worker.\nIf an array of objects, every object must containing two fields:\n* message\n* args"}},isActionOf=function(r){return function(e){return r.some(function(r){return r.message===e.message})}},warnMsg=function(r){return'WARN! An action with message "'+r.message+'" is already registered for this worker'},pushInto=function(r){return function(e){return isActionOf(r)(e)?(console.warn(warnMsg(e)),r.length):r.push(e)}},makeOptionsFor$1=function(r){return{expected:"an array of actions or an action",received:r,extraInfo:"Every action should be an object containing two fields:\n* message\n* func"}},register=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return isValid(e)(["action","actionsArray"])?Array.isArray(e)?e.reduce(function(r,e){return pushInto(r)(e),r},r).length:pushInto(r)(e):(console.error(argumentError(makeOptionsFor$1(e))),null)}},removeFrom=function(r){return function(e){var n=r.findIndex(function(r){return r.message===e});return-1===n?console.warn('WARN! Impossible to unregister action with message "'+e+'".\nIt is not a registered action for this worker.'):r.splice(n,1),r}},makeOptions=function(r){return{expected:"an array of strings or a string",received:r}},unregister=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return isValid(e)(["string","stringsArray"])?Array.isArray(e)?e.reduce(function(r,e){return removeFrom(r)(e),r},r).length:removeFrom(r)(e).length:(console.error(argumentError(makeOptions(e))),null)}},options=function(r){return{expected:"an array of objects",received:r,extraInfo:"Every action should be an object containing two fields:\n* message\n* func"}},create=function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return isValid(r)("actionsArray")?{actions:r,postMessage:post(r),postAll:postAll,register:register(r),unregister:unregister(r)}:(console.error(argumentError(options(r))),null)},createWrapper=function(){return window.Worker?window.URL.createObjectURL||window.webkitURL.createObjectURL?{create:create,run:run}:(console.error("This browser does not have URL.createObjectURL method."),null):(console.error("This browser does not support Workers."),null)},WorkerWrapper=createWrapper();module.exports=WorkerWrapper; +"use strict";function postAll(){var r=this,e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];if(isValid(e)(["arraysArray","postParamsArray","stringsArray"])){if(0===e.length)return Promise.all(this.actions.map(function(e){var n=e.message;return r.postMessage(n)}));if(e.every(function(r){return"string"==typeof r}))return Promise.all(e.map(function(e){return r.postMessage(e)}));if(e.every(function(r){return"object"===(void 0===r?"undefined":_typeof(r))&&!Array.isArray(r)}))return Promise.all(e.map(function(e){var n=e.message,t=e.args;return r.postMessage(n,t)}));if(e.every(function(r){return Array.isArray(r)})&&e.length===this.actions.length)return Promise.all(e.map(function(e,n){return r.postMessage(r.actions[n].message,e)}))}return console.error(argumentError(makeOptionsFor(e))),null}var _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(r){return typeof r}:function(r){return r&&"function"==typeof Symbol&&r.constructor===Symbol&&r!==Symbol.prototype?"symbol":typeof r},isValidObjectWith=function(r){return function(e){return!!e&&!Array.isArray(e)&&r.every(function(r){return e.hasOwnProperty(r)})}},isValidAction=function(r){return isValidObjectWith(["message","func"])(r)&&"function"==typeof r.func&&"string"==typeof r.message},isValidActionsArray=function(r){return r.every(isValidAction)},isValidPostParams=function(r){return isValidObjectWith(["message","args"])(r)&&Array.isArray(r.args)&&"string"==typeof r.message},isValidPostParamsArray=function(r){return r.every(isValidPostParams)},isValidObjectsArray=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return r.every(isValidObjectWith(e))}},testArray={actionsArray:function(r){return isValidActionsArray(r)},arraysArray:function(r){return r.every(function(r){return Array.isArray(r)})},objectsArray:function(r){return isValidObjectsArray(r)()},postParamsArray:function(r){return isValidPostParamsArray(r)},stringsArray:function(r){return r.every(function(r){return"string"==typeof r})}},isValidArg=function(r){return function(e){return"null"===e?null===r:"undefined"===e?void 0===r:"action"===e?isValidAction(r):Array.isArray(r)?!("array"!==e&&!testArray[e])&&("array"===e||testArray[e](r)):!!r&&(void 0===r?"undefined":_typeof(r))===e.toString()}},isValid=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return Array.isArray(e)?e.some(function(e){return isValidArg(r)(e)}):!!isValidArg(r)(e)}},argumentError=function(r){var e=r.expected,n=void 0===e?"":e,t=r.received,o=r.extraInfo,i=void 0===o?"":o;try{return new TypeError("You should provide "+n+"\n"+i+"\nReceived: "+JSON.stringify(t))}catch(r){if(r.message.includes("Converting circular structure to JSON"))return new TypeError("You should provide "+n+"\n"+i+"\nReceived a circular structure: "+t.toString());throw r}},makeResponse=function(r){return"\n self.onmessage = function(event) {\n const args = event.data.message.args\n if (args) {\n self.postMessage(("+r+").apply(null, args))\n return close()\n }\n self.postMessage(("+r+")())\n return close()\n }\n"},createDisposableWorker=function(r){var e=window.URL||window.webkitURL;console.log(r,"response:::");var n=new Blob([r],{type:"application/javascript"}),t=e.createObjectURL(n),o=new Worker(t);return o.post=function(r){return new Promise(function(n,i){o.onmessage=function(r){e.revokeObjectURL(t),n(r.data)},o.onerror=function(r){console.error("Error: Line "+r.lineno+" in "+r.filename+": "+r.message),i(r)},o.postMessage({message:r})})},o},run=function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,e=arguments[1],n=isValid(r)("function"),t=isValid(e)(["array","undefined"]);if(n&&t){return createDisposableWorker(makeResponse(r)).post({args:e})}return n||console.error(argumentError({expected:"a function",received:r})),t||console.error(argumentError({expected:"an array",received:e})),null},warnWork=function(r){return console.warn("WARN! "+r+" is not a registered action for this worker"),r+" is not a registered action for this worker"},post=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,n=arguments[1],t=isValid(e)("string"),o=isValid(n)(["array","undefined"]);if(t&&o){var i=r.filter(function(r){var n=r.message;return JSON.stringify(n)===JSON.stringify(e)}).map(function(r){return r.func}).pop();return i?n?run(i,n):run(i):run(warnWork,[JSON.stringify(e)])}return t||console.error(argumentError({expected:"a string",received:e})),o||console.error(argumentError({expected:"an array",received:n})),null}},makeOptionsFor=function(r){return{expected:"an array of arrays, an array of objects, or an array of strings",received:r,extraInfo:"If an array of arrays, it must have the same length as the actions registered for this worker.\nIf an array of objects, every object must containing two fields:\n* message\n* args"}},isActionOf=function(r){return function(e){return r.some(function(r){return r.message===e.message})}},warnMsg=function(r){return'WARN! An action with message "'+r.message+'" is already registered for this worker'},pushInto=function(r){return function(e){return isActionOf(r)(e)?(console.warn(warnMsg(e)),r.length):r.push(e)}},makeOptionsFor$1=function(r){return{expected:"an array of actions or an action",received:r,extraInfo:"Every action should be an object containing two fields:\n* message\n* func"}},register=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return isValid(e)(["action","actionsArray"])?Array.isArray(e)?e.reduce(function(r,e){return pushInto(r)(e),r},r).length:pushInto(r)(e):(console.error(argumentError(makeOptionsFor$1(e))),null)}},removeFrom=function(r){return function(e){var n=r.findIndex(function(r){return r.message===e});return-1===n?console.warn('WARN! Impossible to unregister action with message "'+e+'".\nIt is not a registered action for this worker.'):r.splice(n,1),r}},makeOptions=function(r){return{expected:"an array of strings or a string",received:r}},unregister=function(r){return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;return isValid(e)(["string","stringsArray"])?Array.isArray(e)?e.reduce(function(r,e){return removeFrom(r)(e),r},r).length:removeFrom(r)(e).length:(console.error(argumentError(makeOptions(e))),null)}},options=function(r){return{expected:"an array of objects",received:r,extraInfo:"Every action should be an object containing two fields:\n* message\n* func"}},create=function(){var r=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];return isValid(r)("actionsArray")?{actions:r,postMessage:post(r),postAll:postAll,register:register(r),unregister:unregister(r)}:(console.error(argumentError(options(r))),null)},createWrapper=function(){return window.Worker?window.URL.createObjectURL||window.webkitURL.createObjectURL?{create:create,run:run}:(console.error("This browser does not have URL.createObjectURL method."),null):(console.error("This browser does not support Workers."),null)},WorkerWrapper=createWrapper();module.exports=WorkerWrapper; //# sourceMappingURL=sww.min.js.map diff --git a/dist/sww.min.js.map b/dist/sww.min.js.map index f1bfb4dd..6e34879a 100644 --- a/dist/sww.min.js.map +++ b/dist/sww.min.js.map @@ -1 +1 @@ -{"version":3,"file":"sww.min.js","sources":["../src/postAll.js","../src/utils.js","../src/createDisposableWorker.js","../src/run.js","../src/post.js","../src/register.js","../src/unregister.js","../src/create.js","../src/index.js"],"sourcesContent":["// import { invalidObjectsArray, isArrayOf, notArray, returnNull, wrongLength, wrongObjects } from './utils'\nimport { isValid, argumentError } from './utils'\n\nconst makeOptionsFor = arr => {\n return {\n expected: 'an array of arrays, an array of objects, or an array of strings',\n received: arr,\n extraInfo: 'If an array of arrays, ' +\n 'it must have the same length as the actions registered for this worker.\\n' +\n 'If an array of objects, every object must containing two fields:\\n* message\\n* args'\n }\n}\nexport function postAll (arr = []) {\n if (isValid(arr)(['arraysArray', 'postParamsArray', 'stringsArray'])) {\n if (arr.length === 0) return Promise.all(this.actions.map(({ message }) => this.postMessage(message)))\n\n if (arr.every(item => typeof item === 'string')) {\n return Promise.all(arr.map(msg => this.postMessage(msg)))\n }\n\n if (arr.every(item => typeof item === 'object' && !Array.isArray(item))) {\n return Promise.all(arr.map(({ message, args }) => this.postMessage(message, args)))\n }\n\n if (arr.every(item => Array.isArray(item)) && arr.length === this.actions.length) {\n return Promise.all(arr.map((args, index) => this.postMessage(this.actions[index].message, args)))\n }\n }\n\n console.error(argumentError(makeOptionsFor(arr)))\n return null\n}\n","// Argument validation\nconst isValidObjectWith = fields => obj =>\n !!obj && !Array.isArray(obj) && fields.every(field => obj.hasOwnProperty(field))\n\nconst isValidAction = obj => {\n return isValidObjectWith(['message', 'func'])(obj) &&\n typeof obj.func === 'function' && typeof obj.message === 'string'\n}\n\nconst isValidActionsArray = arr => arr.every(isValidAction)\n\nconst isValidPostParams = obj => {\n return isValidObjectWith(['message', 'args'])(obj) &&\n Array.isArray(obj.args) && typeof obj.message === 'string'\n}\n\nconst isValidPostParamsArray = arr => arr.every(isValidPostParams)\n\nconst isValidObjectsArray = arr => (fields = []) =>\n arr.every(isValidObjectWith(fields))\n\nconst testArray = {\n 'actionsArray': arr => isValidActionsArray(arr),\n 'arraysArray': arr => arr.every(item => Array.isArray(item)),\n 'objectsArray': arr => isValidObjectsArray(arr)(),\n 'postParamsArray': arr => isValidPostParamsArray(arr),\n 'stringsArray': arr => arr.every(item => typeof item === 'string')\n}\n\nconst isValidArg = arg => type => {\n if (type === 'null') return arg === null\n if (type === 'undefined') return arg === undefined\n if (type === 'action') return isValidAction(arg)\n if (Array.isArray(arg)) {\n if (type !== 'array' && !testArray[type]) return false\n if (type === 'array') return true\n return testArray[type](arg)\n }\n if (arg) return typeof arg === type.toString() // eslint-disable-line\n return false\n}\n\nconst isValid = argument => (types = null) => {\n if (Array.isArray(types)) return types.some(type => isValidArg(argument)(type))\n if (isValidArg(argument)(types)) return true\n return false\n}\n\n// Argument error builder\nconst argumentError = ({ expected = '', received, extraInfo = '' }) => {\n try {\n return new TypeError(`${'You should provide ' + expected}${'\\n' + extraInfo}${'\\nReceived: ' + JSON.stringify(received)}`)\n } catch (err) {\n if (err.message === 'Converting circular structure to JSON') {\n return new TypeError(`${'You should provide ' + expected}${'\\n' + extraInfo}${'\\nReceived a circular structure: ' + received}`)\n }\n throw err\n }\n}\n\n// Response builder\nconst makeResponse = work => `\n self.onmessage = event => {\n const args = event.data.message.args\n if (args) {\n self.postMessage((${work}).apply(null, args))\n return close()\n }\n self.postMessage((${work})())\n return close()\n }\n`\n\nexport {\n makeResponse,\n argumentError,\n isValid\n}\n","export const createDisposableWorker = response => {\n const URL = window.URL || window.webkitURL\n const blob = new Blob([response], { type: 'application/javascript' }) // eslint-disable-line\n const objectURL = URL.createObjectURL(blob)\n const worker = new Worker(objectURL) // eslint-disable-line\n worker.post = message =>\n new Promise((resolve, reject) => {\n worker.onmessage = event => {\n URL.revokeObjectURL(objectURL)\n resolve(event.data)\n }\n worker.onerror = e => {\n console.error(`Error: Line ${e.lineno} in ${e.filename}: ${e.message}`)\n reject(e)\n }\n worker.postMessage({ message })\n })\n return worker\n}\n","import { argumentError, isValid, makeResponse } from './utils'\nimport { createDisposableWorker } from './createDisposableWorker'\n\nexport const run = (work = null, args) => {\n const validWork = isValid(work)('function')\n const validArgs = isValid(args)(['array', 'undefined'])\n if (validWork && validArgs) {\n const worker = createDisposableWorker(makeResponse(work))\n return worker.post({ args })\n }\n if (!validWork) console.error(argumentError({ expected: 'a function', received: work }))\n if (!validArgs) console.error(argumentError({ expected: 'an array', received: args }))\n return null\n}\n","import { argumentError, isValid } from './utils'\nimport { run } from './run'\n\nconst warnWork = msg => {\n console.warn(`WARN! ${msg} is not a registered action for this worker`)\n return `${msg} is not a registered action for this worker`\n}\n\nexport const post = actions => (msg = null, args) => {\n const validMessage = isValid(msg)('string')\n const validArgs = isValid(args)(['array', 'undefined'])\n if (validMessage && validArgs) {\n const work = actions\n .filter(({ message }) => JSON.stringify(message) === JSON.stringify(msg))\n .map(action => action.func)\n .pop()\n\n if (!work) return run(warnWork, [JSON.stringify(msg)])\n if (args) return run(work, args)\n return run(work)\n }\n\n if (!validMessage) console.error(argumentError({ expected: 'a string', received: msg }))\n if (!validArgs) console.error(argumentError({ expected: 'an array', received: args }))\n return null\n}\n","import { argumentError, isValid } from './utils'\n\nconst isActionOf = actions => newAction =>\n actions.some(action => action.message === newAction.message)\n\nconst warnMsg = action =>\n `WARN! An action with message \"${action.message}\" is already registered for this worker`\n\nconst pushInto = actions => action => {\n if (isActionOf(actions)(action)) {\n console.warn(warnMsg(action))\n return actions.length\n }\n return actions.push(action)\n}\n\nconst makeOptionsFor = action => {\n return {\n expected: 'an array of actions or an action',\n received: action,\n extraInfo: 'Every action should be an object containing two fields:\\n* message\\n* func'\n }\n}\n\nexport const register = actions => (action = null) => {\n if (isValid(action)(['action', 'actionsArray'])) {\n if (Array.isArray(action)) {\n return action.reduce((actions, action) => {\n pushInto(actions)(action)\n return actions\n }, actions).length\n }\n\n return pushInto(actions)(action)\n }\n console.error((argumentError(makeOptionsFor(action))))\n return null\n}\n","import { argumentError, isValid } from './utils'\n\nconst removeFrom = actions => msg => {\n const index = actions.findIndex(({ message }) => message === msg)\n index === -1\n ? console.warn(`WARN! Impossible to unregister action with message \"${msg}\".\\nIt is not a registered action for this worker.`)\n : actions.splice(index, 1)\n return actions\n}\n\nconst makeOptions = msg => {\n return {\n expected: 'an array of strings or a string',\n received: msg\n }\n}\n\nexport const unregister = actions => (msg = null) => {\n if (isValid(msg)(['string', 'stringsArray'])) {\n if (Array.isArray(msg)) {\n return msg.reduce((actions, message) => {\n removeFrom(actions)(message)\n return actions\n }, actions).length\n }\n return removeFrom(actions)(msg).length\n }\n\n console.error(argumentError(makeOptions(msg)))\n return null\n}\n","import { argumentError, isValid } from './utils'\nimport { post } from './post'\nimport { postAll } from './postAll'\nimport { register } from './register'\nimport { unregister } from './unregister'\n\nconst options = actions => {\n return {\n expected: 'an array of objects',\n received: actions,\n extraInfo: 'Every action should be an object containing two fields:\\n* message\\n* func'\n }\n}\n\nexport const create = (actions = []) => {\n if (isValid(actions)('actionsArray')) {\n return {\n actions: actions,\n postMessage: post(actions),\n postAll: postAll,\n register: register(actions),\n unregister: unregister(actions)\n }\n }\n console.error(argumentError(options(actions)))\n return null\n}\n","import { create } from './create'\nimport { run } from './run'\n\nconst createWrapper = () => {\n if (!window.Worker) {\n console.error('This browser does not support Workers.')\n return null\n }\n if (!(window.URL.createObjectURL || window.webkitURL.createObjectURL)) {\n console.error('This browser does not have URL.createObjectURL method.')\n return null\n }\n return { create, run }\n}\n\nconst WorkerWrapper = createWrapper()\n\nexport default WorkerWrapper\n"],"names":["postAll","arr","isValid","length","Promise","all","this","actions","map","message","_this","postMessage","every","item","msg","Array","isArray","args","index","error","argumentError","makeOptionsFor","isValidObjectWith","obj","fields","hasOwnProperty","field","isValidAction","func","isValidActionsArray","isValidPostParams","isValidPostParamsArray","isValidObjectsArray","testArray","isValidArg","type","arg","undefined","toString","types","some","argument","expected","received","extraInfo","TypeError","JSON","stringify","err","makeResponse","work","createDisposableWorker","URL","window","webkitURL","blob","Blob","response","objectURL","createObjectURL","worker","Worker","post","resolve","reject","onmessage","revokeObjectURL","event","data","onerror","e","lineno","filename","run","validWork","validArgs","console","warnWork","warn","validMessage","filter","action","pop","isActionOf","newAction","warnMsg","pushInto","push","register","reduce","removeFrom","findIndex","splice","makeOptions","unregister","options","create","createWrapper","WorkerWrapper"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"sww.min.js","sources":["../src/postAll.js","../src/utils.js","../src/createDisposableWorker.js","../src/run.js","../src/post.js","../src/register.js","../src/unregister.js","../src/create.js","../src/index.js"],"sourcesContent":["// import { invalidObjectsArray, isArrayOf, notArray, returnNull, wrongLength, wrongObjects } from './utils'\nimport { isValid, argumentError } from './utils'\n\nconst makeOptionsFor = arr => {\n return {\n expected: 'an array of arrays, an array of objects, or an array of strings',\n received: arr,\n extraInfo: 'If an array of arrays, ' +\n 'it must have the same length as the actions registered for this worker.\\n' +\n 'If an array of objects, every object must containing two fields:\\n* message\\n* args'\n }\n}\nexport function postAll (arr = []) {\n if (isValid(arr)(['arraysArray', 'postParamsArray', 'stringsArray'])) {\n if (arr.length === 0) return Promise.all(this.actions.map(({ message }) => this.postMessage(message)))\n\n if (arr.every(item => typeof item === 'string')) {\n return Promise.all(arr.map(msg => this.postMessage(msg)))\n }\n\n if (arr.every(item => typeof item === 'object' && !Array.isArray(item))) {\n return Promise.all(arr.map(({ message, args }) => this.postMessage(message, args)))\n }\n\n if (arr.every(item => Array.isArray(item)) && arr.length === this.actions.length) {\n return Promise.all(arr.map((args, index) => this.postMessage(this.actions[index].message, args)))\n }\n }\n\n console.error(argumentError(makeOptionsFor(arr)))\n return null\n}\n","// Argument validation\nconst isValidObjectWith = fields => obj =>\n !!obj && !Array.isArray(obj) && fields.every(field => obj.hasOwnProperty(field))\n\nconst isValidAction = obj => {\n return isValidObjectWith(['message', 'func'])(obj) &&\n typeof obj.func === 'function' && typeof obj.message === 'string'\n}\n\nconst isValidActionsArray = arr => arr.every(isValidAction)\n\nconst isValidPostParams = obj => {\n return isValidObjectWith(['message', 'args'])(obj) &&\n Array.isArray(obj.args) && typeof obj.message === 'string'\n}\n\nconst isValidPostParamsArray = arr => arr.every(isValidPostParams)\n\nconst isValidObjectsArray = arr => (fields = []) =>\n arr.every(isValidObjectWith(fields))\n\nconst testArray = {\n 'actionsArray': arr => isValidActionsArray(arr),\n 'arraysArray': arr => arr.every(item => Array.isArray(item)),\n 'objectsArray': arr => isValidObjectsArray(arr)(),\n 'postParamsArray': arr => isValidPostParamsArray(arr),\n 'stringsArray': arr => arr.every(item => typeof item === 'string')\n}\n\nconst isValidArg = arg => type => {\n if (type === 'null') return arg === null\n if (type === 'undefined') return arg === undefined\n if (type === 'action') return isValidAction(arg)\n if (Array.isArray(arg)) {\n if (type !== 'array' && !testArray[type]) return false\n if (type === 'array') return true\n return testArray[type](arg)\n }\n if (arg) return typeof arg === type.toString() // eslint-disable-line\n return false\n}\n\nconst isValid = argument => (types = null) => {\n if (Array.isArray(types)) return types.some(type => isValidArg(argument)(type))\n if (isValidArg(argument)(types)) return true\n return false\n}\n\n// Argument error builder\nconst argumentError = ({ expected = '', received, extraInfo = '' }) => {\n try {\n return new TypeError(`${'You should provide ' + expected}${'\\n' + extraInfo}${'\\nReceived: ' + JSON.stringify(received)}`)\n } catch (err) {\n if (err.message.includes('Converting circular structure to JSON')) {\n return new TypeError(`${'You should provide ' + expected}${'\\n' + extraInfo}${'\\nReceived a circular structure: ' + received.toString()}`)\n }\n throw err\n }\n}\n\n// Response builder\nconst makeResponse = work => `\n self.onmessage = function(event) {\n const args = event.data.message.args\n if (args) {\n self.postMessage((${work}).apply(null, args))\n return close()\n }\n self.postMessage((${work})())\n return close()\n }\n`\n\nexport {\n makeResponse,\n argumentError,\n isValid\n}\n","export const createDisposableWorker = response => {\n const URL = window.URL || window.webkitURL\n console.log(response, 'response:::');\n const blob = new Blob([response], { type: 'application/javascript' }) // eslint-disable-line\n const objectURL = URL.createObjectURL(blob)\n const worker = new Worker(objectURL) // eslint-disable-line\n worker.post = message =>\n new Promise((resolve, reject) => {\n worker.onmessage = event => {\n URL.revokeObjectURL(objectURL)\n resolve(event.data)\n }\n worker.onerror = e => {\n console.error(`Error: Line ${e.lineno} in ${e.filename}: ${e.message}`)\n reject(e)\n }\n worker.postMessage({ message })\n })\n return worker\n}\n","import { argumentError, isValid, makeResponse } from './utils'\nimport { createDisposableWorker } from './createDisposableWorker'\n\nexport const run = (work = null, args) => {\n const validWork = isValid(work)('function')\n const validArgs = isValid(args)(['array', 'undefined'])\n if (validWork && validArgs) {\n const worker = createDisposableWorker(makeResponse(work))\n return worker.post({ args })\n }\n if (!validWork) console.error(argumentError({ expected: 'a function', received: work }))\n if (!validArgs) console.error(argumentError({ expected: 'an array', received: args }))\n return null\n}\n","import { argumentError, isValid } from './utils'\nimport { run } from './run'\n\nconst warnWork = msg => {\n console.warn(`WARN! ${msg} is not a registered action for this worker`)\n return `${msg} is not a registered action for this worker`\n}\n\nexport const post = actions => (msg = null, args) => {\n const validMessage = isValid(msg)('string')\n const validArgs = isValid(args)(['array', 'undefined'])\n if (validMessage && validArgs) {\n const work = actions\n .filter(({ message }) => JSON.stringify(message) === JSON.stringify(msg))\n .map(action => action.func)\n .pop()\n if (!work) return run(warnWork, [JSON.stringify(msg)])\n if (args) return run(work, args)\n return run(work)\n }\n\n if (!validMessage) console.error(argumentError({ expected: 'a string', received: msg }))\n if (!validArgs) console.error(argumentError({ expected: 'an array', received: args }))\n return null\n}\n","import { argumentError, isValid } from './utils'\n\nconst isActionOf = actions => newAction =>\n actions.some(action => action.message === newAction.message)\n\nconst warnMsg = action =>\n `WARN! An action with message \"${action.message}\" is already registered for this worker`\n\nconst pushInto = actions => action => {\n if (isActionOf(actions)(action)) {\n console.warn(warnMsg(action))\n return actions.length\n }\n return actions.push(action)\n}\n\nconst makeOptionsFor = action => {\n return {\n expected: 'an array of actions or an action',\n received: action,\n extraInfo: 'Every action should be an object containing two fields:\\n* message\\n* func'\n }\n}\n\nexport const register = actions => (action = null) => {\n if (isValid(action)(['action', 'actionsArray'])) {\n if (Array.isArray(action)) {\n return action.reduce((actions, action) => {\n pushInto(actions)(action)\n return actions\n }, actions).length\n }\n\n return pushInto(actions)(action)\n }\n console.error((argumentError(makeOptionsFor(action))))\n return null\n}\n","import { argumentError, isValid } from './utils'\n\nconst removeFrom = actions => msg => {\n const index = actions.findIndex(({ message }) => message === msg)\n index === -1\n ? console.warn(`WARN! Impossible to unregister action with message \"${msg}\".\\nIt is not a registered action for this worker.`)\n : actions.splice(index, 1)\n return actions\n}\n\nconst makeOptions = msg => {\n return {\n expected: 'an array of strings or a string',\n received: msg\n }\n}\n\nexport const unregister = actions => (msg = null) => {\n if (isValid(msg)(['string', 'stringsArray'])) {\n if (Array.isArray(msg)) {\n return msg.reduce((actions, message) => {\n removeFrom(actions)(message)\n return actions\n }, actions).length\n }\n return removeFrom(actions)(msg).length\n }\n\n console.error(argumentError(makeOptions(msg)))\n return null\n}\n","import { argumentError, isValid } from './utils'\nimport { post } from './post'\nimport { postAll } from './postAll'\nimport { register } from './register'\nimport { unregister } from './unregister'\n\nconst options = actions => {\n return {\n expected: 'an array of objects',\n received: actions,\n extraInfo: 'Every action should be an object containing two fields:\\n* message\\n* func'\n }\n}\n\nexport const create = (actions = []) => {\n if (isValid(actions)('actionsArray')) {\n return {\n actions: actions,\n postMessage: post(actions),\n postAll: postAll,\n register: register(actions),\n unregister: unregister(actions)\n }\n }\n console.error(argumentError(options(actions)))\n return null\n}\n","import { create } from './create'\nimport { run } from './run'\n\nconst createWrapper = () => {\n if (!window.Worker) {\n console.error('This browser does not support Workers.')\n return null\n }\n if (!(window.URL.createObjectURL || window.webkitURL.createObjectURL)) {\n console.error('This browser does not have URL.createObjectURL method.')\n return null\n }\n return { create, run }\n}\n\nconst WorkerWrapper = createWrapper()\n\nexport default WorkerWrapper\n"],"names":["postAll","arr","isValid","length","Promise","all","this","actions","map","message","_this","postMessage","every","item","msg","Array","isArray","args","index","error","argumentError","makeOptionsFor","isValidObjectWith","obj","fields","hasOwnProperty","field","isValidAction","func","isValidActionsArray","isValidPostParams","isValidPostParamsArray","isValidObjectsArray","testArray","isValidArg","type","arg","undefined","toString","types","some","argument","expected","received","extraInfo","TypeError","JSON","stringify","err","includes","makeResponse","work","createDisposableWorker","URL","window","webkitURL","log","response","blob","Blob","objectURL","createObjectURL","worker","Worker","post","resolve","reject","onmessage","revokeObjectURL","event","data","onerror","e","lineno","filename","run","validWork","validArgs","console","warnWork","warn","validMessage","filter","action","pop","isActionOf","newAction","warnMsg","pushInto","push","register","reduce","removeFrom","findIndex","splice","makeOptions","unregister","options","create","createWrapper","WorkerWrapper"],"mappings":"YAYA,SAAgBA,sBAASC,+DACnBC,QAAQD,IAAM,cAAe,kBAAmB,iBAAkB,IACjD,IAAfA,EAAIE,OAAc,MAAOC,SAAQC,IAAIC,KAAKC,QAAQC,IAAI,eAAGC,KAAAA,cAAcC,GAAKC,YAAYF,SAExFR,EAAIW,MAAM,kBAAwB,gBAATC,WACpBT,SAAQC,IAAIJ,EAAIO,IAAI,kBAAOE,GAAKC,YAAYG,SAGjDb,EAAIW,MAAM,kBAAwB,qBAATC,sBAAAA,MAAsBE,MAAMC,QAAQH,WACxDT,SAAQC,IAAIJ,EAAIO,IAAI,eAAGC,KAAAA,QAASQ,IAAAA,WAAWP,GAAKC,YAAYF,EAASQ,SAG1EhB,EAAIW,MAAM,kBAAQG,OAAMC,QAAQH,MAAUZ,EAAIE,SAAWG,KAAKC,QAAQJ,aACjEC,SAAQC,IAAIJ,EAAIO,IAAI,SAACS,EAAMC,SAAUR,GAAKC,YAAYD,EAAKH,QAAQW,GAAOT,QAASQ,qBAItFE,MAAMC,cAAcC,eAAepB,KACpC,2NC7BHqB,kBAAoB,kBAAU,qBAChCC,IAAQR,MAAMC,QAAQO,IAAQC,EAAOZ,MAAM,kBAASW,GAAIE,eAAeC,OAErEC,cAAgB,kBACbL,oBAAmB,UAAW,SAASC,IACxB,kBAAbA,GAAIK,MAA8C,gBAAhBL,GAAId,SAG3CoB,oBAAsB,kBAAO5B,GAAIW,MAAMe,gBAEvCG,kBAAoB,kBACjBR,oBAAmB,UAAW,SAASC,IAC5CR,MAAMC,QAAQO,EAAIN,OAAgC,gBAAhBM,GAAId,SAGpCsB,uBAAyB,kBAAO9B,GAAIW,MAAMkB,oBAE1CE,oBAAsB,kBAAO,eAACR,mEAClCvB,GAAIW,MAAMU,kBAAkBE,MAExBS,wBACY,kBAAOJ,qBAAoB5B,gBAC5B,kBAAOA,GAAIW,MAAM,kBAAQG,OAAMC,QAAQH,mBACtC,kBAAOmB,qBAAoB/B,sBACxB,kBAAO8B,wBAAuB9B,iBACjC,kBAAOA,GAAIW,MAAM,kBAAwB,gBAATC,OAG5CqB,WAAa,kBAAO,mBACX,SAATC,EAAgC,OAARC,EACf,cAATD,MAAqCE,KAARD,EACpB,WAATD,EAA0BR,cAAcS,GACxCrB,MAAMC,QAAQoB,KACH,UAATD,IAAqBF,UAAUE,MACtB,UAATA,GACGF,UAAUE,GAAMC,MAErBA,aAAmBA,sBAAAA,MAAQD,EAAKG,aAIhCpC,QAAU,kBAAY,eAACqC,0DAAQ,WAC/BxB,OAAMC,QAAQuB,GAAeA,EAAMC,KAAK,kBAAQN,YAAWO,GAAUN,OACrED,WAAWO,GAAUF,KAKrBnB,cAAgB,oBAAGsB,SAAAA,aAAW,KAAIC,IAAAA,aAAUC,UAAAA,aAAY,eAEnD,IAAIC,WAAa,sBAAwBH,EAAW,KAAOE,EAAY,eAAiBE,KAAKC,UAAUJ,IAC9G,MAAOK,MACHA,EAAIvC,QAAQwC,SAAS,+CAChB,IAAIJ,WAAa,sBAAwBH,EAAW,KAAOE,EAAY,oCAAsCD,EAASL,iBAEzHU,KAKJE,aAAe,gJAIKC,8EAGFA,qCCpEXC,uBAAyB,eAC9BC,GAAMC,OAAOD,KAAOC,OAAOC,kBACzBC,IAAIC,EAAU,kBAChBC,GAAO,GAAIC,OAAMF,IAAatB,KAAM,2BACpCyB,EAAYP,EAAIQ,gBAAgBH,GAChCI,EAAS,GAAIC,QAAOH,YACnBI,KAAO,kBACZ,IAAI5D,SAAQ,SAAC6D,EAASC,KACbC,UAAY,cACbC,gBAAgBR,KACZS,EAAMC,SAETC,QAAU,oBACPpD,qBAAqBqD,EAAEC,cAAaD,EAAEE,cAAaF,EAAE/D,WACtD+D,MAEF7D,aAAcF,eAElBqD,GCfIa,IAAM,cAACxB,0DAAO,KAAMlC,eACzB2D,EAAY1E,QAAQiD,GAAM,YAC1B0B,EAAY3E,QAAQe,IAAO,QAAS,iBACtC2D,GAAaC,EAAW,OACXzB,wBAAuBF,aAAaC,IACrCa,MAAO/C,eAElB2D,IAAWE,QAAQ3D,MAAMC,eAAgBsB,SAAU,aAAcC,SAAUQ,KAC3E0B,GAAWC,QAAQ3D,MAAMC,eAAgBsB,SAAU,WAAYC,SAAU1B,KACvE,MCTH8D,SAAW,2BACPC,cAAclE,iDACZA,iDAGCkD,KAAO,kBAAW,eAAClD,0DAAM,KAAMG,eACpCgE,EAAe/E,QAAQY,GAAK,UAC5B+D,EAAY3E,QAAQe,IAAO,QAAS,iBACtCgE,GAAgBJ,EAAW,IACvB1B,GAAO5C,EACV2E,OAAO,eAAGzE,KAAAA,cAAcqC,MAAKC,UAAUtC,KAAaqC,KAAKC,UAAUjC,KACnEN,IAAI,kBAAU2E,GAAOvD,OACrBwD,YACEjC,GACDlC,EAAa0D,IAAIxB,EAAMlC,GACpB0D,IAAIxB,GAFOwB,IAAII,UAAWjC,KAAKC,UAAUjC,WAK7CmE,IAAcH,QAAQ3D,MAAMC,eAAgBsB,SAAU,WAAYC,SAAU7B,KAC5E+D,GAAWC,QAAQ3D,MAAMC,eAAgBsB,SAAU,WAAYC,SAAU1B,KACvE,OJpBHI,eAAiB,4BAET,2EACApB,YACC,wLKLToF,WAAa,kBAAW,mBAC5B9E,GAAQiC,KAAK,kBAAU2C,GAAO1E,UAAY6E,EAAU7E,YAEhD8E,QAAU,mDACmBJ,EAAO1E,mDAEpC+E,SAAW,kBAAW,mBACtBH,YAAW9E,GAAS4E,YACdH,KAAKO,QAAQJ,IACd5E,EAAQJ,QAEVI,EAAQkF,KAAKN,KAGhB9D,iBAAiB,4BAET,4CACA8D,YACC,+EAIFO,SAAW,kBAAW,eAACP,0DAAS,WACvCjF,SAAQiF,IAAS,SAAU,iBACzBpE,MAAMC,QAAQmE,GACTA,EAAOQ,OAAO,SAACpF,EAAS4E,mBACpB5E,GAAS4E,GACX5E,GACNA,GAASJ,OAGPqF,SAASjF,GAAS4E,YAEnBhE,MAAOC,cAAcC,iBAAe8D,KACrC,QClCHS,WAAa,kBAAW,gBACtB1E,GAAQX,EAAQsF,UAAU,qBAAGpF,UAA0BK,WAClD,MACPgE,QAAQE,4DAA4DlE,wDACpEP,EAAQuF,OAAO5E,EAAO,GACnBX,IAGHwF,YAAc,4BAEN,2CACAjF,IAIDkF,WAAa,kBAAW,eAAClF,0DAAM,WACtCZ,SAAQY,IAAM,SAAU,iBACtBC,MAAMC,QAAQF,GACTA,EAAI6E,OAAO,SAACpF,EAASE,qBACfF,GAASE,GACbF,GACNA,GAASJ,OAEPyF,WAAWrF,GAASO,GAAKX,gBAG1BgB,MAAMC,cAAc2E,YAAYjF,KACjC,QCvBHmF,QAAU,4BAEF,+BACA1F,YACC,+EAIF2F,OAAS,cAAC3F,mEACjBL,SAAQK,GAAS,yBAERA,cACIyD,KAAKzD,WACTP,iBACC0F,SAASnF,cACPyF,WAAWzF,aAGnBY,MAAMC,cAAc6E,QAAQ1F,KAC7B,OCtBH4F,cAAgB,iBACf7C,QAAOS,OAINT,OAAOD,IAAIQ,iBAAmBP,OAAOC,UAAUM,iBAI5CqC,cAAQvB,kBAHPxD,MAAM,0DACP,eALCA,MAAM,0CACP,OASLiF,cAAgBD"} \ No newline at end of file diff --git a/src/createDisposableWorker.js b/src/createDisposableWorker.js index 0ca2bbbe..e7a3a9fd 100644 --- a/src/createDisposableWorker.js +++ b/src/createDisposableWorker.js @@ -1,4 +1,6 @@ -export const createDisposableWorker = response => { +import { CLOSE_WORKER } from './utils'; + +export const createDisposableWorker = (response, isAsyncFunc = false) => { const URL = window.URL || window.webkitURL const blob = new Blob([response], { type: 'application/javascript' }) // eslint-disable-line const objectURL = URL.createObjectURL(blob) @@ -7,7 +9,11 @@ export const createDisposableWorker = response => { new Promise((resolve, reject) => { worker.onmessage = event => { URL.revokeObjectURL(objectURL) - resolve(event.data) + if (isAsyncFunc) { + resolve({ data: event.data, close: () => worker.postMessage({ message: CLOSE_WORKER }) }) + } else { + resolve(event.data) + } } worker.onerror = e => { console.error(`Error: Line ${e.lineno} in ${e.filename}: ${e.message}`) diff --git a/src/run.js b/src/run.js index f2fe73a1..a3778c18 100644 --- a/src/run.js +++ b/src/run.js @@ -1,14 +1,14 @@ -import { argumentError, isValid, makeResponse } from './utils' +import { argumentError, isValid, isAsyncFunc, makeResponse, makeManualCloseResponse } from './utils' import { createDisposableWorker } from './createDisposableWorker' export const run = (work = null, args) => { const validWork = isValid(work)('function') const validArgs = isValid(args)(['array', 'undefined']) if (validWork && validArgs) { - const worker = createDisposableWorker(makeResponse(work)) + const worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), isAsyncFunc) : createDisposableWorker(makeResponse(work)) return worker.post({ args }) } if (!validWork) console.error(argumentError({ expected: 'a function', received: work })) if (!validArgs) console.error(argumentError({ expected: 'an array', received: args })) return null -} +} \ No newline at end of file diff --git a/src/tests/integration/config/sworker.js b/src/tests/integration/config/sworker.js index a491adfe..6913b12a 100644 --- a/src/tests/integration/config/sworker.js +++ b/src/tests/integration/config/sworker.js @@ -6,6 +6,7 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +var CLOSE_WORKER = '__CLOSE_WORKER__'; // Argument validation var isValidObjectWith = function isValidObjectWith(fields) { return function (obj) { @@ -98,7 +99,7 @@ var argumentError = function argumentError(_ref) { try { return new TypeError('' + ('You should provide ' + expected) + ('\n' + extraInfo) + ('\nReceived: ' + JSON.stringify(received))); } catch (err) { - if (err.message === 'Converting circular structure to JSON') { + if (err.message.includes('Converting circular structure to JSON')) { return new TypeError('' + ('You should provide ' + expected) + ('\n' + extraInfo) + ('\nReceived a circular structure: ' + received)); } throw err; @@ -107,10 +108,20 @@ var argumentError = function argumentError(_ref) { // Response builder var makeResponse = function makeResponse(work) { - return '\n self.onmessage = event => {\n const args = event.data.message.args\n if (args) {\n self.postMessage((' + work + ').apply(null, args))\n return close()\n }\n self.postMessage((' + work + ')())\n return close()\n }\n'; + return '\n self.onmessage = function(event) {\n const args = event.data.message.args\n if (args) {\n self.postMessage((' + work + ').apply(null, args))\n return close()\n }\n self.postMessage((' + work + ')())\n return close()\n }\n'; +}; + +var makeManualCloseResponse = function makeManualCloseResponse(work) { + return '\nself.onmessage = async function(event) {\n if(event.data.message === \'' + CLOSE_WORKER + '\'){\n return close()\n }\n\n const args = event.data.message.args\n \n if (args) {\n const msg = await (' + work + ').apply(null, args)\n self.postMessage(msg)\n }\n const msg = await (' + work + ')()\n self.postMessage(msg)\n}\n'; +}; + +var isAsyncFunc = function isAsyncFunc(func) { + return Object.prototype.toString.call(func) === "[object AsyncFunction]"; }; var createDisposableWorker = function createDisposableWorker(response) { + var isAsyncFunc$$1 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + var URL = window.URL || window.webkitURL; var blob = new Blob([response], { type: 'application/javascript' }); // eslint-disable-line var objectURL = URL.createObjectURL(blob); @@ -119,7 +130,13 @@ var createDisposableWorker = function createDisposableWorker(response) { return new Promise(function (resolve, reject) { worker.onmessage = function (event) { URL.revokeObjectURL(objectURL); - resolve(event.data); + if (isAsyncFunc$$1) { + resolve({ data: event.data, close: function close() { + return worker.postMessage({ message: CLOSE_WORKER }); + } }); + } else { + resolve(event.data); + } }; worker.onerror = function (e) { console.error('Error: Line ' + e.lineno + ' in ' + e.filename + ': ' + e.message); @@ -138,7 +155,7 @@ var run = function run() { var validWork = isValid(work)('function'); var validArgs = isValid(args)(['array', 'undefined']); if (validWork && validArgs) { - var worker = createDisposableWorker(makeResponse(work)); + var worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), isAsyncFunc) : createDisposableWorker(makeResponse(work)); return worker.post({ args: args }); } if (!validWork) console.error(argumentError({ expected: 'a function', received: work })); diff --git a/src/tests/integration/config/tests.js b/src/tests/integration/config/tests.js index cda6e4f7..9ef099d7 100644 --- a/src/tests/integration/config/tests.js +++ b/src/tests/integration/config/tests.js @@ -23,7 +23,7 @@ const postAllTests = { } } ]), - t1 () { + t1() { return this.worker.postAll() .then(result => { resultEl.innerHTML = stringify(result) @@ -31,7 +31,7 @@ const postAllTests = { }) .catch(err => err) }, - t2 () { + t2() { return this.worker.postAll(['a']) .then(result => { resultEl.innerHTML = stringify(result) @@ -39,7 +39,7 @@ const postAllTests = { }) .catch(err => err) }, - t3 () { + t3() { return this.worker.postAll(['a', 'b']) .then(result => { resultEl.innerHTML = stringify(result) @@ -47,7 +47,7 @@ const postAllTests = { }) .catch(err => err) }, - t4 () { + t4() { return this.worker.postAll([{ message: 'a', args: [] }]) .then(result => { resultEl.innerHTML = stringify(result) @@ -55,7 +55,7 @@ const postAllTests = { }) .catch(err => err) }, - t5 () { + t5() { return this.worker.postAll([ { message: 'a', args: [] }, { message: 'b', args: [] } @@ -66,7 +66,7 @@ const postAllTests = { }) .catch(err => err) }, - t6 () { + t6() { return this.worker.postAll([[null], [null], [null], [null]]) .then(result => { console.log(result) @@ -75,7 +75,7 @@ const postAllTests = { }) .catch(err => err) }, - t7 () { + t7() { return this.worker.postAll([[], ['ignored', 'args'], ['something'], ['overwrited']]) .then(result => { resultEl.innerHTML = stringify(result) @@ -83,7 +83,7 @@ const postAllTests = { }) .catch(err => err) }, - t8 () { + t8() { return this.worker.postAll([[], ['ignored', 'args'], ['something'], []]) .then(result => { resultEl.innerHTML = stringify(result) @@ -94,14 +94,14 @@ const postAllTests = { } const unregisterTests = { - t1 () { + t1() { const worker = WorkerWrapper.create([{ message: 'a', func: () => 'a' }]) const result = worker.unregister('a') resultEl.innerHTML = result return result }, - t2 () { + t2() { const worker = WorkerWrapper.create([ { message: 'a', func: () => 'a' }, { message: 'b', func: () => 'b' } @@ -111,14 +111,14 @@ const unregisterTests = { return result }, - t3 () { + t3() { const worker = WorkerWrapper.create([]) const result = worker.unregister('a') resultEl.innerHTML = result return result }, - t4 () { + t4() { const worker = WorkerWrapper.create([ { message: 'c', func: () => 'c' }, { message: 'd', func: () => 'd' } @@ -128,7 +128,7 @@ const unregisterTests = { return result }, - t5 () { + t5() { const worker = WorkerWrapper.create([ { message: 'a', func: () => 'a' }, { message: 'b', func: () => 'b' }, @@ -141,14 +141,14 @@ const unregisterTests = { } const registerTests = { - t1 () { + t1() { const worker = WorkerWrapper.create([]) const result = worker.register({ message: 'a', func: () => 'a' }) resultEl.innerHTML = result return result }, - t2 () { + t2() { const worker = WorkerWrapper.create([]) const result = worker.register([ { message: 'a', func: () => 'a' }, @@ -158,14 +158,14 @@ const registerTests = { return result }, - t3 () { + t3() { const worker = WorkerWrapper.create([{ message: 'a', func: () => 'a' }]) const result = worker.register({ message: 'a', func: () => 'a' }) resultEl.innerHTML = result return result }, - t4 () { + t4() { const worker = WorkerWrapper.create([ { message: 'a', func: () => 'a' }, { message: 'b', func: () => 'b' } @@ -178,7 +178,7 @@ const registerTests = { return result }, - t5 () { + t5() { const worker = WorkerWrapper.create([ { message: 'a', func: () => 'a' }, { message: 'b', func: () => 'b' } @@ -194,18 +194,20 @@ const registerTests = { } const postMessageTests = { - t1 () { - const worker = WorkerWrapper.create([{message: 'a', func: () => 'a'}]) + t1() { + const worker = WorkerWrapper.create([{ + message: 'a', func: () => 'a' + }]) return worker.postMessage('a') .then(result => { - resultEl.innerHTML = result + resultEl.innerHTML = result; return result }) .catch(err => err) }, - t2 () { - const worker = WorkerWrapper.create([{message: 'a', func: (arg) => `${arg}`}]) + t2() { + const worker = WorkerWrapper.create([{ message: 'a', func: (arg) => `${arg}` }]) return worker.postMessage('a') .then(result => { resultEl.innerHTML = result @@ -214,7 +216,7 @@ const postMessageTests = { .catch(err => err) }, - t3 () { + t3() { const worker = WorkerWrapper.create([{ message: 'a', func: function (arg) { @@ -229,8 +231,8 @@ const postMessageTests = { .catch(err => err) }, - t4 () { - const worker = WorkerWrapper.create([{message: 'a', func: () => 'a'}]) + t4() { + const worker = WorkerWrapper.create([{ message: 'a', func: () => 'a' }]) return worker.postMessage('a', ['Ignored', 'arguments']) .then(result => { resultEl.innerHTML = result @@ -239,8 +241,8 @@ const postMessageTests = { .catch(err => err) }, - t5 () { - const worker = WorkerWrapper.create([{message: 'a', func: (arg) => `${arg}`}]) + t5() { + const worker = WorkerWrapper.create([{ message: 'a', func: (arg) => `${arg}` }]) return worker.postMessage('a', ['a']) .then(result => { resultEl.innerHTML = result @@ -249,7 +251,7 @@ const postMessageTests = { .catch(err => err) }, - t6 () { + t6() { const worker = WorkerWrapper.create([{ message: 'a', func: function (arg) { @@ -264,8 +266,8 @@ const postMessageTests = { .catch(err => err) }, - t7 () { - const worker = WorkerWrapper.create([{message: 'a', func: () => 'a'}]) + t7() { + const worker = WorkerWrapper.create([{ message: 'a', func: () => 'a' }]) return worker.postMessage('Darth Vader') .then(result => { resultEl.innerHTML = result @@ -277,7 +279,7 @@ const postMessageTests = { const runTests = { // Run without args and without arrow function - t1 () { + t1() { return WorkerWrapper.run(function () { return 'Run without args and without arrow function' }) .then(result => { resultEl.innerHTML = result @@ -287,7 +289,7 @@ const runTests = { }, // Run without args and with arrow function - t2 () { + t2() { return WorkerWrapper.run(() => 'Run without args and with arrow function') .then(result => { resultEl.innerHTML = result @@ -297,7 +299,7 @@ const runTests = { }, // Run with args and without arrow function - t3 () { + t3() { return WorkerWrapper.run(function (arg1, arg2) { return `Run ${arg1} and ${arg2}` }, ['with args', 'without arrow function']) .then(result => { resultEl.innerHTML = result @@ -307,7 +309,7 @@ const runTests = { }, // Run with args and with arrow function - t4 () { + t4() { return WorkerWrapper.run((arg1, arg2) => `Run ${arg1} and ${arg2}`, ['with args', 'with arrow function']) .then(result => { resultEl.innerHTML = result @@ -317,7 +319,7 @@ const runTests = { }, // Run without args but expecting them - t5 () { + t5() { return WorkerWrapper.run((arg1, arg2) => `Run ${arg1} and ${arg2}`) .then(result => { resultEl.innerHTML = result @@ -327,7 +329,7 @@ const runTests = { }, // Run without args but with default arg value - t6 () { + t6() { /** REASON FOR THAT UGLY FUNCTION (TIP: I CAN'T USE DEFAULT VALUES FOR ARGUMENTS IN THESE TESTS!): * I don't know why, but it is not possible to use default arguments in this test, like: * (arg1 = 'default arg value') => `Run with ${arg1}` @@ -368,12 +370,40 @@ const runTests = { }, // Run without args but without default - t7 () { + t7() { return WorkerWrapper.run((arg1) => `Run with ${arg1}`, undefined) .then(result => { - resultEl.innerHTML = result + resultEl.innerHTML = result.data return result }) .catch(err => err) } } + + +const asyncPostMessageTests = { + t1() { + const worker = WorkerWrapper.create([{ + message: 'a', func: async (args) => { + setInterval(() => { + console.log('hello async func'); + }, 1000); + const p = new Promise((resolve) => { + setTimeout(() => { + resolve(args) + }, 3000); + }); + return await p; + } + }]) + return worker.postMessage('a', ['async func']) + .then(result => { + resultEl.innerHTML = result.data; + setTimeout(() => { + console.log('work1 closed'); + result.close() + }, 5000); + }) + .catch(err => err) + } +} \ No newline at end of file diff --git a/src/utils.js b/src/utils.js index 89f18edf..f7f2e638 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,3 +1,4 @@ +const CLOSE_WORKER = '__CLOSE_WORKER__'; // Argument validation const isValidObjectWith = fields => obj => !!obj && !Array.isArray(obj) && fields.every(field => obj.hasOwnProperty(field)) @@ -51,7 +52,7 @@ const argumentError = ({ expected = '', received, extraInfo = '' }) => { try { return new TypeError(`${'You should provide ' + expected}${'\n' + extraInfo}${'\nReceived: ' + JSON.stringify(received)}`) } catch (err) { - if (err.message === 'Converting circular structure to JSON') { + if (err.message.includes('Converting circular structure to JSON')) { return new TypeError(`${'You should provide ' + expected}${'\n' + extraInfo}${'\nReceived a circular structure: ' + received}`) } throw err @@ -71,8 +72,30 @@ const makeResponse = work => ` } ` +const makeManualCloseResponse = work => ` +self.onmessage = async function(event) { + if(event.data.message === '${CLOSE_WORKER}'){ + return close() + } + + const args = event.data.message.args + + if (args) { + const msg = await (${work}).apply(null, args) + self.postMessage(msg) + } + const msg = await (${work})() + self.postMessage(msg) +} +` + +const isAsyncFunc = (func) => Object.prototype.toString.call(func) === "[object AsyncFunction]" + export { makeResponse, + isAsyncFunc, + makeManualCloseResponse, argumentError, - isValid + isValid, + CLOSE_WORKER } From 25eb57365e3ccf152237c78a19b3492e6be22ca1 Mon Sep 17 00:00:00 2001 From: yuanpengfei03 Date: Wed, 9 Feb 2022 18:59:33 +0800 Subject: [PATCH 2/3] fix(run): fix transfer params bug --- src/run.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/run.js b/src/run.js index a3778c18..e8f4cda1 100644 --- a/src/run.js +++ b/src/run.js @@ -5,7 +5,7 @@ export const run = (work = null, args) => { const validWork = isValid(work)('function') const validArgs = isValid(args)(['array', 'undefined']) if (validWork && validArgs) { - const worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), isAsyncFunc) : createDisposableWorker(makeResponse(work)) + const worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), true) : createDisposableWorker(makeResponse(work)) return worker.post({ args }) } if (!validWork) console.error(argumentError({ expected: 'a function', received: work })) From ead9c932b6452c5c2421808bec473332efea6314 Mon Sep 17 00:00:00 2001 From: yuanpengfei03 Date: Wed, 9 Feb 2022 19:00:04 +0800 Subject: [PATCH 3/3] fix(run): fix transfer params bug and build --- src/tests/integration/config/sworker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/integration/config/sworker.js b/src/tests/integration/config/sworker.js index 6913b12a..039edc2c 100644 --- a/src/tests/integration/config/sworker.js +++ b/src/tests/integration/config/sworker.js @@ -155,7 +155,7 @@ var run = function run() { var validWork = isValid(work)('function'); var validArgs = isValid(args)(['array', 'undefined']); if (validWork && validArgs) { - var worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), isAsyncFunc) : createDisposableWorker(makeResponse(work)); + var worker = isAsyncFunc(work) ? createDisposableWorker(makeManualCloseResponse(work), true) : createDisposableWorker(makeResponse(work)); return worker.post({ args: args }); } if (!validWork) console.error(argumentError({ expected: 'a function', received: work }));