4.2 KiB
@suaveplan/api-router-hono — Hono-backed Router adapter
Package: @suaveplan/api-router-hono
Status: PROPOSED
Type: new-package
Stage: 4 (Base adapters) — see umbrella openspec/changes/api-plugin-foundation/
Why
The plugin host needs a production-grade HTTP router. Hono is fast, Bun-native, has a mature middleware ecosystem, and supports streaming. This package implements the abstract Router contract from @suaveplan/api-router against Hono, including blue-green slot management so a plugin's route table can be swapped atomically during hot reload (design doc §8.1).
Per design doc §15 Stage 4: every adapter ships both a direct callable surface and a MessagePort-marshalled worker-proxy surface so it can serve trusted-tier and isolated/sandboxed-tier plugins from one codebase (§5.2a). The same conformance suite (runRouterConformance from §13.4) MUST pass against both surfaces — anything less is not shippable.
What changes
Net-new package depending on @suaveplan/api-router (contract), @suaveplan/api-types, @suaveplan/api-worker-rpc, @suaveplan/error, @suaveplan/logger, and hono as a peer dependency.
- ADDED:
createHonoRouter(opts)— factory returning the direct in-processRouterimplementation backed by a Hono instance per blue-green slot. - ADDED:
createHonoRouterWorkerProxy(port, opts)— factory returning the proxy surface; calls marshall over aMessagePortto a host-side Hono instance viaapi-worker-rpc. - ADDED:
HonoRouterOptions— Zod-validated config (basePath, trustProxy, maxBodyBytes, streamingTimeoutMs, blue-green strategy:"swap-on-health" | "swap-immediately"). - ADDED:
HonoBlueGreenSlot— internalBlueGreenSlotimpl managing two Hono instances (blue + green) and an atomic pointer. In-flight requests complete on the old slot; new requests route to the new slot once health passes. - ADDED:
ROUTER_HONO_*error codes (e.g.ROUTER_HONO_BLUE_GREEN_SWAP_FAILED,ROUTER_HONO_SLOT_NOT_READY,ROUTER_HONO_DUPLICATE_ROUTE,ROUTER_HONO_INVALID_PATTERN). - ADDED:
./testingsubpath — re-exportsrunRouterConformancefrom@suaveplan/api-router/testingalready bound tocreateHonoRouter; convenience for downstream tests.
Out of scope
- The abstract
Routerinterface, conformance suite, andBlueGreenSlotcontract — those live inapi-router(Stage 1). - HTTP server lifecycle (Bun.serve, address binding) —
api-router-honois a router only;api-hostowns the listening socket. - WebSocket upgrade —
api-ws-bunStage 7. - OpenAPI integration —
api-openapiStage 8 consumes route metadata from this adapter via theRoutercontract.
Source mapping
Genesis-original. Source of design intent: docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md.
| Requirement | Design doc section |
|---|---|
Router contract implementation |
§2.1, §6 (steps 1-2, 10) |
| Blue-green slot management | §8.1 |
| Worker-proxy variant required | §5.2a |
| Streaming bypasses buffering | §6 (streaming bullet) |
| Conformance suite passes both surfaces | §5.2a, §13.4 |
Verification approach
src/factory/create-hono-router.test.ts— direct-surface unit tests: route registration, dispatch, middleware ordering, streaming response.src/factory/create-hono-router.spec-conformance.test.ts— runsrunRouterConformance("hono-direct", createHonoRouter)and asserts the full ~30 invariants pass.src/proxy/create-hono-router-worker-proxy.test.ts— proxy-surface unit tests over an in-processMessageChannel.src/proxy/create-hono-router-worker-proxy.spec-conformance.test.ts— runsrunRouterConformance("hono-worker-proxy", makeProxyFactory)over a realWorker(orMessageChannelsimulation) and asserts every invariant passes.src/blue-green/hono-blue-green-slot.test.ts— atomic swap, in-flight completion on old slot, health-gated cutover, swap rollback on health failure.tests/integration/integration.test.ts— bootingcreateHonoRouteragainst a realBun.servelistener and exercising the full request pipeline end-to-end.
Migration impact
None — additive only. No package consumes @suaveplan/api-router-hono yet.