Event stream
useEventStream subscribes to workspace events and invalidates queries automatically.
useEventStream opens a WebSocket to the workspace event hub and debounces cache invalidations so your queries stay fresh in near real-time. In most cases, adding it once at the top of your app is all you need.
Basic — auto-invalidate all caches
import { useEventStream } from "@aeontel/react";
function WorkspaceShell({ workspaceId, children }: Props) {
const { connected } = useEventStream(workspaceId);
return (
<>
<ConnectionPill connected={connected} />
{children}
</>
);
}Every event routes to the matching entity's key factory and calls invalidateQueries — agent.updated invalidates agentKeys.all(), run.completed invalidates runKeys.all(), and so on. Invalidations batch on a 500ms debounce to avoid thrash.
With callbacks and filters
useEventStream(workspaceId, {
filter: ["run.completed", "agent.*"], // glob patterns
onEvent: (event) => {
if (event.type === "run.completed")
toast.success(`Run ${event.subjectId} done`);
},
});The filter is server-side — only matching events are sent over the wire.
Disabling
Pass undefined as the workspace id to keep the hook mounted but inactive (e.g. while the user is on a workspace-less route):
const { connected } = useEventStream(currentWorkspaceId ?? undefined);Polling fallback
When connected is true, you can drop list polling to a 60s safety net. See getRefetchInterval for the pattern.