Files
2026-05-27 23:29:53 +01:00

3.5 KiB

options

Purpose

Zod schema validating SsePluginOptions at the factory boundary. createSsePlugin calls SsePluginOptionsSchema.safeParse(options) and raises SseError(SSE_INVALID_INPUT) with the ZodError as cause on failure. The schema also encodes the canonical defaults so the plugin descriptor's resolved config reflects every documented default value without the implementation hand-coding them.

Features

  • Strict object validation rejects unknown keys to catch typos like heartBeatInterval.
  • Defaults applied via Zod's .default() so the resolved type has every field non-optional.
  • Numeric fields constrained: positive integers for time/cap fields; non-negative integer for retention (zero disables replay).
  • routePrefix regex matches /, /sse, /v1/sse, rejecting trailing-slash and missing-leading-slash forms.
  • Runtime objects (idGenerator, clock, logger) validated structurally via z.custom so duck-typed implementations are accepted.

Usage: Basic

import { SsePluginOptionsSchema } from "@suaveplan/api-plugin-sse/schemas/options";

const parsed = SsePluginOptionsSchema.parse({
    heartbeatIntervalMs: 15_000,
    maxConnectionsPerPrincipal: 4,
});
console.log(parsed.routePrefix); // "/sse" (defaulted)

Usage: Advanced

import { SsePluginOptionsSchema } from "@suaveplan/api-plugin-sse/schemas/options";
import { SSE_CODES, SseError } from "@suaveplan/api-plugin-sse/error-codes/error-codes";

function validateOrThrow(input: unknown) {
    const result = SsePluginOptionsSchema.safeParse(input);
    if (!result.success) {
        throw new SseError(SSE_CODES.INVALID_INPUT, "invalid SSE config", {
            cause: result.error,
        });
    }
    return result.data;
}

// User-supplied logger duck-typed against LoggerLike — accepted.
validateOrThrow({
    logger: {
        debug: console.debug,
        info: console.info,
        warn: console.warn,
        error: console.error,
    },
});

API Reference

  • SsePluginOptionsSchema — Zod object schema. Fields and defaults:
    • heartbeatIntervalMs — positive integer (default 30_000).
    • routePrefix — string matching ^/[A-Za-z0-9\-_/]*[A-Za-z0-9\-_]$|^/$ (default "/sse").
    • attachDefaultRoute — boolean (default true).
    • retentionPerChannel — non-negative integer (default 100).
    • maxConnectionsPerPrincipal — positive integer (default 16).
    • maxTotalConnections — positive integer (default 10_000).
    • queueHighWaterMark — positive integer (default 256).
    • overflowPolicy — "drop-oldest" | "drop-newest" (default "drop-oldest").
    • idGenerator — optional () => string.
    • clock — optional Clock from @suaveplan/types.
    • logger — optional LoggerLike from @suaveplan/types.
  • type SsePluginOptionsInput — z.input<typeof SsePluginOptionsSchema> (caller-facing shape).
  • type SsePluginOptionsResolved — z.output<typeof SsePluginOptionsSchema> (post-default shape).

Implementation Notes

  • The schema is .strict() — unknown keys produce a ZodIssueCode.unrecognized_keys issue. Intentionally strict so a typo doesn't silently fall back to a default.
  • The runtime-object validators do not require structural typing of every method — they sniff the presence of one canonical method (logger.info, clock.now) so callers can pass extended objects without rewriting them.
  • Defaults are intentionally generous for production use; tighten them in your createSsePlugin call if you run behind aggressive proxies or with constrained memory budgets.