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

@linxs/amors

v0.5.0

Published

Amors is a minimalist request tool library

Readme

@linxs/amors

A lightweight, promise-based HTTP client for the browser and Node.js with interceptors, caching, and request/response transformation.

中文文档:API Reference

Features

  • 🚀 Promise-based HTTP client for browser and Node.js
  • 🔄 Request and response interceptors with proper body consumption handling
  • 💾 Built-in request caching with LRU strategy
  • ⏱️ Advanced timeout handling with AbortController support
  • 🛠️ Extensible configuration
  • 📦 Full TypeScript support with strict type safety
  • 🔄 Automatic request/response transformation
  • 🛡️ Safe Response body consumption - prevents "body stream already read" errors
  • ⚡ Optimized queue management for concurrent requests
  • 🔌 Pluggable adapter architecture

Installation

# Using npm
npm install @linxs/amors

# Using yarn
yarn add @linxs/amors

# Using pnpm
pnpm add @linxs/amors

Quick Start

Basic Amors Usage

import { Amors } from '@linxs/amors';

// Create an instance
const api = new Amors({
  baseURL: 'https://api.example.com',
  prefix: '/v1',
  timeout: 30000 // 30 seconds
});

// Make requests
const response = await api.get('/users');
const data = await response.json();

// POST request with data
// Body objects are automatically JSON.stringify'd
// Content-Type defaults to 'application/json'
const newUser = await api.post('/users', {
  body: { name: 'John Doe' }
});

Adapter Usage

import { AmorsAdapter } from '@linxs/amors';
import { Amors } from '@linxs/amors/fetch';

// Create an adapter with queue and cache support
const adapter = new AmorsAdapter({
  adapter: Amors,
  config: {
    baseURL: 'https://api.example.com',
    timeout: 30000
  },
  cache: {
    capacity: 100,
    ttl: 5 * 60 * 1000 // 5 minutes
  },
  queue: {
    global: true,
    concurrent: 3
  }
});

// Use the adapter
const response = await adapter.get('/users');

// Use queue
const queue = adapter.queue();
const queuedResponse = await queue.get('/data');

Interceptors

Interceptors support access to full request context information, including original URL, config, and request method:

const api = new Amors({
  baseURL: 'https://api.example.com',
  interceptors: {
    // Request interceptor - using object-style parameters
    request: ({ config, context }) => {
      // context contains: url, config, options, method
      console.log('Request URL:', context.url);
      console.log('Request method:', context.method);

      // Add different auth based on URL
      if (context.url.startsWith('/admin')) {
        config.headers.set('X-Admin-Token', 'admin-token');
      } else {
        const token = localStorage.getItem('token');
        if (token) {
          config.headers.set('Authorization', `Bearer ${token}`);
        }
      }
      return config;
    },

    // Response interceptor - also has access to request context
    response: async ({ response, context }) => {
      console.log('Response from:', context.url);
      console.log('Request method:', context.method);

      // Different data handling based on endpoint
      if (context.method === 'POST') {
        const data = await response.json();
        console.log('POST response data:', data);
        return data; // Return parsed data directly
      }

      // Return response (Amors handles cloning automatically)
      return response;
    }
  }
});

// Using interceptors
const response = await api.get('/users');
const userData = await response.json(); // ✅ Works perfectly!

Caching

const api = new Amors({
  cache: {
    capacity: 50,
    ttl: 5 * 60 * 1000 // 5 minutes
  }
});

// First request - fetches from network
const data1 = await api.get('/data');

// Subsequent request - returns from cache
const data2 = await api.get('/data');

// Force update from network
const freshData = await api.get('/data', {}, {
  cache: { forceUpdate: true }
});

Error Handling

try {
  const response = await api.get('/users/123');
  // Handle success
} catch (error) {
  if (error.name === 'TimeoutError') {
    console.log('Request timed out');
  } else if (error.name === 'AbortError') {
    console.log('Request was aborted');
  } else if (error.response) {
    console.log('HTTP Error:', error.response.status);
  } else {
    console.log('Network Error:', error.message);
  }
}

Architecture

Amors provides two main components:

  1. Amors: Core HTTP client with fetch-based implementation
  2. AmorsAdapter: Pluggable adapter with queue management and enhanced caching

API Overview

Core Methods

  • get(url, config?, options?) - GET request
  • post(url, config?, options?) - POST request
  • put(url, config?, options?) - PUT request
  • delete(url, config?, options?) - DELETE request
  • patch(url, config?, options?) - PATCH request
  • head(url, config?, options?) - HEAD request
  • options(url, config?, options?) - OPTIONS request

Configuration Options

  • baseURL - Base URL for all requests
  • prefix - URL prefix to append to baseURL
  • timeout - Request timeout in milliseconds
  • cache - Cache configuration with capacity and TTL
  • interceptors - Request and response interceptors
  • queue - Queue configuration for concurrent request management

Documentation

For detailed documentation and advanced usage:

Browser Support

Amors supports all modern browsers and Node.js 16+. For older browsers, you may need polyfills for:

  • Promise
  • Fetch API
  • Object.entries
  • AbortController

TypeScript

Fully typed with TypeScript. All types are exported for your convenience:

import type { 
  AmorsRequestInit, 
  AmorsRequestOptions,
  AmorsConfigInit 
} from '@linxs/amors';

License

MIT © Lin.xs


Why Amors?

Amors solves common pain points in HTTP client libraries:

  • Response Body Consumption: Automatically handles response cloning to prevent "body stream already read" errors
  • Type Safety: Full TypeScript support with strict typing
  • Performance: Built-in caching and queue management for optimal performance
  • Flexibility: Pluggable adapter architecture for different use cases
  • Developer Experience: Clean API with comprehensive error handling

Perfect for applications that need reliable HTTP communication with advanced features like request queuing, response caching, and safe interceptor handling.