JS utilities for AJAX and GraphQL
npm install @nlabs/rip-hunter> Rip Hunter: Your Universal Gateway to Modern API Endpoints with Unmatched Speed and Reliability






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.
---
- 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
---
``bash
npm install @nlabs/rip-hunteror
yarn add @nlabs/rip-hunter
---
β‘ Quick Start
$3
`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
});
`$3
`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 });
`$3
`js
import { subscribe } from '@nlabs/rip-hunter';// Subscribe to real-time GraphQL updates
const unsubscribe = subscribe(
'wss://api.example.com/graphql',
,
{
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();
`$3
`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
$3
####
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####
get(url, params?, options?)HTTP GET request.
- url:
string
- params: object
- options: { headers?, token?, timeout?, cache? }
- Returns: Promise####
post(url, params?, options?)HTTP POST request.
- url:
string
- params: object
- options: { headers?, token?, timeout? }
- Returns: Promise####
put(url, params?, options?)HTTP PUT request.
- url:
string
- params: object
- options: { headers?, token?, timeout? }
- Returns: Promise####
del(url, params?, options?)HTTP DELETE request.
- url:
string
- params: object
- options: { headers?, token?, timeout? }
- Returns: Promise---
$3
####
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####
mutation(url, body, options?)Send a GraphQL mutation.
- url:
string
- body: string
- options: { headers?, token?, variables?, stripWhitespace?, timeout? }
- Returns: Promise####
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 β GraphQL variables
- connectionParams?: Record β 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####
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}'
`---
$3
####
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####
HunterSSEEventTypeSSE event object with:
-
data: string β Event data
- type: string β Event type
- id?: string β Event ID
- retry?: number β Retry interval (if specified by server)---
$3
####
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.
####
ApiErrorAll errors are wrapped in a consistent
ApiError object for easy handling.- .errors:
string[] β List of error messages
- .source: Error β Original error object---
Advanced Usage
$3
`js
// Cache GET requests for 5 minutes
const data = await get('/api/users', {}, { cache: true });
`$3
`js
// Set 10 second timeout
const result = await post('/api/data', payload, { timeout: 10000 });
`$3
`js
const headers = new Headers({
'X-Custom-Header': 'value',
'Content-Type': 'application/json'
});const data = await get('/api/data', {}, { headers });
`$3
`js
const query = ;const variables = { id: '123' };
const user = await query('/graphql', query, { variables });
`$3
`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---
PRs and issues welcome! Please see CONTRIBUTING.md for guidelines.
MIT Β© Nitrogen Labs, Inc.