Skip to main content

Connection

The event stream is one long-lived HTTP response of server-sent events. Open it with the browser's built-in EventSource; you need no library.

Endpoint​

Method and pathGET /api/stream
Response typetext/event-stream
Reconnect delayretry: 1000 — one second, sent first on every connection
Keepalivea comment line, : keepalive, after 15 seconds with nothing else sent
Event namesnone: every event arrives as a plain message

Each event is one data: line holding a JSON object, the envelope. The stream sends only events you are allowed to see; the event catalog says who receives each entity.

Keepalives​

The keepalive is an SSE comment, so EventSource never surfaces it as an event. It keeps proxies and load balancers from closing a quiet connection.

Reconnecting​

When the connection drops, EventSource reconnects by itself after the one-second retry delay, the standard behaviour of any EventSource. You do not need to reconnect by hand.

The stream does not replay what you missed. Events carry no id: line, and a reconnect that sends Last-Event-ID gets no backlog. Anything that changed while you were disconnected is not resent, so refetch the state you show after every reconnect — the open event fires each time the connection is made, and is the place to do it.

The server may also close the stream itself, for example when your access changes. The same reconnect then brings you back with your current access.

Example — subscribe and filter by entity​

Paste this into the browser console on a page of the Jaah console, then edit a task in another tab. Each change to a task prints one line.

const stream = new EventSource('/api/stream')
const wanted = new Set(['task']) // the entities to act on; see the event catalog

stream.addEventListener('open', () => {
// Connected or reconnected: nothing is replayed, so refetch what you display here.
console.log('event stream open')
})

stream.addEventListener('message', (message) => {
const event = JSON.parse(message.data) // { entity, id, action }
if (!wanted.has(event.entity)) return
console.log(`${event.entity} ${event.id}: ${event.action}`)
// Refetch that item here, for example the task with this id.
})

stream.addEventListener('error', () => {
// A dropped connection. EventSource retries on its own after one second.
console.log('event stream interrupted, reconnecting')
})

// Stop listening: stream.close()

Editing a task's title prints a line such as task 4916: updated.