Client
EventProvider and typed hooks from @g14o/events/client.
pnpm add @g14o/events reactImport from @g14o/events/client in Client Components only.
Provider
"use client";
import { EventProvider } from "@g14o/events/client";
export function Providers({ children }: { children: React.ReactNode }) {
return (
<EventProvider
api={{ url: "/api/events", withCredentials: true }}
maxReconnectAttempts={3}
>
{children}
</EventProvider>
);
}EventProvider owns one shared EventSource. It connects after a hook registers at least one channel.
maxReconnectAttempts
| Value | Behavior |
|---|---|
0 | No retries — first drop sets status to error |
1…n | Retry up to n times with backoff, then error |
3 (default) | Same as above |
Infinity | Retry forever while subscribers exist |
Server-driven rotation (reconnect system events from maxDurationSecs) does not consume the failure budget; the counter resets on a successful connection.
Typed hooks
"use client";
import { createEvent } from "@g14o/events/client";
import type { Events } from "./events";
export const { useEvent, useChannel, useEventStatus } =
createEvent<Events>();Channel scoping and useChannel live on Channel.
useEvent
Primary subscribe API. Omit events to receive all user events on the joined channels. Set enabled: false to unregister without unmounting. When events is a literal union, narrowing event in onData narrows data to the matching payload type.
const { status } = useEvent({
events: ["notification.alert"],
enabled: true,
onData({ event, data }) {
console.log(event, data);
},
});See UseEventOptions for the full option table. Pass channels to scope delivery — see Channel.
useEventStatus
Returns the provider connection status: disconnected | connecting | connected | error.
Next steps
Subscribe and join delivery scopes on Channel. Wire the SSE edge on Handler and emit from Server.