Markdown Files
name: ssexi description: | ssexi.js is a small companion to fixi that adds Server-Sent Events support: a long-lived HTTP stream where the server pushes HTML to the browser as things happen.
when_to_load: | LOAD when the user:
- Works with Server-Sent Events (SSE) in the browser
- Needs real-time server-to-client HTML streaming
- Uses ssexi with fixi.js for event-driven updates
- Handles text/event-stream responses
- Implements live feeds, notifications, or real-time dashboards
scope: | The ssexi skill covers:
- Server-Sent Events basics and browser support
- Integration with fixi.js lifecycle
- ssexi-specific events (fx:sse:open, fx:sse:message, etc.)
- Event routing to multiple targets
- Error handling for SSE streams
- JSON event routing for multi-target streaming
ssexi.js Skill Reference
Overview
ssexi.js is a small companion to fixi that adds Server-Sent Events support: a long-lived HTTP stream where the server pushes HTML to the browser as things happen.
ssexi adds no new attributes of its own. It hooks into fixi's request lifecycle and treats any response with Content-Type: text/event-stream as a live stream, swapping each incoming message into fx-target using fx-swap.
That means every fixi attribute you already use applies; the only thing that changes is the server's content type.
Events
ssexi dispatches a set of events on the target element during the stream lifecycle. All events bubble and are cancelable.
| event | when |
|---|---|
fx:sse:open | the SSE stream has been detected and is about to start. preventDefault() aborts processing. |
fx:sse:message | fired for every SSE message before swapping. preventDefault() stops the stream. |
fx:sse:swapped | after a message's data has been swapped in. Useful for auto-scroll, syntax highlighting, etc. |
fx:sse:{eventName} | fired for messages with a (non-JSON) event: field. These messages are not swapped. |
fx:sse:close | the stream has ended normally. |
fx:sse:error | an error occurred during streaming. |
The event.detail object includes cfg (the fixi config) along with response, message, or error depending on the event.
Examples
Live Feed
A div that subscribes to a /feed stream on init and appends each incoming message to its inner contents:
<div fx-trigger="fx:init" fx-action="/feed" fx-swap="beforeend"></div>
The server responds with text/event-stream and emits one data: <p>...</p> per push. fx-swap="beforeend" appends each fragment as it arrives.
Routing One Stream To Multiple Targets
By default one stream feeds one target. If a single stream needs to drive several parts of the page, the server can name an event with a JSON object instead of a plain word:
event: {"target":"#sidebar","swap":"innerHTML"}
data: <ul>...</ul>
event: {"target":"#feed","swap":"beforeend"}
data: <article>...</article>
ssexi parses the event name as JSON, resolves target via document.querySelector, and swaps using the named strategy. Any of target, swap, and transition can be omitted; they fall back to the values on cfg.
Plain (non-JSON) event names fire as ordinary fx:sse:{name} events on the subscribing element, so moxi handlers like on-fx:sse:done can react to them.
Auto-Scrolling Log
Streaming a log to a fixed-height div with a moxi handler that pins the scroll to the bottom after each swap:
<div id="log"
fx-trigger="fx:init"
fx-action="/logs/stream"
fx-swap="beforeend"
on-fx:sse:swapped="this.scrollTop = this.scrollHeight"></div>
fx:sse:swapped fires after each message has been inserted into the DOM, which is exactly when reading and setting scrollHeight gives the right value.
How It Works
ssexi integrates with fixi's request pipeline:
- Request issued - fixi makes the HTTP request as normal
- Response detected - If
Content-Type: text/event-stream, ssexi intercepts - Stream established - ssexi fires
fx:sse:openevent - Message received - For each SSE message:
- Parse the event name and data
- If event name is JSON, route to specified target/swap
- Otherwise, fire
fx:sse:{eventName}or process as default - Fire
fx:sse:messagebefore swapping - Swap data into target using specified swap mode
- Fire
fx:sse:swappedafter swap
- Stream ends - ssexi fires
fx:sse:closeevent - Error handling - Any errors fire
fx:sse:errorevent
Server-Sent Events Basics
SSE is a standard browser API for receiving push notifications from a server over HTTP. Key characteristics:
- Unidirectional - Server to client only (use POST/PUT for client to server)
- HTTP-based - Works over standard HTTP/HTTPS, no special protocols
- Auto-reconnect - Browser automatically reconnects if connection drops
- Text-only - Data is sent as UTF-8 text
- Event streaming - Multiple messages can be sent in a single long-lived connection
Server Response Format
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: First message\n\n
data: Second message\n\n
event: customEvent\ndata: Message with custom event\n\n
id: 123\ndata: Message with ID\n\n
Field names are case-sensitive. Each message is terminated by two newlines.
Integration with fixi
ssexi works transparently with fixi:
- Same attributes - Use
fx-action,fx-target,fx-swap, etc. as normal - Automatic detection - ssexi detects
text/event-streamresponses automatically - Event routing - All fixi lifecycle events still fire (
fx:config,fx:before, etc.) - Configuration - Use
fx:configto customize SSE requests before they're sent
Best Practices
- Use meaningful event names - For multi-target streaming, use JSON event names with clear target/swap specifications
- Handle errors gracefully - Listen for
fx:sse:errorand show user-friendly messages - Clean up on disconnect - Use
fx:sse:closeto clean up resources or show reconnection UI - Consider backpressure - For high-volume streams, be mindful of browser memory limits
- Use
beforeendfor feeds - Appending new content is the most common pattern for SSE - Leverage
fx:sse:swapped- For post-processing like auto-scroll, syntax highlighting, or animations - Combine with moxi - Use moxi handlers to add interactivity to streamed content
Common Use Cases
- Live feeds - Social media feeds, news updates, activity streams
- Notifications - Real-time notifications from the server
- Dashboards - Live updating metrics and status displays
- Collaboration tools - Seeing other users' changes in real-time
- Logging - Live server logs or debugging output
- Chat applications - Message delivery without polling
- Stock tickers - Real-time financial data updates
- Multiplayer games - Game state updates from the server
Quick Reference Card
┌─────────────────────────────────────────────────────────────┐
│ SSEXI.JS QUICK REFERENCE │
├─────────────────────────────────────────────────────────────┤
│ OVERVIEW │
│ Server-Sent Events support for fixi │
│ - Long-lived HTTP streams │
│ - Server pushes HTML to client │
│ - No new attributes │
│ - Integrates with fixi lifecycle │
├─────────────────────────────────────────────────────────────┤
│ EVENTS │
│ fx:sse:open - Stream starting (cancelable) │
│ fx:sse:message - Message received (before swap) │
│ fx:sse:swapped - After message swapped in │
│ fx:sse:{name} - Custom event name │
│ fx:sse:close - Stream ended normally │
│ fx:sse:error - Stream error occurred │
├─────────────────────────────────────────────────────────────┤
│ CONTENT-TYPE │
│ text/event-stream │
├─────────────────────────────────────────────────────────────┤
│ JSON EVENT ROUTING │
│ event: {"target":"#el","swap":"innerHTML"} │
├─────────────────────────────────────────────────────────────┤
│ USAGE WITH FIXI │
│ fx-trigger="fx:init" - Start on element init │
│ fx-action="/stream" - SSE endpoint │
│ fx-swap="beforeend" - Append new content │
└─────────────────────────────────────────────────────────────┘