qhttpx 1.9.4 → 2.0.1

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 (94) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +28 -35
  3. package/dist/examples/api-server.js +38 -35
  4. package/dist/examples/basic.js +3 -4
  5. package/dist/examples/compression.js +6 -8
  6. package/dist/examples/cors.js +5 -6
  7. package/dist/examples/errors.js +12 -11
  8. package/dist/examples/file-upload.js +4 -6
  9. package/dist/examples/fusion.js +6 -6
  10. package/dist/examples/rate-limiting.js +10 -10
  11. package/dist/examples/validation.js +5 -6
  12. package/dist/examples/websockets.js +3 -4
  13. package/dist/package.json +3 -8
  14. package/dist/src/benchmarks/quantam-users.js +2 -2
  15. package/dist/src/benchmarks/quick-bench.js +57 -0
  16. package/dist/src/benchmarks/simple-json.js +133 -22
  17. package/dist/src/benchmarks/ultra-mode.js +8 -38
  18. package/dist/src/core/context-pool.d.ts +12 -0
  19. package/dist/src/core/context-pool.js +34 -0
  20. package/dist/src/core/fusion.js +0 -2
  21. package/dist/src/core/metrics.d.ts +3 -1
  22. package/dist/src/core/metrics.js +11 -5
  23. package/dist/src/core/scheduler.d.ts +4 -0
  24. package/dist/src/core/scheduler.js +75 -34
  25. package/dist/src/core/scope.d.ts +23 -8
  26. package/dist/src/core/scope.js +53 -14
  27. package/dist/src/core/serializer.d.ts +1 -1
  28. package/dist/src/core/serializer.js +45 -7
  29. package/dist/src/core/server.d.ts +51 -10
  30. package/dist/src/core/server.js +688 -259
  31. package/dist/src/core/timer.d.ts +11 -0
  32. package/dist/src/core/timer.js +29 -0
  33. package/dist/src/core/types.d.ts +41 -13
  34. package/dist/src/core/types.js +6 -6
  35. package/dist/src/index.d.ts +6 -4
  36. package/dist/src/index.js +19 -20
  37. package/dist/src/middleware/security.js +6 -1
  38. package/dist/src/router/radix-tree.d.ts +5 -2
  39. package/dist/src/router/radix-tree.js +58 -14
  40. package/dist/src/router/router.d.ts +5 -2
  41. package/dist/src/router/router.js +80 -63
  42. package/dist/tests/fusion.test.js +4 -4
  43. package/dist/tests/rate-limit.test.js +2 -2
  44. package/dist/tests/schema-routes.test.js +3 -1
  45. package/docs/AEGIS.md +18 -28
  46. package/docs/BENCHMARKS.md +8 -6
  47. package/docs/DATABASE.md +4 -4
  48. package/docs/MIDDLEWARE.md +3 -3
  49. package/docs/ROUTING.md +21 -13
  50. package/docs/VALIDATION.md +9 -31
  51. package/package.json +3 -8
  52. package/binding.gyp +0 -18
  53. package/dist/src/benchmarks/compare-frameworks.js +0 -119
  54. package/dist/src/benchmarks/compare.js +0 -288
  55. package/dist/src/buffer-pool.js +0 -70
  56. package/dist/src/config.js +0 -50
  57. package/dist/src/cookies.js +0 -59
  58. package/dist/src/core/native-adapter.d.ts +0 -11
  59. package/dist/src/core/native-adapter.js +0 -211
  60. package/dist/src/cors.js +0 -66
  61. package/dist/src/logger.js +0 -45
  62. package/dist/src/metrics.js +0 -111
  63. package/dist/src/native/index.d.ts +0 -32
  64. package/dist/src/native/index.js +0 -141
  65. package/dist/src/presets.js +0 -33
  66. package/dist/src/radix-router.js +0 -89
  67. package/dist/src/radix-tree.js +0 -81
  68. package/dist/src/resources.js +0 -25
  69. package/dist/src/router.js +0 -138
  70. package/dist/src/scheduler.js +0 -85
  71. package/dist/src/security.js +0 -69
  72. package/dist/src/server.js +0 -685
  73. package/dist/src/signals.js +0 -31
  74. package/dist/src/static.js +0 -107
  75. package/dist/src/stream.js +0 -71
  76. package/dist/src/tasks.js +0 -87
  77. package/dist/src/testing.js +0 -40
  78. package/dist/src/types.js +0 -19
  79. package/dist/src/utils/testing.js +0 -40
  80. package/dist/src/worker-queue.js +0 -73
  81. package/dist/tests/native-adapter.test.d.ts +0 -1
  82. package/dist/tests/native-adapter.test.js +0 -71
  83. package/prebuilds/darwin-arm64/qhttpx.node +0 -0
  84. package/prebuilds/linux-x64/qhttpx.node +0 -0
  85. package/prebuilds/win32-x64/qhttpx.node +0 -0
  86. package/scripts/install-native.js +0 -26
  87. package/src/native/README.md +0 -31
  88. package/src/native/addon.cc +0 -8
  89. package/src/native/index.ts +0 -158
  90. package/src/native/picohttpparser.c +0 -608
  91. package/src/native/picohttpparser.h +0 -76
  92. package/src/native/server.cc +0 -264
  93. package/src/native/server.h +0 -30
  94. /package/dist/src/benchmarks/{compare.d.ts → quick-bench.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [2.0.0] - 2026-01-21
6
+ **"The Ultra-Simple API Update"**
7
+
8
+ ### Added
9
+ - **Ultra-Simple API**: Introduced `import { app } from "qhttpx"` singleton pattern for zero-boilerplate setup.
10
+ - **Fluent Configuration**: Chained methods `.database()`, `.security()`, `.log()`, `.validate()`, `.production()` for one-line feature enabling.
11
+ - **Return-Based Responses**: Route handlers can now directly return objects (auto-serialized to JSON) or strings, replacing manual `ctx.json()` calls.
12
+ - **Inline Validation**: Declarative schema validation directly in route definitions: `app.post("/", { body: Schema, handler: ... })`.
13
+ - **Semantic Errors**: Added `api.httpError(404, "Message")` helper for consistent, throw-able error handling.
14
+ - **Fluent Rate Limiting**: New `.rateLimit("strict")` presets and `.allow(N).per("interval")` builder for intuitive DDoS protection.
15
+ - **Modular Plugins**: New `plugin(api => ...)` helper for creating reusable, encapsulated route modules.
16
+ - **Production Defaults**: `.production()` method automatically enables Clustering, Compression, Caching, and Adaptive Scheduler.
17
+
18
+ ### Changed
19
+ - **Architecture**: Complete shift to **Pure TypeScript** core. Removed Native C++ bindings to improve portability, reduce build complexity, and eliminate `node-gyp` dependencies while maintaining high performance.
20
+ - **Routing**: `app.routes()` now accepts plugin modules for cleaner code organization.
21
+ - **Status Codes**: POST requests returning data automatically default to `201 Created`.
22
+
23
+ ### Removed
24
+ - **Native Mode**: Removed C++ addon (`node-addon-api`) and associated build steps. QHTTPX is now 100% JS/TS, running everywhere Node.js runs.
25
+
5
26
  ## [1.9.4] - 2026-01-20
6
27
  **"The Silent Performance Update"**
7
28
 
package/README.md CHANGED
@@ -13,6 +13,7 @@
13
13
 
14
14
  [![npm version](https://img.shields.io/npm/v/qhttpx.svg?style=flat-square)](https://www.npmjs.com/package/qhttpx)
15
15
  [![Downloads](https://img.shields.io/npm/dm/qhttpx.svg?style=flat-square)](https://www.npmjs.com/package/qhttpx)
16
+ [![Website](https://img.shields.io/badge/website-qhttpx.gridrr.com-blueviolet.svg?style=flat-square)](https://qhttpx.gridrr.com)
16
17
  [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/Quantam-Open-Source/qhttpx/blob/main/LICENSE)
17
18
  [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
18
19
  [![TypeScript](https://img.shields.io/badge/Written%20in-TypeScript-blue?style=flat-square)](https://www.typescriptlang.org)
@@ -44,10 +45,10 @@ Most Node.js frameworks rely on the event loop blindly. QHTTPX introduces a **Co
44
45
 
45
46
  | Feature | **QHTTPX** | Fastify | Express | Hono |
46
47
  | :--- | :---: | :---: | :---: | :---: |
47
- | **Core Runtime** | **⚡ Hybrid (C++ / JS)** | JS | JS | JS |
48
+ | **Core Runtime** | **⚡ Pure TypeScript** | JS | JS | JS |
48
49
  | **Request Fusion** | **✅ Native** | ❌ | ❌ | ❌ |
49
50
  | **DDoS Protection** | **✅ Built-in (Aegis)** | ❌ | ❌ | ❌ |
50
- | **JSON Serialization** | **✅ Zero-Copy (C++)** | Schema-based | Slow | Slow |
51
+ | **JSON Serialization** | **✅ Optimized Fast-Path** | Schema-based | Slow | Slow |
51
52
  | **Concurrency Model** | **✅ Async Scheduler** | Event Loop | Event Loop | Event Loop |
52
53
  | **Rate Limiting** | **✅ Zero-Overhead** | Plugin | Middleware | Middleware |
53
54
  | **Routing Algorithm** | **✅ Optimized Radix** | Radix Tree | Linear/Regex | RegExp/Trie |
@@ -93,13 +94,13 @@ fastify.listen({ port: 3000 });
93
94
  ```typescript
94
95
  import { app } from 'qhttpx';
95
96
 
96
- app.get('/hello', ({ query, setHeader, json }) => {
97
+ app.get('/hello', ({ query, setHeader }) => {
97
98
  const name = query.name || 'World';
98
99
  setHeader('X-Powered-By', 'QHTTPX');
99
- json({ message: `Hello ${name}` });
100
+ return { message: `Hello ${name}` };
100
101
  });
101
102
 
102
- app.listen(3000);
103
+ app.start(3000);
103
104
  ```
104
105
 
105
106
  ---
@@ -158,8 +159,14 @@ npm install qhttpx tsx
158
159
  ```typescript
159
160
  import { app } from 'qhttpx';
160
161
 
161
- app.get('/', ({ json }) => json({ msg: 'Works!' }));
162
- app.listen(3000, () => console.log('Server running on http://localhost:3000'));
162
+ app.get('/', () => ({ msg: 'Works!' }));
163
+
164
+ // Ultra-Simple One-Liners
165
+ app.security()
166
+ .log()
167
+ .production();
168
+
169
+ app.start(3000).then(({ port }) => console.log(`Server running on http://localhost:${port}`));
163
170
  ```
164
171
 
165
172
  Run with: `npx tsx src/index.ts`
@@ -175,32 +182,32 @@ npm install qhttpx
175
182
  ```javascript
176
183
  const { app } = require('qhttpx');
177
184
 
178
- app.get('/', ({ json }) => json({ msg: 'Works!' }));
179
- app.listen(3000, () => console.log('Running on http://localhost:3000'));
185
+ app.get('/', () => ({ msg: 'Works!' }));
186
+ app.start(3000).then(() => console.log('Running on http://localhost:3000'));
180
187
  ```
181
188
 
182
189
  Run with: `node index.js`
183
190
 
184
- ### 3. The Advanced Way (Custom Configuration)
185
- When you need specific configuration options or multiple instances.
191
+ ### 3. The Fluent Way (Advanced Configuration)
192
+ Use the chainable API to configure advanced features like Request Fusion, Metrics, and Body Limits.
186
193
 
187
194
  ```typescript
188
- import { createHttpApp } from "qhttpx";
195
+ import { app } from 'qhttpx';
189
196
 
190
- const app = createHttpApp({
191
- enableRequestFusion: true, // Enable coalescing
192
- maxBodySize: "1mb"
193
- });
197
+ app.fusion(true) // Enable Request Coalescing
198
+ .metrics(true) // Enable Prometheus-style metrics
199
+ .bodyLimit(1024 * 1024)// Set 1MB body limit
200
+ .security({ cors: true });
194
201
 
195
- app.get("/users", async ({ json, query }) => {
196
- const { page } = query;
197
- // ...
198
- json({ page });
202
+ app.get('/heavy-compute', async () => {
203
+ // If 1000 users hit this at once, it executes ONLY ONCE
204
+ return await db.query('SELECT * FROM heavy_table');
199
205
  });
200
206
 
201
- app.listen(3000);
207
+ app.start(3000);
202
208
  ```
203
209
 
210
+
204
211
  ---
205
212
 
206
213
  ## 📚 Documentation
@@ -218,21 +225,7 @@ Detailed guides for every feature of QHTTPX:
218
225
 
219
226
  ---
220
227
 
221
- ## 📊 Benchmarks
222
-
223
- Benchmarks comparing **QHTTPX v1.8.6** against popular Node.js frameworks.
224
- *(Run on local environment: Windows, 100 connections, 10 pipelining, 40s duration. Average of 2 runs, taking the second result.)*
225
228
 
226
- | Framework | Req/Sec | Latency (Avg) | Throughput |
227
- | :--- | :--- | :--- | :--- |
228
- | **Fastify** | 16,050 | 256.78 ms | 3.00 Mb/s |
229
- | **QHTTPX** | **14,179** | **291.13 ms** | **3.02 Mb/s** |
230
- | **Hono** | 14,176 | 294.09 ms | 2.43 Mb/s |
231
- | **Express** | 10,450 | 407.12 ms | 1.94 Mb/s |
232
-
233
- > **Note**: QHTTPX achieves comparable throughput to Fastify while offering advanced features like **Request Fusion** (deduplication) which can significantly reduce database load in real-world scenarios.
234
-
235
- ---
236
229
 
237
230
  ## 🤝 Ecosystem Compatibility
238
231
 
@@ -4,21 +4,26 @@ const index_1 = require("../src/index");
4
4
  const dotenv_1 = require("dotenv");
5
5
  // Load .env
6
6
  (0, dotenv_1.config)();
7
- // 1. Initialize App (Fusion + Aegis enabled)
8
- const app = (0, index_1.createHttpApp)({
9
- enableRequestFusion: true, // ⚡ Auto-coalesce duplicate requests
10
- metricsEnabled: true, // 📊 Expose /__qhttpx/metrics
7
+ // Configure App via Fluent API
8
+ index_1.app.fusion(true)
9
+ .metrics(true)
10
+ .production() // Enables Compression & Performance Mode
11
+ .security({
12
+ cors: true,
11
13
  rateLimit: {
12
14
  windowMs: 15 * 60 * 1000,
13
15
  max: 100,
14
16
  trustProxy: true
15
- },
16
- cors: true, // 🛡️ Built-in CORS
17
- compression: true // 🗜️ Built-in Compression (Gzip/Brotli)
17
+ }
18
+ });
19
+ // Routes
20
+ index_1.app.get('/', ({ json }) => json({ status: 'online', fusion: true }));
21
+ // Fused Endpoint: 1000 concurrent requests -> 1 DB execution
22
+ index_1.app.get('/heavy', async ({ json }) => {
23
+ await new Promise(r => setTimeout(r, 100)); // Simulate DB
24
+ json({ data: 'Expensive Result', timestamp: Date.now() });
18
25
  });
19
- // 2. Global Middleware (Logging is built-in by default)
20
- // No manual app.use(rateLimit(...)) needed!
21
- // 3. Validation Schema
26
+ // Validation Schema
22
27
  const UserSchema = {
23
28
  body: {
24
29
  type: 'object',
@@ -26,52 +31,50 @@ const UserSchema = {
26
31
  properties: { name: { type: 'string' }, role: { type: 'string' } }
27
32
  }
28
33
  };
29
- // 4. Routes (Clean & Destructured)
30
- app.get('/', ({ json }) => json({ status: 'online', fusion: true }));
31
- // ⚡ Fused Endpoint: 1000 concurrent requests -> 1 DB execution
32
- app.get('/heavy', async ({ json }) => {
33
- await new Promise(r => setTimeout(r, 100)); // Simulate DB
34
- json({ data: 'Expensive Result', timestamp: Date.now() });
35
- });
36
- // 🛡️ Validated & Typed Route
37
- app.post('/users', { schema: UserSchema }, async ({ body, json }) => {
34
+ // Validated & Typed Route
35
+ index_1.app.post('/users', { schema: UserSchema }, async ({ body, json }) => {
38
36
  // Body is already validated and typed here
39
37
  json({ created: true, user: body }, 201);
40
38
  });
41
- // Header Auth Example
42
- app.post('/auth/verify', async ({ headers, json }) => {
39
+ // Header Auth Example
40
+ index_1.app.post('/auth/verify', async ({ headers, json }) => {
43
41
  const token = headers.authorization?.replace('Bearer ', '');
44
42
  if (!token)
45
43
  return json({ error: 'No token provided' }, 401);
46
44
  // Verify token...
47
45
  json({ valid: true, token });
48
46
  });
49
- // �📂 File Uploads (Typed)
50
- app.post('/upload', ({ files, json }) => {
47
+ // File Uploads
48
+ index_1.app.post('/upload', ({ files, json }) => {
51
49
  if (!files?.doc)
52
50
  return json({ error: 'No file' }, 400);
53
51
  const doc = Array.isArray(files.doc) ? files.doc[0] : files.doc;
54
52
  json({ filename: doc.filename, size: doc.size });
55
53
  });
56
- // 📡 WebSockets (Pub/Sub)
57
- app.upgrade('/chat', (ws) => {
54
+ // WebSockets
55
+ index_1.app.upgrade('/chat', (ws) => {
58
56
  ws.join('general'); // Auto-join room
59
57
  ws.on('message', (msg) => {
60
58
  // Broadcast to room
61
- app.websocket.to('general').emit(`Echo: ${msg}`);
59
+ index_1.app.websocket.to('general').emit(`Echo: ${msg}`);
62
60
  });
63
61
  });
64
- // 5. Unified Error Handling
65
- app.onError(({ error, json }) => {
66
- if (error instanceof index_1.HttpError) {
62
+ // Unified Error Handling
63
+ index_1.app.onError(({ error, json }) => {
64
+ // Use duck typing or check prototype if HttpError is not imported
65
+ // But here we can use the error code or status property
66
+ // Or since we removed HttpError import, we can just check properties
67
+ if (error && typeof error === 'object' && 'status' in error && 'code' in error) {
68
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ const err = error;
67
70
  return json({
68
- error: error.message,
69
- code: error.code,
70
- details: error.details
71
- }, error.status);
71
+ error: err.message,
72
+ code: err.code,
73
+ details: err.details
74
+ }, err.status);
72
75
  }
73
76
  console.error(error); // Log internal error
74
77
  json({ error: 'Internal Server Error', handled: true }, 500);
75
78
  });
76
- // 6. Start Server
77
- app.listen(3000, () => console.log('🚀 Server running on http://localhost:3000'));
79
+ // Start Server
80
+ index_1.app.start(3000).then(() => console.log('🚀 Server running on http://localhost:3000'));
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)();
5
- app.get('/', ({ json }) => {
4
+ index_1.app.get('/', ({ json }) => {
6
5
  json({ message: 'Hello from QHTTPX!' });
7
6
  });
8
- app.listen(3000, () => {
9
- console.log('Server running on http://localhost:3000');
7
+ index_1.app.start(3000).then(({ port }) => {
8
+ console.log(`Server running on http://localhost:${port}`);
10
9
  });
@@ -1,17 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)({
5
- // Enable Gzip/Brotli compression
6
- compression: true
7
- // Or with options:
8
- // compression: { threshold: 2048 } // Only compress responses > 2KB
9
- });
10
- app.get('/large', ({ json }) => {
4
+ // Enable Production Mode
5
+ // - Enables Compression (Gzip/Brotli)
6
+ // - Sets Performance Mode
7
+ index_1.app.production();
8
+ index_1.app.get('/large', ({ json }) => {
11
9
  // Generate a large response to trigger compression
12
10
  const data = Array(1000).fill('some repeated data to compress');
13
11
  json({ data });
14
12
  });
15
- app.listen(3000, () => {
13
+ index_1.app.start(3000).then(() => {
16
14
  console.log('Compression-enabled server running on http://localhost:3000');
17
15
  });
@@ -1,19 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)({
5
- // Simple: Enable CORS for all origins
6
- // cors: true
7
- // Advanced: Configure specific origins
4
+ // Enable CORS via Security Helper
5
+ index_1.app.security({
8
6
  cors: {
9
7
  origin: ['http://localhost:5173', 'https://myapp.com'],
10
8
  methods: ['GET', 'POST'],
11
9
  credentials: true
12
10
  }
13
11
  });
14
- app.get('/api/data', ({ json }) => {
12
+ // Or simple: app.security({ cors: true });
13
+ index_1.app.get('/api/data', ({ json }) => {
15
14
  json({ data: 'This data is accessible via CORS' });
16
15
  });
17
- app.listen(3000, () => {
16
+ index_1.app.start(3000).then(() => {
18
17
  console.log('CORS-enabled server running on http://localhost:3000');
19
18
  });
@@ -1,25 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)();
5
- app.get('/missing', () => {
6
- throw new index_1.NotFoundException('Resource not found');
4
+ index_1.app.get('/missing', () => {
5
+ throw index_1.app.error(404, 'Resource not found');
7
6
  });
8
- app.get('/private', () => {
9
- throw new index_1.ForbiddenException('You do not have access');
7
+ index_1.app.get('/private', () => {
8
+ throw index_1.app.error(403, 'You do not have access');
10
9
  });
11
10
  // Custom global error handler
12
- app.onError(({ error, json }) => {
13
- if (error instanceof index_1.HttpError) {
11
+ index_1.app.onError(({ error, json }) => {
12
+ if (error && typeof error === 'object' && 'status' in error) {
13
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
+ const err = error;
14
15
  return json({
15
16
  status: 'error',
16
- code: error.code,
17
- message: error.message
18
- }, error.status);
17
+ code: err.code,
18
+ message: err.message
19
+ }, err.status);
19
20
  }
20
21
  console.error('Unexpected error:', error);
21
22
  json({ status: 'error', message: 'Internal Server Error' }, 500);
22
23
  });
23
- app.listen(3000, () => {
24
+ index_1.app.start(3000).then(() => {
24
25
  console.log('Error handling demo running on http://localhost:3000');
25
26
  });
@@ -1,11 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)({
5
- // Limits for uploads
6
- maxBodyBytes: 10 * 1024 * 1024 // 10MB
7
- });
8
- app.post('/upload', ({ files, json }) => {
4
+ // Configure upload limits
5
+ index_1.app.bodyLimit(10 * 1024 * 1024); // 10MB
6
+ index_1.app.post('/upload', ({ files, json }) => {
9
7
  if (!files || !files.document) {
10
8
  return json({ error: 'No file uploaded' }, 400);
11
9
  }
@@ -18,7 +16,7 @@ app.post('/upload', ({ files, json }) => {
18
16
  size: doc.size
19
17
  });
20
18
  });
21
- app.listen(3000, () => {
19
+ index_1.app.start(3000).then(() => {
22
20
  console.log('Upload server running on http://localhost:3000');
23
21
  console.log('Send POST to /upload with form-data field "document"');
24
22
  });
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)({
5
- // Enable Request Fusion (Request Coalescing)
6
- enableRequestFusion: true
7
- });
4
+ // Enable Request Fusion (Request Coalescing)
5
+ index_1.app.fusion(true);
6
+ // Enable Production Mode (Compression + Opts)
7
+ index_1.app.production();
8
8
  // Simulate a slow database call
9
9
  const heavyTask = async () => {
10
10
  await new Promise(resolve => setTimeout(resolve, 500));
@@ -12,10 +12,10 @@ const heavyTask = async () => {
12
12
  };
13
13
  // If 1000 users hit this endpoint simultaneously,
14
14
  // the handler runs ONLY ONCE, and the result is shared.
15
- app.get('/heavy', async ({ json }) => {
15
+ index_1.app.get('/heavy', async ({ json }) => {
16
16
  const result = await heavyTask();
17
17
  json(result);
18
18
  });
19
- app.listen(3000, () => {
19
+ index_1.app.start(3000).then(() => {
20
20
  console.log('Fusion-enabled server running on http://localhost:3000');
21
21
  });
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)({
5
- rateLimit: {
6
- windowMs: 15 * 60 * 1000, // 15 minutes
7
- max: 100, // Limit each IP to 100 requests per window
8
- message: 'Too many requests, please try again later.',
9
- trustProxy: true // Trust X-Forwarded-For header (useful behind proxies like Nginx)
10
- }
11
- });
12
- app.get('/', ({ json }) => {
4
+ // 1. Fluent Rate Limiting
5
+ // Limit to 100 requests per 15 minutes
6
+ index_1.app.rateLimit(100, '15m');
7
+ // Alternative: Use presets
8
+ // app.rateLimit('strict'); // 10 req / 15 min
9
+ // app.rateLimit('relaxed'); // 1000 req / 1 hour
10
+ // Alternative: Fluent Builder
11
+ // app.allow(50).per('1m');
12
+ index_1.app.get('/', ({ json }) => {
13
13
  json({ status: 'OK', message: 'Request accepted' });
14
14
  });
15
- app.listen(3000, () => {
15
+ index_1.app.start(3000).then(() => {
16
16
  console.log('Rate-limited server running on http://localhost:3000');
17
17
  });
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)();
5
- // Define a simple schema (or use Zod if configured)
4
+ // Initialize Validator
5
+ index_1.app.validate();
6
6
  const UserSchema = {
7
7
  body: {
8
8
  type: 'object',
@@ -13,11 +13,10 @@ const UserSchema = {
13
13
  }
14
14
  }
15
15
  };
16
- // Apply schema to route
17
- app.post('/register', { schema: UserSchema }, ({ body, json }) => {
18
- // 'body' is already validated and typed here (if using TS with inferred types)
16
+ index_1.app.post('/register', { schema: UserSchema }, ({ body, json }) => {
17
+ // 'body' is already validated and typed here
19
18
  json({ success: true, user: body });
20
19
  });
21
- app.listen(3000, () => {
20
+ index_1.app.start(3000).then(() => {
22
21
  console.log('Validation server running on http://localhost:3000');
23
22
  });
@@ -1,20 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
- const app = (0, index_1.createHttpApp)();
5
- app.upgrade('/chat', (ws) => {
4
+ index_1.app.upgrade('/chat', (ws) => {
6
5
  console.log('Client connected');
7
6
  ws.join('general');
8
7
  ws.on('message', (msg) => {
9
8
  console.log(`Received: ${msg}`);
10
9
  // Broadcast to everyone in 'general' room
11
- app.websocket.to('general').emit(`Echo: ${msg}`);
10
+ index_1.app.websocket.to('general').emit(`Echo: ${msg}`);
12
11
  });
13
12
  ws.on('close', () => {
14
13
  console.log('Client disconnected');
15
14
  });
16
15
  });
17
- app.listen(3000, () => {
16
+ index_1.app.start(3000).then(() => {
18
17
  console.log('WebSocket Server running on http://localhost:3000');
19
18
  console.log('Test with a WebSocket client at ws://localhost:3000/chat');
20
19
  });
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qhttpx",
3
- "version": "1.9.4",
3
+ "version": "2.0.1",
4
4
  "gypfile": false,
5
5
  "description": "The Ultra-Fast HTTP Framework for Node.js",
6
6
  "main": "dist/src/index.js",
@@ -17,10 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "dist",
20
- "src/native",
21
- "prebuilds",
22
20
  "scripts",
23
- "binding.gyp",
24
21
  "README.md",
25
22
  "LICENSE",
26
23
  "CHANGELOG.md",
@@ -30,7 +27,6 @@
30
27
  "doc": "docs"
31
28
  },
32
29
  "scripts": {
33
- "prebuild": "node -e \"try{require('child_process').execSync('prebuildify --napi --strip', {stdio: 'ignore'})}catch(e){}\"",
34
30
  "prepublishOnly": "npm run build",
35
31
  "build": "tsc -p tsconfig.json",
36
32
  "lint": "eslint src tests --ext .ts",
@@ -72,6 +68,7 @@
72
68
  "type": "git",
73
69
  "url": "https://github.com/Quantam-Open-Source/qhttpx"
74
70
  },
71
+ "homepage": "https://qhttpx.gridrr.com",
75
72
  "type": "commonjs",
76
73
  "devDependencies": {
77
74
  "@types/autocannon": "^7.12.7",
@@ -91,7 +88,6 @@
91
88
  "eslint-plugin-prettier": "^5.5.5",
92
89
  "mongodb": "^7.0.0",
93
90
  "pg": "^8.17.1",
94
- "prebuildify": "^6.0.1",
95
91
  "prettier": "^3.8.0",
96
92
  "tsx": "^4.21.0",
97
93
  "typescript": "^5.9.3",
@@ -101,8 +97,7 @@
101
97
  "better-sqlite3": "^12.6.2",
102
98
  "busboy": "^1.6.0",
103
99
  "fast-json-stringify": "^5.15.1",
104
- "node-addon-api": "^8.5.0",
105
- "node-gyp-build": "^4.8.4",
100
+ "fastify": "^5.7.1",
106
101
  "pino": "^10.2.0",
107
102
  "pino-pretty": "^13.1.3",
108
103
  "quantam-async": "^0.1.1",
@@ -7,8 +7,8 @@ async function run() {
7
7
  maxConcurrency: 512,
8
8
  requestTimeoutMs: 10000,
9
9
  });
10
- app.get('/json', (ctx) => {
11
- ctx.json({ message: 'hello from qhttpx' });
10
+ app.get('/json', ({ json }) => {
11
+ json({ message: 'hello from qhttpx' });
12
12
  });
13
13
  const { port } = await app.listen(0, '127.0.0.1');
14
14
  const url = `http://127.0.0.1:${port}/json`;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const autocannon_1 = __importDefault(require("autocannon"));
7
+ const index_1 = require("../index");
8
+ function runAutocannon(url) {
9
+ return new Promise((resolve, reject) => {
10
+ const instance = (0, autocannon_1.default)({
11
+ url,
12
+ connections: 100,
13
+ pipelining: 10,
14
+ duration: 5, // Shorter duration for quick verification
15
+ }, (err, result) => {
16
+ if (err) {
17
+ reject(err);
18
+ return;
19
+ }
20
+ resolve(result);
21
+ });
22
+ instance.on('error', (err) => {
23
+ reject(err);
24
+ });
25
+ });
26
+ }
27
+ async function run() {
28
+ const payloadBuffer = Buffer.from(JSON.stringify({ message: 'hello from qhttpx' }));
29
+ const app = new index_1.QHTTPX({
30
+ maxConcurrency: 512,
31
+ metricsEnabled: false,
32
+ jsonSerializer: () => payloadBuffer,
33
+ });
34
+ app.get('/json', ({ json }) => {
35
+ json({ message: 'hello from qhttpx' });
36
+ });
37
+ const { port } = await app.listen(0, '127.0.0.1');
38
+ const url = `http://127.0.0.1:${port}/json`;
39
+ console.log('Running quick benchmark...');
40
+ const result = await runAutocannon(url);
41
+ autocannon_1.default.printResult(result);
42
+ const totalRequests = result.requests.total;
43
+ const sent = result.requests.sent;
44
+ const avgRps = result.requests.average.toFixed(0);
45
+ const p99 = result.latency.p99.toFixed(1);
46
+ const connections = result.connections;
47
+ const pipelining = result.pipelining;
48
+ console.log(`QHTTPX QUICK bench: total=${totalRequests} (sent=${sent}) req, ` +
49
+ `${avgRps} req/sec, p99=${p99}ms, connections=${connections}, ` +
50
+ `pipelining=${pipelining}`);
51
+ await app.close();
52
+ process.exit(0);
53
+ }
54
+ run().catch((err) => {
55
+ console.error(err);
56
+ process.exit(1);
57
+ });