diff --git a/Thread.bundle.js b/Thread.bundle.js deleted file mode 100644 index e41558d..0000000 --- a/Thread.bundle.js +++ /dev/null @@ -1,83 +0,0 @@ -// deno-fmt-ignore-file -// deno-lint-ignore-file -// This code was bundled using `deno bundle` and it's not recommended to edit it manually - -class Thread { - worker; - imports; - blob; - blobURL = ""; - stopped = false; - constructor(operation, type, imports){ - this.imports = imports || []; - this.blob = this.populateFile(operation); - this.worker = this.makeWorker(type); - } - async makeWorker(type) { - this.blobURL = URL.createObjectURL(await this.blob); - return new Worker(this.blobURL, { - type: type || "module" - }); - } - async populateFile(code) { - const imported = this.imports?.flatMap(async (val)=>(await this.copyDep(val)).join("\n")); - return new Blob([ - ` - ${(await Promise.all(imported)).join("\n")} - - var global = {}; - var userCode = ${code.toString()} - - onmessage = async function(e) { - postMessage(await userCode(e, global)); - } - - ` - ]); - } - async copyDep(str) { - const importPathRegex = /('|"|`)(.+(\.js|\.ts))(\1)/ig; - const importInsRegex = /(import( |))({.+}|.+)(from( |))/ig; - const matchedPath = importPathRegex.exec(str) || ""; - let file = false; - let fqfn = ""; - if (!matchedPath[0].includes("http://") && !matchedPath[0].includes("https://")) { - file = true; - fqfn = matchedPath[0].replaceAll(/('|"|`)/ig, ""); - } - const matchedIns = importInsRegex.exec(str) || ""; - if (!matchedIns) { - throw new Error("The import instruction seems to be unreadable try formatting it, for example: \n" + "import { something } from './somet.js' \n "); - } - if (file) { - const x = await import(fqfn); - return Object.keys(x).map((v)=>x[v].toString()); - } else { - const filePath = matchedPath[0].replaceAll(/'|"/g, ""); - if (filePath.endsWith(".ts")) { - return [ - str - ]; - } - const x1 = await import(filePath); - return Object.keys(x1).map((v)=>x1[v].toString()); - } - } - postMessage(msg) { - this.worker.then((w)=>w.postMessage(msg)); - return this; - } - async stop() { - this.stopped = true; - (await this.worker).terminate(); - } - async remove() { - if (this.stopped == false) await this.stop(); - URL.revokeObjectURL(this.blobURL); - } - onMessage(callback) { - this.worker.then((w)=>w.onmessage = (e)=>callback(e.data)); - return this; - } -} -export { Thread as default }; diff --git a/Thread.ts b/Thread.ts index ab9646c..e9e86c4 100644 --- a/Thread.ts +++ b/Thread.ts @@ -8,6 +8,8 @@ export default class Thread { private imports: Array; private blob: Promise; private blobURL = ""; + public debugMode: boolean; + /** * Tells if the worker has been stopped */ @@ -23,8 +25,12 @@ export default class Thread { ) => T | Promise, type?: "classic" | "module", imports?: Array, + opts: { debug?: boolean } = { debug: false }, ) { + this.debugMode = opts.debug ?? false; this.imports = imports || []; + + // these methods are asynchronous, because we're in the constructor, we must make sure they're at the end this.blob = this.populateFile(operation); this.worker = this.makeWorker(type); } @@ -44,17 +50,18 @@ export default class Thread { const imported = this.imports?.flatMap(async (val) => (await this.copyDep(val)).join("\n") ); - return new Blob([` - ${(await Promise.all(imported)).join("\n")} - - var global = {}; - var userCode = ${code.toString()} - - onmessage = async function(e) { - postMessage(await userCode(e, global)); - } - - `]); + const blobContent = ` +${(await Promise.all(imported)).join("\n")} + +var global = {}; +var userCode = ${code.toString()} + +onmessage = async function(e) { + postMessage(await userCode(e, global)); +} +`; + this.debug(`Blob content:${blobContent}\n\n\n`); + return new Blob([blobContent]); } /** @@ -65,6 +72,8 @@ export default class Thread { const importPathRegex = /('|"|`)(.+(\.js|\.ts))(\1)/ig; // for the path string ("lorem/ipsum.js") const importInsRegex = /(import( |))({.+}|.+)(from( |))/ig; // for the instruction before the path (import {som} from) const matchedPath = importPathRegex.exec(str) || ""; + this.debug("attempting to import: ", str); + let file = false; let fqfn = ""; @@ -74,6 +83,7 @@ export default class Thread { ) { file = true; fqfn = matchedPath[0].replaceAll(/('|"|`)/ig, ""); + this.debug("file identified as local file"); } const matchedIns = importInsRegex.exec(str) || ""; // matchedIns[0] > import {sss} from @@ -85,18 +95,36 @@ export default class Thread { } if (file) { - const x = await import(fqfn); //Deno.realPathSync(fqfn) + this.debug( + "importing file: ", + import.meta.resolve("file://" + Deno.realPathSync(fqfn)), + ); + const x = await import("file://" + Deno.realPathSync(fqfn)); + this.debug( + "file imported, inlining the following: ", + Object.keys(x).join(","), + ); return Object.keys(x).map((v) => x[v].toString()); } else { const filePath = matchedPath[0].replaceAll(/'|"/g, ""); + this.debug("importing from the net: ", filePath); if (filePath.endsWith(".ts")) { - return [str]; // dont import the content if ts just paste import string + this.debug("filePath ends with .ts, returning: ", str); + return [str]; // do nothing if plain import string } const x = await import(filePath); + this.debug( + "imported from the net, inlining the following: ", + Object.keys(x).join(","), + ); return Object.keys(x).map((v) => x[v].toString()); } } + private debug(...msg: unknown[]) { + if (this.debugMode) console.debug(`[${new Date()}]\t`, ...msg); + } + /** * Sends data to the Thread * @param msg diff --git a/egg.json b/egg.json index 2263ad4..ec152ea 100644 --- a/egg.json +++ b/egg.json @@ -4,7 +4,7 @@ "entry": "./Thread.ts", "description": "Type-safe multi-threading made 'easier'", "homepage": "https://github.com/duart38/Thread", - "version": "4.1.0", + "version": "4.2.0", "releaseType": null, "unstable": false, "unlisted": false, diff --git a/examples/example_async_support.ts b/examples/example_async_support.ts index 4f46df9..c3de391 100644 --- a/examples/example_async_support.ts +++ b/examples/example_async_support.ts @@ -9,12 +9,12 @@ import Thread from "../Thread.ts"; const thread = new Thread(async (e) => { console.log("Worker: Message received from main script"); const result = e.data[0] * e.data[1]; - await new Promise((resolve) => setTimeout(resolve, 5 * 1000)) + await new Promise((resolve) => setTimeout(resolve, 5 * 1000)); if (isNaN(result)) { return 0; } else { console.log("Worker: Posting message back to main script"); - return (result); + return result; } }, "module"); diff --git a/examples/example_simple.ts b/examples/example_simple.ts index 6b7cca0..64f56af 100644 --- a/examples/example_simple.ts +++ b/examples/example_simple.ts @@ -7,7 +7,7 @@ const thread = new Thread((e) => { return 0; } else { console.log("Worker: Posting message back to main script"); - return (result); + return result; } });