Files
skills/docs/api-stack/api/api-sse-bun/src/last-event-id/last-event-id.md
2026-05-29 08:20:56 +01:00

2.1 KiB

last-event-id

(no submodules)

Purpose

The last-event-id module parses and validates the Last-Event-Id header browsers send automatically on EventSource reconnects. The engine consults the parsed value against the replay buffer; an empty or missing value means "start at live delivery", a well-formed value means "replay events with id > supplied first", a malformed value means "reject the handshake with SSE_BUN.LAST_EVENT_ID_INVALID".

Features

  • Returns null on missing/empty header (engine starts at live).
  • Validates decimal-string format /^\d+$/ so non-numeric ids cannot poison the replay-buffer lookup.
  • Throws SseBunError(LAST_EVENT_ID_INVALID) on bad input — never silently fails.

Usage: Basic

import { parseLastEventId } from "@suaveplan/api-sse-bun";

const id = parseLastEventId(request.headers.get("last-event-id"));
if (id !== null) {
    // ...consult replay buffer...
}

Usage: Advanced

import {
    parseLastEventId,
    SSE_BUN_CODES,
    SseBunError,
} from "@suaveplan/api-sse-bun";

try {
    const id = parseLastEventId(request.headers.get("last-event-id"));
    return id;
} catch (err) {
    if (
        err instanceof SseBunError &&
        err.code === SSE_BUN_CODES.LAST_EVENT_ID_INVALID
    ) {
        return new Response("bad Last-Event-Id", { status: 400 });
    }
    throw err;
}

API Reference

  • function parseLastEventId(raw: string | null): string | null — null in → null out; numeric string in → trimmed numeric string out; anything else → throws SseBunError(LAST_EVENT_ID_INVALID).

Implementation Notes

The decimal-only format is a deliberate choice: it sorts numerically when the engine reasons about "events with id > n" and it forbids the WHATWG-allowed embedded newlines that would otherwise need their own trimming pass. If the contract grows to admit ULIDs or UUIDs the validator becomes a discriminated union; the engine never builds the event id itself (it relies on the replay buffer's since to do the comparison), so callers downstream do not need to be updated when the format widens.