import type { Context } from "jsr:@hono/hono@4"; import { streamSSE } from "jsr:@hono/hono@4/streaming"; export interface DatastarSSEEvent { event?: string; // usually 'datastar-fragment', 'datastar-signal', etc data: string; // The HTML fragment or JSON payload id?: string; retry?: number; } export function streamDatastar( c: Context, callback: (stream: { write: (event: DatastarSSEEvent) => Promise; close: () => Promise; sleep: (ms: number) => Promise; aborted: boolean; }) => Promise, ) { // Set anti-buffering headers for Nginx / Traefik reverse proxies c.header("X-Accel-Buffering", "no"); c.header("Cache-Control", "no-cache, no-transform"); return streamSSE(c, async (stream) => { // Add custom datastar helper methods const adapter = { write: async (event: DatastarSSEEvent) => { await stream.writeSSE({ data: event.data, event: event.event || "datastar-fragment", id: event.id, retry: event.retry, }); }, close: async () => { await stream.close(); }, sleep: async (ms: number) => { await stream.sleep(ms); }, get aborted() { return stream.aborted; }, }; await callback(adapter); }); }