Loading repository data…
Loading repository data…
SourceRegistry / repository
Typed Server-Sent Events (SSE) integration for SvelteKit featuring strongly typed client-server communication, custom event channels, and first-class TypeScript support.
Typed Server-Sent Events (SSE) integration for SvelteKit — strongly-typed client–server communication, custom event channels, and a protocol-level control layer.
App.Events, giving compile-time guarantees for both event names and payloadsevent: field support with multiple application events per streamnpm install @sourceregistry/sveltekit-eventsource
Peer dependency: svelte@^5
Events are defined centrally using SvelteKit's App.Events interface:
// src/app.d.ts
declare global {
namespace App {
interface Events {
status: {
heartbeat: number;
};
}
}
}
export {};
This single definition drives server-side emit() typing, client-side on() typing, and compile-time safety across the entire SSE pipeline.
// src/routes/sse/+server.ts
import type { RequestHandler } from "./$types";
import { EventSource } from "@sourceregistry/sveltekit-eventsource/server";
export const GET: RequestHandler = () => {
const sse = new EventSource("status", { debug: true });
const timer = setInterval(() => {
sse.emit("heartbeat", Date.now());
}, 2000);
sse.once("close", () => {
clearInterval(timer);
});
// Ask the client to close after 5 s
setTimeout(() => {
sse.stop();
}, 5000);
return sse.response();
};
| Method / Property | Description |
|---|---|
emit(event, payload, id?) | Send a typed application event |
stop() | Send a protocol-level close request to the client |
response(init?) | Return a Response with Content-Type: text/event-stream |
isOpen | Whether the stream is currently open |
on(event, handler) | Subscribe to lifecycle events (open, close, ping) |
once(event, handler) | Subscribe once to a lifecycle event |
off(event, handler) | Unsubscribe from a lifecycle event |
unsafe.send(data, opts?) | Send an arbitrary untyped SSE message |
unsafe.events | Raw EventEmitter for lifecycle hooks |
<script lang="ts">
import { onMount, onDestroy } from "svelte";
import { EventSource } from "@sourceregistry/sveltekit-eventsource/client";
const events = $state<number[]>([]);
let state = $state<"open" | "closed">("closed");
let es: EventSource<"status">;
onMount(() => {
es = new EventSource("/sse", { debug: true });
es.onOpen(() => (state = "open"));
es.onClose(() => (state = "closed"));
es.on("heartbeat", (n) => {
events.push(n);
});
});
onDestroy(() => {
es?.close();
});
</script>
<p>Connection: {state}</p>
<ul>
{#each events as e}
<li>{e}</li>
{/each}
</ul>
| Method | Description |
|---|---|
on(event, handler) | Subscribe to a typed application event |
once(event, handler) | Subscribe once to a typed application event |
off(event, handler) | Unsubscribe a handler registered with on or once |
onOpen(handler) | Subscribe to the open lifecycle event |
onClose(handler) | Subscribe to the close lifecycle event |
onError(handler) | Subscribe to the error lifecycle event |
onMessage(handler) | Subscribe to default (unnamed) SSE messages |
close() | Initiate client-side close |
readyState | Native EventSource.readyState |
All handlers are fully typed via App.Events.
This library implements a protocol-level control channel independent of user serialization. User serializers (JSON, base64, msgpack, etc.) must not interfere with control messages such as server-requested close.
Wire format:
event: __MAGIC_EVENT__
data: {"v":1,"op":"close"}
Control messages are always JSON, versioned (v), validated at runtime, and forward-compatible.
Full specification: docs/sse-magic-protocol.md
| Path | Purpose |
|---|---|
@sourceregistry/sveltekit-eventsource/client | Browser client |
@sourceregistry/sveltekit-eventsource/server | SvelteKit server endpoint |
Protocol compatibility tests are included using Vitest:
npm test
Coverage includes protocol encoding, version mismatch handling, schema validation, and forward-compatibility safeguards.
Generate API documentation with TypeDoc:
npm run docs:build
Output is written to /docs.
Issues and pull requests are welcome. Please follow Conventional Commits — this project uses semantic-release for automated versioning and changelog generation.
Apache-2.0 © A.P.A. Slaa