2.8 KiB
helpers
Purpose
helpers.ts co-locates the small utilities the base manager and the
message bus both depend on: a default wall-clock implementation, a default
id generator backed by crypto.getRandomValues, the transfer-list validator
that raises WEB_WORKERS.INVALID_TRANSFER, and a one-shot abort-signal
wiring helper that returns a cleanup closure.
Extracting them avoids duplication between BaseWorkerManager and
MessageBus (both need clock, id-generator, and abort wiring) and keeps
the base manager's main file under the 300-line ceiling.
Features
defaultClock— wall-clockDate.now()Clock implementation.defaultIdGenerator— cryptographically random 16-hex-character ids.validateTransfer(transfer)— passes throughundefinedand arrays, throwsWebWorkersError(INVALID_TRANSFER)for anything else (string, object, number).wireAbortSignal(signal, onAbort)— registers a one-shot abort listener and returns a cleanup function that removes it.
Usage: Basic Example
import {
defaultIdGenerator,
validateTransfer,
} from "@suaveplan/web-workers/base-manager";
const id = defaultIdGenerator();
const transfer = validateTransfer(opts?.transfer);
Usage: Advanced Example
import { wireAbortSignal } from "@suaveplan/web-workers/base-manager";
function withAbort<T>(
signal: AbortSignal | undefined,
onTimeout: () => void,
promise: Promise<T>
): Promise<T> {
const cleanup = wireAbortSignal(signal, onTimeout);
return promise.finally(() => {
cleanup?.();
});
}
API Reference
defaultClock: Clock—() => Date.now().defaultIdGenerator: IdGenerator—() => stringreturning 16 lowercase-hex chars (64 bits of entropy).validateTransfer(transfer: Transferable[] | undefined): Transferable[] | undefined— pass-through on undefined / array; throws on non-array.wireAbortSignal(signal: AbortSignal | undefined, onAbort: () => void): (() => void) | undefined— returns a cleanup closure orundefinedwhensignalis undefined.
Implementation Notes
defaultIdGenerator uses crypto.getRandomValues(new Uint8Array(8)) and
hex-encodes the bytes. 64 bits of entropy is sufficient for per-process
RPC correlation (birthday-paradox collision probability is < 1e-9 for
fewer than 10⁵ outstanding requests). wireAbortSignal uses
addEventListener('abort', listener, { once: true }) so the listener
removes itself after firing — the returned cleanup is therefore safe to
call any number of times. validateTransfer is intentionally permissive
on the array's contents (it doesn't try to prove every element is actually
Transferable); structured-clone will throw at postMessage time if a
non-transferable slips in. Surfacing that error is the transport's job,
not the validator's.