qhttpx 1.9.3 → 2.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 (98) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +17 -12
  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 +1 -0
  22. package/dist/src/core/metrics.js +3 -0
  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 +695 -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 +64 -12
  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 -18
  37. package/dist/src/middleware/presets.d.ts +1 -2
  38. package/dist/src/middleware/presets.js +1 -1
  39. package/dist/src/middleware/security.d.ts +2 -13
  40. package/dist/src/middleware/security.js +6 -1
  41. package/dist/src/router/radix-tree.d.ts +5 -2
  42. package/dist/src/router/radix-tree.js +58 -14
  43. package/dist/src/router/router.d.ts +5 -2
  44. package/dist/src/router/router.js +80 -63
  45. package/dist/src/utils/logger.d.ts +1 -11
  46. package/dist/tests/fusion.test.js +4 -4
  47. package/dist/tests/rate-limit.test.js +2 -2
  48. package/dist/tests/schema-routes.test.js +3 -1
  49. package/docs/AEGIS.md +18 -28
  50. package/docs/BENCHMARKS.md +8 -6
  51. package/docs/DATABASE.md +4 -4
  52. package/docs/MIDDLEWARE.md +3 -3
  53. package/docs/ROUTING.md +21 -13
  54. package/docs/VALIDATION.md +9 -31
  55. package/package.json +3 -8
  56. package/binding.gyp +0 -18
  57. package/dist/src/benchmarks/compare-frameworks.js +0 -119
  58. package/dist/src/benchmarks/compare.js +0 -288
  59. package/dist/src/buffer-pool.js +0 -70
  60. package/dist/src/config.js +0 -50
  61. package/dist/src/cookies.js +0 -59
  62. package/dist/src/core/native-adapter.d.ts +0 -11
  63. package/dist/src/core/native-adapter.js +0 -211
  64. package/dist/src/cors.js +0 -66
  65. package/dist/src/logger.js +0 -45
  66. package/dist/src/metrics.js +0 -111
  67. package/dist/src/native/index.d.ts +0 -32
  68. package/dist/src/native/index.js +0 -141
  69. package/dist/src/presets.js +0 -33
  70. package/dist/src/radix-router.js +0 -89
  71. package/dist/src/radix-tree.js +0 -81
  72. package/dist/src/resources.js +0 -25
  73. package/dist/src/router.js +0 -138
  74. package/dist/src/scheduler.js +0 -85
  75. package/dist/src/security.js +0 -69
  76. package/dist/src/server.js +0 -685
  77. package/dist/src/signals.js +0 -31
  78. package/dist/src/static.js +0 -107
  79. package/dist/src/stream.js +0 -71
  80. package/dist/src/tasks.js +0 -87
  81. package/dist/src/testing.js +0 -40
  82. package/dist/src/types.js +0 -19
  83. package/dist/src/utils/testing.js +0 -40
  84. package/dist/src/worker-queue.js +0 -73
  85. package/dist/tests/native-adapter.test.d.ts +0 -1
  86. package/dist/tests/native-adapter.test.js +0 -71
  87. package/prebuilds/darwin-arm64/qhttpx.node +0 -0
  88. package/prebuilds/linux-x64/qhttpx.node +0 -0
  89. package/prebuilds/win32-x64/qhttpx.node +0 -0
  90. package/scripts/install-native.js +0 -26
  91. package/src/native/README.md +0 -31
  92. package/src/native/addon.cc +0 -8
  93. package/src/native/index.ts +0 -158
  94. package/src/native/picohttpparser.c +0 -608
  95. package/src/native/picohttpparser.h +0 -76
  96. package/src/native/server.cc +0 -264
  97. package/src/native/server.h +0 -30
  98. /package/dist/src/benchmarks/{compare.d.ts → quick-bench.d.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
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
+
26
+ ## [1.9.4] - 2026-01-20
27
+ **"The Silent Performance Update"**
28
+
29
+ ### Changed
30
+ - **Performance**: Disabled logging by default in standard presets to reduce I/O overhead and improve throughput in production environments.
31
+
5
32
  ## [1.9.3] - 2026-01-20
6
33
  **"The Distribution Fix"**
7
34
 
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)
@@ -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,13 +182,14 @@ 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
191
  ### 3. The Advanced Way (Custom Configuration)
192
+
185
193
  When you need specific configuration options or multiple instances.
186
194
 
187
195
  ```typescript
@@ -192,13 +200,10 @@ const app = createHttpApp({
192
200
  maxBodySize: "1mb"
193
201
  });
194
202
 
195
- app.get("/users", async ({ json, query }) => {
203
+ app.get("/users", ({ json, query }) => {
196
204
  const { page } = query;
197
- // ...
198
- json({ page });
205
+ return { page };
199
206
  });
200
-
201
- app.listen(3000);
202
207
  ```
203
208
 
204
209
  ---
@@ -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.3",
3
+ "version": "2.0.0",
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
+ });