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

4.1 KiB

Tasks — Add @suaveplan/broadcast-channel

Every checkbox MUST reflect work actually done in this change. Retroactive ticking is the failure mode this template guards against.

1. Spec authoring

  • 1.1 Read ../suaveplan/enterprise/broadcast-channel.md end-to-end
  • 1.2 Read upstream src ../suaveplan/packages/browser/broadcast-channel/src/
  • 1.3 Read openspec/AGENTS.md §§2a/6a/7/12/13/14, CLAUDE.md, templates
  • 1.4 Draft proposal.md with ## Source mapping and ### Excluded from this migration
  • 1.5 Draft specs/broadcast-channel/spec.md with one ## ADDED Requirements block; every requirement has a **Verified by:** line authored at draft time

2. Implementation

  • 2.1 src/errors/codes.ts — BROADCAST_CHANNEL_CODES via defineCodes + four typed subclasses extending SuaveplanError
  • 2.2 src/id/id.ts — generateId(rng) using injectable Rng from @suaveplan/types
  • 2.3 src/schemas/messages.ts — ChannelMessageSchema, ChannelConfigSchema (Zod default import)
  • 2.4 src/types/broadcast-channel.types.ts — ChannelConfig, ChannelMessage<T>, TabInfo, BroadcastChannelEventMap, DEFAULT_CHANNEL_CONFIG, MAX_MESSAGE_BYTES_DEFAULT
  • 2.5 src/transport/transport.types.ts — ChannelLike (typed MessageEvent), ChannelFactory
  • 2.6 src/transport/native.ts — nativeChannelFactory wrapping global BroadcastChannel
  • 2.7 src/transport/local-storage.ts — StorageLike-backed polyfill factory
  • 2.8 src/otel/metrics.ts — six counters + refreshBroadcastChannelMeters
  • 2.9 src/channel/channel.ts — TypedBroadcastChannel (Zod boundary, OTel emission, payload guard, typed listener, injectables)
  • 2.10 src/index.ts — explicit named re-exports only

3. Tests

  • 3.1 src/channel/channel.test.ts — parity + payload guard + Zod boundary + logger injection
  • 3.2 src/transport/native.test.ts — happy-dom BroadcastChannel round-trip
  • 3.3 src/transport/local-storage.test.ts — fallback round-trip via in-memory StorageLike
  • 3.4 src/schemas/messages.test.ts — Zod accept/reject
  • 3.5 src/otel/metrics.test.ts — every counter asserted via in-memory MeterProvider
  • 3.6 src/id/id.test.ts — deterministic ID via seeded Rng
  • 3.7 src/errors/codes.test.ts — every code reachable from production path
  • 3.8 All tests import from @suaveplan/testing/runner; every it() has { timeout: 5000 } (or 30000 for async heartbeat)

4. Documentation

  • 4.1 Sibling .md for every implementation .ts (≥200 words, Purpose / Features / Basic / Advanced / API Reference / Implementation Notes)
  • 4.2 README.md linking every co-located .md under ## Modules

5. Pre-archive verification (5-gate triple)

  • 5.1 bunx biome check src/ (package-scoped) — 0 errors
  • 5.2 bunx turbo lint typecheck test --filter=@suaveplan/broadcast-channel — green
  • 5.3 bunx turbo test:coverage --filter=@suaveplan/broadcast-channel — 100/100/100/100
  • 5.4 bun scripts/openspec-conformance.ts @suaveplan/broadcast-channel — exit 0
  • 5.5 bunx turbo build --filter=@suaveplan/broadcast-channel — green

6. Pre-archive 9-row checklist

  • 6.1 Generics threaded (TypedBroadcastChannel, ChannelMessage<T>, send<T>, on<T>)
  • 6.2 Zod schemas wired at every declared boundary (inbound ChannelMessage frames)
  • 6.3 Every code in BROADCAST_CHANNEL_CODES thrown by ≥1 production path
  • 6.4 Strict-mode behaviors tested (closed-channel send, malformed message drop)
  • 6.5 OTel instruments emitted from production paths and asserted via real in-memory MeterProvider
  • 6.6 Lifecycle dedup tested (re-open is idempotent; close-before-open is no-op)
  • 6.7 No retroactive tick
  • 6.8 No export * in any feature-module barrel — explicit named exports only
  • 6.9 No direct vitest / bun:test imports — all tests via @suaveplan/testing/runner

7. Archive

  • 7.1 Fold spec delta into openspec/specs/broadcast-channel/spec.md
  • 7.2 Move openspec/changes/add-broadcast-channel/ → openspec/archive/2026-05-19-add-broadcast-channel/