UNPKG

multithreading

Version:

⚡ Multithreading functions in JavaScript to speedup heavy workloads, designed to feel like writing vanilla functions.

2 lines (1 loc) 9.93 kB
"use strict";var e,t,n="undefined"!=typeof document?document.currentScript:null;(e=Promise).withResolvers??(e.withResolvers=function(){var e,t,n=new this((function(n,s){e=n,t=s}));return{resolve:e,reject:t,promise:n}}),(t={url:"undefined"==typeof document?require("url").pathToFileURL(__filename).href:n&&n.src||new URL("index.min.js",document.baseURI).href}).resolve??(t.resolve=async function(e,t){const{Module:{createRequire:s}}=await import("node:module");return s("undefined"==typeof document?require("url").pathToFileURL(__filename).href:n&&n.src||new URL("index.min.js",document.baseURI).href).resolve(e,{...t?{paths:[t]}:{}})});const s=Symbol.for("events");class o{addEventListener(e,t,n){let o=this[s].get(e);o||this[s].set(e,o=[]),o.push(t)}dispatchEvent(e){if(e.target=e.currentTarget=this,this["on"+e.type])try{this["on"+e.type](e)}catch(e){console.error(e)}const t=this[s].get(e.type);return null==t||t.forEach((t=>{try{t.call(this,e)}catch(e){console.error(e)}})),!1}removeEventListener(e,t,n){let o=this[s].get(e);if(o){const e=o.indexOf(t);-1!==e&&o.splice(e,1)}}constructor(){Object.defineProperty(this,s,{value:new Map})}}class r{composedPath(){throw new Error("Method not implemented.")}initEvent(e,t,n){throw new Error("Method not implemented.")}preventDefault(){}stopImmediatePropagation(){}stopPropagation(){}constructor(e,t=null){this.bubbles=!1,this.cancelBubble=!1,this.cancelable=!1,this.composed=!1,this.currentTarget=null,this.defaultPrevented=!1,this.eventPhase=0,this.isTrusted=!1,this.returnValue=!1,this.srcElement=null,this.target=null,this.NONE=0,this.CAPTURING_PHASE=1,this.AT_TARGET=2,this.BUBBLING_PHASE=3,this.type=e,this.timeStamp=Date.now()}}var a;(a=globalThis).Worker??(a.Worker=(async()=>{const{default:e}=await import("node:worker_threads"),{URL:t,pathToFileURL:s,fileURLToPath:a}=await import("node:url"),i=Symbol.for("worker");return class extends o{postMessage(e,t){this[i].postMessage(e,t)}terminate(){this[i].terminate()}constructor(o,c={}){super(),this.onmessage=null,this.onmessageerror=null,this.onerror=null;const{name:l,type:u}=c;let d;if(/^data:/.test(o+=""))d=o;else{const e=s(process.cwd()+"/");d=a(new t(o,e))}const f=new e.Worker(new t("undefined"==typeof document?require("url").pathToFileURL(__filename).href:n&&n.src||new URL("index.min.js",document.baseURI).href),{workerData:{mod:d,name:l,type:u}});Object.defineProperty(this,i,{value:f}),f.on("message",(e=>{const t=new r("message");t.data=e,this.dispatchEvent(t)})),f.on("error",(e=>{e.type="error",this.dispatchEvent(e)})),f.on("exit",(()=>{this.dispatchEvent(new r("close"))}))}}})());class i extends r{constructor(e){super("error"),this.colno=0,this.filename="",this.lineno=0,this.message="",Object.assign(this,e)}}var c=Worker instanceof Promise?(async()=>{const{default:e}=await import("node:worker_threads");return class extends o{postMessage(t,n){e.parentPort.postMessage(t,n)}close(){process.exit()}}})():void 0;class l extends r{constructor(e){super("unhandledrejection"),Object.assign(this,e)}}Worker instanceof Promise&&(async()=>{const{default:e}=await import("node:worker_threads"),{default:t}=await import("node:vm"),n=await c;return e.isMainThread||async function(){let{mod:t,name:o,type:a}=e.workerData;if(!t)return await Worker;const c=global.self=global;let u=[];function d(){const e=u;u=null,e.forEach((e=>{c.dispatchEvent(e)}))}e.parentPort.on("message",(e=>{const t=new r("message");t.data=e,null==u?c.dispatchEvent(t):u.push(t)})),e.parentPort.on("error",(e=>{e.type="Error",c.dispatchEvent(new i({error:e}))})),process.on("unhandledRejection",((e,t)=>{c.dispatchEvent(new l({reason:e,promise:t}))})),process.on("uncaughtException",((e,t)=>{c.dispatchEvent(new i({error:e}))}));let f=Object.getPrototypeOf(global);delete f.constructor,Object.defineProperties(n.prototype,f),f=Object.setPrototypeOf(global,new n),["postMessage","addEventListener","removeEventListener","dispatchEvent"].forEach((e=>{f[e]=f[e].bind(global)})),global.name=o;const p=/^data:/.test(t);if("module"===a)import(t).catch((e=>{if(p&&"Not supported"===e.message)return console.warn("Worker(): Importing data: URLs requires Node 12.10+. Falling back to classic worker."),s(t,o);console.error(e)})).then(d);else{try{p?s(t,o):require(t)}catch(e){console.error(e)}Promise.resolve().then(d)}}();function s(e,n){const{data:s}=function(e){let[t,n,s,o]=e.match(/^data: *([^;,]*)(?: *; *([^,]*))? *,(.*)$/)||[];if(!t)throw Error("Invalid Data URL.");if(s){if("base64"!==s.toLowerCase())throw Error('Unknown Data URL encoding "'+s+'"');o=Buffer.from(o,"base64").toString()}return{type:n,data:o}}(e);return t.runInThisContext(s,{filename:"worker.<"+(n||"data:")+">"})}})();const u=8,d="c",f="d",p="f",h="i",m="",g="";function w(e,t,n){e[0].postMessage({[d]:u,[f]:{[p]:t,[h]:n}})}function b(e,t,n,s,o,r,a){e.onmessage=i=>{switch(i.data[d]){case 7:const c=i.data[f].h,l=i.data[f][h],{resolve:u}=s.get(c);u(l),s.delete(c);break;case 5:{const s=i.data[f],o=t[s],r=n.get(o);r.push(e),1===r.length&&w(r,s,o);break}case 6:{const s=i.data[f],r=s[p],a=t[r],c=n.get(a);if(c[0]!==e)break;const l=s[h];!function(e,t){if(Array.isArray(e))e.length=0,t.forEach((t=>e.push(t)));else if(e instanceof Map)e.clear(),t.forEach((([t,n])=>e.set(t,n)));else if(e instanceof Set)e.clear(),t.forEach((t=>e.add(t)));else{if("object"!=typeof e||null===e)throw new Error("Unsupported object type");for(const t in e)delete e[t];Object.assign(e,t)}}(a,l);for(const t of o)t!==e&&e.postMessage({[d]:13,[f]:{[p]:r,[h]:l}});c.shift(),c.length>0&&w(c,r,a);break}case 14:{const e=i.data[f];e.message=function(e,t,n){const[s,...o]=e.stack.split("\n"),r=o.find((e=>e.includes("data:application/javascript;base64")));if(!r)return e.stack;const[a,i]=r.split(","),[c,l,u]=i.split(":"),d=parseInt(l),f=parseInt(u),p=t.split(/\r?\n/),h=Math.min(3,d-1),w=p.slice(d-(h+1),d+2),b=p[d-1].trimEnd().length-f;w.splice(h+1,0,""+" ".repeat(f-1)+"^".repeat(b)+" "+s+m);const v=o.indexOf(r);return o[v]=` at <Thread_${n}>${g}\n`+m+" "+w.join("\n ")+g,s.split(":").slice(1).join(":").trim()+"\n"+o.slice(0,v+1).join("\n")}(e,r,a),e.stack="",s.forEach((({reject:t})=>t(e)))}}}}async function v(e){const t=await require.resolve(e);if(t.startsWith("http://")||t.startsWith("https://")||t.startsWith("npm:")||t.startsWith("node:"))return t;if("undefined"!=typeof window)return t;const{pathToFileURL:n}=await import("node:url");return n(t).toString()}const y=new WeakMap,E=new WeakMap;exports.$claim=async function(e){},exports.$unclaim=function(e){},exports.threaded=function(e,t){const n={debug:!1,maxThreads:"undefined"!=typeof navigator?navigator.hardwareConcurrency:4};let s;"function"==typeof e?s=e:(Object.assign(n,e),s=t);let o={};const r=[],a=new Map;y.set(s,r);let i=0;const c=(async()=>{const e=s.toString(),t=await async function(e){const t=e.indexOf("{")+1,n=e.slice(t,-1).trim().split(/(?:\s*[;\r\n]+\s*)+/),s=[];for(const e of n){if(!e.includes("yield "))continue;const t=e.split("yield ")[1];if(/^["'`]/.test(t)){const e=t.slice(1,-1);s.push({l:"import",[p]:e,m:await v(e)})}else s.push({l:"variable",[p]:t})}return s}(e),i=s();for(const e of t){const t=await i.next({});"variable"===e.l&&(o[e[p]]=t.value)}for(const e in o)E.set(o[e],[]);const c=['"use strict";Promise.withResolvers??=function(){var e,t,n=new this((function(n,s){e=n,t=s}));return{resolve:e,reject:t,promise:n}};const e="c",t="d",n="i";function s(e,t){if(Array.isArray(e))e.length=0,t.forEach((t=>e.push(t)));else if(e instanceof Map)e.clear(),t.forEach((([t,n])=>e.set(t,n)));else if(e instanceof Set)e.clear(),t.forEach((t=>e.add(t)));else{if("object"!=typeof e||null===e)throw new Error("Unsupported object type");for(const t in e)delete e[t];Object.assign(e,t)}}globalThis.__internal=function(){const o={p:function*(){},n:""};globalThis.$claim=async function(n){const s=c.get(n);return r[s]++,i.has(s)||(i.set(s,Promise.withResolvers()),postMessage({[e]:5,[t]:s})),i.get(s).promise},globalThis.$unclaim=function(s){const o=c.get(s);--r[o]>0||(i.delete(o),postMessage({[e]:6,[t]:{f:o,[n]:s}}))};let a=[];const c=new WeakMap,i=new Map,r={};return self.addEventListener("unhandledrejection",(n=>{n.preventDefault(),postMessage({[e]:14,[t]:n.reason}),close()})),self.addEventListener("error",(n=>{n.preventDefault(),postMessage({[e]:14,[t]:n.error}),close()})),globalThis.onmessage=async l=>{switch(l.data[e]){case 4:!async function(e){e.j,a=e.g,o.n=e.n;const t=(e=>{const t={};for(const[n,s]of Object.entries(e))"object"==typeof s&&"e"in s?(s.e,t[n]=s):t[n]=s;return t})(e.a);for(const e in t){const n=t[e];n instanceof Object&&(c.set(n,e),r[e]=0)}Object.assign(globalThis,t)}(l.data[t]);break;case 12:!async function(s){const c=o.p(...s.b);let i,r=!1,l=!0;for(const e of a)if("import"===e.l){const t=await import(e.m);l&&(await c.next(),l=!1);const n=await c.next(t);if(n.done){r=!0,i=n.value;break}}else{const e=await c.next();if(e.done){r=!0,i=e.value;break}}r||(i=(await c.next()).value),postMessage({[e]:7,[t]:{h:s.h,[n]:i}})}(l.data[t]);break;case 8:!function(e){const t=e.f;s(globalThis[t],e[n]),i.get(t).resolve()}(l.data[t]);break;case 13:!async function(e){const t=e.f;s(globalThis[t],e[n])}(l.data[t])}},o}();\n',`__internal.p = ${e};`],l=(e=>{const t={};for(const[n,s]of Object.entries(e))t[n]="function"==typeof s?{e:2,value:s.toString()}:s;return t})(o);for(const[e,t]of Object.entries(l))2===t.e&&(c.unshift(`globalThis.${e} = ${t.value};`),delete l[e]);const u=c.join("\r\n");for(let e=0;e<n.maxThreads;e++){const s=new(await Worker)(encodeURI("data:application/javascript;base64,"+btoa(u)),{type:"module"});b(s,o,E,a,r,u,e),r.push(s),s.postMessage({[d]:4,[f]:{j:e,g:t,a:l,n:u,k:n.debug}})}})(),l=async(...e)=>{await c;const t=r[i%n.maxThreads],s=Promise.withResolvers();return a.set(i,s),t.postMessage({[d]:12,[f]:{h:i++,b:e}}),s.promise};return l.dispose=()=>{for(const e of r)e.terminate();y.delete(s),a.forEach((e=>e.reject("Disposed"))),a.clear()},l};