Files
suaveplan/packages/api-stack/api/api-host/README.md
2026-05-27 23:29:53 +01:00

119 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# @suaveplan/api-host - Host orchestration core for the Suaveplan API plugin system. Provides the stable error-code registry (HOST/PLUGIN/RELOAD/CAPABILITY/ADMIN/LEDGER), the author-facing definePlugin DX, the runtime CapabilityRegistry, the LifecycleDriver + ReloadDriver + PluginLedger + admin Hono sub-router, the ErrorBoundary, the §6 11-step RequestPipeline, the top-level createHost(config) entry point composing every internal driver, and the HostInstruments registry covering the §12.3 metric surface. The ./testing subpath is reserved.
> host orchestration core for the Suaveplan API plugin system.
This package is the **keystone** of the API plugin system. Every downstream package either consumes `api-host` directly (worker proxies talk to it) or extends it (adapters register with its `CapabilityRegistry`).
<!-- begin:auto-docs -->
## Documentation tree
- [admin-api](./src/admin-api/admin-api.md) — `createAdminApi` builds the host-side Hono sub-router that exposes the design §8.4 admin surface — every operational en…
- [admin-api](./src/admin-api/admin-api.md) — `createAdminApi` builds the host-side Hono sub-router that exposes the design §8.4 admin surface — every operational en…
- [audit-sink](./src/admin-api/audit-sink.md) — `MemoryAdminAuditSink` is the in-memory default audit sink for the host's admin API. Every admin endpoint emits a struc…
- [idempotency-store](./src/admin-api/idempotency-store.md) — `InMemoryIdempotencyStore` is the process-local default for the admin API's `Idempotency-Key` enforcement. Mutating adm…
- [rate-limiter](./src/admin-api/rate-limiter.md) — `AdminRateLimiter` enforces the design §8.4 per-principal rate limits on every admin endpoint. Read endpoints share a 6…
- [capability-registry](./src/capability-registry/capability-registry.md) — The `CapabilityRegistry` is the live, single-instance store of every capability adapter wired into a host process. Stag…
- [capability-registry](./src/capability-registry/capability-registry.md) — The `CapabilityRegistry` is the live, single-instance store of every capability adapter wired into a host process. Stag…
- [define-plugin](./src/define-plugin/define-plugin.md) — `definePlugin` is the canonical entry point plugin authors call to declare their `name` / `version` / `requires` / `iso…
- [define-plugin](./src/define-plugin/define-plugin.md) — `definePlugin` is the canonical entry point plugin authors call to declare their `name` / `version` / `requires` / `iso…
- [empty-secrets](./src/empty-secrets/empty-secrets.md) — `EmptySecrets` is the no-op default `SecretsLike` implementation the host injects into every `PluginContext` / `Request…
- [empty-secrets](./src/empty-secrets/empty-secrets.md) — `EmptySecrets` is the no-op default `SecretsLike` implementation the host injects into every `PluginContext` / `Request…
- [error-boundary](./src/error-boundary/error-boundary.md) — The `ErrorBoundary` wraps every step of the per-request pipeline (design doc §6 steps 1–11) and projects every captured…
- [error-boundary](./src/error-boundary/error-boundary.md) — The `ErrorBoundary` wraps every step of the per-request pipeline (design doc §6 steps 1–11) and projects every captured…
- [error-codes](./src/error-codes/error-codes.md) — This module owns every stable error code raised by `@suaveplan/api-host` and its sub-drivers (lifecycle, hot reload, ca…
- [error-codes](./src/error-codes/error-codes.md) — This module owns every stable error code raised by `@suaveplan/api-host` and its sub-drivers (lifecycle, hot reload, ca…
- [host](./src/host/host.md) — `createHost(config)` composes every internal driver (`LifecycleDriver`, `ReloadDriver`, `PluginLedger`, `CapabilityRegi…
- [host](./src/host/host.md) — `createHost(config)` composes every internal driver (`LifecycleDriver`, `ReloadDriver`, `PluginLedger`, `CapabilityRegi…
- [hot-reload](./src/hot-reload/hot-reload.md) — `ReloadDriver` implements the §8.1 blue-green hot-reload primitive plus the §8.1a `RollbackJournal` integration. Each `…
- [file-watcher](./src/hot-reload/file-watcher.md) — `FileWatcher` is the dev-mode file-system watch primitive consumed by `ReloadDriver`'s §8.3 trigger path. Each `registe…
- [hot-reload](./src/hot-reload/hot-reload.md) — `ReloadDriver` implements the §8.1 blue-green hot-reload primitive plus the §8.1a `RollbackJournal` integration. Each `…
- [lifecycle](./src/lifecycle/lifecycle.md) — `LifecycleDriver` is the runtime executor for the per-plugin lifecycle FSM defined in `@suaveplan/api-lifecycle`. It ow…
- [lifecycle](./src/lifecycle/lifecycle.md) — `LifecycleDriver` is the runtime executor for the per-plugin lifecycle FSM defined in `@suaveplan/api-lifecycle`. It ow…
- [otel](./src/otel/otel.md) — `createHostInstruments` builds the frozen bundle of every OpenTelemetry counter and histogram the host emits on a produ…
- [otel](./src/otel/otel.md) — `createHostInstruments` builds the frozen bundle of every OpenTelemetry counter and histogram the host emits on a produ…
- [in-memory-bus](./src/pipeline-events-bus/in-memory-bus.md) — `InMemoryPipelineEventsBus` is the canonical fixture wired by `createTestHost` (test keystone) and consumed by every…
- [noop-bus](./src/pipeline-events-bus/noop-bus.md) — `NoopPipelineEventsBus` is the default value the host installs on `HostAdapters.pipelineEvents` when no operator-suppli…
- [pipeline-events-constants](./src/pipeline-events-bus/pipeline-events-constants.md) — `@suaveplan/api-types` is types-only — adding a runtime export there breaks the byte-size invariant CI enforces. The `P…
- [plugin-ledger](./src/plugin-ledger/plugin-ledger.md) — `PluginLedger` is the host-owned metadata store backing every plugin record the API host orchestrates. It persists the…
- [migrations](./src/plugin-ledger/migrations.md) — `HostMigrationRunner` is the forward-only idempotent migration engine the API host runs against its plugin ledger DB. I…
- [plugin-ledger](./src/plugin-ledger/plugin-ledger.md) — `PluginLedger` is the host-owned metadata store backing every plugin record the API host orchestrates. It persists the…
- [request-pipeline](./src/request-pipeline/request-pipeline.md) — `RequestPipeline` implements the design-doc §6 per-request data flow exactly: tenant resolve, CSRF check, session resol…
- [request-pipeline-driver](./src/request-pipeline/request-pipeline-driver.md) — This module exports the `runPipeline` function: the orchestrator that chains the §6 step gates (`request-pipeline-steps…
- [request-pipeline-emitters](./src/request-pipeline/request-pipeline-emitters.md) — This module owns the three side-effecting closers the §6 pipeline calls once a request has reached its outcome: `emitAu…
- [request-pipeline-helpers](./src/request-pipeline/request-pipeline-helpers.md) — This module concentrates the pure (no-`this`, no side-effecting) helpers the §6 request pipeline relies on: request-id…
- [request-pipeline-outcomes](./src/request-pipeline/request-pipeline-outcomes.md) — This module ties the bare emitters and validators together for the orchestrator. It exposes `DriverConfig` (the frozen…
- [request-pipeline-stage-emit](./src/request-pipeline/request-pipeline-stage-emit.md) — This module wraps the `PipelineEventsBus.emit` calls the §6 11-step driver makes around every stage. The helper central…
- [request-pipeline-stage-skip](./src/request-pipeline/request-pipeline-stage-skip.md) — The §6 11-step request pipeline has four stages (`csrf`, `capability`, `idempotency`, `audit`) that may be conditionall…
- [request-pipeline-steps](./src/request-pipeline/request-pipeline-steps.md) — This module hosts the six per-request gate functions the §6 pipeline runs after route match and before plugin handler i…
- [request-pipeline-validation](./src/request-pipeline/request-pipeline-validation.md) — This module owns the two Zod-validation functions the §6 pipeline runs: `validateRequest` (step 6) parses body / query…
- [request-pipeline](./src/request-pipeline/request-pipeline.md) — `RequestPipeline` implements the design-doc §6 per-request data flow exactly: tenant resolve, CSRF check, session resol…
- [reserved-prefix](./src/reserved-prefix/reserved-prefix.md) — The reserved-prefix contract publishes the canonical list of URL path prefixes that `@suaveplan/api-host` (and every fi…
- [reserved-prefix](./src/reserved-prefix/reserved-prefix.md) — The reserved-prefix contract publishes the canonical list of URL path prefixes that `@suaveplan/api-host` (and every fi…
- [testing](./src/testing/testing.md) — `@suaveplan/api-host/testing` is a **reserved subpath** in API plugin system. The intent is to popul…
- [create-test-host](./src/testing/create-test-host/create-test-host.md) — `createTestHost` is The keystone of the `@suaveplan/api-host/testing` subpath. It composes every in-memory adap…
- [create-test-host](./src/testing/create-test-host/create-test-host.md) — `createTestHost` is The keystone of the `@suaveplan/api-host/testing` subpath. It composes every in-memory adap…
- [pipeline-events-conformance](./src/testing/pipeline-events-conformance/pipeline-events-conformance.md) — This harness drives a host factory's `RequestPipeline` through a known-shape happy-path request and a known-shape 404 r…
- [pipeline-events-conformance](./src/testing/pipeline-events-conformance/pipeline-events-conformance.md) — This harness drives a host factory's `RequestPipeline` through a known-shape happy-path request and a known-shape 404 r…
- [testing](./src/testing/testing.md) — `@suaveplan/api-host/testing` is a **reserved subpath** in API plugin system. The intent is to popul…
<!-- end:auto-docs -->
## Chunk status
`@suaveplan/api-host` ships in **chunks** per the precedent set by the `@suaveplan/pdf` migration. Chunk A — this release — ships the pieces every later chunk depends on:
| Subpath | Status | Description |
|---|---|---|
| `./error-codes` | ✅ Chunk A | Full union of `HOST_*` / `PLUGIN_*` / `RELOAD_*` / `CAPABILITY_*` / `ADMIN_*` codes + default status map + `HostError` class. Every later chunk's codes are pre-declared so the union is stable. |
| `./define-plugin` | ✅ Chunk A | `definePlugin<const Caps>(spec)` author DX + `PluginModule<Caps>` + derived context types. |
| `./capability-registry` | ✅ Chunk A | Runtime `CapabilityRegistry` with semver-shape validation, duplicate detection, `assertSatisfies` compat check, reverse-order disposers. `defineCapability(...)` helper. |
| `./otel` | ✅ Chunk A | `createHostInstruments` + `HOST_COUNTER_NAMES` (12) + `HOST_HISTOGRAM_NAMES` (4) covering the §12.3 surface; per-plugin meter cache. |
| `./testing` | ✅ Test tier | Populated with `createTestHost(config?)` — composes every test in-memory adapter into a running `Host` in one line. The legacy `STAGE_2_RESERVED` sentinel flips to `false`. The `runPipelineRouterConformance` harness still ships from this subpath. |
| `./lifecycle` | ⏳ Chunk B | `LifecycleDriver` — per-plugin FSM mutex, every §4 transition, auto-rollback hand-off, worker-tier `crashed` auto-restart. |
| `./hot-reload` | ⏳ Chunk B | `ReloadDriver` — blue-green primitive, `RollbackJournal` ring buffer, drain timer, native-binding guard. |
| `./plugin-ledger` | ⏳ Chunk C | Host-owned metadata DB + forward-only idempotent migrations. |
| `./admin-api` | ⏳ Chunk C | Hono sub-router for §8.4 endpoints + RBAC + rate-limit + audit envelope. |
| `./error-boundary` | ⏳ Chunk D | Per-step boundary mapping `SuaveplanError → manifest statusMap`, `AbortError → 499`. |
| `./request-pipeline` | ⏳ Chunk D | Steps 1–11 from §6 in documented order + CSRF gating + streaming bypass. |
| `./host` | ⏳ Chunk D | Top-level `createHost(config)` composing every driver. |
Until the follow-up chunks ship, this package is **not** a runnable host — it is the contract surface every downstream package can compile and link against.
## Modules
- [`src/error-codes/error-codes.md`](src/error-codes/error-codes.md) — error-code registry.
- [`src/define-plugin/define-plugin.md`](src/define-plugin/define-plugin.md) — author-facing plugin entry point.
- [`src/capability-registry/capability-registry.md`](src/capability-registry/capability-registry.md) — runtime capability registry.
- [`src/lifecycle/lifecycle.md`](src/lifecycle/lifecycle.md) — `LifecycleDriver` driving every §4 transition.
- [`src/hot-reload/hot-reload.md`](src/hot-reload/hot-reload.md) — `ReloadDriver` blue-green primitive (§8.1).
- [`src/hot-reload/file-watcher.md`](src/hot-reload/file-watcher.md) — debounced filesystem watcher.
- [`src/plugin-ledger/plugin-ledger.md`](src/plugin-ledger/plugin-ledger.md) — SQLite-backed host metadata store.
- [`src/plugin-ledger/migrations.md`](src/plugin-ledger/migrations.md) — forward-only migration runner.
- [`src/admin-api/admin-api.md`](src/admin-api/admin-api.md) — Hono admin sub-router (§8.4).
- [`src/admin-api/audit-sink.md`](src/admin-api/audit-sink.md) — pluggable audit sink.
- [`src/admin-api/idempotency-store.md`](src/admin-api/idempotency-store.md) — Idempotency-Key store.
- [`src/admin-api/rate-limiter.md`](src/admin-api/rate-limiter.md) — admin token-bucket limiter.
- [`src/error-boundary/error-boundary.md`](src/error-boundary/error-boundary.md) — §12.7 pipeline-step throw containment.
- [`src/request-pipeline/request-pipeline.md`](src/request-pipeline/request-pipeline.md) — §6 11-step per-request driver.
- [`src/host/host.md`](src/host/host.md) — top-level `createHost(config)` composing every internal driver.
- [`src/otel/otel.md`](src/otel/otel.md) — host instrument registry.
- [`src/testing/testing.md`](src/testing/testing.md) — RESERVED subpath for test utilities.
## Conformance posture
`api-host` carries `suaveplan.conformanceSkip` for `api-lifecycle`, `api-loader`, `api-manifest`, and `api-secrets`. These four packages each export a `run*Conformance(factory)` harness expecting the consumer to PROVIDE a concrete implementation of the contract (`LifecycleDriverFactory`, `ManifestSchemaSet`, etc.). `api-host` is the orchestrator that DRIVES those contracts — it consumes the abstract types, composes them via `LifecycleDriver` / `ReloadDriver` / `RequestPipeline`, and threads `SecretsLike` through `ctx.secrets`. It does not implement the abstract types itself.
The `./testing` `createTestHost(...)` factory is the canonical proof that `api-host` composes the four contracts correctly. The `e2e/foundation-stack-test-host` Playwright suite drives every contract through `createTestHost` end-to-end and asserts on the observable behaviour (lifecycle install → start → handler invocation → secret resolution → ledger persistence). When the §16 `check-conformance-tests.ts` lint reports `api-host` as a consumer without conformance tests, the skip plus the e2e smoke is the documented answer.
If a future change extracts the conformance harnesses into adapter-agnostic forms (i.e., the harness signature shifts from `factory: () => Impl` to `factory: () => Driver`), the skip can be removed and the harness invoked through `createTestHost`'s adapter bag.
## Install
```bash
bun add @suaveplan/api-host
```
## License
MIT