Feather Pen Youssef Moussaoui
October 21, 2023  ·  2 min read

Async iteration of Server-sent events with stream-event-source

One of my favorite features added to Javascript in recent years is asynchronous iteration. It allows you to take an asynchronous iterable object and have the code in your loop execute each time a Promise to fetch the next value resolves. The end result is code that looks very much like a simple for...of loop, and is often more readable and simpler to reason about than the alternatives.

One use case for which async iteration seems especially well tailored is the streaming of Server-sent events or SSE. SSE has become especially popular lately as a way of sending streaming events back from a server, finding its way into many popular AI applications, including ChatGPT and the AI product I happen to work on, Pi. In these cases, the server is able to send events with partial text updates as they get generated by the large language model in real time.

So today, I’d like to introduce a package that lets you apply async iteration to Server-sent events. stream-event-source is a small package that provides you with an async iterator over any stream of SSE events. It’s a thin wrapper on top of Microsoft’s fetch-event-source package and works seamlessly both in the browser and within Node. Here’s a simple example showing how to stream changes to Wikimedia in real time:

import { streamEventSource } from "stream-event-source";

async function main() {
  const controller = new AbortController();
  const stream = streamEventSource(
    "https://stream.wikimedia.org/v2/stream/recentchange",
    { signal: controller.signal },
  );

  const now = Date.now();

  for await (const event of stream) {
    console.log(event.event);
    console.log(event.data);

    if (Date.now() - now > 5000) {
      controller.abort();
      break;
    }
  }
}

main();

To get started with stream-event-source today, simply install it with your favorite package manager:

npm install stream-event-source
Signature