Comparing version 0.2.1 to 0.2.3
@@ -17,2 +17,3 @@ var wk = function (c, msg, transfer, cb) { | ||
wk.t = [ArrayBuffer, MessagePort]; | ||
wk.c = [Blob, File, FileList, ImageData]; | ||
if (typeof ImageBitmap != 'undefined') | ||
@@ -33,2 +34,8 @@ wk.t.push(ImageBitmap); | ||
]; | ||
var setExists = typeof Set != 'undefined'; | ||
var mapExists = typeof Map != 'undefined'; | ||
if (setExists && !Set.prototype.values) | ||
wk.c.push(Set); | ||
if (mapExists && !Map.prototype.entries) | ||
wk.c.push(Map); | ||
if (typeof BigInt64Array != 'undefined') | ||
@@ -164,10 +171,11 @@ abvList.push(BigInt64Array); | ||
return 'null'; | ||
var proto = Object.getPrototypeOf(v); | ||
var abv; | ||
if (abvList.indexOf(proto.constructor) != -1) | ||
abv = v.buffer; | ||
else if (wk.t.indexOf(proto.constructor) != -1) | ||
abv = v; | ||
if (abv) { | ||
ab.push(abv); | ||
var proto = Object.getPrototypeOf(v), ctr = proto.constructor; | ||
var cln = 0; | ||
if (abvList.indexOf(ctr) != -1) | ||
cln = ab.push(v.buffer); | ||
else if (wk.t.indexOf(ctr) != -1) | ||
cln = ab.push(v); | ||
else if (wk.c.indexOf(ctr) != -1) | ||
cln = 1; | ||
if (cln) { | ||
dat.push([renderCtx(ctx, ab, m) + "=" + toReplace + ";", v]); | ||
@@ -181,5 +189,5 @@ return toReplace; | ||
var keys = getAllPropertyKeys(v); | ||
if (proto.constructor == Object) | ||
if (ctr == Object) | ||
out += "{}"; | ||
else if (proto.constructor == Array) { | ||
else if (ctr == Array) { | ||
var arrStr = ''; | ||
@@ -198,4 +206,33 @@ for (var i = 0; i < v.length; ++i) { | ||
} | ||
else if (setExists && ctr == Set) { | ||
var setStr = ''; | ||
var getsSets = ''; | ||
var it = v.values(); | ||
for (var i = 0, v_1 = it.next(); !v_1.done; ++i, v_1 = it.next()) { | ||
var dl = dat.length; | ||
var sn = "__iwinit" + i + "__"; | ||
setStr += encoder[typeof v_1.value](v_1.value, ab, m, g, s, ctx.concat(sn), dat) + ","; | ||
if (dat.length != dl) | ||
getsSets += ";Object.defineProperty(v,\"" + sn + "\",{get:function(){return i[" + i + "]},set:function(n){v.delete(i[" + i + "]);v.add(i[" + i + "]=n)}})"; | ||
} | ||
out += "0;var i=[" + setStr.slice(0, -1) + "];v=new Set(i)" + getsSets; | ||
} | ||
else if (mapExists && ctr == Map) { | ||
var mapStr = ''; | ||
var getsSets = ''; | ||
var it = v.entries(); | ||
for (var i = 0, v_2 = it.next(); !v_2.done; ++i, v_2 = it.next()) { | ||
var _a = v_2.value, key = _a[0], val = _a[1]; | ||
var dl = dat.length; | ||
var sn = "__iwinit" + i + "__"; | ||
mapStr += "[" + encoder[typeof key](key, ab, m, g, s, ctx.concat(sn, 0), dat) + "," + encoder[typeof val](val, ab, m, g, s, ctx.concat(sn, 1), dat) + "],"; | ||
if (dat.length != dl) | ||
getsSets += ";Object.defineProperty(v,\"" + sn + "\",{value:{get 0(){return i[" + i + "][0]},set 0(n){v.delete(i[" + i + "][0]);v.set(i[" + i + "][0]=n,i[" + i + "][1])},get 1(){return i[" + i + "][1]},set 1(n){v.set(i[" + i + "][0],i[" + i + "][1]=n)}}})"; | ||
} | ||
out += "0;var i=[" + mapStr.slice(0, -1) + "];v=new Map(i)" + getsSets; | ||
} | ||
else if (ctr == Date) | ||
out += "new Date(" + v.getTime() + ")"; | ||
else | ||
out += "Object.create(" + encoder["function"](proto.constructor, ab, m, g, s, ctx.concat('constructor'), dat) + ".prototype)"; | ||
out += "Object.create(" + encoder["function"](ctr, ab, m, g, s, ctx.concat('constructor'), dat) + ".prototype)"; | ||
return out + vDescriptors(v, keys, ab, m, g, s, ctx, dat) + ';return v})()'; | ||
@@ -252,7 +289,7 @@ } | ||
return vals.reduce(function (a, v) { | ||
var proto = Object.getPrototypeOf(v); | ||
if (abvList.indexOf(proto.constructor) != -1) { | ||
var proto = Object.getPrototypeOf(v), ctr = proto.constructor; | ||
if (abvList.indexOf(ctr) != -1) { | ||
a.push(v.buffer); | ||
} | ||
else if (wk.t.indexOf(proto.constructor) != -1) { | ||
else if (wk.t.indexOf(ctr) != -1) { | ||
a.push(v); | ||
@@ -316,3 +353,3 @@ } | ||
} | ||
var worker = wk(str + ";onmessage=function(e){" + assignStr + "var v=" + fn + ";var _p=function(d){typeof d.then=='function'?d.then(_p,_e):postMessage(d,d?d.__transfer:[])};var _e=function(e){!(e instanceof Error)&&(e=new Error(e));postMessage({__iwerr__:{s:e.stack,m:e.message,n:e.name}})};onmessage=function(e){try{_p(v.apply(self,e.data))}catch(e){_e(e)}}}", msg, transfer, function (err, res) { | ||
var worker = wk(str + ";onmessage=function(e){" + assignStr + "var v=" + fn + ";var _p=function(d){d?typeof d.then=='function'?d.then(_p,_e):postMessage(d,d.__transfer):postMessage(d)};var _e=function(e){!(e instanceof Error)&&(e=new Error(e));postMessage({__iwerr__:{s:e.stack,m:e.message,n:e.name}})};onmessage=function(e){try{_p(v.apply(self,e.data))}catch(e){_e(e)}}}", msg, transfer, function (err, res) { | ||
++runCount; | ||
@@ -319,0 +356,0 @@ var rtErr = res && |
{ | ||
"name": "isoworker", | ||
"version": "0.2.1", | ||
"version": "0.2.3", | ||
"description": "Isomorphic workerization with dependencies", | ||
@@ -5,0 +5,0 @@ "main": "./lib/index.cjs", |
# isoworker | ||
Isomorphic workerization with context in under 4kB | ||
Isomorphic workerization with context in 6kB | ||
@@ -9,5 +9,5 @@ ## Why? | ||
If you're not experienced with build tools or are creating a library, however, using worker threads is virtually impossible. Nothing works on all platforms, with all build tools, and doesn't require embedding the codebase as a string. That's why most "asynchronous" packages such as [JSZip](https://github.com/Stuk/jszip) still run on the main thread in an event loop. While running in the event loop is fine, it doesn't allow your JS to take advantage of multiple CPU cores. | ||
If you're not experienced with build tools or are creating a library, however, using worker threads is virtually impossible. Nothing works on all platforms, with all build tools, and doesn't require embedding the codebase as a string. Moreover, it's not possible to transfer data, particularly complex classes and objects, to the worker thread without using JSON. That's why most "asynchronous" packages such as [JSZip](https://github.com/Stuk/jszip) still run on the main thread in an event loop. While running in the event loop is fine, it doesn't allow your code to take advantage of the multiple CPU cores that exist on most devices; everything still runs on one thread. | ||
This package abstracts all difficulties away by making your standard functions magically run in a separate thread in all environments. You don't even need a new file to run your code, and unlike other workerization packages, you can actually call other functions and use variables from your worker. | ||
In just 6kB of pure JavaScript (3kB gzipped), `isoworker` abstracts all these difficulties away by making your standard functions magically run in a separate thread in all environments. You don't even need a new file to run your code, and unlike other workerization packages, you can actually call other functions and use variables from your worker. The serializer is the heart of the package; | ||
@@ -84,2 +84,3 @@ A subset of this package is used in [`fflate`](https://github.com/101arrowz/fflate), the fastest compression library for JavaScript. It's been immensely useful for supporting Node.js and browsers as old as IE11 while still offering *true* parallelization potential. | ||
const runWasmMainThread = async (wasmName, method, ...args) => { | ||
// The wasm object acts as a cache for WASM files | ||
if (!wasm[wasmName]) { | ||
@@ -183,3 +184,20 @@ wasm[wasmName] = (await WebAssembly.instantiateStreaming( | ||
## Possible Pitfalls | ||
Although `isoworker` can handle most dependencies, including objects of user-created classes, certain native classes and objects will not work. Of course, the basic ones (primitives, dates, objects, arrays, sets, maps, etc.) work well, but more advanced types such as `MediaRecorder` and `Audio` cannot be used as dependencies. You'll need to send over information that you used to construct them (for `Audio`, the URL) via function parameters. | ||
Another point to note is that much of the package is based off of elaborate (but fallible) pseudo-parsers for stringified functions. In other words, if you try to break things, you can. However, as long as you don't do something like this: | ||
```js | ||
const dontDoThis = { | ||
get ["(please)"] /* function() { */ () { | ||
console.log('hi') | ||
} | ||
}; | ||
workerize(() => dontDoThis["(please)"], () => [dontDoThis]); | ||
``` | ||
you will be fine. | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
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
92012
2018
200