MarkdownCommitsConfig

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.

eventwhen
fx:sse:openthe SSE stream has been detected and is about to start. preventDefault() aborts processing.
fx:sse:messagefired for every SSE message before swapping. preventDefault() stops the stream.
fx:sse:swappedafter 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:closethe stream has ended normally.
fx:sse:erroran 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:

  1. Request issued - fixi makes the HTTP request as normal
  2. Response detected - If Content-Type: text/event-stream, ssexi intercepts
  3. Stream established - ssexi fires fx:sse:open event
  4. 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:message before swapping
    • Swap data into target using specified swap mode
    • Fire fx:sse:swapped after swap
  5. Stream ends - ssexi fires fx:sse:close event
  6. Error handling - Any errors fire fx:sse:error event

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:

  1. Same attributes - Use fx-action, fx-target, fx-swap, etc. as normal
  2. Automatic detection - ssexi detects text/event-stream responses automatically
  3. Event routing - All fixi lifecycle events still fire (fx:config, fx:before, etc.)
  4. Configuration - Use fx:config to customize SSE requests before they're sent

Best Practices

  1. Use meaningful event names - For multi-target streaming, use JSON event names with clear target/swap specifications
  2. Handle errors gracefully - Listen for fx:sse:error and show user-friendly messages
  3. Clean up on disconnect - Use fx:sse:close to clean up resources or show reconnection UI
  4. Consider backpressure - For high-volume streams, be mindful of browser memory limits
  5. Use beforeend for feeds - Appending new content is the most common pattern for SSE
  6. Leverage fx:sse:swapped - For post-processing like auto-scroll, syntax highlighting, or animations
  7. 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                   │
└─────────────────────────────────────────────────────────────┘