diff --git a/browser/src/Workerize.ts b/browser/src/Workerize.ts new file mode 100644 index 0000000000..698b5a8fcd --- /dev/null +++ b/browser/src/Workerize.ts @@ -0,0 +1,35 @@ +interface IArgs { + data: T +} + +type Callback = (args?: T) => any + +/** + * Takes a CPU intensive function + * passes it off to a dynamically generated WebWorker + * and returns a promise to resolve the return value of the function + * + * limitations: function has to be Pure! -> no external dependencies etc. + * @name workerize + * @function + * @param Callback + * @param args?: T + * @returns Promise + */ +export function workerize(work: Callback, args?: T) { + const handleResult = ({ data }: IArgs) => { + const result = work(data) + const webWorker: Worker = self as any + return webWorker.postMessage(result) + } + + // courtesy of this gem - + // https://stackoverflow.com/questions/42773714/is-async-await-truly-non-blocking-in-the-browser + // writes the contents of the string passed in to a file and executes it. + const blob = new Blob([`var work = ${work};\n onmessage = ${handleResult.toString()}`], { + type: "text/javascript", + }) + const worker = new Worker(URL.createObjectURL(blob)) + worker.postMessage(args) + return new Promise(resolve => (worker.onmessage = evt => resolve(evt.data))) +}