58 lines
2.8 KiB
Markdown
58 lines
2.8 KiB
Markdown
# 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.
|