🍡 mochi

SSR framework for Svelte 5 + Bun with islands-based selective hydration

On this page

Server-Sent Events

Register an SSE stream with Mochi.sse(handler); the handler receives a MochiSseStream and the underlying Request, and runs once per client connection.

// file: src/index.ts
import { Mochi } from 'mochi-framework';

await Mochi.serve({
  routes: {
    '/sse/time': Mochi.sse((stream) => {
      stream.send(new Date().toISOString());
      const interval = setInterval(() => {
        stream.send(new Date().toISOString());
      }, 1000);
      stream.onClose(() => clearInterval(interval));
    }),
  },
});

stream.send(data, options?)

Push a single SSE frame to the client. data is a string; options accepts event (named event type) and id (last-event-id).

stream.send(JSON.stringify({ ok: true }), { event: 'tick', id: '42' });

stream.close()

End the stream from the server side. The connection terminates and any registered onClose callbacks fire.

stream.send('done');
stream.close();

stream.onClose(callback)

Register cleanup that runs when the stream ends — whether the server called close() or the client disconnected. Use it to clear timers, unsubscribe from event buses, and release per-connection state.

const interval = setInterval(() => stream.send('ping'), 1000);
stream.onClose(() => clearInterval(interval));

Events

Mochi.sse emits sse:open, sse:message, and sse:close on mochiEvents. logger() prints them by default.

See it in action

Live demos showing key concepts from this page