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 🙏

© 2025 – Pkg Stats / Ryan Hefner

sockress-client

v0.2.6

Published

Socket-first client SDK for Sockress servers with automatic HTTP fallback and FormData serialization.

Readme

Sockress Client SDK

sockress-client is the companion SDK for Sockress-powered backends. It automatically prefers the WebSocket transport (sharing the same request/response semantics as HTTP) and silently falls back to fetch when a socket is unavailable. Multipart uploads (FormData) are serialized over the wire, so you can use a single API surface for avatars, profile forms, and realtime commands.

Created by Also Coder · GitHub @alsocoders


Features

  • Socket-first requests with automatic HTTP fallback
  • FormData, Blob, and JSON serialization handled automatically
  • Familiar API: api.request(), api.get(), api.post(), api.put(), api.patch(), api.delete()
  • Built-in event emitters for open, close, error, and reconnect
  • Works in browsers and Node.js (inject custom fetch / wsFactory)
  • Automatic cookie handling (browser only)
  • Request queuing when socket is not yet connected
  • Automatic reconnection with exponential backoff

Installation

npm install sockress-client

Sockress Client supports both ESM and CommonJS:

// ESM
import { sockressClient } from 'sockress-client';

// CommonJS
const { sockressClient } = require('sockress-client');

Quick Start

import { sockressClient } from 'sockress-client';

const api = sockressClient({
  baseUrl: 'http://localhost:5051',
  autoConnect: true,
  preferSocket: true
});

// GET request
const users = await api.get('/api/users');
console.log(users.body);

// POST request
const response = await api.post('/api/auth/login', {
  body: { email: '[email protected]', password: 'secret' }
});
console.log(response.body.token);

API Methods

api.request(options)

Make a request with full control:

const response = await api.request({
  path: '/api/users',
  method: 'GET',
  headers: { 'Authorization': 'Bearer token' },
  query: { page: 1, limit: 10 },
  body: { name: 'John' },
  timeout: 5000,
  signal: abortController.signal,
  disableHttpFallback: false
});

api.get(path, options?)

const response = await api.get('/api/users', {
  query: { page: 1 },
  headers: { 'Authorization': 'Bearer token' }
});

api.post(path, options?)

const response = await api.post('/api/users', {
  body: { name: 'John', email: '[email protected]' }
});

api.put(path, options?)

const response = await api.put('/api/users/123', {
  body: { name: 'Jane' }
});

api.patch(path, options?)

const response = await api.patch('/api/users/123', {
  body: { email: '[email protected]' }
});

api.delete(path, options?)

const response = await api.delete('/api/users/123');

Response Object

All methods return a SockressClientResponse:

interface SockressClientResponse<T> {
  status: number;           // HTTP status code
  ok: boolean;              // true if status is 200-299
  headers: Record<string, string>;  // response headers
  body: T;                  // parsed response body
  json: <R = T>() => R;    // get body as JSON (type-safe)
  text: () => string;       // get body as string
  raw: () => T;             // get raw body
}

Example:

const response = await api.get('/api/users');
console.log(response.status);  // 200
console.log(response.ok);      // true
console.log(response.body);    // parsed JSON
console.log(response.json()); // same as body
console.log(response.text());  // JSON string

File Uploads

Upload files using FormData:

const formData = new FormData();
formData.append('avatar', file);
formData.append('name', 'John Doe');

const response = await api.post('/api/profile/avatar', {
  body: formData,
  headers: { 'Authorization': 'Bearer token' }
});

console.log(response.body.avatarUrl);

The client automatically serializes FormData for socket transport and uses native FormData for HTTP fallback.


Events

Listen to socket events:

// Socket opened
api.on('open', () => {
  console.log('Socket connected');
});

// Socket closed
api.on('close', ({ code, reason }) => {
  console.log('Socket closed', code, reason);
});

// Error occurred
api.on('error', (error) => {
  console.error('Socket error:', error);
});

// Reconnection attempt
api.on('reconnect', ({ attempt }) => {
  console.log('Reconnecting, attempt:', attempt);
});

Remove listeners:

const unsubscribe = api.on('open', () => {
  console.log('Connected');
});

// Later
api.off('open', handler);
// or
unsubscribe();

Configuration

Create a client with custom options:

const api = sockressClient({
  baseUrl: 'http://localhost:5051',      // required
  socketPath: '/sockress',                 // WebSocket path (default: '/sockress')
  headers: { 'X-Custom': 'value' },       // default headers
  timeout: 15_000,                         // request timeout in ms (default: 15000)
  reconnectInterval: 1_000,                // initial reconnect delay (default: 1000)
  maxReconnectInterval: 15_000,            // max reconnect delay (default: 15000)
  autoConnect: true,                       // auto-connect on creation (default: true)
  preferSocket: true,                      // prefer socket over HTTP (default: true)
  credentials: 'include',                  // fetch credentials (default: 'include')
  fetchImpl: fetch,                        // custom fetch implementation
  wsFactory: (url) => new WebSocket(url)   // custom WebSocket factory
});

Node.js Usage

In Node.js, you may need to provide custom implementations:

import fetch from 'node-fetch';
import WebSocket from 'ws';

const api = sockressClient({
  baseUrl: 'https://api.example.com',
  fetchImpl: fetch as any,
  wsFactory: (url) => new WebSocket(url) as any
});

Manual Connection Management

Control socket connection manually:

const api = sockressClient({
  baseUrl: 'http://localhost:5051',
  autoConnect: false  // don't auto-connect
});

// Connect manually
await api.connect();

// Close manually
api.close();

The client automatically closes the socket on process exit (Node.js) or page unload (browser).


Request Options

path (required)

Request path (e.g., '/api/users')

method (optional)

HTTP method: 'GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS' (default: 'GET')

headers (optional)

Request headers object

query (optional)

Query parameters object (values can be strings, numbers, booleans, or arrays)

await api.get('/api/users', {
  query: {
    page: 1,
    limit: 10,
    tags: ['js', 'ts'],
    active: true
  }
});

body (optional)

Request body. Can be:

  • Plain object (serialized as JSON)
  • FormData (for file uploads)
  • Blob or ArrayBuffer
  • URLSearchParams
  • String

timeout (optional)

Request timeout in milliseconds (overrides default)

signal (optional)

AbortSignal for canceling requests

disableHttpFallback (optional)

If true, throws an error if socket is unavailable instead of falling back to HTTP (default: false)


Error Handling

Handle errors with try/catch:

try {
  const response = await api.post('/api/users', {
    body: { name: 'John' }
  });
  console.log(response.body);
} catch (error) {
  console.error('Request failed:', error);
}

TypeScript Support

Sockress Client is written in TypeScript and provides full type safety:

interface User {
  id: number;
  name: string;
  email: string;
}

const response = await api.get<User[]>('/api/users');
const users: User[] = response.body;

Links

PRs and feedback welcome!