@llm-eaf/node-event-source
TypeScript icon, indicating that this package has built-in type declarations

1.0.1 • Public • Published

Node Event Source

This library was inspired by and includes some code from @microsoft/fetch-event-source. We are grateful to the author and contributors of that library.

This library offers an enhanced API for making Event Source requests, also known as server-sent events, incorporating all the features available in the Axios API for use within a Node.js environment.

The default browser EventSource API imposes several restrictions on the type of request you're allowed to make: the only parameters you're allowed to pass in are the url and withCredentials, so:

  • You cannot pass in a request body: you have to encode all the information necessary to execute the request inside the URL, which is limited to 2000 characters in most browsers.
  • You cannot pass in custom request headers
  • You can only make GET requests - there is no way to specify another method.
  • If the connection is cut, you don't have any control over the retry strategy: the browser will silently retry for you a few times and then stop, which is not good enough for any sort of robust application.

This library provides an alternate interface for consuming server-sent events, based on the Axios API. It is fully compatible with the Event Stream format, so if you already have a server emitting these events, you can consume it just like before. However, you now have greater control over the request and response so:

  • You can use any request method/headers/body, plus all the other functionality exposed by axios() except responseType and validateStatus.
  • You have access to the response object if you want to do some custom validation/processing before parsing the event source. This is useful in case you have API gateways (like nginx) in front of your application server: if the gateway returns an error, you might want to handle it correctly.
  • If the connection gets cut or an error occurs, you have full control over the retry strategy.

Install

npm install @llm-eaf/node-event-source

Usage

import { nodeEventSource } from "@llm-eaf/node-event-source";

await nodeEventSource("/api/sse", {
  onMessage(ev) {
    console.log(ev.data);
  },
});

If your server not response with text/event-stream Content-Type, please use your own onOpen callBack.

import { nodeEventSource } from "@llm-eaf/node-event-source";

await nodeEventSource("/api/sse", {
  onOpen(response) {
  },
  onMessage(ev) {
    console.log(ev.data);
  },
});

You can pass in all the other parameters except responseType and validateStatus exposed by the default axios API, for example:

const ctrl = new AbortController();
nodeEventSource("/api/sse", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: {
    foo: "bar",
  },
  signal: ctrl.signal,
});

You can add better error handling, for example:

class FatalError extends Error {}

nodeEventSource("/api/sse", {
  async onopen(response) {
    
  },
  onMessage(msg) {
    // if the server emits an error message, throw an exception
    // so it gets handled by the onerror callback below:
    if (msg.event === "FatalError") {
      throw new FatalError(msg.data);
    }
  },
  onError(err) {
    if (err instanceof FatalError) {
      throw err; // rethrow to stop the operation
    } else if (err instanceof NodeEventSourceError) {
      switch (err.type) {
        case NodeEventSourceErrorType.Request:
          const axiosError = err.origin as AxiosError;
          // you can handle the axios error here https://axios-http.com/docs/handling_errors
          break;
        case NodeEventSourceErrorType.Other:
          break;
        default:
          break;
      }
    } else {
      console.error(err);
    }
    // return true to retry.
  },
});

Package Sidebar

Install

npm i @llm-eaf/node-event-source

Weekly Downloads

4

Version

1.0.1

License

MIT

Unpacked Size

25.7 kB

Total Files

9

Last publish

Collaborators

  • aiephoenix