npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

http-streaming-request

v2.2.0

Published

Consume HTTP Streaming with ease

Downloads

658

Readme

http-streaming-request

Introduction

I've built this library to help to work with streaming requests for the OpenAI APIs that returns JSON. That said, you can use it with any other API that returns JSON via a streamed HTTP response.

| Move from this | To this | | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | | no streaming | streaming |

HTTP Streaming & JSON

🐢 Slow API endpoints turn users away from your app. For example, a request to the OpenAI API usually takes around 10 seconds. But if you stream a response you can start showing results to users almost straight away. That's how ChatGPT works - when it prints out a response character by character (well, token by token actually).

📖 It's all good if you return text, but what if you return JSON? Streaming JSON means that almost at every single moment your JSON is not well formed, for example, it may look like this:

[{"name": "Joe

💔 If you put it through JSON.parse() you'll get an error. And chances are you'll only get a well formed JSON only after a request completes.

🕒 But if you wait for it to complete you won't be able to show anything to a user. And that will defeat the purpose of using streaming.

A way out

🚀 This library solves this problem. Just call makeStreamingJsonRequest() and it'll give a stream of well formed JSON, even if the underlying response JSON is still malformed. For example,

const stream = makeStreamingJsonRequest({
  url: "/some-api",
  method: "POST",
});

for await (const data of stream) {
  // if the API only returns [{"name": "Joe
  // the line below will print `[{ name: "Joe" }]`

  console.log(data);
}

Installation

npm install --save-dev http-streaming-request
# or
yarn add --dev http-streaming-request

Examples

Example with React

Run this example

import { makeStreamingJsonRequest } from "http-streaming-request";

const PeopleListWithMakeStreamingJsonRequest: React.FC = () => {
  const [people, setPeople] = useState<Person[] | null>(null);

  const onGetPeopleClick = async () => {
    for await (const peopleSoFar of makeStreamingJsonRequest<Person[]>({
      url: "/api/people",
      method: "GET",
    })) {
      setPeople(peopleSoFar);
    }
  };

  return (
    <>
      <button onClick={onGetPeopleClick}>Run example</button>

      {people && people.length > 0 && (
        <div>
          {people.map((person, i) => (
            <div key={i}>
              <div>
                <strong>Name:</strong> {person.name}
              </div>
              <div>
                <strong>Age:</strong> {person.age}
              </div>
              <div>
                <strong>City:</strong> {person.city}
              </div>
              <div>
                <strong>Country:</strong> {person.country}
              </div>
            </div>
          ))}
        </div>
      )}
    </>
  );
};

Example with React Hooks

Run this example

import { useJsonStreaming } from "http-streaming-request";

const PeopleListWithHooks: React.FC = () => {
  const { data: people, run } = useJsonStreaming<Person[]>({
    url: "/api/people",
    method: "GET",
  });

  return (
    <>
      {people && people.length > 0 && (
        <div>
          {people.map((person, i) => (
            <div key={i}>
              <div>
                <strong>Name:</strong> {person.name}
              </div>
              <div>
                <strong>Age:</strong> {person.age}
              </div>
              <div>
                <strong>City:</strong> {person.city}
              </div>
              <div>
                <strong>Country:</strong> {person.country}
              </div>
            </div>
          ))}
        </div>
      )}
    </>
  );
};

API

makeStreamingJsonRequest

makeStreamingJsonRequest<T>(params: MakeStreamingRequestParams): AsyncGenerator

makeStreamingJsonRequest() makes a request to a steaming HTTP endpoint and returns an asynchrnous generator.

Usage

const stream = makeStreamingJsonRequest({
  url: "/some-api",
  method: "POST",
});

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

makeStreamingRequestParams

  • url: string - the API endpoint URL
  • method: "GET" | "POST" | "PUT" | "DELETE" - HTTP method
  • payload?: any - any payload
  • jsonRepairFunction?: (data: string) => string - an optional function that helps to repair JSON. Sometimes, an LLM can give you a malformed JSON that cannot be parsed. For example, [title": instead of [{"title. In this case, it's not even the case for optimistic parsing, as the beginning of JSON is simply wrong. Passing a parameter here can help to fix it on the fly.

You can also provide a generic type parameter for type safety:

const stream = makeStreamingJsonRequest<Person[]>({
  url: "/some-api",
  method: "POST",
});

for await (const data of stream) {
  // data is now instance of Person[]
  console.log(data);
}

useJsonStreaming()

useJsonStreaming<T>(params: MakeStreamingRequestParams): { data T, run }

useJsonStreaming() is a React hook that makes a request to a steaming HTTP endpoint.

  • jsonRepairFunction?: (data: string) => string - an optional function that helps to repair JSON. Sometimes, an LLM can give you a malformed JSON that cannot be parsed. For example, [title": instead of [{"title. In this case, it's not even the case for optimistic parsing, as the beginning of JSON is simply wrong. Passing a parameter here can help to fix it on the fly.

Usage

const { data, run } = useJsonStreaming<Person[]>({
  url: "/api/people",
  method: "GET",
  payload: somePayload,
});

const onReRun = () => {
  // you can also easily re-run the request with a differnt payload

  run({ payload: someOtherPayload });
};