0
# Hyperquest
1
2
Hyperquest is a Node.js HTTP client library that treats HTTP requests as streaming transport. It solves critical problems with Node.js core HTTP functionality by eliminating connection pooling (default limit of 5 concurrent connections) and idle timeouts (2 minutes default) that cause applications to hang unexpectedly in production. Hyperquest provides a streaming API similar to the popular 'request' module but with better performance characteristics.
3
4
## Package Information
5
6
- **Package Name**: hyperquest
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install hyperquest`
10
11
## Core Imports
12
13
```javascript
14
const hyperquest = require('hyperquest');
15
```
16
17
ESM (with compatible bundler):
18
19
```javascript
20
import hyperquest from 'hyperquest';
21
```
22
23
## Basic Usage
24
25
```javascript
26
const hyperquest = require('hyperquest');
27
28
// Simple GET request - returns readable stream
29
const req = hyperquest('http://api.example.com/data');
30
req.pipe(process.stdout);
31
32
// POST request with data - returns duplex stream
33
const postReq = hyperquest.post('http://api.example.com/submit');
34
postReq.write('{"message": "hello"}');
35
postReq.end();
36
37
// Handle response
38
postReq.on('response', (res) => {
39
console.log('Status:', res.statusCode);
40
console.log('Headers:', res.headers);
41
});
42
43
// Collect response data
44
let data = '';
45
postReq.on('data', (chunk) => data += chunk);
46
postReq.on('end', () => console.log('Response:', data));
47
```
48
49
## Architecture
50
51
Hyperquest is built around these key components:
52
53
- **Stream-First Design**: All requests return Node.js streams (readable for GET/HEAD/DELETE, duplex for POST/PUT)
54
- **No Connection Pooling**: Sets `agent: false` by default to avoid the 5-connection limit
55
- **No Idle Timeouts**: Uses maximum timeout value to prevent 2-minute hangs
56
- **Browser Compatibility**: Works with Browserify for client-side usage
57
- **Minimal Dependencies**: Only requires buffer-from, duplexer2, and through2
58
59
## Capabilities
60
61
### HTTP Requests
62
63
Create streaming HTTP requests with various methods and options.
64
65
```javascript { .api }
66
/**
67
* Create an outgoing HTTP request
68
* @param {string|object} uri - Request URI or options object
69
* @param {object} [opts={}] - Request options
70
* @param {function} [cb] - Optional callback for error/response events
71
* @returns {Stream} Readable stream (GET/HEAD/DELETE) or duplex stream (POST/PUT)
72
*/
73
function hyperquest(uri, opts, cb);
74
75
/**
76
* Create a GET request (alias for hyperquest)
77
* @param {string|object} uri - Request URI or options object
78
* @param {object} [opts={}] - Request options
79
* @param {function} [cb] - Optional callback for error/response events
80
* @returns {Stream} Readable stream
81
*/
82
hyperquest.get(uri, opts, cb);
83
84
/**
85
* Create a POST request
86
* @param {string|object} uri - Request URI or options object
87
* @param {object} [opts={}] - Request options
88
* @param {function} [cb] - Optional callback for error/response events
89
* @returns {Stream} Duplex stream (readable and writable)
90
*/
91
hyperquest.post(uri, opts, cb);
92
93
/**
94
* Create a PUT request
95
* @param {string|object} uri - Request URI or options object
96
* @param {object} [opts={}] - Request options
97
* @param {function} [cb] - Optional callback for error/response events
98
* @returns {Stream} Duplex stream (readable and writable)
99
*/
100
hyperquest.put(uri, opts, cb);
101
102
/**
103
* Create a DELETE request
104
* @param {string|object} uri - Request URI or options object
105
* @param {object} [opts={}] - Request options
106
* @param {function} [cb] - Optional callback for error/response events
107
* @returns {Stream} Readable stream
108
*/
109
hyperquest.delete(uri, opts, cb);
110
```
111
112
**Usage Examples:**
113
114
```javascript
115
const hyperquest = require('hyperquest');
116
117
// GET request
118
const getReq = hyperquest('http://api.example.com/users');
119
getReq.pipe(process.stdout);
120
121
// POST request with JSON data
122
const postReq = hyperquest.post('http://api.example.com/users');
123
postReq.setHeader('content-type', 'application/json');
124
postReq.write(JSON.stringify({ name: 'Alice', age: 25 }));
125
postReq.end();
126
127
// PUT request with authentication
128
const putReq = hyperquest.put('http://user:pass@api.example.com/users/123');
129
putReq.write('{"name": "Alice Updated"}');
130
putReq.end();
131
132
// DELETE request
133
const deleteReq = hyperquest.delete('http://api.example.com/users/123');
134
deleteReq.on('response', (res) => {
135
console.log('Deleted:', res.statusCode === 204);
136
});
137
```
138
139
### Request Configuration
140
141
Configure requests with headers, authentication, and other options.
142
143
```javascript { .api }
144
/**
145
* Set an outgoing HTTP header
146
* @param {string} key - Header name
147
* @param {string} value - Header value
148
* @returns {Stream} The request stream for chaining
149
* @throws {Error} Throws "request already sent" if called after request has been sent
150
*/
151
setHeader(key, value);
152
153
/**
154
* Set the request URI after creation
155
* @param {string} uri - Request URI
156
* @returns {Stream} The request stream for chaining
157
*/
158
setLocation(uri);
159
```
160
161
**Usage Examples:**
162
163
```javascript
164
const req = hyperquest.post('http://api.example.com/data');
165
req.setHeader('content-type', 'application/json');
166
req.setHeader('authorization', 'Bearer token123');
167
req.setLocation('http://api.example.com/updated-endpoint');
168
169
// Note: setHeader must be called before request is sent
170
req.on('request', () => {
171
// This would throw "request already sent" error:
172
// req.setHeader('late-header', 'value');
173
});
174
```
175
176
### Events
177
178
Handle request lifecycle events.
179
180
```javascript { .api }
181
/**
182
* Event fired with the underlying ClientRequest object
183
* @event request
184
* @param {http.ClientRequest} req - The underlying HTTP request object
185
*/
186
187
/**
188
* Event fired with the HTTP response object
189
* @event response
190
* @param {http.IncomingMessage} res - The HTTP response object
191
*/
192
193
/**
194
* Event fired when an error occurs
195
* @event error
196
* @param {Error} err - The error object
197
*/
198
```
199
200
**Usage Examples:**
201
202
```javascript
203
const req = hyperquest('http://api.example.com/data');
204
205
req.on('request', (clientReq) => {
206
console.log('Request started:', clientReq.method, clientReq.path);
207
});
208
209
req.on('response', (res) => {
210
console.log('Response received:', res.statusCode);
211
console.log('Content-Type:', res.headers['content-type']);
212
});
213
214
req.on('error', (err) => {
215
console.error('Request failed:', err.message);
216
});
217
```
218
219
## Options Object
220
221
Configuration options for HTTP requests.
222
223
```javascript { .api }
224
/**
225
* Request options object
226
* @typedef {Object} RequestOptions
227
* @property {string} [method='GET'] - HTTP method
228
* @property {Object} [headers={}] - HTTP headers object
229
* @property {string} [auth] - Basic auth in "user:pass" format
230
* @property {boolean|http.Agent} [agent=false] - HTTP agent (false disables pooling)
231
* @property {number} [timeout=2147483647] - Request timeout in milliseconds
232
* @property {string} [localAddress] - Local interface to bind for connections
233
* @property {string} [uri] - Request URI
234
* @property {boolean} [withCredentials] - Browser credentials option
235
* @property {string|Buffer} [pfx] - PFX certificate for HTTPS
236
* @property {string|Buffer} [key] - Private key for HTTPS
237
* @property {string|Buffer} [cert] - Certificate for HTTPS
238
* @property {string|Buffer|Array} [ca] - Certificate authorities for HTTPS
239
* @property {string} [ciphers] - Cipher suites for HTTPS
240
* @property {boolean} [rejectUnauthorized] - Verify server certificates for HTTPS
241
* @property {string} [secureProtocol] - SSL/TLS protocol version for HTTPS
242
*/
243
```
244
245
**Usage Examples:**
246
247
```javascript
248
// Basic options
249
const req = hyperquest('http://api.example.com/data', {
250
method: 'POST',
251
headers: { 'content-type': 'application/json' },
252
timeout: 5000
253
});
254
255
// Authentication via URL
256
const authReq = hyperquest('http://user:pass@api.example.com/private');
257
258
// Authentication via options
259
const authReq2 = hyperquest('http://api.example.com/private', {
260
auth: 'user:pass'
261
});
262
263
// HTTPS with custom certificates
264
const httpsReq = hyperquest('https://secure-api.example.com/data', {
265
ca: fs.readFileSync('ca-cert.pem'),
266
cert: fs.readFileSync('client-cert.pem'),
267
key: fs.readFileSync('client-key.pem'),
268
rejectUnauthorized: true
269
});
270
```
271
272
## Stream Properties
273
274
Properties available on returned request streams.
275
276
```javascript { .api }
277
/**
278
* Reference to hyperquest's internal request object containing metadata
279
* @property {Object} request - Object with method, headers, auth, options properties
280
*/
281
282
/**
283
* Reference to the HTTP response object (available after 'response' event)
284
* @property {http.IncomingMessage} response
285
*/
286
```
287
288
**Usage Examples:**
289
290
```javascript
291
const req = hyperquest('http://api.example.com/data');
292
293
req.on('response', (res) => {
294
// Access response via event parameter
295
console.log('Event response:', res.statusCode);
296
297
// Or via stream property (same object)
298
console.log('Stream response:', req.response.statusCode);
299
});
300
301
// Access underlying request object
302
console.log('Request method:', req.request.method);
303
```
304
305
## Error Handling
306
307
Handle various error conditions that may occur during HTTP requests.
308
309
**Usage Examples:**
310
311
```javascript
312
const req = hyperquest('http://api.example.com/data');
313
314
req.on('error', (err) => {
315
if (err.code === 'ECONNREFUSED') {
316
console.error('Connection refused - server may be down');
317
} else if (err.code === 'ENOTFOUND') {
318
console.error('Host not found - check the URL');
319
} else if (err.code === 'ETIMEDOUT') {
320
console.error('Request timed out');
321
} else {
322
console.error('Request error:', err.message);
323
}
324
});
325
326
// Using callback for error handling
327
const req2 = hyperquest('http://api.example.com/data', (err, res) => {
328
if (err) {
329
console.error('Request failed:', err.message);
330
return;
331
}
332
console.log('Request succeeded:', res.statusCode);
333
});
334
```