first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
# event
## Purpose
Zod schema validating the `SseEvent` shape accepted by `SseService.broadcast`. Ensures application payloads cannot bypass the boundary with malformed ids, negative `retry` values, or empty event names. Validation failure raises `SseError(SSE_INVALID_INPUT)` with the `ZodError` chained as `cause` so consumers can surface field-level diagnostics to upstream handlers.
## Features
- `id` is optional at the boundary — the service generates one via the configured `idGenerator` when absent. When supplied it must be a non-empty string.
- `event` (the SSE `event:` field) optional but non-empty when supplied.
- `data` accepts any JSON-serialisable value (`z.unknown()`); the handler is responsible for JSON serialisation on the wire.
- `retry` constrained to positive integers so a `retry: 0` or `retry: -1` cannot be sent (both are confusing in browsers).
## Usage: Basic
```ts
import { SseEventSchema } from "@suaveplan/api-plugin-sse/schemas/event";
const parsed = SseEventSchema.parse({ data: { kind: "ping" } });
// parsed.id is undefined; the service fills it from idGenerator
```
## Usage: Advanced
```ts
import { SseEventSchema } from "@suaveplan/api-plugin-sse/schemas/event";
import { SSE_CODES, SseError } from "@suaveplan/api-plugin-sse/error-codes/error-codes";
function safeBroadcast(service: { broadcast: (c: string, e: unknown) => void }, channel: string, raw: unknown) {
const parsed = SseEventSchema.safeParse(raw);
if (!parsed.success) {
throw new SseError(SSE_CODES.INVALID_INPUT, "invalid SSE event", {
cause: parsed.error,
context: { channel, raw },
});
}
service.broadcast(channel, parsed.data);
}
safeBroadcast(service, "notifications", { event: "ping", data: { ts: Date.now() } });
```
## API Reference
- `SseEventSchema` — Zod object schema. Fields:
- `id` — optional non-empty string.
- `event` — optional non-empty string.
- `data` — `z.unknown()` (any JSON-serialisable value).
- `retry` — optional positive integer (milliseconds).
- `type SseEventInputParsed` — `z.input<typeof SseEventSchema>` (caller-facing).
- `type SseEventResolved` — `z.output<typeof SseEventSchema>` (post-validation).
## Implementation Notes
- The schema is intentionally NOT `.strict()` because applications may pass through additional metadata as part of the broadcast call (`tags`, `severity`, etc.). The service does not propagate unknown fields to the wire — only `id`, `event`, `retry`, `data` are framed.
- `data: undefined` is rejected — `undefined` cannot be JSON-stringified and would silently drop the payload at framing time.
- A stricter `data` schema (e.g. `z.object({ kind: z.string() })`) belongs in application code that composes its own broadcast wrappers. The plugin level is intentionally permissive to support arbitrary payloads.