Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# `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-clock `Date.now()` Clock implementation.
- `defaultIdGenerator` — cryptographically random 16-hex-character ids.
- `validateTransfer(transfer)` — passes through `undefined` and arrays,
throws `WebWorkersError(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
```ts
import {
defaultIdGenerator,
validateTransfer,
} from "@suaveplan/web-workers/base-manager";
const id = defaultIdGenerator();
const transfer = validateTransfer(opts?.transfer);
```
## Usage: Advanced Example
```ts
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` — `() => string` returning 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 or `undefined` when `signal` is 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.