51 lines
2.0 KiB
TypeScript
51 lines
2.0 KiB
TypeScript
import type { WorkerFactory, WorkerLike } from "../types/web-workers.types.js";
|
|
|
|
/** Options accepted by {@link defineWorker}. */
|
|
export interface DefineWorkerOptions {
|
|
/** Worker entrypoint URL — typically `new URL("./worker.ts", import.meta.url)`. */
|
|
readonly url: string | URL;
|
|
/** Worker type. Defaults to "module". */
|
|
readonly type?: "classic" | "module";
|
|
/**
|
|
* Optional override of the global `Worker` constructor. Provided for
|
|
* tests; production callers rely on the default (the DOM `Worker`).
|
|
*/
|
|
readonly workerConstructor?: WorkerConstructorLike;
|
|
}
|
|
|
|
/** Subset of `WorkerConstructor` used by {@link defineWorker}. */
|
|
export type WorkerConstructorLike = new (
|
|
url: string | URL,
|
|
options?: { type?: "classic" | "module" }
|
|
) => WorkerLike;
|
|
|
|
/**
|
|
* Bind a worker entrypoint URL + type into a reusable {@link WorkerFactory}.
|
|
*
|
|
* `WorkerManager` accepts a factory rather than a constructor so consumers
|
|
* can substitute fakes in tests. `defineWorker` is the canonical production
|
|
* factory — it wraps the standard `new Worker(url, { type })` pattern with
|
|
* the Vite/Webpack-friendly `new URL('./worker.ts', import.meta.url)` idiom
|
|
* and removes the temptation to inline `new Worker(...)` at call sites.
|
|
*/
|
|
export function defineWorker(opts: DefineWorkerOptions): WorkerFactory {
|
|
const baseType: "classic" | "module" = opts.type ?? "module";
|
|
const ctor = opts.workerConstructor ?? getGlobalWorker();
|
|
return (urlOverride, options) => {
|
|
const url = urlOverride ?? opts.url;
|
|
const type = options?.type ?? baseType;
|
|
return new ctor(url, { type });
|
|
};
|
|
}
|
|
|
|
function getGlobalWorker(): WorkerConstructorLike {
|
|
const globalCtor = (globalThis as { Worker?: WorkerConstructorLike })
|
|
.Worker;
|
|
if (globalCtor === undefined) {
|
|
throw new Error(
|
|
"defineWorker: globalThis.Worker is undefined; pass workerConstructor explicitly in non-browser environments."
|
|
);
|
|
}
|
|
return globalCtor;
|
|
}
|