From 182bd4c0baddf4f966ef573b53720d7e5124981f Mon Sep 17 00:00:00 2001 From: Akin909 Date: Sat, 6 Oct 2018 00:56:12 +0100 Subject: [PATCH 1/4] add workerize utitlity --- browser/src/Workerize.ts | 53 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 browser/src/Workerize.ts diff --git a/browser/src/Workerize.ts b/browser/src/Workerize.ts new file mode 100644 index 0000000000..9f8cab9606 --- /dev/null +++ b/browser/src/Workerize.ts @@ -0,0 +1,53 @@ +interface IArgs { + data: T +} + +interface IContext { + [key: string]: any +} + +type Callback = (args?: T) => void + +/** + * 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 + * + * @name workerize + * @function + * @param Callback + * @param args?: T + * @param context?: any + * @returns Promise + */ +export function workerize(work: Callback, args?: T, context?: IContext) { + const handleResult = ({ data }: IArgs) => { + const result = work(data) + const worker: Worker = self as any + return worker.postMessage(result) + } + + const globalVars = createContextVars(context) + // 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 ${globalVars} 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))) +} + +const createContextVars = (context: IContext) => { + if (!context) { + return "" + } + return Object.keys(context).reduce((acc, key) => { + acc += `var ${key} = ${context[key]};\n` + return acc + }, "") +} From baf331b2b3ce17aeb98949863e2a193503e8ffe5 Mon Sep 17 00:00:00 2001 From: Akin909 Date: Sat, 6 Oct 2018 00:59:09 +0100 Subject: [PATCH 2/4] remove additional global vars argument --- browser/src/Workerize.ts | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/browser/src/Workerize.ts b/browser/src/Workerize.ts index 9f8cab9606..97e3672a92 100644 --- a/browser/src/Workerize.ts +++ b/browser/src/Workerize.ts @@ -2,10 +2,6 @@ interface IArgs { data: T } -interface IContext { - [key: string]: any -} - type Callback = (args?: T) => void /** @@ -13,41 +9,27 @@ type Callback = (args?: T) => void * 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 - * @param context?: any * @returns Promise */ -export function workerize(work: Callback, args?: T, context?: IContext) { +export function workerize(work: Callback, args?: T) { const handleResult = ({ data }: IArgs) => { const result = work(data) const worker: Worker = self as any return worker.postMessage(result) } - const globalVars = createContextVars(context) // 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 ${globalVars} onmessage = ${handleResult.toString()}`], - { - type: "text/javascript", - }, - ) + 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))) } - -const createContextVars = (context: IContext) => { - if (!context) { - return "" - } - return Object.keys(context).reduce((acc, key) => { - acc += `var ${key} = ${context[key]};\n` - return acc - }, "") -} From 03e94b691e1b4e4d64aad93ba0ae74fac7b546ca Mon Sep 17 00:00:00 2001 From: Akin909 Date: Sat, 6 Oct 2018 01:05:42 +0100 Subject: [PATCH 3/4] fix lint errors --- browser/src/Workerize.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/browser/src/Workerize.ts b/browser/src/Workerize.ts index 97e3672a92..99e8997756 100644 --- a/browser/src/Workerize.ts +++ b/browser/src/Workerize.ts @@ -19,8 +19,8 @@ type Callback = (args?: T) => void export function workerize(work: Callback, args?: T) { const handleResult = ({ data }: IArgs) => { const result = work(data) - const worker: Worker = self as any - return worker.postMessage(result) + const webWorker: Worker = self as any + return webWorker.postMessage(result) } // courtesy of this gem - From d969d5edc2cf0eca19d22e228db44b48a720e1a4 Mon Sep 17 00:00:00 2001 From: Akin909 Date: Sat, 6 Oct 2018 12:49:40 +0100 Subject: [PATCH 4/4] fix callbacks type signature --- browser/src/Workerize.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browser/src/Workerize.ts b/browser/src/Workerize.ts index 99e8997756..698b5a8fcd 100644 --- a/browser/src/Workerize.ts +++ b/browser/src/Workerize.ts @@ -2,7 +2,7 @@ interface IArgs { data: T } -type Callback = (args?: T) => void +type Callback = (args?: T) => any /** * Takes a CPU intensive function