Files
2026-05-27 23:29:53 +01:00

121 lines
5.8 KiB
Markdown

# Tasks: enterprise-browser-web-workers
**Change ID**: enterprise-browser-web-workers
**Package**: `@suaveplan/web-workers`
**Target path**: `browser/platform/web-workers`
**Prerequisite packages on Verdaccio**: `@suaveplan/events`, `@suaveplan/error`, `@suaveplan/logger`
---
## 0. Pre-flight (non-negotiable)
- [ ] 0.1 Confirm clean working tree (`git status` reports nothing) and no in-flight worktrees with uncommitted work (`git worktree list` then `git status` in each)
- [ ] 0.2 If any worktrees exist under `.claude/worktrees/`, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (`git worktree remove`) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
- [ ] 0.3 Confirm the package set in `MANIFEST.md` matches `find packages -maxdepth 3 -name package.json` count. Drift here means a prior change archived without regenerating the manifest.
## 1. Scaffold
- [ ] Create directory tree per `proposal.md`.
- [ ] `package.json` v0.0.0, `"sideEffects": false`.
- `dependencies`: `@suaveplan/events workspace:^`, `@suaveplan/error workspace:^`, `@suaveplan/types workspace:^`, `@suaveplan/logger workspace:^`, `@suaveplan/schema-registry workspace:^`, `zod catalog:forms`, `@opentelemetry/api catalog:observability`, `tslib catalog:build`
- `devDependencies`: `vitest catalog:testing`, `@vitest/coverage-istanbul catalog:testing`, `happy-dom catalog:testing`, `@suaveplan/testing workspace:^`
- Subpath exports: `"."`, `"./worker-manager"`, `"./shared-worker-manager"`, `"./worker-pool"`, `"./message-bus"`, `"./helpers/vite-worker"`
- [ ] `tsconfig.json`, `vitest.config.ts` (pool: forks, happy-dom environment).
---
## 2. Error codes
- [ ] `WORKER_NOT_FOUND`, `WORKER_QUEUE_FULL`, `WORKER_REQUEST_TIMEOUT`, `WORKER_CIRCUIT_OPEN`.
- [ ] `registerWebWorkerErrorCodes()` — call eagerly.
---
## 3. Types (`src/types/web-workers.types.ts`)
- [ ] `WorkerConfig`, `WorkerStatus`, `WorkerFactory`, `WorkerLike`, `WorkerMessage`, `WorkerPoolConfig`, `WorkerTask`, `PoolMetrics`, `MessageBusEventMap`, `WorkerManagerEventMap`, `RequestOptions`, `SharedWorkerFactory`.
- [ ] Write `web-workers.types.md`.
---
## 4. `BaseWorkerManager` (`src/core/base-manager/`)
- [ ] `base-manager.ts` — shared correlation-ID map, timeout logic, event emission, `AbortSignal` wiring.
- [ ] `WorkerManager` and `SharedWorkerManager` both extend this.
- [ ] Write `base-manager.md`.
---
## 5. Circuit breaker (`src/worker-manager/circuit-breaker/`)
- [ ] `circuit-breaker.ts` — state machine (closed → open → half-open); injectable clock; `record(success)`, `isOpen()`, `reset()`.
- [ ] Write `circuit-breaker.test.ts` (open on N failures, half-open after cooldown, reset on success). Write `circuit-breaker.md`.
---
## 6. `WorkerManager` (`src/worker-manager/worker-manager/`)
- [ ] `worker-manager.ts` — extends `BaseWorkerManager`; `create`, `postMessage` (with transfer list), `sendRequest` (with `AbortSignal` + backpressure ceiling), `terminate`, `terminateAll`, `has`, `getStatus`, `getWorkerNames`, `onError`.
- [ ] Wire circuit breaker and OTel metrics.
- [ ] Wire `@suaveplan/events` runtime emission.
- [ ] Write `worker-manager.test.ts` (create, postMessage, sendRequest, abort, backpressure, circuit open). Write `worker-manager.md`.
---
## 7. `SharedWorkerManager` (`src/shared-worker-manager/shared-worker-manager/`)
- [ ] `shared-worker-manager.ts` — `new SharedWorker(url)`; one `MessagePort` per named connection; `connect`, `disconnect`, `sendRequest` (AbortSignal).
- [ ] Write `shared-worker-manager.test.ts` (connect, message, disconnect). Write `shared-worker-manager.md`.
---
## 8. `WorkerPool` (`src/worker-pool/worker-pool/`)
- [ ] `worker-pool.ts` — FIFO task queue, round-robin dispatch, `minIdle`/`maxIdle`, health checks, per-task timeout, drain.
- [ ] `getMetrics()` returning `PoolMetrics` (size, idle, pending, completed, failed).
- [ ] Write `worker-pool.test.ts` (submit, saturation, backpressure, drain, health-check eviction). Write `worker-pool.md`.
---
## 9. `MessageBus` (`src/message-bus/message-bus/`)
- [ ] `message-bus.ts` — topic pub/sub, `subscribeOnce`, `broadcast`, `request` (AbortSignal), `registerHandler`, subscriber count, topic enumeration.
- [ ] Wire `@suaveplan/events` runtime emission via `MessageBusEventMap`.
- [ ] Write `message-bus.test.ts` (subscribe, publish, request/response, abort, broadcast). Write `message-bus.md`.
---
## 10. Streaming RPC (`src/streaming/stream/`)
- [ ] `stream.ts` — `sendStream<T>(manager, name, type, payload): AsyncIterable<T>` using correlation IDs and `MessagePort` transfer.
- [ ] Write `stream.test.ts`. Write `stream.md`.
---
## 11. Vite worker helper (`src/helpers/vite-worker/`)
- [ ] `vite-worker.ts` — `defineWorker(url, options?)` using `new URL(url, import.meta.url)`; exports factory and type.
- [ ] Write `vite-worker.test.ts`. Write `vite-worker.md`.
---
## 12. Integration test (`tests/integration.test.ts`)
- [ ] `WorkerManager` + `MessageBus` together: publish from worker, subscribe in main.
- [ ] `WorkerPool` saturation test with 10 concurrent tasks and `maxIdle: 3`.
- [ ] `AbortSignal` cancels in-flight `sendRequest`.
- [ ] Transfer `ArrayBuffer` via transfer list (verify zero-copy).
---
## 13. Docs + verify
- [ ] Write `.md` per module (≥200 words, API reference, examples).
- [ ] Write `README.md` with subpath table, pool guide, streaming RPC example, circuit-breaker reference.
- [ ] `bunx turbo lint typecheck test --filter=@suaveplan/web-workers` — green.
- [ ] `bunx turbo test:coverage` — 100%.
- [ ] No `@ts-expect-error` in `src/` or tests. No `vi.stubGlobal`.
- [ ] `SharedWorkerManager` and `WorkerPool` fully implemented (no stubs).
- [ ] `bun scripts/publish.ts --package @suaveplan/web-workers`.
- [ ] Archive to `openspec/archive/2026-04-24-enterprise-browser-web-workers/`.