Skip to content
easy-web-worker

The message API

The original API of easy-web-worker - send, sendToMethod and onMessage - which typed methods are built on.

GuideTypeScriptTry an example

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

worker.ts
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());
});
main.ts
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.

main.ts
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); // 42

Typed methods on top of it

A worker written with the message API can still be called with typed methods. Describe them in the generic:

main.ts
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.

search.ts
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

MethodPurpose
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
Documentation
↑↓ Navigate ↵ Open Esc Closeeasy-web-worker docs
Get started

Real Web Workers. Typed methods.
Cancelable promises.