first commit
This commit is contained in:
76
docs/foundation/data/web-workers/src/base-manager/helpers.md
Normal file
76
docs/foundation/data/web-workers/src/base-manager/helpers.md
Normal 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.
|
||||
Reference in New Issue
Block a user