@0xshariq/voxa-core 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/CHANGELOG.md +250 -0
  2. package/LICENSE +21 -0
  3. package/README.md +782 -0
  4. package/dist/config/index.d.ts +1 -0
  5. package/dist/config/index.js +1 -0
  6. package/dist/index.d.ts +1 -0
  7. package/dist/index.js +1 -0
  8. package/dist/lib/client/http-methods.d.ts +1 -0
  9. package/dist/lib/client/http-methods.js +1 -0
  10. package/dist/lib/client/logging.d.ts +1 -0
  11. package/dist/lib/client/logging.js +1 -0
  12. package/dist/lib/client/request.d.ts +1 -0
  13. package/dist/lib/client/request.js +1 -0
  14. package/dist/lib/client/security.d.ts +1 -0
  15. package/dist/lib/client/security.js +1 -0
  16. package/dist/lib/client/utils.d.ts +1 -0
  17. package/dist/lib/client/utils.js +1 -0
  18. package/dist/lib/client/voxa.d.ts +1 -0
  19. package/dist/lib/client/voxa.js +1 -0
  20. package/dist/lib/features/cache/file-storage.d.ts +1 -0
  21. package/dist/lib/features/cache/file-storage.js +1 -0
  22. package/dist/lib/features/cache/manager.d.ts +1 -0
  23. package/dist/lib/features/cache/manager.js +1 -0
  24. package/dist/lib/features/deduplication/manager.d.ts +1 -0
  25. package/dist/lib/features/deduplication/manager.js +1 -0
  26. package/dist/lib/features/errors/classifier.d.ts +1 -0
  27. package/dist/lib/features/errors/classifier.js +1 -0
  28. package/dist/lib/features/interceptors/manager.d.ts +1 -0
  29. package/dist/lib/features/interceptors/manager.js +1 -0
  30. package/dist/lib/features/logging/file-logger.d.ts +1 -0
  31. package/dist/lib/features/logging/file-logger.js +1 -0
  32. package/dist/lib/features/metadata/manager.d.ts +1 -0
  33. package/dist/lib/features/metadata/manager.js +1 -0
  34. package/dist/lib/features/queue/manager.d.ts +1 -0
  35. package/dist/lib/features/queue/manager.js +1 -0
  36. package/dist/lib/features/rate/limiter.d.ts +1 -0
  37. package/dist/lib/features/rate/limiter.js +1 -0
  38. package/dist/lib/features/retry/manager.d.ts +1 -0
  39. package/dist/lib/features/retry/manager.js +1 -0
  40. package/dist/lib/features/schema/validator.d.ts +1 -0
  41. package/dist/lib/features/schema/validator.js +1 -0
  42. package/dist/lib/index.d.ts +1 -0
  43. package/dist/lib/index.js +1 -0
  44. package/dist/lib/types/client-types.d.ts +1 -0
  45. package/dist/lib/types/client-types.js +1 -0
  46. package/dist/lib/version.d.ts +1 -0
  47. package/dist/lib/version.js +1 -0
  48. package/package.json +76 -0
