first commit
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
# `define-worker`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## 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
|
||||
|
||||
```ts
|
||||
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
|
||||
|
||||
```ts
|
||||
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.
|
||||
Reference in New Issue
Block a user