remix-sseServer Side Events (SSE) for Remix, made easy.
useSubscribe and only listen to events that match the topicnpm i remix-sse
See examples directory.
See basic example for more detail.
/routes/emitter.tsx for simplicityNote: This MUST be a resource route, you cannot return a component from this route.
import { EventStream } from 'remix-sse'
export const loader: LoaderFunction = ({ request }) => {
// Return the EventStream from your route loader
return new EventStream(request, (send) => {
// In the init function, setup your SSE Event source
// This can be any asynchronous data source, that will send
// events to the client periodically
// Here we will just use a `setInterval`
const interval = setInterval(() => {
// You can send events to the client via the `send` function
send('greeting', JSON.stringify({ hello: 'world'}))
}, 1000)
return () => {
// Return a cleanup function
clearInterval(interval)
};
});
};
Note: the first argument passed to the
sendfunction is theEventKey, this can be anything you want - but you will need to reference it again viauseSubscribe.
root.tsx with RemixSseProvider.
import { RemixSseProvider} from 'remix-sse/dist/client'
<RemixSseProvider>
<Outlet />
</RemixSseProvider>
Note: v4 has temporarily broken the flat file structure we used to have ie.
remix-sse/dist/clientinstead ofremix-sse/client
useEventSource to setup an EventSource in your browserimport { useEventSource } from 'remix-sse/dist/client'
useEventSource('/emitter');
useSubscribe from anywhere in your tree to begin listening to events emitted from the event source// This value is a react state object, and will change everytime
// an event is emitted
// By default this is a string[]
const greeting = useSubscribe('/emitter', 'greeting')
// But you can return only the latest event as follows
const latestGreeting = useSubscribe('/emitter', 'greeting', {
returnLatestOnly: true
})
// Or you can type the return by deserializing the event data
const typedGreeting = useSubscribe('/emitter', 'greeting', {
returnLatestOnly: true,
deserialize: (raw) => JSON.parse(raw) as Greeting
})
By default the data returned from useSubscribe is a string[]
You can pass a deserialize function to de-deserialize each event as it comes in.
Note: this feature is experimental and is subject to change.
See deserialize for more details.
useSubscribe options| Option | Description | Default |
|---|---|---|
maxEventRetention |
The maximum number of events that will be kept. | 50 |
returnLatestOnly |
Returns only the most recently emitted event - ie. returns TEvent instead of TEvent[] |
false |
These are currently being tested, and are subject to change at any point.
| Option | Description | Default |
|---|---|---|
deserialize |
A function that will receive the raw event data and returns a deserialized value. See deserialize example | undefined |
.
$ claude mcp add remix-sse \
-- python -m otcore.mcp_server <graph>