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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@czf0613/http_client

v0.1.2

Published

Simple http client with fetch, supporting modified SSE protocol

Readme

@czf0613/http_client

A simple HTTP client library built with fetch API, supporting a modified SSE (Server-Sent Events) protocol for browser environments.

No any dependencies, it is very lightweight.

Requirements

  • Runtime: ES2018+ compatible browsers
  • Module System: ES Module only (not compatible with CommonJS)
  • Environment: Browser only (Chrome, Firefox, Safari)
  • Browser Support: Works well on all major modern browsers

Installation

Install the package using your preferred package manager:

# npm
npm install @czf0613/http_client

# pnpm
pnpm add @czf0613/http_client

# yarn
yarn add @czf0613/http_client

Usage

joinUrlWithParams

Concatenates a URL with query parameters, automatically handling URL encoding.

Parameters:

  • url (string): The base URL without any query parameters
  • queryParams (Record<string, string | number | boolean>): Query parameters as key-value pairs

Returns: string - The complete URL with query parameters

Example:

import { joinUrlWithParams } from '@czf0613/http_client';

const url = joinUrlWithParams('https://api.example.com/users', {
  page: 1,
  limit: 10,
  search: 'hello world'
});
// Result: 'https://api.example.com/users?page=1&limit=10&search=hello%20world'

// Automatic URL encoding for special characters
const url2 = joinUrlWithParams('https://api.example.com/search', {
  keyword: '你好世界'
});
// Result: 'https://api.example.com/search?keyword=%E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C'

makeHttpRequest

Makes an HTTP request with default configuration using the Fetch API.

Parameters:

  • url (string): The request URL (without query parameters)
  • method (HttpMethod): HTTP method ('GET', 'POST', 'PUT', 'DELETE', 'HEAD'). Default: 'GET'
  • queryParams (Record<string, string | number> | null): Query parameters to be appended to the URL. Default: null
  • customHeaders (Record<string, string> | null): Custom headers (Content-Type is handled automatically). Important: Do NOT include Content-Type in customHeaders as it will interfere with the automatic Content-Type generation. Default: null
  • body (any | null): Request body for POST/PUT requests. Default: null
    • String or number: sent as text/plain
    • Object: sent as application/json
    • FormData: sent as multipart/form-data
  • timeoutMs (number): Timeout in milliseconds. Default: 5000. Note: this value is the connect timeout, not the total request timeout. You need to handle the read timeout in your application logic.

Returns: Promise<ExtendedResponse> - Extended Response object with additional helper methods. It's the same as the standard Response object, but with additional methods for convenience.

ExtendedResponse Methods

In addition to all standard Response methods (json(), text(), arrayBuffer(), blob(), bytes()), ExtendedResponse provides the following timeout-enabled methods:

jsonWithTimeout<T>(readTimeoutMs?: number): Promise<T> Reads the response body as JSON with a configurable timeout. Default timeout is 5000ms.

  • Throws Error with message "JSON read timeout after Xms" if timeout occurs
  • Throws parsing errors if JSON is invalid

textWithTimeout(readTimeoutMs?: number): Promise<string> Reads the response body as text with a configurable timeout. Default timeout is 5000ms.

  • Throws Error with message "Text read timeout after Xms" if timeout occurs

arrayBufferWithTimeout(readTimeoutMs?: number): Promise<ArrayBuffer> Reads the response body as ArrayBuffer with a configurable timeout. Default timeout is 5000ms.

  • Throws Error with message "ArrayBuffer read timeout after Xms" if timeout occurs

blobWithTimeout(readTimeoutMs?: number): Promise<Blob> Reads the response body as Blob with a configurable timeout. Default timeout is 5000ms.

  • Throws Error with message "Blob read timeout after Xms" if timeout occurs

bytesWithTimeout(readTimeoutMs?: number): Promise<Uint8Array<ArrayBuffer>> Reads the response body as Uint8Array with a configurable timeout. Default timeout is 5000ms.

  • Throws Error with message "Bytes read timeout after Xms" if timeout occurs

Note: This function(including methods in ExtendedResponse) does not handle exceptions by default. You should wrap it in a try-catch block or using a promise chain.

Example:

import { makeHttpRequest } from '@czf0613/http_client';

// GET request with query parameters
const response = await makeHttpRequest(
  'https://api.example.com/users',
  'GET',
  { page: 1, limit: 10 }
);
const data = await response.json();

// POST request with JSON body
const response = await makeHttpRequest(
  'https://api.example.com/users',
  'POST',
  null,
  null,
  { name: 'John', age: 30 }
);

// POST request with FormData
const formData = new FormData();
formData.append('file', fileInput.files[0]);
const response = await makeHttpRequest(
  'https://api.example.com/upload',
  'POST',
  null,
  null,
  formData
);

// Custom timeout
const response = await makeHttpRequest(
  'https://api.example.com/slow-endpoint',
  'GET',
  null,
  null,
  null,
  10000 // 10 seconds timeout
);

makeSSERequest

Makes an SSE (Server-Sent Events) request and returns an async generator that yields streaming responses. This is an enhanced version of the browser's EventSource with additional features, but it's not fully compatible with the standard SSE protocol.

Parameters:

  • url (string): The request URL (without query parameters)
  • method (HttpMethod): HTTP method ('GET', 'POST', 'PUT', 'DELETE', 'HEAD'). Default: 'GET'
  • queryParams (Record<string, string | number> | null): Query parameters to be appended to the URL. Default: null
  • customHeaders (Record<string, string> | null): Custom headers. Important: Do NOT include Content-Type in customHeaders. Default: null
  • body (any | null): Request body for POST/PUT requests. Default: null
  • connectTimeoutMs (number): Connection timeout in milliseconds. Default: 30000
  • messageTimeoutMs (number): Timeout for each message read in milliseconds. Default: 30000

Note: For detailed parameter descriptions, see makeHttpRequest above. This function only handles responses in the format data: xxx\n\n. It does not throw exceptions by default; success/failure is indicated in the generator's return value.

This method will not throw exceptions, you can get the success/failure status from the generator's return value.

Returns: AsyncGenerator<string, boolean, undefined> - An async generator that yields each message as a string, and returns a boolean indicating success (true) or failure (false)

Example:

import { makeSSERequest } from '@czf0613/http_client';

async function streamChat() {
  const generator = makeSSERequest(
    'https://api.example.com/chat',
    'POST',
    null,
    null,
    { message: 'Hello' },
    30000,  // connectTimeoutMs
    10000   // messageTimeoutMs
  );

  // Manually iterate to receive chunks
  while(true) {
    const { done, value } = await generator.next();

    if (done) {
      // Check if the stream completed successfully
      if (!value) {
        console.error('SSE stream failed');
      }

      break;
    }

    // Get the message value
    console.log('Received:', value);
  }
}

Test

Run tests using:

npm test

License

MIT