npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@flamefrontend/sse-runtime-core

v0.10.0

Published

Framework-agnostic runtime for the Server-Sent Events lifecycle: typed events, reconnect with backoff, Last-Event-ID resumption, auth refresh, and connection status.

Readme

@flamefrontend/sse-runtime-core

Framework-agnostic TypeScript runtime for Server-Sent Events clients.

It provides typed event dispatch, reconnects with jittered backoff, Last-Event-ID resumption, auth refresh on 401, connection status, cleanup, and optional single-tab coordination across browser tabs.

Install

pnpm add @flamefrontend/sse-runtime-core

Quick Start

import { createSSEClient } from "@flamefrontend/sse-runtime-core";

type Events = {
  message: {
    id: string;
    text: string;
  };
};

const client = createSSEClient<Events>({
  key: ["chat", "123"],
  url: "/api/chats/123/stream",
  events: {
    message: (message) => {
      console.log(message.text);
    }
  }
});

await client.connect();
client.disconnect();

Event Format

id: 42
event: message
data: {"id":"42","text":"hello"}

JSON data: payloads are parsed before dispatch. Invalid JSON is delivered as the raw string payload.

Client API

  • connect(): Promise<void>
  • disconnect(): void
  • reconnect(): Promise<void> — force a fresh connection even when already open, resuming from the last event id; recovers a stream that looks open but has gone silent
  • ensureOpen(options?: { timeout?: number }): Promise<boolean> — wait until the stream is open; starts connecting if needed
  • getStatus(): SSEConnectionStatus
  • getError(): SSEError | null
  • getLastEventAt(): number | undefined — timestamp of the most recent event; a staleness signal for custom watchdogs
  • subscribeStatus(listener): () => void
  • subscribeError(listener): () => void
  • subscribeEvent(eventName, handler): () => void
  • subscribeAnyEvent(handler): () => void — observe every event as { type, data, raw } (raw is the unparsed data string)
  • getRole(): CoordinationRole | null / subscribeRole(listener): () => void — coordinated clients only; observe whether this tab is the "leader" or a "follower"

Core Options

  • key: stable stream identity, for example ["chat", chatId].
  • url: SSE endpoint URL.
  • enabled: set to false to start idle. The client still opens when you call connect(); enabled only controls auto-connect in the React adapter.
  • headers: static or async headers, resolved before each connection attempt.
  • credentials: passed to fetch, for example "include".
  • events: typed event handlers registered at creation time.
  • reconnect: backoff and retry limits.
  • auth: 401 refresh callback.
  • coordination: optional single-tab coordination.
  • heartbeat: reconnect when the stream is silent for too long.
  • openTimeout: abort the connection attempt if the server does not respond within this many ms.
  • retry: custom per-error shouldRetry predicate and getDelay function.
  • diagnostics: structured observability callbacks (onOpen, onDisconnect, onRawEvent, etc.).

Reconnect And Resumption

Reconnect is enabled by default. The runtime uses jittered exponential backoff, honors server retry fields, and stops reconnecting after manual disconnect().

When events include id, the latest id is sent as Last-Event-ID on reconnect.

attachLifecycleResume(client, options?) reconnects when the page regains focus, comes back online, or becomes visible again. It returns a cleanup function and is a no-op outside the browser:

import { attachLifecycleResume } from "@flamefrontend/sse-runtime-core";

const detach = attachLifecycleResume(client, { strategy: "reconnect" });

Set staleTimeoutMs and/or wakeDriftMs to also run a background watchdog that recovers a stream the browser never reported as broken — one that went silent or whose socket died while the device slept. minHiddenMs suppresses the visible trigger after a brief tab switch. See the API reference for all options.

Auth Refresh

const client = createSSEClient<Events>({
  key: ["chat", chatId],
  url: `/api/chats/${chatId}/stream`,
  headers: async () => ({
    Authorization: `Bearer ${await getAccessToken()}`
  }),
  auth: {
    onUnauthorized: refreshAccessToken,
    retryAfterRefresh: true
  }
});

createBearerAuth(getToken, options?) builds the headers + auth pair for the common case — the token is resolved before every attempt and again on 401:

createSSEClient<Events>({
  key: ["chat", chatId],
  url: `/api/chats/${chatId}/stream`,
  ...createBearerAuth(getAccessToken)
});

Reconnect Notifications

attachReconnectNotifications(client, handlers) maps status transitions to reconnect-lifecycle callbacks (drops and recoveries only, not the initial connect or a manual disconnect). It returns a cleanup function.

const detach = attachReconnectNotifications(client, {
  onReconnecting: () => showToast("Reconnecting…"),
  onReconnected: () => dismissToast(),
  onFailed: () => showToast("Connection lost")
});

Single-Tab Coordination

const client = createSSEClient<Events>({
  key: ["chat", chatId],
  url: `/api/chats/${chatId}/stream`,
  coordination: {
    enabled: true,
    mode: "single-tab"
  }
});

Tabs with the same key elect one leader through Web Locks. The leader owns the SSE connection and forwards events/status/errors through BroadcastChannel. When the leader goes away, a follower is promoted and resumes the stream from the last seen Last-Event-ID. Unsupported environments fall back to independent per-tab connections.

Known Limitations

  • A leader that reaches a terminal error status (for example after exhausting reconnect retries) keeps leadership and does not hand it off, so other tabs wait rather than racing to open a fresh connection that would likely fail the same way.
  • During the leadership handoff there is a sub-millisecond window in which an event from the new leader may be delivered ahead of a still-draining event from the previous leader. The window is bounded by microtask timing and does not affect steady-state ordering.

More Documentation

Full guide: https://github.com/FlameFront-end/sse-runtime#readme

License

MIT