troika-worker-utils
Advanced tools
Comparing version 0.22.0 to 0.23.0
import {defineWorkerModule} from '../src/WorkerModules.js' | ||
import ThenableWorkerModule from '../src/ThenableWorkerModule.js' | ||
require('./_jsdom-worker.js') | ||
// Sometimes URL.$$objects hangs around between suites which prevents jsdom-worker | ||
// from attaching its custom `fetch` override that knows how to read fake blob URLs | ||
delete global.URL.$$objects | ||
require('jsdom-worker') | ||
beforeEach(() => { | ||
@@ -11,0 +7,0 @@ // Functions that are run in the worker can place breadcrumbs in this object that |
import {defineWorkerModule} from '../src/WorkerModules.js' | ||
require('./_jsdom-worker.js') | ||
// Sometimes URL.$$objects hangs around between suites which prevents jsdom-worker | ||
// from attaching its custom `fetch` override that knows how to read fake blob URLs | ||
delete global.URL.$$objects | ||
require('jsdom-worker') | ||
beforeEach(() => { | ||
@@ -10,0 +5,0 @@ // Functions that are run in the worker can place breadcrumbs in this object that |
@@ -6,2 +6,13 @@ # Change Log | ||
# [0.23.0](https://github.com/protectwise/troika/compare/v0.22.0...v0.23.0) (2020-04-16) | ||
### Features | ||
* **troika-worker-modules:** improve rehydration of functions in worker ([8f63090](https://github.com/protectwise/troika/commit/8f63090a5ad4fa3569faeade8e5c532ebfb065c5)), closes [#31](https://github.com/protectwise/troika/issues/31) | ||
# [0.22.0](https://github.com/protectwise/troika/compare/v0.21.0...v0.22.0) (2020-04-02) | ||
@@ -8,0 +19,0 @@ |
@@ -179,3 +179,3 @@ /** | ||
// Handle messages for registering a module | ||
function registerModule({id, dependencies=[], init=function(){}, getTransferables=null}, callback) { | ||
function registerModule({id, name, dependencies=[], init=function(){}, getTransferables=null}, callback) { | ||
// Only register once | ||
@@ -197,9 +197,14 @@ if (modules[id]) return | ||
// Rehydrate functions | ||
init = new Function(`return (${init})`)(); | ||
init = rehydrate(`<${name}>.init`, init); | ||
if (getTransferables) { | ||
getTransferables = new Function(`return (${getTransferables})`)(); | ||
getTransferables = rehydrate(`<${name}>.getTransferables`, getTransferables); | ||
} | ||
// Initialize the module and store its value | ||
const value = init(...dependencies); | ||
let value = null; | ||
if (typeof init === 'function') { | ||
value = init(...dependencies); | ||
} else { | ||
console.error('worker module init function failed to rehydrate'); | ||
} | ||
modules[id] = { | ||
@@ -248,2 +253,21 @@ id, | ||
function rehydrate(name, str) { | ||
let result = void 0; | ||
self.troikaDefine = r => result = r; | ||
let url = URL.createObjectURL( | ||
new Blob( | ||
[`/** ${name.replace(/\*/g, '')} **/\n\ntroikaDefine(\n${str}\n)`], | ||
{type: 'application/javascript'} | ||
) | ||
); | ||
try { | ||
importScripts(url); | ||
} catch(err) { | ||
console.error(err); | ||
} | ||
URL.revokeObjectURL(url); | ||
delete self.troikaDefine; | ||
return result | ||
} | ||
// Handler for all messages within the worker | ||
@@ -301,2 +325,3 @@ self.addEventListener('message', e => { | ||
let _messageId = 0; | ||
let _allowInitAsString = false; | ||
const workers = Object.create(null); | ||
@@ -330,2 +355,4 @@ const openRequests = Object.create(null); | ||
* in the response that can/should be transfered rather than cloned. | ||
* @param {string} [options.name] - A descriptive name for this module; this can be useful for | ||
* debugging but is not currently used for anything else. | ||
* @param {string} [options.workerId] - By default all modules will run in the same dedicated worker, | ||
@@ -339,3 +366,3 @@ * but if you want to use multiple workers you can pass a `workerId` to indicate a specific | ||
function defineWorkerModule(options) { | ||
if (!options || typeof options.init !== 'function') { | ||
if ((!options || typeof options.init !== 'function') && !_allowInitAsString) { | ||
throw new Error('requires `options.init` function') | ||
@@ -348,2 +375,3 @@ } | ||
const id = `workerModule${++_workerModuleId}`; | ||
const name = options.name || id; | ||
let registrationThenable = null; | ||
@@ -354,6 +382,9 @@ | ||
if (typeof dep === 'function' && !dep.workerModuleData) { | ||
_allowInitAsString = true; | ||
dep = defineWorkerModule({ | ||
workerId, | ||
init: new Function(`return function(){return (${stringifyFunction(dep)})}`)() | ||
name: `<${name}> function dependency: ${dep.name}`, | ||
init: `function(){return (\n${stringifyFunction(dep)}\n)}` | ||
}); | ||
_allowInitAsString = false; | ||
} | ||
@@ -385,2 +416,3 @@ // Grab postable data for worker modules | ||
id, | ||
name, | ||
dependencies, | ||
@@ -416,3 +448,6 @@ init: stringifyFunction(init), | ||
URL.createObjectURL( | ||
new Blob([`;(${bootstrap})()`], {type: 'application/javascript'}) | ||
new Blob( | ||
[`/** Worker Module Bootstrap: ${workerId.replace(/\*/g, '')} **/\n\n;(${bootstrap})()`], | ||
{type: 'application/javascript'} | ||
) | ||
) | ||
@@ -466,2 +501,3 @@ ); | ||
var ThenableWorkerModule = defineWorkerModule({ | ||
name: 'Thenable', | ||
dependencies: [Thenable], | ||
@@ -468,0 +504,0 @@ init: function(Thenable) { |
@@ -190,2 +190,3 @@ (function (global, factory) { | ||
var id = ref.id; | ||
var name = ref.name; | ||
var dependencies = ref.dependencies; if ( dependencies === void 0 ) dependencies = []; | ||
@@ -211,9 +212,14 @@ var init = ref.init; if ( init === void 0 ) init = function(){}; | ||
// Rehydrate functions | ||
init = new Function(("return (" + init + ")"))(); | ||
init = rehydrate(("<" + name + ">.init"), init); | ||
if (getTransferables) { | ||
getTransferables = new Function(("return (" + getTransferables + ")"))(); | ||
getTransferables = rehydrate(("<" + name + ">.getTransferables"), getTransferables); | ||
} | ||
// Initialize the module and store its value | ||
var value = init.apply(void 0, dependencies); | ||
var value = null; | ||
if (typeof init === 'function') { | ||
value = init.apply(void 0, dependencies); | ||
} else { | ||
console.error('worker module init function failed to rehydrate'); | ||
} | ||
modules[id] = { | ||
@@ -266,2 +272,21 @@ id: id, | ||
function rehydrate(name, str) { | ||
var result = void 0; | ||
self.troikaDefine = function (r) { return result = r; }; | ||
var url = URL.createObjectURL( | ||
new Blob( | ||
[("/** " + (name.replace(/\*/g, '')) + " **/\n\ntroikaDefine(\n" + str + "\n)")], | ||
{type: 'application/javascript'} | ||
) | ||
); | ||
try { | ||
importScripts(url); | ||
} catch(err) { | ||
console.error(err); | ||
} | ||
URL.revokeObjectURL(url); | ||
delete self.troikaDefine; | ||
return result | ||
} | ||
// Handler for all messages within the worker | ||
@@ -322,2 +347,3 @@ self.addEventListener('message', function (e) { | ||
var _messageId = 0; | ||
var _allowInitAsString = false; | ||
var workers = Object.create(null); | ||
@@ -351,2 +377,4 @@ var openRequests = Object.create(null); | ||
* in the response that can/should be transfered rather than cloned. | ||
* @param {string} [options.name] - A descriptive name for this module; this can be useful for | ||
* debugging but is not currently used for anything else. | ||
* @param {string} [options.workerId] - By default all modules will run in the same dedicated worker, | ||
@@ -360,3 +388,3 @@ * but if you want to use multiple workers you can pass a `workerId` to indicate a specific | ||
function defineWorkerModule(options) { | ||
if (!options || typeof options.init !== 'function') { | ||
if ((!options || typeof options.init !== 'function') && !_allowInitAsString) { | ||
throw new Error('requires `options.init` function') | ||
@@ -372,2 +400,3 @@ } | ||
var id = "workerModule" + (++_workerModuleId); | ||
var name = options.name || id; | ||
var registrationThenable = null; | ||
@@ -378,6 +407,9 @@ | ||
if (typeof dep === 'function' && !dep.workerModuleData) { | ||
_allowInitAsString = true; | ||
dep = defineWorkerModule({ | ||
workerId: workerId, | ||
init: new Function(("return function(){return (" + (stringifyFunction(dep)) + ")}"))() | ||
name: ("<" + name + "> function dependency: " + (dep.name)), | ||
init: ("function(){return (\n" + (stringifyFunction(dep)) + "\n)}") | ||
}); | ||
_allowInitAsString = false; | ||
} | ||
@@ -414,2 +446,3 @@ // Grab postable data for worker modules | ||
id: id, | ||
name: name, | ||
dependencies: dependencies, | ||
@@ -445,3 +478,6 @@ init: stringifyFunction(init), | ||
URL.createObjectURL( | ||
new Blob([(";(" + bootstrap + ")()")], {type: 'application/javascript'}) | ||
new Blob( | ||
[("/** Worker Module Bootstrap: " + (workerId.replace(/\*/g, '')) + " **/\n\n;(" + bootstrap + ")()")], | ||
{type: 'application/javascript'} | ||
) | ||
) | ||
@@ -495,2 +531,3 @@ ); | ||
var ThenableWorkerModule = defineWorkerModule({ | ||
name: 'Thenable', | ||
dependencies: [Thenable], | ||
@@ -497,0 +534,0 @@ init: function(Thenable) { |
@@ -1,9 +0,10 @@ | ||
'use strict';(function(l,q){"object"===typeof exports&&"undefined"!==typeof module?q(exports):"function"===typeof define&&define.amd?define(["exports"],q):(l=l||self,q(l.troika_worker_utils={}))})(this,function(l){function q(){function c(b,e){u++;var t=0;try{e===r&&h();var l=0<b&&a(e);l?l.call(e,f(function(a){t++;c(1,a)}),f(function(a){t++;c(-1,a)})):(k=b,p=e,g||(setTimeout(d,0),g=1))}catch(z){k||t||c(-1,z)}}function d(){var a=e;g=0;e=[];a.forEach(b)}function b(a){a()}function a(a){a=a&&(m(a)||"object"=== | ||
typeof a)&&a.then;return m(a)&&a}function f(a){var c=0;return function(){for(var f=[],g=arguments.length;g--;)f[g]=arguments[g];c++||a.apply(this,f)}}function h(){throw new TypeError("Chaining cycle detected");}var k=0,e=[],p,g=0,u=0,l=f(function(a){u||c(1,a)}),n=f(function(a){u||c(-1,a)}),m=function(a){return"function"===typeof a},r={then:function(c,f){var b=q();e.push(function(){var g=0<k?c:f;if(m(g))try{var e=g(p);e===b&&h();var d=a(e);d?d.call(e,b.resolve,b.reject):b.resolve(e)}catch(A){b.reject(A)}else b[0< | ||
k?"resolve":"reject"](p)});k&&!g&&(setTimeout(d,0),g=1);return b},resolve:l,reject:n};return r}function B(){var c,d,b=new Promise(function(a,b){c=a;d=b});return{then:b.then.bind(b),resolve:c,reject:d}}function C(){function c(a,f){var h=a.id,k=a.dependencies;void 0===k&&(k=[]);var e=a.init;void 0===e&&(e=function(){});a=a.getTransferables;void 0===a&&(a=null);if(!b[h])try{k=k.map(function(a){a&&a.isWorkerModule&&(c(a,function(a){if(a instanceof Error)throw a;}),a=b[a.id].value);return a});e=(new Function("return ("+ | ||
e+")"))();a&&(a=(new Function("return ("+a+")"))());var d=e.apply(void 0,k);b[h]={id:h,value:d,getTransferables:a};f(d)}catch(g){g&&g.noLog||console.error(g),f(g)}}function d(a,c){function f(a){try{var f=b[e].getTransferables&&b[e].getTransferables(a);f&&Array.isArray(f)&&f.length||(f=void 0);c(a,f)}catch(w){console.error(w),c(w)}}var d,e=a.id;a=a.args;b[e]&&"function"===typeof b[e].value||c(Error("Worker module "+e+": not found or its 'init' did not return a function"));try{var p=(d=b[e]).value.apply(d, | ||
a);p&&"function"===typeof p.then?p.then(f,function(a){return c(a instanceof Error?a:Error(""+a))}):f(p)}catch(g){c(g)}}var b=Object.create(null);self.addEventListener("message",function(a){var b=a.data,h=b.messageId;a=b.action;b=b.data;try{"registerModule"===a&&c(b,function(a){a instanceof Error?postMessage({messageId:h,success:!1,error:a.message}):postMessage({messageId:h,success:!0,result:{isCallable:"function"===typeof a}})}),"callModule"===a&&d(b,function(a,b){a instanceof Error?postMessage({messageId:h, | ||
success:!1,error:a.message}):postMessage({messageId:h,success:!0,result:a},b||void 0)})}catch(k){postMessage({messageId:h,success:!1,error:k.stack})}})}function r(c){function d(){for(var a=[],b=arguments.length;b--;)a[b]=arguments[b];e||(e=x(h,"registerModule",d.workerModuleData));return e.then(function(b){if(b.isCallable)return x(h,"callModule",{id:k,args:a});throw Error("Worker module function was called but `init` did not return a callable function");})}if(!c||"function"!==typeof c.init)throw Error("requires `options.init` function"); | ||
var b=c.dependencies,a=c.init,f=c.getTransferables,h=c.workerId;null==h&&(h="#default");var k="workerModule"+ ++D,e=null;b=b&&b.map(function(a){"function"!==typeof a||a.workerModuleData||(a=r({workerId:h,init:(new Function("return function(){return ("+m(a)+")}"))()}));a&&a.workerModuleData&&(a=a.workerModuleData);return a});d.workerModuleData={isWorkerModule:!0,id:k,dependencies:b,init:m(a),getTransferables:f&&m(f)};return d}function m(c){c=c.toString();!/^function/.test(c)&&/^\w+\s*\(/.test(c)&& | ||
(c="function "+c);return c}function E(c){var d=y[c];d||(d=m(C),d=y[c]=new Worker(URL.createObjectURL(new Blob([";("+d+")()"],{type:"application/javascript"}))),d.onmessage=function(b){b=b.data;var a=b.messageId,c=n[a];if(!c)throw Error("WorkerModule response with empty or unknown messageId");delete n[a];n.count--;c(b)});return d}function x(c,d,b){var a=v(),f=++F;n[f]=function(b){b.success?a.resolve(b.result):a.reject(Error("Error in worker "+d+" call: "+b.error))};n._count++;1E3<n.count&&console.warn("Large number of open WorkerModule requests, some may not be returning"); | ||
E(c).postMessage({messageId:f,action:d,data:b});return a}var v="function"===typeof Promise?B:q,D=0,F=0,y=Object.create(null),n=Object.create(null);n._count=0;var G=r({dependencies:[v],init:function(c){return c}});l.Thenable=v;l.ThenableWorkerModule=G;l.defineWorkerModule=r;l.stringifyFunction=m;Object.defineProperty(l,"__esModule",{value:!0})}) | ||
'use strict';(function(n,r){"object"===typeof exports&&"undefined"!==typeof module?r(exports):"function"===typeof define&&define.amd?define(["exports"],r):(n=n||self,r(n.troika_worker_utils={}))})(this,function(n){function r(){function b(e,c){h++;var u=0;try{c===q&&k();var t=0<e&&f(c);t?t.call(c,a(function(a){u++;b(1,a)}),a(function(a){u++;b(-1,a)})):(l=e,m=c,d||(setTimeout(g,0),d=1))}catch(B){l||u||b(-1,B)}}function g(){var a=e;d=0;e=[];a.forEach(c)}function c(a){a()}function f(a){a=a&&(p(a)||"object"=== | ||
typeof a)&&a.then;return p(a)&&a}function a(a){var b=0;return function(){for(var e=[],d=arguments.length;d--;)e[d]=arguments[d];b++||a.apply(this,e)}}function k(){throw new TypeError("Chaining cycle detected");}var l=0,e=[],m,d=0,h=0,t=a(function(a){h||b(1,a)}),n=a(function(a){h||b(-1,a)}),p=function(a){return"function"===typeof a},q={then:function(a,b){var h=r();e.push(function(){var e=0<l?a:b;if(p(e))try{var d=e(m);d===h&&k();var c=f(d);c?c.call(d,h.resolve,h.reject):h.resolve(d)}catch(C){h.reject(C)}else h[0< | ||
l?"resolve":"reject"](m)});l&&!d&&(setTimeout(g,0),d=1);return h},resolve:t,reject:n};return q}function D(){var b,g,c=new Promise(function(c,a){b=c;g=a});return{then:c.then.bind(c),resolve:b,reject:g}}function E(){function b(a,k){var l=a.id,e=a.name,m=a.dependencies;void 0===m&&(m=[]);var d=a.init;void 0===d&&(d=function(){});a=a.getTransferables;void 0===a&&(a=null);if(!f[l])try{m=m.map(function(a){a&&a.isWorkerModule&&(b(a,function(a){if(a instanceof Error)throw a;}),a=f[a.id].value);return a}), | ||
d=c("<"+e+">.init",d),a&&(a=c("<"+e+">.getTransferables",a)),e=null,"function"===typeof d?e=d.apply(void 0,m):console.error("worker module init function failed to rehydrate"),f[l]={id:l,value:e,getTransferables:a},k(e)}catch(h){h&&h.noLog||console.error(h),k(h)}}function g(a,b){function c(a){try{var d=f[k].getTransferables&&f[k].getTransferables(a);d&&Array.isArray(d)&&d.length||(d=void 0);b(a,d)}catch(y){console.error(y),b(y)}}var e,k=a.id;a=a.args;f[k]&&"function"===typeof f[k].value||b(Error("Worker module "+ | ||
k+": not found or its 'init' did not return a function"));try{var d=(e=f[k]).value.apply(e,a);d&&"function"===typeof d.then?d.then(c,function(a){return b(a instanceof Error?a:Error(""+a))}):c(d)}catch(h){b(h)}}function c(a,b){var c=void 0;self.troikaDefine=function(a){return c=a};a=URL.createObjectURL(new Blob(["/** "+a.replace(/\*/g,"")+" **/\n\ntroikaDefine(\n"+b+"\n)"],{type:"application/javascript"}));try{importScripts(a)}catch(e){console.error(e)}URL.revokeObjectURL(a);delete self.troikaDefine; | ||
return c}var f=Object.create(null);self.addEventListener("message",function(a){var c=a.data,f=c.messageId;a=c.action;c=c.data;try{"registerModule"===a&&b(c,function(a){a instanceof Error?postMessage({messageId:f,success:!1,error:a.message}):postMessage({messageId:f,success:!0,result:{isCallable:"function"===typeof a}})}),"callModule"===a&&g(c,function(a,b){a instanceof Error?postMessage({messageId:f,success:!1,error:a.message}):postMessage({messageId:f,success:!0,result:a},b||void 0)})}catch(e){postMessage({messageId:f, | ||
success:!1,error:e.stack})}})}function v(b){function g(){for(var a=[],b=arguments.length;b--;)a[b]=arguments[b];m||(m=z(k,"registerModule",g.workerModuleData));return m.then(function(b){if(b.isCallable)return z(k,"callModule",{id:l,args:a});throw Error("Worker module function was called but `init` did not return a callable function");})}if(!(b&&"function"===typeof b.init||w))throw Error("requires `options.init` function");var c=b.dependencies,f=b.init,a=b.getTransferables,k=b.workerId;null==k&&(k= | ||
"#default");var l="workerModule"+ ++F,e=b.name||l,m=null;c=c&&c.map(function(a){"function"!==typeof a||a.workerModuleData||(w=!0,a=v({workerId:k,name:"<"+e+"> function dependency: "+a.name,init:"function(){return (\n"+q(a)+"\n)}"}),w=!1);a&&a.workerModuleData&&(a=a.workerModuleData);return a});g.workerModuleData={isWorkerModule:!0,id:l,name:e,dependencies:c,init:q(f),getTransferables:a&&q(a)};return g}function q(b){b=b.toString();!/^function/.test(b)&&/^\w+\s*\(/.test(b)&&(b="function "+b);return b} | ||
function G(b){var g=A[b];g||(g=q(E),g=A[b]=new Worker(URL.createObjectURL(new Blob(["/** Worker Module Bootstrap: "+b.replace(/\*/g,"")+" **/\n\n;("+g+")()"],{type:"application/javascript"}))),g.onmessage=function(b){b=b.data;var c=b.messageId,a=p[c];if(!a)throw Error("WorkerModule response with empty or unknown messageId");delete p[c];p.count--;a(b)});return g}function z(b,g,c){var f=x(),a=++H;p[a]=function(a){a.success?f.resolve(a.result):f.reject(Error("Error in worker "+g+" call: "+a.error))}; | ||
p._count++;1E3<p.count&&console.warn("Large number of open WorkerModule requests, some may not be returning");G(b).postMessage({messageId:a,action:g,data:c});return f}var x="function"===typeof Promise?D:r,F=0,H=0,w=!1,A=Object.create(null),p=Object.create(null);p._count=0;var I=v({name:"Thenable",dependencies:[x],init:function(b){return b}});n.Thenable=x;n.ThenableWorkerModule=I;n.defineWorkerModule=v;n.stringifyFunction=q;Object.defineProperty(n,"__esModule",{value:!0})}) |
{ | ||
"name": "troika-worker-utils", | ||
"version": "0.22.0", | ||
"version": "0.23.0", | ||
"description": "Utilities for executing code in Web Workers", | ||
@@ -17,3 +17,3 @@ "author": "Jason Johnston <jason.johnston@protectwise.com>", | ||
"module:src": "src/index.js", | ||
"gitHead": "c3ff4002b468f00bc7c4775578e0ad9d950ff52d" | ||
"gitHead": "c58983745861fe3fc4a5ec15a24addce603061c9" | ||
} |
@@ -10,2 +10,3 @@ import Thenable from './Thenable.js' | ||
export default defineWorkerModule({ | ||
name: 'Thenable', | ||
dependencies: [Thenable], | ||
@@ -12,0 +13,0 @@ init: function(Thenable) { |
@@ -9,3 +9,3 @@ /** | ||
// Handle messages for registering a module | ||
function registerModule({id, dependencies=[], init=function(){}, getTransferables=null}, callback) { | ||
function registerModule({id, name, dependencies=[], init=function(){}, getTransferables=null}, callback) { | ||
// Only register once | ||
@@ -27,9 +27,14 @@ if (modules[id]) return | ||
// Rehydrate functions | ||
init = new Function(`return (${init})`)() | ||
init = rehydrate(`<${name}>.init`, init) | ||
if (getTransferables) { | ||
getTransferables = new Function(`return (${getTransferables})`)() | ||
getTransferables = rehydrate(`<${name}>.getTransferables`, getTransferables) | ||
} | ||
// Initialize the module and store its value | ||
const value = init(...dependencies) | ||
let value = null | ||
if (typeof init === 'function') { | ||
value = init(...dependencies) | ||
} else { | ||
console.error('worker module init function failed to rehydrate') | ||
} | ||
modules[id] = { | ||
@@ -78,2 +83,21 @@ id, | ||
function rehydrate(name, str) { | ||
let result = void 0 | ||
self.troikaDefine = r => result = r | ||
let url = URL.createObjectURL( | ||
new Blob( | ||
[`/** ${name.replace(/\*/g, '')} **/\n\ntroikaDefine(\n${str}\n)`], | ||
{type: 'application/javascript'} | ||
) | ||
) | ||
try { | ||
importScripts(url) | ||
} catch(err) { | ||
console.error(err) | ||
} | ||
URL.revokeObjectURL(url) | ||
delete self.troikaDefine | ||
return result | ||
} | ||
// Handler for all messages within the worker | ||
@@ -80,0 +104,0 @@ self.addEventListener('message', e => { |
@@ -6,2 +6,3 @@ import Thenable from './Thenable.js' | ||
let _messageId = 0 | ||
let _allowInitAsString = false | ||
const workers = Object.create(null) | ||
@@ -35,2 +36,4 @@ const openRequests = Object.create(null) | ||
* in the response that can/should be transfered rather than cloned. | ||
* @param {string} [options.name] - A descriptive name for this module; this can be useful for | ||
* debugging but is not currently used for anything else. | ||
* @param {string} [options.workerId] - By default all modules will run in the same dedicated worker, | ||
@@ -44,3 +47,3 @@ * but if you want to use multiple workers you can pass a `workerId` to indicate a specific | ||
export function defineWorkerModule(options) { | ||
if (!options || typeof options.init !== 'function') { | ||
if ((!options || typeof options.init !== 'function') && !_allowInitAsString) { | ||
throw new Error('requires `options.init` function') | ||
@@ -53,2 +56,3 @@ } | ||
const id = `workerModule${++_workerModuleId}` | ||
const name = options.name || id | ||
let registrationThenable = null | ||
@@ -59,6 +63,9 @@ | ||
if (typeof dep === 'function' && !dep.workerModuleData) { | ||
_allowInitAsString = true | ||
dep = defineWorkerModule({ | ||
workerId, | ||
init: new Function(`return function(){return (${stringifyFunction(dep)})}`)() | ||
name: `<${name}> function dependency: ${dep.name}`, | ||
init: `function(){return (\n${stringifyFunction(dep)}\n)}` | ||
}) | ||
_allowInitAsString = false | ||
} | ||
@@ -90,2 +97,3 @@ // Grab postable data for worker modules | ||
id, | ||
name, | ||
dependencies, | ||
@@ -121,3 +129,6 @@ init: stringifyFunction(init), | ||
URL.createObjectURL( | ||
new Blob([`;(${bootstrap})()`], {type: 'application/javascript'}) | ||
new Blob( | ||
[`/** Worker Module Bootstrap: ${workerId.replace(/\*/g, '')} **/\n\n;(${bootstrap})()`], | ||
{type: 'application/javascript'} | ||
) | ||
) | ||
@@ -124,0 +135,0 @@ ) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
72944
16
1913
3