typed-web-workers
v4.0.0
Published
Create web workers with type safety
Downloads
1,290
Readme
typed-web-workers
Library that help you get quickly up and running with web workers in TypeScript or JavaScript projects.
❗️❗️❗️ The
workerFunction
is executed in an isolated context. It can not rely on its surrounding context. UseimportScripts
if you need something added to the worker context
Installation
npm install typed-web-workers
tl;dr
import { createWorker } from 'typed-web-workers'
const worker = createWorker({
workerFunction: ({input, callback}) => callback(input * 2),
onMessage: result => console.log(`Worker returned: ${result}`),
onError: error => console.log(`unhandled exception in Worker`)
})
worker.postMessage(1) // Worker returned: 2
worker.postMessage(2) // Worker returned: 4
Only workerFunction
is required by createWorker
.
Fiddles
Motivation for Web Workers
- avoid blocking the main thread with long running tasks
When the main thread is blocked, the UI will be unresponsive to user events.
Note Using a web worker does not make a function run faster.
Motivation for Typed Web Workers
- a fully typesafe web worker
- quickly created
- all of the benefits of a native web worker
Usage
Worker with local state
/**
* Function that will be executed on the Worker
* */
function workerFunction({
input,
callback,
getState,
setState
}: WorkerFunctionProps<number, number, number>) {
const previousValue = getState() || 0
callback(previousValue + input)
setState(input)
}
createWorker({
workerFunction,
onMessage: data => console.log(data)
})
Worker with moment.js
const momentWorker = createWorker({
workerFunction: ({input,callback}) => callback(moment(input).format('YYYY')),
onMessage: data => console.log(data)
importScripts: [
'https://unpkg.com/[email protected]/min/moment.min.js'
]
})
importScripts
Use importScripts
to import external files into your Worker (mdn docs).
The provided URIs in importScripts
must link to a JavaScript file that can be loaded by the Worker at runtime. The scripts must be CommonJs/umd as Workers do not support ES modules.
If something goes wrong during the import an exception will be thrown and onError
will be called. If this happens, you can assume the worker is no longer responsive.
Using local files
How you solve this depends on how you build and deploy your project.
You will most likely need to create a new entrypoint bundle that you can import with importScripts
. For example importScripts["www.example.com/public/my-script.js"]
.
Worker Scope
The workerFunction
that we give our worker can only use the data provided from the input
variable, from its state and from importScripts
. It does not have access to variables or functions outside its scope.
const results = []
function workerFunction({input, callback}) {
results.push(input.x + input.y) // this would not work
}
It will compile, but would not work because the two variables are not in the same context/thread.
const results = [] // main context
function workerFunction({input, callback}) {
results.push(input.x + input.y) // worker context
}
How does this work?
In short, createWorker
:
- Converts your
workerFunction
to a string - Creates a new native Worker using this string (by using Blob)
- returns a instance of a
TypedWorker
that acts as a wrapper to the native worker.
Check the source code of TypedWorker.ts
if you want more information.