package/README.md ADDED
@@ -0,0 +1,782 @@
1
+ # Voxa HTTP Client
2
+
3
+ <p align="center">
4
+ <em>Modern, feature-rich HTTP client for Node.js and browsers, built on the native Fetch API. Modular architecture with separate feature packages for optimal bundle size.</em>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <a href="https://www.npmjs.com/package/@0xshariq/voxa-core"><img src="https://img.shields.io/npm/v/@0xshariq/voxa-core.svg" alt="npm version"></a>
9
+ <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
10
+ </p>
11
+
12
+ ---
13
+
14
+ ## πŸ“Š Why Voxa?
15
+
16
+ Voxa isn't just another HTTP clientβ€”it's a **complete request management system** with a **modular architecture**. Install only the features you need, keeping your bundle size minimal while having access to advanced capabilities that Axios, Fetch, and other popular clients simply don't have.
17
+
18
+ ### 🎯 Modular Design
19
+
20
+ Voxa is split into multiple packages:
21
+
22
+ - **@0xshariq/voxa-core** (~140KB) - Essential HTTP client with caching, retry, queue, rate limiting, and deduplication
23
+ - **@0xshariq/voxa-streaming-images** - Image streaming with progress tracking
24
+ - **@0xshariq/voxa-streaming-videos** - Video streaming with progress tracking
25
+ - **@0xshariq/voxa-http2** - HTTP/2 Server Push support
26
+ - **@0xshariq/voxa-graphql** - GraphQL query support
27
+ - **@0xshariq/voxa-batch** - Request batching
28
+ - **@0xshariq/voxa-offline** - Offline queue management
29
+ - **@0xshariq/voxa-circuit-breaker** - Circuit breaker pattern
30
+ - **@0xshariq/voxa-token** - OAuth/JWT token management
31
+ - **@0xshariq/voxa-metrics** - Performance metrics tracking
32
+ - **@0xshariq/voxa-cancel** - Advanced request cancellation
33
+
34
+ ---
35
+
36
+ ## Future Plans
37
+
38
+ - Voxa CLI (Under Development)
39
+ - Voxa API (Private API only for trusted users and organizations) (Done)
40
+ - Voxa SDKs (Go,Rust,Python and Ruby) (Not Planned Yet)
41
+
42
+ ---
43
+
44
+ ## Feature Comparison
45
+
46
+ | Feature | Voxa | Axios | Fetch | ky | Got | node-fetch |
47
+ | --------------------------------- | :---------: | :------: | :------: | :------: | :---------: | :--------: |
48
+ | **Bundle Size** | 140KB-372KB | ~13KB | 0KB | ~11KB | ~45KB | ~6KB |
49
+ | **Dependencies** | 0 | 4 | 0 | 0 | 15 | 0 |
50
+ | **Modular Architecture** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
51
+ | **TypeScript First** | βœ… | βœ… | βœ… | βœ… | βœ… | ⚠️ |
52
+ | **Browser + Node.js** | βœ… | βœ… | βœ… | βœ… | ❌ | ❌ |
53
+ | **Automatic Retry** | βœ… | ❌ | ❌ | βœ… | βœ… | ❌ |
54
+ | **Response Caching** | βœ… Advanced | ❌ | ❌ | βœ… Basic | βœ… Advanced | ❌ |
55
+ | **Request Deduplication** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
56
+ | **Priority Queue** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
57
+ | **Batch Requests** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
58
+ | **Token Management** | βœ… Advanced | ❌ | ❌ | ❌ | ❌ | ❌ |
59
+ | **Offline Queue** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
60
+ | **GraphQL Support** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
61
+ | **Streaming Progress** | βœ… Advanced | βœ… Basic | βœ… Basic | βœ… | βœ… | βœ… |
62
+ | **Request/Response Interceptors** | βœ… | βœ… | ❌ | βœ… | βœ… | ❌ |
63
+ | **Circuit Breaker** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
64
+ | **Rate Limiting** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
65
+ | **SSRF Protection** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
66
+ | **Debug Mode** | βœ… | ⚠️ | ❌ | ⚠️ | βœ… | ❌ |
67
+ | **Cancel Requests** | βœ… | βœ… | βœ… | βœ… | βœ… | βœ… |
68
+ | **Schema Validation** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
69
+ | **Error Classification** | βœ… | ⚠️ | ❌ | ⚠️ | βœ… | ❌ |
70
+ | **Metadata Tracking** | βœ… | ❌ | ❌ | ❌ | ❌ | ❌ |
71
+
72
+ ---
73
+
74
+ ## ✨ Core Features (in @0xshariq/voxa-core)
75
+
76
+ - πŸ”„ **Automatic Retry** (exponential backoff)
77
+ - πŸ’Ύ **Response Caching** (memory/file/custom)
78
+ - 🎯 **Request Deduplication**
79
+ - ⚑ **Priority Queue**
80
+ - πŸ”’ **TypeScript First**
81
+ - πŸ”Œ **Interceptors**
82
+ - πŸ“Š **Request Tracking & Metadata**
83
+ - ⏱️ **Timeout Control**
84
+ - πŸš€ **Static Methods**
85
+ - πŸ“‘ **Schema Validation**
86
+ - πŸ” **SSRF Protection**
87
+ - πŸ› **Debug Mode**
88
+ - πŸ§ͺ **Automatic JSON Parsing**
89
+ - βš–οΈ **Rate Limiting**
90
+
91
+ ## 🎁 Optional Feature Packages
92
+
93
+ Install only what you need:
94
+
95
+ - πŸ“Ή **@0xshariq/voxa-streaming-images** - Image upload/download with progress
96
+ - 🎬 **@0xshariq/voxa-streaming-videos** - Video upload/download with progress
97
+ - ⚑ **@0xshariq/voxa-http2** - HTTP/2 Server Push
98
+ - πŸ” **@0xshariq/voxa-graphql** - GraphQL queries
99
+ - πŸ“¦ **@0xshariq/voxa-batch** - Request batching
100
+ - πŸ“΄ **@0xshariq/voxa-offline** - Offline queue
101
+ - πŸ”Œ **@0xshariq/voxa-circuit-breaker** - Circuit breaker pattern
102
+ - 🎫 **@0xshariq/voxa-token** - OAuth/JWT token management
103
+ - πŸ“Š **@0xshariq/voxa-metrics** - Performance metrics
104
+ - πŸ›‘ **@0xshariq/voxa-cancel** - Advanced cancellation
105
+
106
+ ---
107
+
108
+ ## πŸ“¦ Installation
109
+
110
+ ### Core Package (Required)
111
+
112
+ ```bash
113
+ npm install @0xshariq/voxa-core
114
+ # or
115
+ pnpm install @0xshariq/voxa-core
116
+ # or
117
+ yarn add @0xshariq/voxa-core
118
+ ```
119
+
120
+ ### Feature Packages (Optional)
121
+
122
+ ```bash
123
+ # Install only the features you need
124
+ npm install @0xshariq/voxa-graphql @0xshariq/voxa-streaming-images
125
+ ```
126
+
127
+ ---
128
+
129
+ ## πŸš€ Quick Start
130
+
131
+ ### Basic Usage (Core Only)
132
+
133
+ ```typescript
134
+ import { Voxa } from "@0xshariq/voxa-core";
135
+
136
+ const client = new Voxa({
137
+ baseURL: "https://api.example.com",
138
+ timeout: 5000,
139
+ cache: {
140
+ enabled: true,
141
+ ttl: 60000,
142
+ },
143
+ retry: {
144
+ enabled: true,
145
+ count: 3,
146
+ },
147
+ });
148
+
149
+ const response = await client.get("/users");
150
+ console.log(response.data);
151
+ ```
152
+
153
+ ### With Feature Packages
154
+
155
+ ```typescript
156
+ import { Voxa } from "@0xshariq/voxa-core";
157
+ import "@0xshariq/voxa-graphql"; // Types auto-merge
158
+ import "@0xshariq/voxa-batch";
159
+ import { StreamingImageManager } from "@0xshariq/voxa-streaming-images";
160
+
161
+ const client = new Voxa({
162
+ baseURL: "https://api.example.com",
163
+ graphql: {
164
+ // TypeScript knows about this!
165
+ enabled: true,
166
+ endpoint: "/graphql",
167
+ },
168
+ batch: {
169
+ enabled: true,
170
+ wait: 100,
171
+ },
172
+ });
173
+
174
+ // Use streaming
175
+ const imageManager = new StreamingImageManager();
176
+ await imageManager.upload("/upload", imageFile, {}, (sent, total) => {
177
+ console.log(`Progress: ${((sent / total) * 100).toFixed(2)}%`);
178
+ });
179
+ ```
180
+
181
+ ---
182
+
183
+ ### Complete Instance Example
184
+
185
+ ```typescript
186
+ import { Voxa } from "@0xshariq/voxa-core";
187
+
188
+ const api = new Voxa({
189
+ baseURL: "https://api.example.com",
190
+ timeout: 5000,
191
+ headers: {
192
+ "Content-Type": "application/json", // string
193
+ Authorization: "Bearer <token>", // string
194
+ },
195
+ priority: "high", // 'critical' | 'high' | 'normal' | 'low'
196
+ retry: {
197
+ enabled: true, // boolean (default: true)
198
+ count: 5, // number (max: 5)
199
+ delay: 1000, // number (ms)
200
+ exponentialBackoff: true, // boolean
201
+ maxRetry: 10000, // number (ms)
202
+ statusCodes: [429, 500, 502, 503, 504], // number[]
203
+ },
204
+ deduplication: {
205
+ enabled: true, // boolean (default: true)
206
+ ttl: 300000, // number (ms)
207
+ },
208
+ cache: {
209
+ enabled: true, // boolean (default: true)
210
+ ttl: 300000, // number (ms, default: 5 min)
211
+ storage: "memory", // 'memory' | 'custom'
212
+ adapter: undefined, // custom cache adapter (optional)
213
+ },
214
+ queue: {
215
+ enabled: true, // boolean
216
+ maxConcurrent: 5, // number
217
+ },
218
+ batch: {
219
+ enabled: true, // boolean
220
+ endpoint: "/batch", // string (optional)
221
+ wait: 100, // number (ms, optional)
222
+ maxBatchSize: 10, // number (optional)
223
+ },
224
+ token: {
225
+ enabled: true, // boolean
226
+ type: "bearer", // 'bearer' | 'oauth2' | 'jwt'
227
+ tokenEndpoint: "/auth/token", // string
228
+ clientId: "client-id", // string
229
+ clientSecret: "client-secret", // string
230
+ refreshEndpoint: "/auth/refresh", // string
231
+ storage: "memory", // 'memory' | 'localStorage'
232
+ getToken: async () => "token", // function
233
+ setToken: (token: string) => {}, // function
234
+ refreshToken: async () => "new-token", // function
235
+ },
236
+ // Token refresh failure hook
237
+ onTokenRefreshFailure: (error, context) => {
238
+ // Custom logic: log, alert, or trigger re-authentication
239
+ console.error("Token refresh failed:", error, context);
240
+ // Optionally, redirect user or clear session
241
+ },
242
+
243
+ // Multi-tenant/multi-user support example
244
+ getToken: async (userId) => {
245
+ // Fetch token for a specific user/tenant
246
+ return await fetchTokenForUser(userId);
247
+ },
248
+ setToken: (token, userId) => {
249
+ // Store token for a specific user/tenant
250
+ saveTokenForUser(token, userId);
251
+ },
252
+ refreshToken: async (userId) => {
253
+ // Refresh token for a specific user/tenant
254
+ return await refreshUserToken(userId);
255
+ },
256
+
257
+ // Usage:
258
+ // await api.get('/resource', { userId: 'user-42' });
259
+ offline: {
260
+ enabled: true, // boolean (default: true)
261
+ storage: "localStorage", // 'localStorage' | 'indexedDB'
262
+ },
263
+ circuitBreaker: {
264
+ enabled: true, // boolean
265
+ threshold: 5, // number
266
+ timeout: 10000, // number (ms)
267
+ onOpen: () => {}, // function (optional)
268
+ },
269
+ metrics: {
270
+ enabled: true, // boolean
271
+ },
272
+ errors: {
273
+ enabled: true, // boolean (default: true)
274
+ },
275
+ rate: {
276
+ enabled: true, // boolean (default: true)
277
+ maxRequests: 100, // number
278
+ perMilliseconds: 60000, // number (ms)
279
+ },
280
+ schema: {
281
+ enabled: true, // boolean
282
+ requestSchema: undefined, // any (optional)
283
+ responseSchema: undefined, // any (optional)
284
+ library: "zod", // 'zod' | 'yup' (optional)
285
+ },
286
+ cancel: {
287
+ enabled: true, // boolean (default: true)
288
+ },
289
+ graphql: {
290
+ enabled: true, // boolean
291
+ endpoint: "https://graphqlzero.almansi.me/api", // string
292
+ logErrors: true, // boolean
293
+ headers: undefined, // Record<string, string> (optional)
294
+ timeout: undefined, // number (optional)
295
+ cache: undefined, // boolean (optional)
296
+ },
297
+ interceptors: {
298
+ request: [
299
+ (config) => {
300
+ /* modify config */ return config;
301
+ },
302
+ ],
303
+ response: [
304
+ (response) => {
305
+ /* log/modify response */ return response;
306
+ },
307
+ ],
308
+ },
309
+ metadata: {
310
+ enabled: true, // boolean (default: true)
311
+ log: true, // boolean (log metadata events)
312
+ fields: [
313
+ "id",
314
+ "method",
315
+ "endpoint",
316
+ "priority",
317
+ "timestamp",
318
+ "startTime",
319
+ "endTime",
320
+ ], // string[] (fields to track)
321
+ maxEntries: 100, // number (max entries to keep)
322
+ customHandler: (meta) => {}, // function (custom handler)
323
+ },
324
+ });
325
+ ```
326
+
327
+ ---
328
+
329
+ ## πŸš€ Usage
330
+
331
+ ### 🧩 Feature Modularity & Extensibility
332
+
333
+ Voxa's features (cache, retry, queue, batch, deduplication, interceptors, etc.) are fully modular and can be enabled, disabled, or extended at runtime.
334
+
335
+ ---
336
+
337
+ ### Enabling/Disabling Features at Runtime
338
+
339
+ You can toggle features on/off by updating the instance configuration:
340
+
341
+ ```typescript
342
+ // Disable cache and queue at runtime
343
+ api.updateConfig({
344
+ cache: { enabled: false },
345
+ queue: { enabled: false },
346
+ });
347
+
348
+ // Enable retry and set new retry count
349
+ api.updateConfig({
350
+ retry: { enabled: true, count: 10 },
351
+ });
352
+ ```
353
+
354
+ > **Note:** Not all features support dynamic reconfiguration in-flight. For critical changes, create a new instance with the desired config.
355
+
356
+ ---
357
+
358
+ ### Extending with Plugins (Custom Features)
359
+
360
+ You can add your own features or override built-in ones by attaching custom managers or hooks:
361
+
362
+ ```typescript
363
+ // Example: Add a custom logging plugin
364
+ api.usePlugin({
365
+ onRequest(config) {
366
+ console.log("Request:", config.url);
367
+ return config;
368
+ },
369
+ onResponse(response) {
370
+ console.log("Response:", response.status);
371
+ return response;
372
+ },
373
+ });
374
+ ```
375
+
376
+ ---
377
+
378
+ #### Plugin Interface
379
+
380
+ A plugin is an object with any of these hooks:
381
+
382
+ - `onRequest(config)`
383
+ - `onResponse(response)`
384
+ - `onError(error)`
385
+ - `onBatch(batch)`
386
+ - `onCacheEvent(event)`
387
+
388
+ You can register multiple plugins. They are called in the order added.
389
+
390
+ ---
391
+
392
+ #### Disabling a Feature for a Single Request
393
+
394
+ ```typescript
395
+ // Disable cache for a single request
396
+ await api.get('/users', { cache: { enabled: false } });
397
+
398
+ // Set custom queue priority for a single request
399
+ await api.post('/orders', { ... }, { priority: 'critical' });
400
+ ```
401
+
402
+ See [Advanced Features](./docs/ADVANCED.md) for more on feature modularity and plugins.
403
+
404
+ ---
405
+
406
+ ### Using Voxa with an Instance
407
+
408
+ ### Injecting Custom requestId & Metadata
409
+
410
+ RequestId will generate automatically and will use in features (like retry,batching,etc..):
411
+
412
+ ```typescript
413
+ // Provide a custom requestId and metadata for tracing
414
+ const response = await api.get("/users/1", {
415
+ requestId: "trace-abc-123", // requestid will generate per request
416
+ metadata: {
417
+ traceId: "trace-abc-123",
418
+ userId: "user-42",
419
+ customField: "my-value",
420
+ },
421
+ });
422
+ console.log(response.metadata); // includes your custom fields
423
+ ```
424
+
425
+ > **Note:** The `requestId` generates automatically and use in all features.
426
+
427
+ Create a client instance to reuse configuration and advanced features:
428
+
429
+ ```typescript
430
+ import voxa from "@0xshariq/voxa";
431
+
432
+ const api = voxa.create({
433
+ baseURL: "https://api.example.com",
434
+ timeout: 5000,
435
+ // ...other options
436
+ });
437
+
438
+ // Make requests (response is always parsed JSON)
439
+ const response = await api.get<User>("/users/1");
440
+ console.log(response.data); // { id, name, ... }
441
+
442
+ // You can also use other HTTP methods:
443
+ await api.post("/users", { name: "John" });
444
+ await api.put("/users/1", { name: "Jane" });
445
+ await api.delete("/users/1");
446
+ ```
447
+
448
+ ---
449
+
450
+ ### Using Voxa Without an Instance (Static Methods)
451
+
452
+ Call static methods directly for one-off requests:
453
+
454
+ ```typescript
455
+ import { Voxa } from "@0xshariq/voxa";
456
+
457
+ const response = await Voxa.get<User>("https://api.example.com/users/1");
458
+ console.log(response.data);
459
+
460
+ // Other static methods:
461
+ await Voxa.post("https://api.example.com/users", { name: "John" });
462
+ await Voxa.put("https://api.example.com/users/1", { name: "Jane" });
463
+ await Voxa.delete("https://api.example.com/users/1");
464
+ ```
465
+
466
+ Use an instance for advanced features (caching, queueing, interceptors, GraphQL, etc.), or static methods for simple requests.
467
+
468
+ ---
469
+
470
+ ### TypeScript Generics
471
+
472
+ ```typescript
473
+ interface User {
474
+ id: number;
475
+ name: string;
476
+ email: string;
477
+ }
478
+
479
+ // Type-safe responses
480
+ const response = await api.get<User>("/users/1");
481
+ const user: User = await response.json();
482
+ ```
483
+
484
+ ---
485
+
486
+ ### Streaming Upload/Download
487
+
488
+ ```typescript
489
+ import { StreamingImageManager, StreamingVideoManager } from "@0xshariq/voxa";
490
+
491
+ // Upload image with progress tracking
492
+ const streamingImages = new StreamingImageManager({});
493
+
494
+ const fileInput = document.querySelector('input[type="file"]');
495
+ const file = fileInput.files[0];
496
+
497
+ await streamingImages.upload(
498
+ "https://api.example.com/images/upload",
499
+ file,
500
+ { "Content-Type": "image/jpeg" },
501
+ (sentBytes, totalBytes) => {
502
+ const percentage = (sentBytes / totalBytes) * 100;
503
+ console.log(`Upload progress: ${percentage.toFixed(2)}%`);
504
+ }
505
+ );
506
+
507
+ // Download video with progress
508
+ const streamingVideos = new StreamingVideoManager({});
509
+
510
+ const response = await streamingVideos.download(
511
+ "https://api.example.com/videos/12345",
512
+ {},
513
+ (receivedBytes, totalBytes) => {
514
+ console.log(`Downloaded: ${receivedBytes}/${totalBytes} bytes`);
515
+ }
516
+ );
517
+
518
+ const blob = await response.blob();
519
+ const videoUrl = URL.createObjectURL(blob);
520
+ ```
521
+
522
+ See [Streaming Guide](./docs/STREAMING.md) for complete examples and advanced usage.
523
+
524
+ ---
525
+
526
+ ## πŸ“– Documentation
527
+
528
+ ### Core Documentation
529
+
530
+ **Documentation:**
531
+
532
+ - [Configuration Guide](./docs/CONFIGURATION.md) β€” All config options.
533
+ - [Advanced Features](./docs/ADVANCED.md) β€” Caching, deduplication, queueing, interceptors, GraphQL, etc.
534
+ - [Streaming Guide](./docs/STREAMING.md) β€” Image/video upload/download with progress tracking.
535
+ - [Developer Experience](./docs/DEVELOPER_EXPERIENCE.md) β€” Debug mode, logging, public getters, type safety.
536
+ - [Troubleshooting](./docs/TROUBLESHOOTING.md) β€” Common issues and solutions.
537
+ - [Custom Cache](./docs/CUSTOM_CACHE.md) β€” Custom cache implementation.
538
+ - [Batch Usage](./docs/BATCH_USAGE.md) β€” Batch request patterns.
539
+ - [Examples](./docs/EXAMPLES.md) β€” Usage patterns and code samples.
540
+ - [Migration](./docs/MIGRATION.md) - Migration from axios to voxa.
541
+
542
+ See docs/ for full details and up-to-date usage.
543
+
544
+ ---
545
+
546
+ ## 🎯 Key Features
547
+
548
+ ### Automatic Retry with Exponential Backoff
549
+
550
+ ```typescript
551
+ const api = voxa.create({
552
+ baseURL: "https://api.example.com",
553
+ retry: {
554
+ count: 3, // Max 3 retries
555
+ delay: 1000, // Initial delay: 1s
556
+ exponentialBackoff: true, // 1s β†’ 2s β†’ 4s
557
+ maxRetry: 10000, // Max delay: 10s
558
+ },
559
+ });
560
+ ```
561
+
562
+ ---
563
+
564
+ ### Response Structure
565
+
566
+ ```typescript
567
+ {
568
+ response: Response, // Http Response object
569
+ data: {}, // Api Data will store here
570
+ metadata: {
571
+ id: "string", // requestId used everywhere
572
+ method: "'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS'",
573
+ endpoint: "string",
574
+ priority: "'critical' | 'high' | 'normal' | 'low'",
575
+ timestamp: 2000,
576
+ startTime: 2000,
577
+ endTime: 2000
578
+ },
579
+ requestId: string, // Unique requestId, used in all features (queue, batch, cache, metrics, etc.)
580
+ status: 200,
581
+ statusText: "Ok"
582
+ }
583
+ ```
584
+
585
+ See [Response Structure](./src/lib/types/client-types.ts) for detailed info.
586
+
587
+ ---
588
+
589
+ ### Response Caching
590
+
591
+ ```typescript
592
+ // Memory cache (default)
593
+ const api = voxa.create({
594
+ cache: {
595
+ enabled: true,
596
+ type: "memory",
597
+ ttl: 300000, // 5 minutes
598
+ },
599
+ });
600
+
601
+ // Redis cache
602
+ const api = voxa.create({
603
+ cache: {
604
+ enabled: true,
605
+ type: "redis",
606
+ ttl: 300000,
607
+ },
608
+ });
609
+ ```
610
+
611
+ ---
612
+
613
+ ### Request Prioritization
614
+
615
+ ```typescript
616
+ // High priority request
617
+ await api.get("/critical-data", { priority: "critical" });
618
+
619
+ // Normal priority (default)
620
+ await api.get("/regular-data");
621
+
622
+ // Low priority
623
+ await api.get("/background-data", { priority: "low" });
624
+ ```
625
+
626
+ ---
627
+
628
+ ### Request Interceptors
629
+
630
+ ```typescript
631
+ // Add authentication header
632
+ api.interceptors.request.use((config) => {
633
+ config.headers = {
634
+ ...config.headers,
635
+ Authorization: `Bearer ${getToken()}`,
636
+ };
637
+ return config;
638
+ });
639
+
640
+ // Log responses
641
+ api.interceptors.response.use((response) => {
642
+ console.log("Response:", response.status);
643
+ return response;
644
+ });
645
+ ```
646
+
647
+ ---
648
+
649
+ ## πŸ”§ Configuration
650
+
651
+ ### Environment Variables
652
+
653
+ Create a `.env` file in your project root:
654
+
655
+ ```env
656
+ # Cache Configuration (Generic - works with any cache backend)
657
+ CACHE_URL=redis://localhost:6379
658
+ CACHE_PASSWORD=your-password
659
+ CACHE_HOST=localhost
660
+ CACHE_PORT=6379
661
+ CACHE_DB=0
662
+
663
+ # HTTP Configuration
664
+ HTTP_TIMEOUT=5000
665
+ HTTP_BASE_URL=https://api.example.com
666
+ ```
667
+
668
+ See [Configuration Guide](./docs/CONFIGURATION.md) for detailed options.
669
+
670
+ ---
671
+
672
+ ## πŸ“Š Monitoring & Statistics
673
+
674
+ ```typescript
675
+ // Get cache statistics
676
+ const cacheStats = api.getCacheStats();
677
+ console.log(cacheStats); // { storage: 'memory', size: 10, entries: [...] }
678
+
679
+ // Get queue statistics
680
+ const queueStats = api.getQueueStats();
681
+ console.log(queueStats); // { queueSize: 2, activeRequests: 3, maxConcurrent: 5 }
682
+
683
+ // Get request metadata
684
+ const metadata = api.getRequestMetadata("request-id-123");
685
+ console.log(metadata); // { id, method, endpoint, duration, ... }
686
+ ```
687
+
688
+ ---
689
+
690
+ ## Request ID Format and Expiry
691
+
692
+ Each request is assigned a unique `requestId` for tracking and feature management. The format is:
693
+
694
+ ```
695
+ <timestamp>-<expiry>-<random>
696
+ ```
697
+
698
+ - `timestamp`: When the request was created
699
+ - `expiry`: When the requestId expires (used for cache/batch conflict avoidance)
700
+ - `random`: Random string for uniqueness
701
+
702
+ - **Cache feature** uses a 5 minute expiry (default).
703
+ - **Batch feature** uses a 15 minute expiry.
704
+
705
+ This prevents conflicts when the same request is sent at different times. Always use the generated requestId for all features (cache, batch, queue, etc.).
706
+
707
+ ---
708
+
709
+ ## Error Classification & Debugging
710
+
711
+ Voxa now provides detailed error classification and debugging messages for every request. Use `api.classifyError(error)` to get both the error category and a helpful message for easier troubleshooting.
712
+
713
+ ---
714
+
715
+ ### Feature Manager Access
716
+
717
+ All feature managers (cache, queue, deduplication, metadata, circuit breaker, batch, rate limiter, metrics, schema, error classifier) are accessible via public methods or stats getters:
718
+
719
+ - `api.getCacheStats()`
720
+ - `api.getQueueStats()`
721
+ - `api.getDeduplicationStats()`
722
+ - `api.getMetadataStats()`
723
+ - `api.circuitBreaker()`
724
+ - `api.batch()`
725
+ - `api.rate()`
726
+ - `api.metrics()`
727
+ - `api.schema()`
728
+ - `api.classifyError(error)`
729
+
730
+ ---
731
+
732
+ ## πŸ§ͺ Testing
733
+
734
+ ```bash
735
+ # Run test file directly
736
+ pnpm test
737
+
738
+ # Or using development mode
739
+ pnpm dev
740
+ ```
741
+
742
+ ---
743
+
744
+ ## πŸ“ HTTP Methods
745
+
746
+ Voxa supports all standard HTTP methods:
747
+
748
+ ```typescript
749
+ await api.get("/users");
750
+ await api.post("/users", { name: "John" });
751
+ await api.put("/users/1", { name: "Jane" });
752
+ await api.patch("/users/1", { email: "new@example.com" });
753
+ await api.delete("/users/1");
754
+ await api.head("/users");
755
+ await api.options("/users");
756
+ ```
757
+
758
+ ---
759
+
760
+ ## 🀝 Contributing
761
+
762
+ Contributions are welcome! Please feel free to submit a Pull Request.
763
+
764
+ See the [Contributing Guide](./CONTRIBUTING.md)
765
+
766
+ ---
767
+
768
+ ## πŸ“„ License
769
+
770
+ MIT Β© [Sharique Chaudhary](https://github.com/0xshariq)
771
+
772
+ ---
773
+
774
+ ## πŸ”— Links
775
+
776
+ - [GitHub Repository](https://github.com/0xshariq/voxa)
777
+ - [npm Package](https://www.npmjs.com/package/@0xshariq/voxa)
778
+ - [Issue Tracker](https://github.com/0xshariq/voxa/issues)
779
+
780
+ ---
781
+
782
+ **Note:** This project is built on the native Fetch API and requires Node.js 18+ or a modern browser environment.