Files
skills/docs/api-stack/api/api-manifest/src/schema/sse.md
2026-05-29 08:20:56 +01:00

2.4 KiB

sseEndpointSchema + sseSchema

Purpose

Server-Sent-Events endpoint declarations. Mirrors the WebSocket block's shape minus the heartbeat/connection cap — SSE is half-duplex and the long-poll-style connection cost is lower so per-endpoint sizing isn't required at the manifest layer.

Features

  • Path must start with /
  • Optional auth scope
  • Optional subscription-subject list
  • Composable with websockets — a plugin can ship both

Basic Example

import { sseEndpointSchema } from "@suaveplan/api-manifest/schema";
sseEndpointSchema.parse({ path: "/feed" });

Advanced Example

import { sseSchema } from "@suaveplan/api-manifest/schema";
const feeds = sseSchema.parse([
  { path: "/feed", auth: "feed:read", subscriptions: ["feed.item"] },
]);

API Reference

  • sseEndpointSchema: z.ZodObject<{ path, auth?, subscriptions? }>
  • sseSchema: z.ZodReadonly<z.ZodArray<typeof sseEndpointSchema>>
  • SseEndpoint, Sse.

Implementation Notes

SSE is intentionally a separate block from WebSockets even though the host could synthesise one from the other — a plugin author typically picks the transport based on browser-support and proxy-traversal trade-offs, so making the choice explicit in the manifest makes the contract auditable. The host can still elect to emulate one over the other when capabilities are missing.

Cross-package Notes

This module is part of the @suaveplan/api-manifest Stage-1 contract package. It sits beneath every Stage-2 consumer (api-host, api-loader, the admin CLI, the IDE plugin) and above the foundation packages (@suaveplan/error, @suaveplan/types). The strict-mode top-level rejection of unknown keys means upgrading from manifest v1 to v2 is an OpenSpec-driven event: a new key landing in a consumer manifest is a parse failure rather than a silent drift, which is exactly the contract this stage exists to guarantee.

When the host reloads a plugin without a full restart, every manifest field this module validates is compared against the install-time manifestHash. A mismatch triggers a hard rollback via the RollbackJournal because the host's invariants (route mounts, registered capabilities, declared scopes) are derived from these exact bytes. Treat the schemas and validators here as the contract surface, not just an input filter — downstream code reads manifest.foo.bar and relies on those keys being present, well-typed, and non-undefined in the documented optionality regions.