Realtime (Server-Sent Events)
A thin wrapper around the browser's EventSource API for Server-Sent Events, with automatic reconnection, heartbeat monitoring, and a few ready-made UI helpers for live counters, lists, and badges.
EventSource, which is one-way (server β browser) and text-based. It's a good fit for live counters, notifications, and activity feeds - not for bidirectional protocols like chat input.
Quick Start
1. Include the Module
<script src="https://cdn.jsdelivr.net/gh/OnigiriJS/onigirijs@v1.0.0/src/framework/realtime/onigiri-realtime.js"></script>
2. Connect and Listen
const connection = Onigiri.realtime.connect('/events/stream');
Onigiri.realtime.on('/events/stream', 'message', (data) => {
console.log('Received:', data);
});
Onigiri.realtime.on('/events/stream', 'open', () => {
console.log('Connected!');
});
API Reference
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
reconnect | Boolean | true | Automatically reconnect on error |
reconnectInterval | Number | 3000 | Delay between reconnect attempts, in ms |
maxReconnectAttempts | Number | 10 | Give up after this many attempts and emit reconnect-failed |
heartbeatInterval | Number | 30000 | How often to check for a stalled connection, in ms (0 disables it) |
withCredentials | Boolean | false | Send cookies with the SSE request (same-origin credentials) |
Pass these as the second argument to connect() to override them per-connection.
Methods
Onigiri.realtime.connect(url, options)
Opens an EventSource connection (or returns the existing one for that URL). Returns a connection object.
Onigiri.realtime.on(url, eventType, handler)
Registers a handler for 'open', 'message', 'error', or any custom SSE event name your server sends. Incoming data is JSON.parse'd automatically when possible, otherwise passed through as a string.
Onigiri.realtime.off(url, eventType, handler)
Removes a specific handler, or every handler for that event type if handler is omitted.
Onigiri.realtime.disconnect(url) / close(url)
Closes the connection for a URL and clears its handlers, heartbeat timer, and reconnect state. disconnectAll() does this for every open connection.
Onigiri.realtime.isConnected(url) / getStatus(url)
getStatus() returns 'connecting', 'connected', 'error', 'closed', or 'disconnected' (no connection at all).
Onigiri.SSE - Class-style wrapper
const stream = new Onigiri.SSE('/events/stream');
stream
.on('message', (data) => console.log(data))
.on('error', () => console.warn('Connection error'));
// Later
stream.close();
UI Helpers
Onigiri.liveCounter(url, selector, options)
Updates an element's text content whenever a matching event arrives, animating between the old and new value by default.
Onigiri.liveCounter('/events/visitors', '#visitor-count', {
eventType: 'count',
format: (n) => n.toLocaleString()
});
| Option | Default | Description |
|---|---|---|
eventType | 'count' | SSE event name to listen for |
initialValue | 0 | Starting displayed value |
format | (v) => v | Formats the number before display |
animate | true | Animate between old and new values |
Onigiri.liveList(url, selector, options)
Prepends (or appends) a rendered item to a list element for each matching event, trimming older items past maxItems.
Onigiri.liveList('/events/activity', '#activity-feed', {
eventType: 'item',
template: (item) => `<li>${Onigiri.security.sanitizeHTML(item.text)}</li>`,
maxItems: 50
});
template HTML-escapes the item before rendering it, since this is live, server-pushed content going straight into the page via innerHTML. If you supply your own template, escape any dynamic fields yourself (as above) - otherwise a value your server ever forwards unescaped (e.g. user-submitted chat/activity text) can inject markup into every connected visitor's page.
| Option | Default | Description |
|---|---|---|
eventType | 'item' | SSE event name to listen for |
template | escaped JSON in an <li> | Function returning the HTML for one item |
prepend | true | Add new items to the top instead of the bottom |
maxItems | 100 | Oldest items beyond this count are removed |
animate | true | Fade/slide new items in |
Onigiri.liveBadge(url, selector, options)
Updates an element's text and toggles a CSS class based on a threshold - handy for an "active now" style indicator.
Onigiri.liveBadge('/events/online', '#online-badge', {
eventType: 'badge',
threshold: 0,
className: 'badge-active'
});
Events
| Event | Fired when |
|---|---|
onigiri:realtime:connected | A connection opens (detail: { url }) |
onigiri:realtime:error | A connection errors (detail: { url, error }) |
onigiri:realtime:closed | A connection is closed via close() (detail: { url }) |
Security Notes
EventSourcefollows normal same-origin/CORS rules - it does not bypass them.- Anything you render from SSE data via
innerHTML(asliveList's template does) should be escaped, since it's effectively rendering server-pushed content live into every connected visitor's page.
β Development Roadmap
Track the progress of OnigiriJS modules. Tasks are marked complete by the development team.
OnigiriJS Module Roadmap
Implementation progress of planned modules