The message API
The original API of easy-web-worker - send, sendToMethod and onMessage - which typed methods are built on.
Messages instead of methods
defineWorker and createWorker are built on a message API that you can use directly. It is fully supported,
and both styles can live in the same worker.
A worker file
import { createStaticEasyWebWorker } from 'easy-web-worker/createStaticEasyWebWorker';
// the callback handles the messages sent with send()
const { onMessage } = createStaticEasyWebWorker<number, number>((message) => {
message.resolve(message.payload * 2);
});
// named handlers are reached with sendToMethod()
onMessage<string, string>('uppercase', (message) => {
message.resolve(message.payload.toUpperCase());
});import { createEasyWebWorker } from 'easy-web-worker';
import workerUrl from './static.worker?worker&url';
export const worker = createEasyWebWorker<number, number>(workerUrl, {
workerOptions: { type: 'module' },
});
export async function run() {
const doubled = await worker.send(21); // the default handler
// the result type comes first, then the payload type
const upper = await worker.sendToMethod<string, string>('uppercase', 'hello');
return { doubled, upper };
}The first generic of createEasyWebWorker is the payload of send(). The second is the value passed to
message.resolve().
A runtime worker
createEasyWebWorker also accepts a function, or an array of functions that share the scope of the worker.
import { createEasyWebWorker } from 'easy-web-worker';
export const worker = createEasyWebWorker<number, number>(({ onMessage }) => {
onMessage((message) => {
message.resolve(message.payload * 2);
});
});
export const doubled = worker.send(21); // 42Typed methods on top of it
A worker written with the message API can still be called with typed methods. Describe them in the generic:
import { createWorker } from 'easy-web-worker/createWorker';
import workerUrl from './static.worker?worker&url';
// typed methods on top of a worker written with the message api
export const worker = createWorker<{ uppercase: (text: string) => string }>(workerUrl, {
workerOptions: { type: 'module' },
});
export const upper = worker.uppercase('hello'); // CancelablePromise<string>Latest request wins
For search, previews and autocomplete, an older request is worthless once a newer one exists. override
cancels what is pending and sends the new message.
import { createEasyWebWorker, type EasyWebWorkerBody } from 'easy-web-worker';
type SearchResult = { id: string; title: string };
declare const searchBody: EasyWebWorkerBody<string, SearchResult[]>;
const search = createEasyWebWorker<string, SearchResult[]>(searchBody);
export function connect(input: HTMLInputElement, render: (results: SearchResult[]) => void) {
input.oninput = async () => {
// cancels what is pending, then sends the new message
const results = await search.override(input.value, 'Superseded');
render(results);
};
}overrideAfterCurrent lets the call in progress finish and replaces only what is waiting behind it.
With typed workers, both are reached through unwrap(worker) and send a message without a method. Handle it in
the worker with unwrap(worker).onMessage(...).
The methods of EasyWebWorker
| Method | Purpose |
|---|---|
send(payload?, transfer?) | Sends a message to the default handler |
sendToMethod<TResult, TPayload>(method, payload?, transfer?) | Sends a message to a named method |
cancelAll(reason?, { force? }) | Cancels every pending call; force restarts instead of waiting |
override(payload?, reason?, { force? }) | Cancels the pending calls and sends a new message |
overrideAfterCurrent(payload?, reason?) | Keeps the current call, cancels the rest, sends a new message |
reboot(reason?) | Terminates the Workers, rejects pending calls, starts again |
dispose() | Cancels pending calls and releases the Workers |