Files
suaveplan/openspec/changes/enterprise-browser-web-workers/tasks.md
2026-05-27 23:29:53 +01:00

5.8 KiB

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/.