🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@eric8810/catcher-napi-http

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@eric8810/catcher-napi-http

catcher HTTP native addon for Node.js via napi-rs

latest
npmnpm
Version
0.3.16
Version published
Maintainers
1
Created
Source

@eric8810/catcher-napi-http

npm version License: MIT

Rust-powered HTTP + SSE client for Node.js via napi-rs. Part of the catcher toolkit.

Wraps catcher-http's HttpTransport — reqwest + retry + circuit breaker, compiled to a native addon. Includes typed TypeScript wrappers with auto-generated .d.ts.

⚠️ Breaking Changes (0.3.0+)

Migrate from 0.2.x → 0.3.x — see napi API docs for full details.

v0.3.2: HttpResponse, RequestOptions, Metrics types now correctly use camelCase (auto-generated by NAPI-RS). JSON config types (HttpClientConfig, etc.) remain snake_case.

ChangeBeforeAfter
Entry pointclient.js / client.d.tsdist/client.js / dist/client.d.ts
Config formatJSON.stringify(config) onlyTyped object or JSON string
Class namesJsHttpClient, JsSseStream, JsSseClientHttpClient, SseStream, SseClient
Callback eventsRaw JSON strings, need JSON.parse()Typed objects, auto-parsed
Default backoffExponentialFixed
Default connect_timeout_ms500010000
Default min_backoff_ms500100
Default max_backoff_ms3000010000
camelCase fieldsNot supported#[serde(alias)] — both snake_case and camelCase accepted
- const client = require('@eric8810/catcher-napi-http').HttpClient
- const c = new HttpClient(JSON.stringify({ base_url: '...' }))
+ import { HttpClient } from '@eric8810/catcher-napi-http'
+ const c = new HttpClient({ base_url: '...' })

Install

npm install @eric8810/catcher-napi-http

Pre-built binaries available for Linux (x64/arm64 gnu/musl), macOS (x64/arm64), and Windows (x64/arm64). Installed automatically via platform-specific optionalDependencies.

Usage

import { HttpClient } from '@eric8810/catcher-napi-http'
import type { HttpClientConfig, SseEvent } from '@eric8810/catcher-napi-http/types'

// Config as typed object (recommended) or JSON string
const client = new HttpClient({
  base_url: 'https://api.example.com',
  connect_timeout_ms: 10000,
  retry: { max_attempts: 3, backoff: 'Fixed' },
  circuit_breaker: { failure_threshold: 5, reset_timeout_ms: 30000 },
  dns: {
    mode: 'catcher',
    cache_size: 512,
    cache_ttl_secs: 300,
    negative_ttl_secs: 60,
    stale_ttl_secs: 3600,
    stale_on_error: true,
    host_mapping: { 'api.internal': '10.0.0.10' },
  },
  msgpack: true,
})

// GET
const resp = await client.get('/users/1')
console.log(resp.status, resp.body.toString())

// POST
await client.post('/messages', Buffer.from(JSON.stringify({ text: 'hello' })), {
  contentType: 'application/json',
})

// Circuit breaker state
console.log(client.circuitBreakerState()) // 'closed' | 'open' | 'half-open'

// SSE (one-shot stream)
import { SseStream } from '@eric8810/catcher-napi-http/sse'

const stream = new SseStream(
  { url: 'https://stream.example.com/events' },
  (event: SseEvent) => {
    if (event.type === 'Line') console.log(event.data)
  },
)
// later: stream.close()

// SSE (auto-reconnect client)
import { SseClient } from '@eric8810/catcher-napi-http/sse'

const sse = new SseClient(
  {
    url: 'https://stream.example.com/events',
    reconnect: { max_retries: 10, initial_delay_ms: 1000 },
  },
  (event: SseEvent) => {
    if (event.type === 'Line') console.log(event.data)
  },
)

API

new HttpClient(config: HttpClientConfig | string)

Create a client from a typed config object or JSON string. All fields are optional with sensible defaults. Supports both snake_case and camelCase field names.

