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,73 @@
# `last-event-id`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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
```ts
import { parseLastEventId } from "@suaveplan/api-sse-bun";
const id = parseLastEventId(request.headers.get("last-event-id"));
if (id !== null) {
// ...consult replay buffer...
}
```
## Usage: Advanced
```ts
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.