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 @@
# `internals`
## Purpose
`internals.ts` holds the small internal types and helpers `worker-pool.ts`
needs but that don't make sense to surface in the public API: the
`PoolSlot` bookkeeping shape, the `QueuedTask` entry used while tasks
wait for a free worker, and the `slotConfig` helper that materialises a
`WorkerConfig` for a slot from the `WorkerPoolConfig`.
Splitting these out keeps the main pool file under the 300-line ceiling
and makes the internal shapes independently importable from a sibling
helper file or future selector.
## Features
- `PoolSlot` — per-slot mutable record: `name`, `restarts`, `pendingCount`.
- `QueuedTask` — pending submit waiting for a worker: `type`, `payload`,
`options`, `resolve`, `reject`.
- `slotConfig(poolConfig, name, defaultTimeoutMs)` — builds a complete
`WorkerConfig` while respecting `exactOptionalPropertyTypes` (no
`undefined`-valued keys leak through).
## Usage: Basic Example
```ts
import { slotConfig } from "@suaveplan/web-workers";
const cfg = slotConfig(
{ url: WORKER_URL, size: 4, taskTimeout: 10_000 },
"pool-0-abc",
30_000
);
// cfg === { name: "pool-0-abc", url: WORKER_URL, timeout: 10_000 }
```
## Usage: Advanced Example
```ts
import { slotConfig } from "@suaveplan/web-workers";
const cfg = slotConfig(
{
url: WORKER_URL,
size: 2,
type: "module",
maxPendingRequests: 64,
circuitBreaker: { failureThreshold: 3, resetMs: 30_000 },
},
"pool-1-xyz",
30_000
);
// cfg.type === "module"
// cfg.maxPendingRequests === 64
// cfg.circuitBreaker is the same object reference
```
## API Reference
- `interface PoolSlot { readonly name: string; restarts: number; pendingCount: number }`.
- `interface QueuedTask { type, payload, options, resolve, reject }`.
- `slotConfig(poolConfig: WorkerPoolConfig, name: string, defaultTimeoutMs: number): WorkerConfig`.
## Implementation Notes
`slotConfig` builds the target object incrementally rather than via
conditional-spread syntax (`...(x !== undefined ? { x } : {})`) because
the spread version flagged uncovered branches in istanbul that couldn't
be exercised once the spread expanded to an empty object. The incremental
`if (x !== undefined) cfg.x = x` form has the same semantics under
`exactOptionalPropertyTypes` (the key is absent rather than
`undefined`-valued) but every branch is reachable from a single test that
exercises the optional config field. The cast `-readonly [K in keyof WorkerConfig]: WorkerConfig[K]`
is used to allow incremental assignment of `readonly` fields on the
local variable, then the value is widened back to `WorkerConfig` at
return.