@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/amorsQuick 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:
- Amors: Core HTTP client with fetch-based implementation
- AmorsAdapter: Pluggable adapter with queue management and enhanced caching
API Overview
Core Methods
get(url, config?, options?)- GET requestpost(url, config?, options?)- POST requestput(url, config?, options?)- PUT requestdelete(url, config?, options?)- DELETE requestpatch(url, config?, options?)- PATCH requesthead(url, config?, options?)- HEAD requestoptions(url, config?, options?)- OPTIONS request
Configuration Options
baseURL- Base URL for all requestsprefix- URL prefix to append to baseURLtimeout- Request timeout in millisecondscache- Cache configuration with capacity and TTLinterceptors- Request and response interceptorsqueue- Queue configuration for concurrent request management
Documentation
For detailed documentation and advanced usage:
- Amors Documentation - Core HTTP client guide
- AmorsAdapter Documentation - Adapter and queue management
- API Reference - Complete API documentation
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.
