UNPKG

@nlabs/rip-hunter

Version:
419 lines (306 loc) β€’ 11.1 kB
# Rip Hunter: HTTP Client for REST & GraphQL** > **Rip Hunter: Your Universal Gateway to Modern API Endpoints with Unmatched Speed and Reliability** [![npm version](https://img.shields.io/npm/v/rip-hunter.svg?style=flat-square)](https://www.npmjs.com/package/rip-hunter) [![npm downloads](https://img.shields.io/npm/dm/rip-hunter.svg?style=flat-square)](https://www.npmjs.com/package/rip-hunter) [![Issues](http://img.shields.io/github/issues/nitrogenlabs/rip-hunter.svg?style=flat-square)](https://github.com/nitrogenlabs/rip-hunter/issues) [![TypeScript](https://badges.frapsoft.com/typescript/version/typescript-next.svg?v=101)](https://github.com/ellerbrock/typescript-badges/) [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](http://opensource.org/licenses/MIT) [![Chat](https://img.shields.io/discord/446122412715802649.svg)](https://discord.gg/Ttgev58) **rip-hunter** is the all-in-one HTTP utility for developers who want a seamless, ESM-first way to connect to REST and GraphQL APIs. Whether you're building in Node.js, the browser, or serverless, rip-hunter makes data fetching, mutations, and error handling effortlessβ€”so you can focus on building features, not plumbing. --- ## Why rip-hunter? - **Unified API**: One package for both REST and GraphQL endpoints - **ESM & TypeScript Native**: Modern, type-safe, and tree-shakable - **Works Everywhere**: Node, browser, serverlessβ€”no config needed - **Built-in Auth & Headers**: Effortlessly add tokens and custom headers - **Automatic Error Handling**: Consistent, developer-friendly errors - **Tiny & Fast**: Minimal dependencies, zero bloat - **Request Caching**: Built-in caching for GET requests - **Timeout Support**: Configurable request timeouts - **Request Deduplication**: Prevents duplicate requests - **Real-time Updates**: Server-Sent Events (SSE) support - **GraphQL Subscriptions**: WebSocket-based subscriptions with automatic reconnection --- ## Installation ```bash npm install @nlabs/rip-hunter # or yarn add @nlabs/rip-hunter # For Node.js SSE support (optional) npm install eventsource ``` --- ## ⚑ Quick Start ### REST Example ```js import { get, post } from '@nlabs/rip-hunter'; const url = 'https://api.example.com/data'; // GET request with caching const data = await get(url, { userId: 123 }, { cache: true }); // POST request with auth token and timeout const result = await post(url, { name: 'Rip Hunter' }, { token: 'your_jwt_token', timeout: 5000 }); ``` ### GraphQL Example ```js import { query, mutation, toGql } from '@nlabs/rip-hunter'; const url = 'https://api.example.com/graphql'; const gql = '{ user { id name } }'; // Query with timeout const userData = await query(url, gql, { timeout: 10000 }); // Mutation with variables const input = { name: 'Rip Hunter' }; const mutationGql = `mutation { createUser(input: ${toGql(input)}) { id name } }`; const created = await mutation(url, mutationGql, { timeout: 5000 }); ``` ### GraphQL Subscription Example ```js import { subscribe } from '@nlabs/rip-hunter'; // Subscribe to real-time GraphQL updates const unsubscribe = subscribe( 'wss://api.example.com/graphql', ` subscription { userUpdated { id name email } } `, { onNext: (data) => { console.log('User updated:', data.userUpdated); }, onError: (error) => { console.error('Subscription error:', error); }, onComplete: () => { console.log('Subscription completed'); }, onReconnect: (attempt) => { console.log(`Reconnecting... (attempt ${attempt})`); } }, { token: 'your_jwt_token', variables: { userId: '123' }, connectionParams: { clientId: 'my-client' }, maxReconnectAttempts: 10, reconnectInterval: 1000 } ); // Later, to unsubscribe: unsubscribe(); ``` ### SSE Example ```js import { subscribeSSE } from '@nlabs/rip-hunter'; // Subscribe to real-time updates const unsubscribe = subscribeSSE('https://api.example.com/stream', { onMessage: (event) => { console.log('Received:', event.data); }, onError: (error) => { console.error('SSE Error:', error); }, onOpen: () => { console.log('SSE connection opened'); } }, { token: 'your_jwt_token', timeout: 30000, retryInterval: 1000, maxRetries: 5 }); // Later, to stop listening: unsubscribe(); ``` --- ## πŸ› οΈ API Reference ### REST Functions #### `ajax(url, method, params?, options?)` Low-level HTTP request for any method. - **url**: `string` – Absolute URL - **method**: `string` – HTTP method (GET, POST, etc.) - **params**: `object` – Data to send (query for GET, body for others) - **options**: `{ headers?, token?, timeout?, cache? }` - **Returns**: `Promise<any>` #### `get(url, params?, options?)` HTTP GET request. - **url**: `string` - **params**: `object` - **options**: `{ headers?, token?, timeout?, cache? }` - **Returns**: `Promise<any>` #### `post(url, params?, options?)` HTTP POST request. - **url**: `string` - **params**: `object` - **options**: `{ headers?, token?, timeout? }` - **Returns**: `Promise<any>` #### `put(url, params?, options?)` HTTP PUT request. - **url**: `string` - **params**: `object` - **options**: `{ headers?, token?, timeout? }` - **Returns**: `Promise<any>` #### `del(url, params?, options?)` HTTP DELETE request. - **url**: `string` - **params**: `object` - **options**: `{ headers?, token?, timeout? }` - **Returns**: `Promise<any>` --- ### GraphQL Functions #### `query(url, body, options?)` Send a GraphQL query. - **url**: `string` – GraphQL endpoint - **body**: `string` – GraphQL query string - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }` - **Returns**: `Promise<any>` #### `mutation(url, body, options?)` Send a GraphQL mutation. - **url**: `string` - **body**: `string` - **options**: `{ headers?, token?, variables?, stripWhitespace?, timeout? }` - **Returns**: `Promise<any>` #### `subscribe(url, query, callbacks, options?)` Subscribe to a GraphQL subscription over WebSocket (graphql-ws protocol). - **url**: `string` – WebSocket URL (ws:// or wss://) - **query**: `string` – GraphQL subscription query string - **callbacks**: `HunterSubscriptionCallbackType` – Event handlers - `onNext?: (data: any) => void` – Called when new data arrives - `onError?: (error: Error | Event) => void` – Called on errors - `onComplete?: () => void` – Called when subscription completes - `onReconnect?: (attempt: number) => void` – Called during reconnection attempts - **options**: `HunterSubscriptionOptionsType` - `token?: string` – Authentication token - `variables?: Record<string, unknown>` – GraphQL variables - `connectionParams?: Record<string, unknown>` – WebSocket connection parameters - `maxReconnectAttempts?: number` – Maximum reconnection attempts (default: 5) - `reconnectInterval?: number` – Delay between reconnection attempts in ms (default: 1000) - `timeout?: number` – Connection timeout - `headers?: Headers` – Custom headers - **Returns**: `() => void` – Unsubscribe function #### `graphqlQuery(url, query, options?)` Low-level GraphQL request. - **url**: `string` – GraphQL endpoint - **query**: `HunterQueryType | HunterQueryType[]` – Query object(s) - **options**: `{ headers?, token?, timeout? }` - **Returns**: `Promise<any>` #### `toGql(data)` Convert JS objects, arrays, or primitives to GraphQL input strings. - **data**: `any` - **Returns**: `string` - **Example**: ```js toGql({ name: 'Rip', age: 42 }) // => '{name: "Rip", age: 42}' ``` --- ### SSE Functions #### `subscribeSSE(url, callbacks, options?)` Subscribe to Server-Sent Events. - **url**: `string` – SSE endpoint URL - **callbacks**: `HunterSSECallbackType` – Event handlers - `onMessage?: (event: HunterSSEEventType) => void` - `onOpen?: (event: Event) => void` - `onError?: (error: Error | Event) => void` - `onRetry?: (attempt: number, delay: number) => void` - **options**: `HunterSSEOptionsType` – Connection options - `headers?: Headers` - `token?: string` - `timeout?: number` (default: 30000) - `retryInterval?: number` (default: 1000) - `maxRetries?: number` (default: 5) - **Returns**: `() => void` – Cleanup function #### `HunterSSEEventType` SSE event object with: - `data: string` – Event data - `type: string` – Event type - `id?: string` – Event ID - `retry?: number` – Retry interval (if specified by server) --- ### Events & Error Handling #### `on(eventType, listener)` Subscribe to events (e.g., error events). - **eventType**: `string` (e.g., 'rip_hunter_error') - **listener**: `Function` #### `off(eventType, listener)` Unsubscribe from events. #### `ApiError` All errors are wrapped in a consistent `ApiError` object for easy handling. - **.errors**: `string[]` – List of error messages - **.source**: `Error` – Original error object --- ## Advanced Usage ### Request Caching ```js // Cache GET requests for 5 minutes const data = await get('/api/users', {}, { cache: true }); ``` ### Timeout Handling ```js // Set 10 second timeout const result = await post('/api/data', payload, { timeout: 10000 }); ``` ### Custom Headers ```js const headers = new Headers({ 'X-Custom-Header': 'value', 'Content-Type': 'application/json' }); const data = await get('/api/data', {}, { headers }); ``` ### GraphQL Variables ```js const query = ` query GetUser($id: ID!) { user(id: $id) { name email } } `; const variables = { id: '123' }; const user = await query('/graphql', query, { variables }); ``` ### SSE with Authentication ```js const headers = new Headers({ 'Authorization': 'Bearer your-token', 'Accept': 'text/event-stream' }); const unsubscribe = subscribeSSE('/api/notifications', { onMessage: (event) => { const notification = JSON.parse(event.data); console.log('New notification:', notification); }, onError: (error) => { console.error('SSE error:', error); } }, { headers, timeout: 60000, maxRetries: 10 }); ``` --- ## Performance Features - **Request Deduplication**: Prevents duplicate requests to the same endpoint - **Built-in Caching**: Automatic caching for GET requests with 5-minute TTL - **Timeout Support**: Configurable request timeouts (default: 30s) - **Optimized Functions**: Lightweight utility functions for better performance - **Memory Efficient**: Minimal object creation and garbage collection - **SSE Reconnection**: Automatic retry with exponential backoff for SSE connections --- ## Environment Support - **Browser**: Full support for all features including SSE - **Node.js**: Full REST/GraphQL support, SSE requires `eventsource` package - **Serverless**: REST/GraphQL support (SSE not recommended in serverless) --- ## Contributing PRs and issues welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. ## License MIT Β© Nitrogen Labs, Inc. ## πŸ”— Links - [GitHub](https://github.com/nitrogenlabs/rip-hunter) - [NPM](https://www.npmjs.com/package/rip-hunter)