π Fetcher
August 19, 2026 Β· View on GitHub
Ultra-lightweight β’ Modular β’ TypeScript-First β’ Interceptor-Powered β’ LLM Streaming API Support
π Why Fetcher?
Fetcher is not just another HTTP clientβit's a complete ecosystem designed for modern web development with native LLM streaming API support. Built on the native Fetch API, Fetcher provides an Axios-like experience with powerful features while maintaining an incredibly small footprint.
π Core Features
π― @ahoo-wang/fetcher - The Foundation
The lightweight core that powers the entire ecosystem:
- β‘ Ultra-Lightweight: Only 3KiB min+gzip - smaller than most alternatives
- π§ Path & Query Parameters: Built-in support for path (
{id}/:id) and query parameters - π Interceptor System: Request, response, and error interceptors with ordered execution for flexible middleware patterns
- β±οΈ Timeout Control: Configurable request timeouts with proper error handling
- π Fetch API Compatible: Fully compatible with the native Fetch API
- π‘οΈ TypeScript Support: Complete TypeScript definitions for type-safe development
- π§© Modular Architecture: Lightweight core with optional extension packages
- π¦ Named Fetcher Support: Automatic registration and retrieval of fetcher instances
- βοΈ Default Fetcher: Pre-configured default fetcher instance for quick start
π¨ @ahoo-wang/fetcher-decorator - Declarative APIs
Transform your API interactions with clean, declarative service definitions:
- π¨ Clean API Definitions: Define HTTP services using intuitive decorators
- π§ Automatic Parameter Binding: Path, query, header, and body parameters automatically bound
- β±οΈ Configurable Timeouts: Per-method and per-class timeout settings
- π Fetcher Integration: Seamless integration with Fetcher's named fetcher system
- β‘ Automatic Implementation: Methods automatically implemented with HTTP calls
- π¦ Metadata System: Rich metadata support for advanced customization
π§ @ahoo-wang/fetcher-generator - OpenAPI Code Generator
A powerful TypeScript code generation tool that automatically generates type-safe API client code based on OpenAPI specifications. It is designed for general use cases and is also deeply optimized for the Wow Domain-Driven Design framework, providing native support for the CQRS architectural pattern.
- π― OpenAPI 3.0+ Support: Full support for OpenAPI 3.0+ specifications (JSON/YAML)
- π¦ TypeScript Code Generation: Generates type-safe TypeScript interfaces, enums, and classes
- π§ CLI Tool: Easy-to-use command-line interface for code generation
- π¨ Decorator-Based APIs: Generates decorator-based client classes for clean API interactions
- π Comprehensive Models: Handles complex schemas including unions, intersections, enums, and references
- π Fetcher Integration: Seamlessly integrates with the Fetcher ecosystem packages
- π Progress Logging: Friendly logging with progress indicators during generation
- π Auto Index Generation: Automatically generates index.ts files for clean module organization
- π Remote Spec Support: Load OpenAPI specs directly from HTTP/HTTPS URLs
- π Event Streaming: Generates both regular and event-stream command clients
- ποΈ Domain-Driven Design Support: Specialized support for Wow framework with aggregates, commands, queries, and events (CQRS patterns)
π― @ahoo-wang/fetcher-eventbus - Event Bus System
A TypeScript event bus library providing multiple implementations for handling events: serial execution, parallel execution, and cross-tab broadcasting.
- π Serial Execution: Execute event handlers in order of priority
- β‘ Parallel Execution: Run event handlers concurrently for better performance
- π Cross-Tab Broadcasting: Broadcast events across browser tabs using BroadcastChannel API or localStorage fallback
- πΎ Storage Messenger: Direct cross-tab messaging with TTL and cleanup
- π¦ Generic Event Bus: Manage multiple event types with lazy loading
- π§ Type-Safe: Full TypeScript support with strict typing
- π§΅ Async Support: Handle both synchronous and asynchronous event handlers
- π Once Handlers: Support for one-time event handlers
- π‘οΈ Error Handling: Robust error handling with logging
- π Auto Fallback: Automatically selects best available cross-tab communication method
π‘ @ahoo-wang/fetcher-eventstream - Real-Time Streaming & LLM Support
Power your real-time applications with Server-Sent Events support, specially designed for Large Language Model streaming APIs:
- π‘ Event Stream Conversion: Converts
text/event-streamresponses to async generators ofServerSentEventobjects - π Side-Effect Module Import: Automatically adds
eventStream()andjsonEventStream()methods to the globalResponse.prototypefor responses withtext/event-streamcontent type - π SSE Parsing: Parses Server-Sent Events according to the specification, including data, event, id, and retry fields
- π Streaming Support: Handles chunked data and multi-line events correctly
- π¬ Comment Handling: Properly ignores comment lines (lines starting with
:) as per SSE specification - π‘οΈ TypeScript Support: Complete TypeScript type definitions
- β‘ Performance Optimized: Efficient parsing and streaming for high-performance applications
- π€ LLM Streaming Ready: Native support for streaming responses from popular LLM APIs like OpenAI GPT, Claude, etc.
π€ @ahoo-wang/fetcher-openai - OpenAI API Client
Type-safe OpenAI API client with native streaming support for chat completions:
- π― Type-Safe OpenAI Integration: Complete TypeScript support for OpenAI Chat Completions API
- π‘ Native Streaming Support: Built-in support for streaming chat completions with Server-Sent Events
- π§ Declarative API: Clean, decorator-based API for OpenAI interactions
- β‘ Fetcher Integration: Seamlessly integrates with the Fetcher ecosystem
πΎ @ahoo-wang/fetcher-storage - Cross-Environment Storage
A lightweight, cross-environment storage library with key-based storage and automatic environment detection:
- π Cross-Environment Support: Consistent API for browser localStorage/sessionStorage and in-memory storage
- π¦ Ultra-Lightweight: Only ~1KB gzip - minimal footprint
- π Storage Change Events: Listen for storage changes with event-driven architecture
- π Automatic Environment Detection: Automatically selects appropriate storage with fallback
- π οΈ Key-Based Storage: Efficient key-based storage with built-in caching and serialization
- π§ Custom Serialization: Support for custom serialization strategies (JSON, Identity)
- π TypeScript Support: Full TypeScript definitions for type-safe storage operations
π§© @ahoo-wang/fetcher-wow - CQRS/DDD Framework Support
First-class integration with the Wow CQRS/DDD framework:
- π CQRS Pattern Implementation: First-class support for Command Query Responsibility Segregation architectural pattern
- π§± DDD Primitives: Essential Domain-Driven Design building blocks including aggregates, events, and value objects
- π¦ Complete TypeScript Support: Full type definitions for all Wow framework entities including commands, events, and queries
- π‘ Real-time Event Streaming: Built-in support for Server-Sent Events to receive real-time command results and data updates
- π Command Client: High-level client for sending commands to Wow services with both synchronous and streaming responses
- π Powerful Query DSL: Rich query condition builder with comprehensive operator support for complex querying
- π Query Clients: Specialized clients for querying snapshot and event stream data with comprehensive query
operations:
- Counting resources
- Listing resources
- Streaming resources as Server-Sent Events
- Paging resources
- Retrieving single resources
π @ahoo-wang/fetcher-cosec - Enterprise Security
Secure your applications with integrated authentication:
- π Automatic Authentication: Automatic CoSec authentication headers
- π± Device Management: Device ID management with localStorage persistence
- π Token Refresh: Automatic token refresh based on response codes (401)
- π Request Tracking: Unique request ID generation for tracking
- πΎ Token Storage: Secure token storage management
π¦ Package Ecosystem
| Package | Description | Version | Size |
|---|---|---|---|
@ahoo-wang/fetcher | Core HTTP Client Ultra-lightweight foundation with Axios-like API | ||
@ahoo-wang/fetcher-decorator | Decorator Support Declarative API service definitions | ||
@ahoo-wang/fetcher-eventstream | Real-Time Streaming & LLM Support Server-Sent Events (SSE) support with native LLM streaming API integration | ||
@ahoo-wang/fetcher-openai | OpenAI Client Type-safe OpenAI API client with streaming support for chat completions | ||
@ahoo-wang/fetcher-generator | OpenAPI Code Generator Powerful TypeScript code generator from OpenAPI specifications, designed to be general-purpose with specialized support for Wow domain-driven design framework's CQRS patterns | ||
@ahoo-wang/fetcher-openapi | OpenAPI TypeScript Types Complete TypeScript type definitions for OpenAPI 3.0+ specifications | ||
@ahoo-wang/fetcher-storage | Cross-Environment Storage Lightweight storage library with key-based storage and automatic environment detection | ||
@ahoo-wang/fetcher-react | React Integration React hooks and components for seamless data fetching with automatic re-rendering | ||
@ahoo-wang/fetcher-wow | CQRS/DDD Framework Support First-class integration with the Wow CQRS/DDD framework | ||
@ahoo-wang/fetcher-cosec | Enterprise Security CoSec authentication integration |
π Getting Started
π¦ Installation
# Install the core package
npm install @ahoo-wang/fetcher
# Or install with all extensions including LLM streaming support
npm install @ahoo-wang/fetcher @ahoo-wang/fetcher-decorator @ahoo-wang/fetcher-eventbus @ahoo-wang/fetcher-eventstream @ahoo-wang/fetcher-cosec
# Using pnpm (recommended)
pnpm add @ahoo-wang/fetcher
# Using yarn
yarn add @ahoo-wang/fetcher
β‘ Quick Examples
Basic HTTP Client
import { Fetcher } from '@ahoo-wang/fetcher';
// Create a fetcher instance
const fetcher = new Fetcher({
baseURL: 'https://api.example.com',
timeout: 5000,
});
// GET request with path and query parameters
const response = await fetcher.get('/users/{id}', {
urlParams: {
path: { id: 123 },
query: { include: 'profile' },
},
});
const userData = await response.json<User>();
// POST request with automatic JSON conversion
const createUserResponse = await fetcher.post('/users', {
body: { name: 'John Doe', email: 'john@example.com' },
});
Declarative API Services
import { NamedFetcher } from '@ahoo-wang/fetcher';
import {
api,
get,
post,
path,
query,
body,
autoGeneratedError,
} from '@ahoo-wang/fetcher-decorator';
// Register a named fetcher
const apiFetcher = new NamedFetcher('api', {
baseURL: 'https://api.example.com',
});
// Define service with decorators
@api('/users', { fetcher: 'api' })
class UserService {
@get('/')
getUsers(@query('limit') limit?: number): Promise<User[]> {
throw autoGeneratedError(limit);
}
@post('/')
createUser(@body() user: User): Promise<User> {
throw autoGeneratedError(user);
}
@get('/{id}')
getUser(@path('id') id: number): Promise<User> {
throw autoGeneratedError(id);
}
}
// Use the service
const userService = new UserService();
const users = await userService.getUsers(10);
OpenAPI Code Generator
# Global Installation Generator CLI
npm install -g @ahoo-wang/fetcher-generator
# Generate TypeScript code from OpenAPI specifications
fetcher-generator generate -i ./openapi-spec.json -o ./src/generated
# or generated from a remote URL
fetcher-generator generate -i https://api.example.com/openapi.json -o ./src/generated
Powerful Interceptors
import { Fetcher } from '@ahoo-wang/fetcher';
const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
// Add request interceptor with ordering
fetcher.interceptors.request.use({
name: 'auth-interceptor',
order: 100,
intercept(exchange) {
exchange.request.headers.Authorization = 'Bearer ' + getAuthToken();
},
});
// Add response interceptor for logging
fetcher.interceptors.response.use({
name: 'logging-interceptor',
order: 10,
intercept(exchange) {
console.log('Response:', exchange.response.status);
},
});
Real-Time Streaming & LLM Support
import { Fetcher } from '@ahoo-wang/fetcher';
import '@ahoo-wang/fetcher-eventstream';
const fetcher = new Fetcher({ baseURL: 'https://api.example.com' });
// Stream real-time events (generic SSE)
const response = await fetcher.get('/events');
if (response.eventStream) {
for await (const event of response.eventStream()) {
console.log('Real-time event:', event);
}
}
// Stream LLM responses token by token
const llmResponse = await fetcher.post('/chat/completions', {
body: {
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello!' }],
stream: true,
},
});
if (llmResponse.jsonEventStream) {
// Specialized for JSON SSE events from LLM APIs
for await (const event of llmResponse.jsonEventStream<ChatCompletionChunk>()) {
const content = event.data.choices[0]?.delta?.content || '';
process.stdout.write(content); // Real-time token output
}
}
OpenAI Chat Completions
import { OpenAI } from '@ahoo-wang/fetcher-openai';
// Initialize OpenAI client
const openai = new OpenAI({
baseURL: 'https://api.openai.com/v1',
apiKey: process.env.OPENAI_API_KEY!,
});
// Non-streaming chat completion
const response = await openai.chat.completions({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Hello, how are you?' }],
stream: false,
});
console.log(response.choices[0].message.content);
// Streaming chat completion
const stream = await openai.chat.completions({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: 'Tell me a story' }],
stream: true,
});
for await (const chunk of stream) {
const content = chunk.data.choices[0]?.delta?.content || '';
process.stdout.write(content); // Real-time output
}
Event Bus for Cross-Tab Communication
import {
BroadcastTypedEventBus,
SerialTypedEventBus,
} from '@ahoo-wang/fetcher-eventbus';
// Create a delegate for local event handling
const delegate = new SerialTypedEventBus<string>('shared-events');
// Create broadcast event bus for cross-tab communication
const eventBus = new BroadcastTypedEventBus(delegate);
// Add event handler
eventBus.on({
name: 'user-action',
order: 1,
handle: action => console.log('User action:', action),
});
// Emit event locally and broadcast to other tabs
await eventBus.emit('button-clicked');
π― Integration Test Examples
Explore comprehensive, production-ready implementations in our integration-test directory:
π HTTP Operations
- Typicode API Integration - Complete integration with JSONPlaceholder API demonstrating real-world usage
- Parameter Handling - Advanced path, query, and body parameter management
- Error Handling - Comprehensive error handling patterns
π§ Advanced Patterns
- COSEC Authentication - Enterprise-grade security integration with token management
- Interceptor Chains - Complex middleware patterns with ordered execution
- Timeout Strategies - Adaptive timeout configurations
π‘ Real-Time Features
- LLM Streaming API - Native support for streaming responses from Large Language Models
- Server-Sent Events - Real-time notifications and updates
- Streaming Data - Continuous data streams with automatic reconnection
π¨ Decorator Patterns
- Declarative Services - Clean, maintainable API service layers using TypeScript decorators
- Metadata Extensions - Custom metadata for advanced use cases
- Type-Safe APIs - Full TypeScript integration with automatic type inference
π― Event Bus Patterns
- Cross-Tab Communication - Seamless event broadcasting between browser tabs
- Typed Event Handling - Type-safe event management with priority ordering
- Async Event Processing - Support for both synchronous and asynchronous event handlers
ποΈ Development & Contributing
π οΈ Prerequisites
- Node.js >= 18.20.8
- pnpm >= 8
π Development Commands
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run unit tests with coverage
pnpm test:unit
# Format code
pnpm format
# Clean build artifacts
pnpm clean
# Run integration tests
#pnpm test:it
π¦ Version Management
Update all packages simultaneously:
pnpm update-version <new-version>
This updates the version field in all package.json files across the monorepo.
π€ Contributing
We welcome contributions! Please see our contributing guide for details:
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a pull request
π§ͺ Quality Assurance
- Code Coverage: Maintained above 95% across all packages
- TypeScript: Strict type checking enabled
- Linting: ESLint with Prettier for consistent code style
- Testing: Comprehensive unit and integration tests
π License
This project is licensed under the Apache-2.0 License.