Skip to main content
Home

latest

๐Ÿ”’โš”๏ธ Memory Efficiency, Buffer Overflow Protection, fetch based for JSON streaming and non-streaming API requests. ๐Ÿ’ช

This package works with Cloudflare Workers, Deno, Bun, BrowsersIt is unknown whether this package works with Node.js
This package works with Cloudflare Workers
It is unknown whether this package works with Node.js
This package works with Deno
This package works with Bun
This package works with Browsers
JSR Score
100%
Published
2 months ago (1.0.26)

Stretto ๐Ÿš€

A robust, high-performance TypeScript fetch wrapper with built-in retry logic, exponential backoff, streaming capabilities, and Server-Sent Events (SSE) support.

  • Memory Efficiency: Zero-copy streaming and buffer reuse keep memory usage low.
  • Minimal Allocations: Optimized hot paths reduce overhead.
  • Buffer Overflow Protection: Configurable limits prevent memory exhaustion attacks.
  • Data Security: Internal buffers are zeroed out to avoid leaks in memory dumps.
Bundle size Dependency count Version Downloads JSDelivr

๐Ÿ“ฆ Installation

# npm
npm install stretto
# Deno
deno add jsr:@wutility/stretto

Or use the CDN:

<script src="https://cdn.jsdelivr.net/npm/stretto/dist/index.umd.min.js"></script>
<!-- window.stretto.default is available -->

๐Ÿš€ Quick Start

Basic Usage

import stretto from 'stretto';
// jsr
// import stretto, { JSONStreamTransformer } from "jsr:@wutility/stretto";

// Simple GET request
const response = await stretto('https://jsonplaceholder.typicode.com/todos/1');
const data = await response.json();

With Options

const response = await stretto('https://api.example.com/data', {
  retries: 5,
  timeout: 10000,
  headers: {'Authorization': 'Bearer token'}
});

Streaming Responses

const response = await stretto('https://stream.wikimedia.org/v2/stream/recentchange', {
  stream: true
});

// Use as AsyncIterable
for await (const chunk of response) {
  console.log('Received chunk:', chunk);
}

Server-Sent Events (SSE)

import stretto, { JSONStreamTransformer } from 'stretto';

const response = await stretto('https://sse.dev/test', {
  stream: true,
  transformers: [new JSONStreamTransformer()]
});

for await (const event of response) {
  console.log('SSE Event:', event);
}

๐Ÿ“– API Reference

stretto(url, options?)

Main function for making HTTP requests.

Parameters:

  • url: string | URL - The URL to fetch
  • options?: StrettoOptions - Configuration options

Returns: Promise<StrettoStreamableResponse<T>>

StrettoOptions

interface StrettoOptions extends Omit<RequestInit, 'signal'> {
  retries?: number;                    // Default: 3
  timeout?: number;                    // Default: 30000ms
  backoffStrategy?: (attempt: number) => number;
  retryOn?: (error: unknown, response?: Response) => boolean;
  stream?: boolean;                    // Default: false
  transformers?: TransformStream<any, any>[];
  signal?: AbortSignal;
}

JSONStreamTransformer

A specialized transformer for parsing Server-Sent Events with JSON payloads.

import { JSONStreamTransformer } from 'stretto';

const transformer = new JSONStreamTransformer({
  maxBuffer: 8192,        // Maximum line buffer size
  parseData: true,        // Parse JSON automatically
  donePrefix: '[DONE]',   // Custom termination marker
  onBufferOverflow: 'skip', // 'skip' | 'throw'
  onParseError: 'skip'      // 'skip' | 'throw'
});

๐Ÿ”ง Advanced Usage

Custom Retry Strategy

const response = await stretto('https://api.example.com/data', {
  retries: 5,
  retryOn: (error, response) => {
    // Custom retry logic
    if (response?.status === 429) return true; // Rate limited
    if (error instanceof TypeError) return true; // Network error
    return false;
  },
  backoffStrategy: (attempt) => {
    // Custom backoff: linear instead of exponential
    return attempt * 1000;
  }
});

Request Cancellation

const controller = new AbortController();

// Cancel after 5 seconds
setTimeout(() => controller.abort(), 5000);

try {
  const response = await stretto('https://api.example.com/data', {
    signal: controller.signal
  });
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('Request was cancelled');
  }
}

Multiple Transform Streams

import stretto, { JSONStreamTransformer } from 'stretto';

const response = await stretto('https://sse.dev/test', {
  stream: true,
  transformers: [new JSONStreamTransformer()]
});

for await (const chunk of stream) {}

๐Ÿ“Š Performance Features

  • Zero-copy streaming: No unnecessary data copying during stream processing
  • Optimized backoff: Uses bitwise operations for fast exponential calculations
  • Memory efficient: Reuses buffers and minimizes allocations
  • V8 optimized: Takes advantage of JavaScript engine optimizations

๐Ÿงช Testing

npm test

๐Ÿค Contributing

Contributions are welcome! Please read our Contributing Guide for details.

๐Ÿ“„ License

MIT License - see the LICENSE file for details.

New Ticket: Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";
or

Import directly with a jsr specifier

import * as stretto from "jsr:@wutility/stretto";

Add Package

pnpm i jsr:@wutility/stretto
or (using pnpm 10.8 or older)
pnpm dlx jsr add @wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";

Add Package

yarn add jsr:@wutility/stretto
or (using Yarn 4.8 or older)
yarn dlx jsr add @wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";

Add Package

vlt install jsr:@wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";

Add Package

npx jsr add @wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";

Add Package

bunx jsr add @wutility/stretto

Import symbol

import * as stretto from "@wutility/stretto";