Initial Commit
This commit is contained in:
51
openspec/archive/2026-05-26-api-router-in-memory/proposal.md
Normal file
51
openspec/archive/2026-05-26-api-router-in-memory/proposal.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# `@suaveplan/api-router-in-memory` — In-memory Router for tests
|
||||
|
||||
**Package**: `@suaveplan/api-router-in-memory`
|
||||
**Status**: PROPOSED
|
||||
**Type**: new-package
|
||||
**Stage**: 5 (Testing kit + conformance suites) — see umbrella `openspec/changes/api-plugin-foundation/`
|
||||
|
||||
## Why
|
||||
|
||||
Per design doc §13.2, the host testing-utility kit (`@suaveplan/api-host/testing`) ships REAL, in-memory implementations of every capability — production-grade adapters that happen to keep state in process memory, not test doubles. `api-router-in-memory` is the router slot of that kit: a `Router` that dispatches via a fetch-shaped function call rather than a real HTTP listener. Tests run with zero network setup, deterministic timing, and the full pipeline (auth → tenant → validation → handler → response validation → telemetry close) exercised in-process.
|
||||
|
||||
The package is also a load-bearing reference: every adapter in Stage 4 runs the same `runRouterConformance` suite (§13.4); this adapter is the canonical in-memory pass — if it fails the suite, the suite itself is suspect.
|
||||
|
||||
## What changes
|
||||
|
||||
Net-new package depending on `@suaveplan/api-router` (contract + `./testing` conformance), `@suaveplan/api-types`, `@suaveplan/error`.
|
||||
|
||||
- ADDED: `createInMemoryRouter(opts)` — direct-surface factory returning a `Router` whose `dispatch(request)` runs the full pipeline synchronously-ish (Promise-returning) without binding a socket.
|
||||
- ADDED: `host.fetch(method, path, init?)` integration — the `Router` exposes a `fetch`-shaped entry point compatible with the `createTestHost` test ergonomics shown in §13.2.
|
||||
- ADDED: `InMemoryRouterOptions` — Zod schema (`basePath?: string`, `trackRequests?: boolean` (default true — record every request for assertion)).
|
||||
- ADDED: `ROUTER_IN_MEMORY_*` error codes (`ROUTER_IN_MEMORY_NO_MATCH`, `ROUTER_IN_MEMORY_DUPLICATE_ROUTE`, `ROUTER_IN_MEMORY_INVALID_OPTIONS`).
|
||||
- ADDED: Test-recording surface — `router.requests` returns an array of every request that landed (for assertions); `router.reset()` clears the history.
|
||||
- ADDED: Registration in `@suaveplan/api-host/testing`'s adapter table as the default `router` adapter when callers pass `router: "in-memory"`.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- HTTP listener — by design.
|
||||
- Worker-proxy surface — Stage 5 adapters are direct-only; the conformance suite that lives in `api-router/testing` is also run against `api-router-hono` (which DOES ship both surfaces) so the proxy invariants are still pinned.
|
||||
- Streaming over network — the in-memory router supports `ReadableStream` body/response but no socket-level flushing semantics.
|
||||
|
||||
## Source mapping
|
||||
|
||||
Genesis-original. Source of design intent: `docs/superpowers/specs/2026-05-13-api-plugin-foundation-design.md`.
|
||||
|
||||
| Requirement | Design doc section |
|
||||
|---|---|
|
||||
| Real in-memory impl, not a double | §13.2 |
|
||||
| `host.fetch` integration | §13.2 |
|
||||
| Request recording for assertions | §13.2 (implicit via `host.events.published` pattern) |
|
||||
| Registered in `api-host/testing` adapter table | §15 Stage 5 |
|
||||
|
||||
## Verification approach
|
||||
|
||||
- `src/factory/create-in-memory-router.test.ts` — register routes, dispatch, recording, reset.
|
||||
- `src/factory/create-in-memory-router.spec-conformance.test.ts` — `runRouterConformance("in-memory-direct", ...)`.
|
||||
- `src/fetch-shape/fetch-shape.test.ts` — `host.fetch("POST", "/x", { body })` returns `Response`-shaped result with status / headers / body.
|
||||
- `tests/integration/integration.test.ts` — booted by `createTestHost`'s default adapter table; end-to-end pipeline executed.
|
||||
|
||||
## Migration impact
|
||||
|
||||
None — additive only.
|
||||
Reference in New Issue
Block a user