interface HttpClientConfig {
  base_url?: string
  connect_timeout_ms?: number      // default: 10000
  response_timeout_ms?: number     // default: 30000
  pool?: PoolConfig
  tls?: TlsConfig
  dns?: DnsConfig
  retry?: RetryConfig
  circuit_breaker?: CircuitBreakerConfig
  max_concurrency?: number         // default: 50
  default_headers?: Record<string, string>
  hostname_override?: string
  proxy?: ProxyConfig
  redirect?: RedirectConfig
  auth?: { username: string; password: string }
  bearer_token?: string
  msgpack?: boolean                  // default: false
}

interface DnsConfig {
  mode?: 'catcher' | 'native'        // default: 'catcher'
  cache_size?: number                // default: 512
  cache_ttl_secs?: number            // default: 300
  negative_ttl_secs?: number         // default: 60
  stale_ttl_secs?: number            // default: 3600
  stale_on_error?: boolean           // default: true
  nameservers?: string[]
  host_mapping?: Record<string, string>
}

When msgpack is enabled, JSON request bodies are encoded as MessagePack and MessagePack responses are decoded back to JSON bytes when the response content type contains msgpack.

Methods

MethodSignature
get(url, options?)async (url: string, options?: RequestOptions) => HttpResponse
post(url, body?, options?)async (url: string, body?: Buffer, options?: RequestOptions) => HttpResponse
put(url, body?, options?)async (url: string, body?: Buffer, options?: RequestOptions) => HttpResponse
delete(url, options?)async (url: string, options?: RequestOptions) => HttpResponse
patch(url, body?, options?)async (url: string, body?: Buffer, options?: RequestOptions) => HttpResponse
circuitBreakerState()() => 'closed' | 'open' | 'half-open'
metrics()() => Metrics
executeStream(method, url, body?, options?, onChunk?)(method: string, url: string, body?: Buffer, options?: RequestOptions, onChunk?: (event: StreamEvent) => void) => void
setAdaptiveTimeout(min, max, mult, win)(min: number, max: number, mult: number, win: number) => void
cancelAll()() => void
cancelRequest(requestId)(requestId: number) => boolean
nextRequestId()() => number

RequestOptions

Per-request options (NAPI-RS auto-generated, camelCase fields):

interface RequestOptions {
  headers?: Record<string, string>
  timeoutMs?: number
  contentType?: string
}

HttpResponse

NAPI-RS auto-generated (camelCase fields):

interface HttpResponse {
  status: number
  headers: Record<string, string>
  body: Buffer
  elapsedMs: number
}

Metrics

Runtime metrics snapshot (NAPI-RS auto-generated, camelCase fields):

interface Metrics {
  httpRequests: number
  httpSuccessRate: number
  httpAvgLatencyUs: number
  httpRetries: number
  wsConnectSuccessRate: number
  wsDisconnects: number
  wsMessagesSent: number
  wsMessagesReceived: number
  cbOpenCount: number
  queueTimeouts: number
}

Note: HttpResponse, RequestOptions, and Metrics are auto-generated by NAPI-RS (camelCase fields). JSON config types like HttpClientConfig use snake_case (serde-based).

SSE

ClassDescription
SseStreamOne-shot SSE stream (no auto-reconnect)
SseClientLong-lived SSE client with auto-reconnect
new SseStream(config: SseClientConfig | string, onEvent: (event: SseEvent) => void)
new SseClient(config: SseClientConfig | string, onEvent: (event: SseEvent) => void)

type SseEvent =
  | { type: 'Line'; data: string }
  | { type: 'Error'; message: string }
  | { type: 'End' }

StreamEvent

type StreamEvent =
  | { type: 'Headers'; status: number; headers: Record<string, string> }
  | { type: 'Chunk'; data: string }  // base64 encoded
  | { type: 'Done' }
  | { type: 'Error'; message: string }

Build from Source

Requires Rust toolchain.

npm run build       # napi build + tsup compile
npm run build:ts    # tsup only (no Rust rebuild)

License

MIT

FAQs

Package last updated on 14 Jun 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts