Client API
Everything exported from hotpipe/client. This is the client-side SDK for subscribing to events, publishing from the browser, and managing the WebSocket connection.
Returns { PipeProvider, usePipe, refreshPipeAuth }.
- Name
events- Type
- Record<string, ZodType>
- Description
- Zod schemas for your events. Required.
- Name
basePath- Type
- string
- Description
- Where your handler is mounted. Defaults to
/api/realtime.
- Name
authHeaders- Type
- () => Promise<Record<string, string>>
- Description
- Custom headers for the auth request (e.g., bearer tokens). Only needed if your auth doesn't use cookies.
- Name
onPipeRevoked- Type
- (pipe: string) => void
- Description
- Called when the server revokes access to a specific pipe.
- Name
onAllPipesRevoked- Type
- () => void
- Description
- Called when the server revokes access to all pipes.
import { createPipeClient } from 'hotpipe/client';
export const { PipeProvider, usePipe, refreshPipeAuth } = createPipeClient({
events: realtimeEvents,
basePath: '/api/realtime',
authHeaders: async () => ({
Authorization: `Bearer ${getAccessToken()}`,
}),
onPipeRevoked: (pipe) => {
// handle single pipe revocation
},
onAllPipesRevoked: () => {
// handle full revocation (e.g., redirect to login)
},
});Wrap your app (or a subtree) to establish the WebSocket connection to the Hotpipe API. The connection is managed automatically — it stays alive across hot reloads and only disconnects when the last provider unmounts.
- Name
pipe- Type
- string
- Description
- The pipe name to subscribe to.
- Name
handlers- Type
- { [event]: (data, metadata) => void }
- Description
- Event handlers, keyed by event name from your schema. Optional.
Each handler receives the typed event data as the first argument and a metadata object as the second:
- Name
metadata.sender- Type
- string | null
- Description
- Verified identity of the publisher. Set automatically from the authenticated user for client publishes,
nullfor server publishes (unless explicitly provided).
- Name
metadata.ts- Type
- number
- Description
- Server timestamp (ms) when the event was broadcast.
Returns { status, publish }:
- Name
status- Type
- 'connecting' | 'connected' | 'disconnected' | 'reconnecting'
- Description
- Reactive connection state. Updates automatically and triggers a re-render on change.
- Name
publish- Type
- (event, data) => boolean
- Description
- Send a typed event to everyone on this pipe. Data is validated against your Zod schema before sending. Returns
trueif the event was sent or queued,falseif the queue is full. Throws if the data fails validation. Events are buffered during brief disconnections (up to 100 events, within 30 seconds).
const { status, publish } = usePipe('team-chat', {
'message.created': (data, metadata) => {
// data is fully typed from your Zod schema
// metadata.sender — verified user ID or null
// metadata.ts — server timestamp (ms)
},
});The hook automatically subscribes when the component mounts and unsubscribes when it unmounts. If multiple components subscribe to the same pipe, Hotpipe ref-counts them — the subscription stays active until the last component unmounts.
Re-runs your authorize function and sends the updated permissions to the API without disconnecting. Call this after any action that changes the user's pipe access — creating a room, joining a channel, leaving a conversation.
Returns a Promise<void> that resolves when the new token has been sent to the API. Safe to call when disconnected (no-op). Concurrent calls are deduplicated into a single auth request.
Callable from anywhere — event handlers, server action callbacks, useEffect. Does not require React context.
import { refreshPipeAuth } from '@/lib/realtime-client';
// call after any action that changes the user's pipe access
await refreshPipeAuth();
