Files
skills/docs/foundation/data/web-workers/src/helpers/define-worker.md
2026-05-29 08:20:56 +01:00

2.8 KiB

define-worker

(no submodules)

Purpose

define-worker.ts exposes defineWorker(), a small helper that wraps the canonical new Worker(url, { type }) pattern in a reusable WorkerFactory. The base manager accepts a factory rather than a constructor so tests can inject in-process fakes; defineWorker is the production factory that consumers wire into WorkerManager / WorkerPool.

Centralising this pattern keeps the Vite / Webpack new URL('./worker.ts', import.meta.url) idiom in one place and removes the temptation to inline new Worker(...) at call sites, which would defeat the factory-injection seam.

Features

  • Returns a WorkerFactory bound to a default URL and type.
  • Per-invocation type override.
  • Optional workerConstructor override for tests (substitute a MessageChannel-backed fake, a Bun Worker, etc.).
  • Clear error when globalThis.Worker is unavailable (Node.js without the worker-threads polyfill, custom runtimes).

Usage: Basic Example

import { defineWorker, WorkerManager } from "@suaveplan/web-workers";

const factory = defineWorker({
    url: new URL("./encode.worker.ts", import.meta.url),
    type: "module",
});

const manager = new WorkerManager({ factory });
manager.create({ name: "encode", url: "ignored-by-factory" });

Usage: Advanced Example

import {
    defineWorker,
    type WorkerConstructorLike,
} from "@suaveplan/web-workers";

class TestWorker {
    constructor(url: string | URL) {
        this.url = url;
    }
    url: string | URL;
    postMessage() {}
    terminate() {}
    addEventListener() {}
}

const factory = defineWorker({
    url: "spec://test",
    workerConstructor: TestWorker as unknown as WorkerConstructorLike,
});

const w = factory("spec://test");

API Reference

  • defineWorker(opts: DefineWorkerOptions): WorkerFactory.
  • interface DefineWorkerOptions { url; type?; workerConstructor? }.
  • type WorkerConstructorLike = new (url, options?) => WorkerLike.

Implementation Notes

The factory accepts a urlOverride parameter so consumers can pass a per-create URL to the same factory (the manager passes config.url here). When the consumer constructs the factory with a default URL and the manager passes a different URL, the per-invocation URL wins — that's what lets a single factory drive multiple workers loaded from different scripts. workerConstructor is an escape hatch for non-browser environments and tests; the production path uses globalThis.Worker. When that's undefined the helper throws an explicit Error("globalThis.Worker is undefined") rather than the cryptic TypeError: undefined is not a constructor that JavaScript would otherwise produce — that diagnostic was specifically worth surfacing because the failure mode is common in Node-based test runs without appropriate polyfills.