Hcs.Sse

hcs · API reference

Server-Sent Events response helpers.

Use this module to format SSE events and return streaming SSE responses. For application fanout, subscribe each connection to a Hive pubsub topic and feed an Eio.Stream consumed by Sse.respond_with_stream or a generator consumed by Sse.respond.

Server-Sent Events response helpers.

Use this module on the server side to produce text/event-stream responses. SSE is a good fit for one-way browser updates, htmx out-of-band swaps, progress feeds, and lightweight live dashboards.

Example with Hive pubsub:

let events_handler bus _req =
  let events = Eio.Stream.create 32 in
  let unsubscribe =
    bus.Hive.Pubsub.subscribe ~topic:"updates" (fun ~payload ->
        Eio.Stream.add events (Hcs.Sse.event payload))
  in
  Hcs.Sse.respond (fun () ->
      try Some (Eio.Stream.take events)
      with Eio.Cancel.Cancelled _ as ex ->
        unsubscribe ();
        raise ex)

Behind buffering proxies, prefer respond_with_heartbeat.

type event = {
  event_type : string option;
  data : string;
  id : string option;
  retry : int option;
}

SSE event fields. data is required; the other fields are optional.

val event : string -> event

Create a default message event with only data.

val event_typed : event_type:string -> string -> event

Create an event with an explicit event type.

val make : ?event_type:string -> ?id:string -> ?retry:int -> string -> event

Create an event with any supported SSE fields. retry is milliseconds.

val format : event -> string

Format one event as SSE wire text.

val comment : string -> string

Format an SSE comment. comment "" returns the canonical keepalive ":\n\n".

val headers : (string * string) list

Standard response headers for SSE.

val respond : 
  ?flush_headers_immediately:bool ->
  (unit -> event option) ->
  Response.t

Build a streaming response from an event generator. Generator exceptions end the stream cleanly except for Eio cancellation, which propagates.

val respond_with_stream : 
  ?flush_headers_immediately:bool ->
  event Eio.Stream.t ->
  Response.t

Build a streaming response from an Eio.Stream of events.

val respond_with_heartbeat : 
  ?flush_headers_immediately:bool ->
  clock:_ Eio.Time.clock ->
  interval:float ->
  event Eio.Stream.t ->
  Response.t

Like respond_with_stream, but emits comment keepalives whenever no event arrives within interval seconds.

val respond_raw : 
  ?flush_headers_immediately:bool ->
  (unit -> string option) ->
  Response.t

Build a streaming response from preformatted SSE wire strings.

val respond_raw_stream : 
  ?flush_headers_immediately:bool ->
  string Eio.Stream.t ->
  Response.t

Build a streaming response from a stream of preformatted SSE wire strings.