qhttpx 1.8.4 → 1.8.11

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 (161) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +72 -52
  3. package/binding.gyp +18 -0
  4. package/dist/examples/api-server.js +29 -8
  5. package/dist/examples/basic.d.ts +1 -0
  6. package/dist/examples/basic.js +10 -0
  7. package/dist/examples/compression.d.ts +1 -0
  8. package/dist/examples/compression.js +17 -0
  9. package/dist/examples/cors.d.ts +1 -0
  10. package/dist/examples/cors.js +19 -0
  11. package/dist/examples/errors.d.ts +1 -0
  12. package/dist/examples/errors.js +25 -0
  13. package/dist/examples/file-upload.d.ts +1 -0
  14. package/dist/examples/file-upload.js +24 -0
  15. package/dist/examples/fusion.d.ts +1 -0
  16. package/dist/examples/fusion.js +21 -0
  17. package/dist/examples/rate-limiting.d.ts +1 -0
  18. package/dist/examples/rate-limiting.js +17 -0
  19. package/dist/examples/validation.d.ts +1 -0
  20. package/dist/examples/validation.js +23 -0
  21. package/dist/examples/websockets.d.ts +1 -0
  22. package/dist/examples/websockets.js +20 -0
  23. package/dist/package.json +12 -1
  24. package/dist/src/benchmarks/simple-json.js +6 -4
  25. package/dist/src/cli/index.js +33 -11
  26. package/dist/src/core/errors.d.ts +34 -0
  27. package/dist/src/core/errors.js +70 -0
  28. package/dist/src/core/native-adapter.d.ts +11 -0
  29. package/dist/src/core/native-adapter.js +211 -0
  30. package/dist/src/core/server.d.ts +52 -4
  31. package/dist/src/core/server.js +390 -259
  32. package/dist/src/core/types.d.ts +39 -1
  33. package/dist/src/index.d.ts +6 -1
  34. package/dist/src/index.js +19 -3
  35. package/dist/src/middleware/compression.d.ts +1 -5
  36. package/dist/src/middleware/cors.d.ts +1 -10
  37. package/dist/src/middleware/presets.d.ts +4 -1
  38. package/dist/src/middleware/presets.js +22 -3
  39. package/dist/src/middleware/rate-limit.d.ts +1 -19
  40. package/dist/src/middleware/rate-limit.js +6 -0
  41. package/dist/src/middleware/security.d.ts +1 -2
  42. package/dist/src/native/index.d.ts +29 -0
  43. package/dist/src/native/index.js +64 -0
  44. package/dist/src/router/radix-tree.d.ts +2 -0
  45. package/dist/src/router/radix-tree.js +54 -4
  46. package/dist/src/router/router.d.ts +1 -0
  47. package/dist/src/router/router.js +42 -2
  48. package/dist/tests/native-adapter.test.d.ts +1 -0
  49. package/dist/tests/native-adapter.test.js +71 -0
  50. package/dist/tests/resources.test.js +3 -0
  51. package/dist/tests/security.test.js +2 -2
  52. package/docs/AEGIS.md +34 -9
  53. package/docs/BENCHMARKS.md +8 -7
  54. package/docs/ERRORS.md +112 -0
  55. package/docs/FUSION.md +68 -0
  56. package/docs/MIDDLEWARE.md +65 -0
  57. package/docs/ROUTING.md +70 -0
  58. package/docs/STATIC.md +61 -0
  59. package/docs/WEBSOCKETS.md +76 -0
  60. package/package.json +12 -1
  61. package/src/native/README.md +31 -0
  62. package/src/native/addon.cc +8 -0
  63. package/src/native/index.ts +78 -0
  64. package/src/native/picohttpparser.c +608 -0
  65. package/src/native/picohttpparser.h +71 -0
  66. package/src/native/server.cc +262 -0
  67. package/src/native/server.h +30 -0
  68. package/.eslintrc.json +0 -22
  69. package/.github/workflows/ci.yml +0 -32
  70. package/.github/workflows/npm-publish.yml +0 -37
  71. package/.github/workflows/release.yml +0 -21
  72. package/.prettierrc +0 -7
  73. package/assets/logo.svg +0 -25
  74. package/eslint.config.cjs +0 -26
  75. package/examples/api-server.ts +0 -62
  76. package/src/benchmarks/quantam-users.ts +0 -70
  77. package/src/benchmarks/simple-json.ts +0 -71
  78. package/src/benchmarks/ultra-mode.ts +0 -127
  79. package/src/cli/index.ts +0 -214
  80. package/src/client/index.ts +0 -93
  81. package/src/core/batch.ts +0 -110
  82. package/src/core/body-parser.ts +0 -151
  83. package/src/core/buffer-pool.ts +0 -96
  84. package/src/core/config.ts +0 -60
  85. package/src/core/fusion.ts +0 -210
  86. package/src/core/logger.ts +0 -70
  87. package/src/core/metrics.ts +0 -166
  88. package/src/core/resources.ts +0 -38
  89. package/src/core/scheduler.ts +0 -126
  90. package/src/core/scope.ts +0 -87
  91. package/src/core/serializer.ts +0 -41
  92. package/src/core/server.ts +0 -1231
  93. package/src/core/stream.ts +0 -111
  94. package/src/core/tasks.ts +0 -138
  95. package/src/core/types.ts +0 -191
  96. package/src/core/websocket.ts +0 -112
  97. package/src/core/worker-queue.ts +0 -90
  98. package/src/database/adapters/memory.ts +0 -99
  99. package/src/database/adapters/mongo.ts +0 -116
  100. package/src/database/adapters/postgres.ts +0 -86
  101. package/src/database/adapters/sqlite.ts +0 -44
  102. package/src/database/coalescer.ts +0 -153
  103. package/src/database/manager.ts +0 -97
  104. package/src/database/types.ts +0 -24
  105. package/src/index.ts +0 -58
  106. package/src/middleware/compression.ts +0 -147
  107. package/src/middleware/cors.ts +0 -98
  108. package/src/middleware/presets.ts +0 -50
  109. package/src/middleware/rate-limit.ts +0 -106
  110. package/src/middleware/security.ts +0 -109
  111. package/src/middleware/static.ts +0 -216
  112. package/src/openapi/generator.ts +0 -167
  113. package/src/router/radix-router.ts +0 -119
  114. package/src/router/radix-tree.ts +0 -106
  115. package/src/router/router.ts +0 -190
  116. package/src/testing/index.ts +0 -104
  117. package/src/utils/cookies.ts +0 -67
  118. package/src/utils/logger.ts +0 -59
  119. package/src/utils/signals.ts +0 -45
  120. package/src/utils/sse.ts +0 -41
  121. package/src/validation/index.ts +0 -3
  122. package/src/validation/simple.ts +0 -93
  123. package/src/validation/types.ts +0 -38
  124. package/src/validation/zod.ts +0 -14
  125. package/src/views/index.ts +0 -1
  126. package/src/views/types.ts +0 -4
  127. package/tests/adapters.test.ts +0 -120
  128. package/tests/batch.test.ts +0 -139
  129. package/tests/body-parser.test.ts +0 -83
  130. package/tests/compression-sse.test.ts +0 -98
  131. package/tests/cookies.test.ts +0 -74
  132. package/tests/cors.test.ts +0 -79
  133. package/tests/database.test.ts +0 -90
  134. package/tests/dx.test.ts +0 -130
  135. package/tests/ecosystem.test.ts +0 -156
  136. package/tests/features.test.ts +0 -51
  137. package/tests/fusion.test.ts +0 -121
  138. package/tests/http-basic.test.ts +0 -161
  139. package/tests/logger.test.ts +0 -48
  140. package/tests/middleware.test.ts +0 -137
  141. package/tests/observability.test.ts +0 -91
  142. package/tests/openapi.test.ts +0 -74
  143. package/tests/plugin.test.ts +0 -85
  144. package/tests/plugins.test.ts +0 -93
  145. package/tests/rate-limit.test.ts +0 -97
  146. package/tests/resources.test.ts +0 -64
  147. package/tests/scheduler.test.ts +0 -71
  148. package/tests/schema-routes.test.ts +0 -89
  149. package/tests/security.test.ts +0 -128
  150. package/tests/server-db.test.ts +0 -72
  151. package/tests/smoke.test.ts +0 -9
  152. package/tests/sqlite-fusion.test.ts +0 -106
  153. package/tests/static.test.ts +0 -111
  154. package/tests/stream.test.ts +0 -58
  155. package/tests/task-metrics.test.ts +0 -78
  156. package/tests/tasks.test.ts +0 -90
  157. package/tests/testing.test.ts +0 -53
  158. package/tests/validation.test.ts +0 -126
  159. package/tests/websocket.test.ts +0 -132
  160. package/tsconfig.json +0 -17
  161. package/vitest.config.ts +0 -9
package/CHANGELOG.md CHANGED
@@ -2,6 +2,65 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.8.11] - 2026-01-20
6
+ **"The Workflow Fix"**
7
+
8
+ ### Fixed
9
+ - **CI/CD**: Changed NPM publish trigger from `release: published` to `push: tags` to bypass GITHUB_TOKEN recursion limits.
10
+
11
+ ## [1.8.10] - 2026-01-20
12
+ **"The Debug Update"**
13
+
14
+ ### Changed
15
+ - **CI/CD**: Enabled verbose logging for NPM publish workflow to diagnose registry errors.
16
+
17
+ ## [1.8.9] - 2026-01-20
18
+ **"The Publishing Fix"**
19
+
20
+ ### Fixed
21
+ - **NPM Publishing**: Fixed `npm publish` failure ("Hard link is not allowed") by explicitly whitelisting package files in `package.json`.
22
+
23
+ ## [1.8.8] - 2026-01-20
24
+ **"The Documentation & Stability Update"**
25
+
26
+ ### Added
27
+ - **Comprehensive Documentation**: Added detailed guides in `docs/` for Routing, Middleware, Errors, Request Fusion, Aegis Rate Limiting, WebSockets, and Static Files.
28
+ - **Documentation Index**: Added a central documentation index to `README.md`.
29
+ - **Feature Comparison**: Expanded `README.md` comparison table to highlight Hybrid Architecture, Request Fusion, and DDoS Protection.
30
+
31
+ ### Fixed
32
+ - **Native Compilation**: Resolved `npm ci` failures on Windows/Linux by fixing macro usage in `picohttpparser.c` and `writev` return handling in `server.cc`.
33
+ - **TypeScript Types**: Fixed `ctx.next` readonly assignment error that prevented middleware destructuring in some environments.
34
+ - **Tests**: Fixed test suite failures in `dx.test.ts` and `resources.test.ts`.
35
+
36
+ ## [1.8.6] - 2026-01-20
37
+ **"The Zero-Boilerplate Update"**
38
+
39
+ ### Added
40
+ - **Zero-Config App Creation**: `createHttpApp` now accepts options for `rateLimit`, `cors`, and `compression` to enable them instantly without manual middleware setup.
41
+ - **CLI Scaffolding**: Added `npm create qhttpx` support via the `create-qhttpx` package. Generates a modern, type-safe project with all best practices enabled.
42
+ - **Standardized Errors**: Added `StandardHttpException` hierarchy (e.g., `NotFoundException`, `TooManyRequestsException`) for consistent error handling.
43
+ - **Rate Limit Improvements**: Added `trustProxy` option to `RateLimitOptions` for correct IP detection behind proxies/load balancers.
44
+ - **Context Utilities**: Added `ctx.ip` (remote address) and `ctx.method` (HTTP method) for easier access.
45
+ - **Native Layer Architecture**: Significant C++ and architectural optimizations for high-throughput scaling:
46
+ - **ABI Lock**: Stabilized C++ interface with `WriteResponse` and `CreateJSONResponse` to prevent future breaking changes.
47
+ - **Zero-Copy JSON**: Implemented `createJSONResponse` fast path in C++ for serialization and HTTP framing without V8 transition overhead.
48
+ - **Object Pooling**: Added `MockResponsePool` to recycle request/response objects, reducing Garbage Collection pressure.
49
+ - **CPU Affinity**: Added `setCPUAffinity` to bind processes/threads to specific CPU cores for linear multi-core scaling.
50
+ - **Ultra Performance**: Optimized Ultra Mode with lazy URL parsing and reduced overhead, achieving >50% reduction in p99 latency (1.4s -> ~0.7s) under heavy load.
51
+
52
+ ### Changed
53
+ - **Simplified CLI**: `qhttpx new` now uses the same template as `create-qhttpx`, ensuring consistency.
54
+ - **Dependency Management**: Scaffolding now uses explicit versioning (`^x.y.z`) for stability instead of `latest`.
55
+ - **Benchmarks**: Updated performance comparisons against Fastify, Hono, and Express in `README.md` and `docs/BENCHMARKS.md`.
56
+
57
+ ## [1.8.5] - 2026-01-20
58
+ **"The Usability IV Update"**
59
+
60
+ ### Added
61
+ - **Context Headers**: Added `ctx.headers` (alias for `req.headers`) for direct access to request headers.
62
+ - **Environment**: Added `dotenv` and updated `@types/node` dependencies.
63
+
5
64
  ## [1.8.4] - 2026-01-20
6
65
  **"The Usability III Update"**
7
66
 
package/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
  <img src="https://raw.githubusercontent.com/Quantam-Open-Source/qhttpx/main/assets/logo.svg" alt="QHTTPX Logo" width="200" height="200" />
3
3
  </div>
4
4
 
5
- <h1 align="center">QHTTPX</h1>
6
5
 
7
6
  <div align="center">
8
7
  <strong>The High-Performance Hybrid HTTP Runtime for Node.js</strong>
@@ -41,6 +40,22 @@ Most Node.js frameworks rely on the event loop blindly. QHTTPX introduces a **Co
41
40
  | **Routing** | Regex / Linear Scan | **Radix Tree** (O(1) lookup) |
42
41
  | **Streaming** | Basic Pipe | **Smart Streams** (Backpressure-aware) |
43
42
 
43
+ ### 🏆 Feature Comparison
44
+
45
+ | Feature | **QHTTPX** | Fastify | Express | Hono |
46
+ | :--- | :---: | :---: | :---: | :---: |
47
+ | **Core Runtime** | **⚡ Hybrid (C++ / JS)** | JS | JS | JS |
48
+ | **Request Fusion** | **✅ Native** | ❌ | ❌ | ❌ |
49
+ | **DDoS Protection** | **✅ Built-in (Aegis)** | ❌ | ❌ | ❌ |
50
+ | **JSON Serialization** | **✅ Zero-Copy (C++)** | Schema-based | Slow | Slow |
51
+ | **Concurrency Model** | **✅ Async Scheduler** | Event Loop | Event Loop | Event Loop |
52
+ | **Rate Limiting** | **✅ Zero-Overhead** | Plugin | Middleware | Middleware |
53
+ | **Routing Algorithm** | **✅ Optimized Radix** | Radix Tree | Linear/Regex | RegExp/Trie |
54
+ | **WebSocket** | **✅ Built-in Pub/Sub** | Plugin | Plugin | Helper |
55
+ | **Multipart Uploads** | **✅ Native** | Plugin | Middleware | Plugin |
56
+ | **Static Assets** | **✅ Smart Streaming** | Standard | Standard | Standard |
57
+ | **Type Safety** | **✅ First-class** | Good | Partial | First-class |
58
+
44
59
  ---
45
60
 
46
61
  ## ✨ Key Features
@@ -77,7 +92,16 @@ npm install qhttpx
77
92
 
78
93
  ## ⚡ Quick Start
79
94
 
80
- ### 1. The Rapid Way (Recommended)
95
+ ### 1. Create a Project (Recommended)
96
+
97
+ Scaffold a production-ready QHTTPX application instantly using our CLI tool:
98
+
99
+ ```bash
100
+ npm create qhttpx@latest
101
+ ```
102
+ This will set up a project with TypeScript, Request Fusion, and best practices pre-configured.
103
+
104
+ ### 2. The Rapid Way (Singleton)
81
105
  Get up and running instantly with the singleton instance and destructuring support.
82
106
 
83
107
  ```typescript
@@ -95,7 +119,7 @@ app.onError(({ error, json }) => {
95
119
  app.listen(3000, () => console.log("Server running on http://localhost:3000"));
96
120
  ```
97
121
 
98
- ### 2. The Custom Way
122
+ ### 3. The Custom Way (Advanced)
99
123
  When you need specific configuration options or multiple instances.
100
124
 
101
125
  ```typescript
@@ -115,65 +139,36 @@ app.get("/users", async ({ json, query }) => {
115
139
  app.listen(3000);
116
140
  ```
117
141
 
118
- ### 2. The Scalable Way (Cluster Mode)
119
- For production workloads utilizing all CPU cores.
120
-
121
- ```bash
122
- # Start your app in cluster mode
123
- npx qhttpx start dist/index.js
124
- ```
125
-
126
142
  ---
127
143
 
128
- ## 🛠️ Advanced Usage
129
-
130
- ### Request Fusion (The "Magic")
131
- Enable `enableRequestFusion` to automatically deduplicate traffic.
132
-
133
- ```typescript
134
- const app = new QHTTPX({
135
- enableRequestFusion: true
136
- });
137
-
138
- // If 50 users hit this endpoint simultaneously,
139
- // the database query runs only ONCE.
140
- app.get("/heavy-query", async (ctx) => {
141
- const data = await db.expensiveQuery();
142
- return ctx.json(data);
143
- });
144
- ```
145
-
146
- ### Real-Time (SSE & WebSockets)
144
+ ## 📚 Documentation
147
145
 
148
- ```typescript
149
- // Server-Sent Events
150
- app.get('/events', (ctx) => {
151
- const stream = createSSE(ctx);
152
- setInterval(() => {
153
- stream.send({ time: Date.now() }, 'tick');
154
- }, 1000);
155
- });
146
+ Detailed guides for every feature of QHTTPX:
156
147
 
157
- // WebSockets with Rooms
158
- app.upgrade('/chat', (ws) => {
159
- ws.join('general');
160
- ws.on('message', (msg) => {
161
- // Broadcast to 'general' room
162
- app.websocket.to('general').emit(`Echo: ${msg}`);
163
- });
164
- });
165
- ```
148
+ - **[Routing](./docs/ROUTING.md)**: Radix tree, parameters, and groups.
149
+ - **[Middleware](./docs/MIDDLEWARE.md)**: Global and route-level hooks.
150
+ - **[Error Handling](./docs/ERRORS.md)**: Standard exceptions and global handlers.
151
+ - **[Aegis Rate Limiter](./docs/AEGIS.md)**: DDoS protection and traffic shaping.
152
+ - **[Request Fusion](./docs/FUSION.md)**: "Thundering Herd" protection engine.
153
+ - **[WebSockets](./docs/WEBSOCKETS.md)**: Real-time Pub/Sub and Rooms.
154
+ - **[Static Files](./docs/STATIC.md)**: Streaming, Range requests, and Caching.
155
+ - **[Ecosystem Integration](./docs/ECOSYSTEM.md)**: Auth, Database, and Validation patterns.
166
156
 
167
157
  ---
168
158
 
169
159
  ## 📊 Benchmarks
170
160
 
171
- In **Ultra Mode**, QHTTPX is designed to saturate 10Gbps links with minimal CPU usage.
161
+ Benchmarks comparing **QHTTPX v1.8.6** against popular Node.js frameworks.
162
+ *(Run on local environment: Windows, 100 connections, 10 pipelining, 40s duration. Average of 2 runs, taking the second result.)*
172
163
 
173
- *(Benchmarks run on AWS c5.large)*
174
- - **QHTTPX (Fusion Enabled)**: ~85,000 req/sec (0% DB Load increase on burst)
175
- - **Fastify**: ~72,000 req/sec
176
- - **Express**: ~14,000 req/sec
164
+ | Framework | Req/Sec | Latency (Avg) | Throughput |
165
+ | :--- | :--- | :--- | :--- |
166
+ | **Fastify** | 16,050 | 256.78 ms | 3.00 Mb/s |
167
+ | **QHTTPX** | **14,179** | **291.13 ms** | **3.02 Mb/s** |
168
+ | **Hono** | 14,176 | 294.09 ms | 2.43 Mb/s |
169
+ | **Express** | 10,450 | 407.12 ms | 1.94 Mb/s |
170
+
171
+ > **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.
177
172
 
178
173
  ---
179
174
 
@@ -187,6 +182,31 @@ QHTTPX is an **Open Runtime**. It works seamlessly with standard tools:
187
182
 
188
183
  ---
189
184
 
185
+ ## 👥 Team
186
+
187
+ QHTTPX is developed and maintained by **Quantam Open Source**.
188
+
189
+ ### Lead Developer
190
+ **Byron Kennedy Pfukwa**
191
+ *Creator & Core Maintainer*
192
+ [![GitHub](https://img.shields.io/badge/GitHub-BYRON--lang-181717?style=flat&logo=github)](https://github.com/BYRON-lang)
193
+ [![NPM](https://img.shields.io/badge/NPM-~brnxdev-CB3837?style=flat&logo=npm)](https://www.npmjs.com/~brnxdev)
194
+ [![X](https://img.shields.io/badge/X-@byronpfukwa-000000?style=flat&logo=x)](https://x.com/byronpfukwa)
195
+
196
+ ### Socials
197
+ Follow us for updates:
198
+ - **QHTTPX (X)**: [@qhttpx](https://x.com/qhttpx)
199
+ - **Open Quantam (X)**: [@openquantam](https://x.com/openquantam)
200
+
201
+ ---
202
+
190
203
  ## 📜 License
191
204
 
192
205
  MIT © [Quantam Open Source](https://github.com/Quantam-Open-Source)
206
+
207
+ <br />
208
+
209
+ <div align="center">
210
+ <p>Project Part of</p>
211
+ <img src="assets/open%20quantam.png" alt="Open Quantam" width="150" />
212
+ </div>
package/binding.gyp ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "targets": [
3
+ {
4
+ "target_name": "qhttpx_native",
5
+ "cflags!": [ "-fno-exceptions" ],
6
+ "cflags_cc!": [ "-fno-exceptions" ],
7
+ "sources": [
8
+ "src/native/addon.cc",
9
+ "src/native/server.cc",
10
+ "src/native/picohttpparser.c"
11
+ ],
12
+ "include_dirs": [
13
+ "<!@(node -p \"require('node-addon-api').include\")"
14
+ ],
15
+ "defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ]
16
+ }
17
+ ]
18
+ }
@@ -1,17 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const index_1 = require("../src/index");
4
+ const dotenv_1 = require("dotenv");
5
+ // Load .env
6
+ (0, dotenv_1.config)();
4
7
  // 1. Initialize App (Fusion + Aegis enabled)
5
8
  const app = (0, index_1.createHttpApp)({
6
9
  enableRequestFusion: true, // ⚡ Auto-coalesce duplicate requests
7
- metricsEnabled: true // 📊 Expose /__qhttpx/metrics
8
- });
9
- // 2. Global Middleware (Logging & Rate Limit)
10
- app.use(async ({ req, next }) => {
11
- console.log(`[${req.method}] ${req.url}`);
12
- if (next)
13
- await next();
10
+ metricsEnabled: true, // 📊 Expose /__qhttpx/metrics
11
+ rateLimit: {
12
+ windowMs: 15 * 60 * 1000,
13
+ max: 100,
14
+ trustProxy: true
15
+ },
16
+ cors: true, // 🛡️ Built-in CORS
17
+ compression: true // 🗜️ Built-in Compression (Gzip/Brotli)
14
18
  });
19
+ // 2. Global Middleware (Logging is built-in by default)
20
+ // No manual app.use(rateLimit(...)) needed!
15
21
  // 3. Validation Schema
16
22
  const UserSchema = {
17
23
  body: {
@@ -32,7 +38,15 @@ app.post('/users', { schema: UserSchema }, async ({ body, json }) => {
32
38
  // Body is already validated and typed here
33
39
  json({ created: true, user: body }, 201);
34
40
  });
35
- // 📂 File Uploads (Typed)
41
+ // Header Auth Example
42
+ app.post('/auth/verify', async ({ headers, json }) => {
43
+ const token = headers.authorization?.replace('Bearer ', '');
44
+ if (!token)
45
+ return json({ error: 'No token provided' }, 401);
46
+ // Verify token...
47
+ json({ valid: true, token });
48
+ });
49
+ // �📂 File Uploads (Typed)
36
50
  app.post('/upload', ({ files, json }) => {
37
51
  if (!files?.doc)
38
52
  return json({ error: 'No file' }, 400);
@@ -49,6 +63,13 @@ app.upgrade('/chat', (ws) => {
49
63
  });
50
64
  // 5. Unified Error Handling
51
65
  app.onError(({ error, json }) => {
66
+ if (error instanceof index_1.HttpError) {
67
+ return json({
68
+ error: error.message,
69
+ code: error.code,
70
+ details: error.details
71
+ }, error.status);
72
+ }
52
73
  console.error(error); // Log internal error
53
74
  json({ error: 'Internal Server Error', handled: true }, 500);
54
75
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../src/index");
4
+ const app = (0, index_1.createHttpApp)();
5
+ app.get('/', ({ json }) => {
6
+ json({ message: 'Hello from QHTTPX!' });
7
+ });
8
+ app.listen(3000, () => {
9
+ console.log('Server running on http://localhost:3000');
10
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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 }) => {
11
+ // Generate a large response to trigger compression
12
+ const data = Array(1000).fill('some repeated data to compress');
13
+ json({ data });
14
+ });
15
+ app.listen(3000, () => {
16
+ console.log('Compression-enabled server running on http://localhost:3000');
17
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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
8
+ cors: {
9
+ origin: ['http://localhost:5173', 'https://myapp.com'],
10
+ methods: ['GET', 'POST'],
11
+ credentials: true
12
+ }
13
+ });
14
+ app.get('/api/data', ({ json }) => {
15
+ json({ data: 'This data is accessible via CORS' });
16
+ });
17
+ app.listen(3000, () => {
18
+ console.log('CORS-enabled server running on http://localhost:3000');
19
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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');
7
+ });
8
+ app.get('/private', () => {
9
+ throw new index_1.ForbiddenException('You do not have access');
10
+ });
11
+ // Custom global error handler
12
+ app.onError(({ error, json }) => {
13
+ if (error instanceof index_1.HttpError) {
14
+ return json({
15
+ status: 'error',
16
+ code: error.code,
17
+ message: error.message
18
+ }, error.status);
19
+ }
20
+ console.error('Unexpected error:', error);
21
+ json({ status: 'error', message: 'Internal Server Error' }, 500);
22
+ });
23
+ app.listen(3000, () => {
24
+ console.log('Error handling demo running on http://localhost:3000');
25
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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 }) => {
9
+ if (!files || !files.document) {
10
+ return json({ error: 'No file uploaded' }, 400);
11
+ }
12
+ const doc = Array.isArray(files.document) ? files.document[0] : files.document;
13
+ console.log(`Received file: ${doc.filename} (${doc.size} bytes)`);
14
+ json({
15
+ uploaded: true,
16
+ filename: doc.filename,
17
+ mimetype: doc.mimeType,
18
+ size: doc.size
19
+ });
20
+ });
21
+ app.listen(3000, () => {
22
+ console.log('Upload server running on http://localhost:3000');
23
+ console.log('Send POST to /upload with form-data field "document"');
24
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../src/index");
4
+ const app = (0, index_1.createHttpApp)({
5
+ // Enable Request Fusion (Request Coalescing)
6
+ enableRequestFusion: true
7
+ });
8
+ // Simulate a slow database call
9
+ const heavyTask = async () => {
10
+ await new Promise(resolve => setTimeout(resolve, 500));
11
+ return { data: 'Expensive Result', timestamp: Date.now() };
12
+ };
13
+ // If 1000 users hit this endpoint simultaneously,
14
+ // the handler runs ONLY ONCE, and the result is shared.
15
+ app.get('/heavy', async ({ json }) => {
16
+ const result = await heavyTask();
17
+ json(result);
18
+ });
19
+ app.listen(3000, () => {
20
+ console.log('Fusion-enabled server running on http://localhost:3000');
21
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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 }) => {
13
+ json({ status: 'OK', message: 'Request accepted' });
14
+ });
15
+ app.listen(3000, () => {
16
+ console.log('Rate-limited server running on http://localhost:3000');
17
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../src/index");
4
+ const app = (0, index_1.createHttpApp)();
5
+ // Define a simple schema (or use Zod if configured)
6
+ const UserSchema = {
7
+ body: {
8
+ type: 'object',
9
+ required: ['username', 'email'],
10
+ properties: {
11
+ username: { type: 'string' },
12
+ email: { type: 'string' }
13
+ }
14
+ }
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)
19
+ json({ success: true, user: body });
20
+ });
21
+ app.listen(3000, () => {
22
+ console.log('Validation server running on http://localhost:3000');
23
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const index_1 = require("../src/index");
4
+ const app = (0, index_1.createHttpApp)();
5
+ app.upgrade('/chat', (ws) => {
6
+ console.log('Client connected');
7
+ ws.join('general');
8
+ ws.on('message', (msg) => {
9
+ console.log(`Received: ${msg}`);
10
+ // Broadcast to everyone in 'general' room
11
+ app.websocket.to('general').emit(`Echo: ${msg}`);
12
+ });
13
+ ws.on('close', () => {
14
+ console.log('Client disconnected');
15
+ });
16
+ });
17
+ app.listen(3000, () => {
18
+ console.log('WebSocket Server running on http://localhost:3000');
19
+ console.log('Test with a WebSocket client at ws://localhost:3000/chat');
20
+ });
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qhttpx",
3
- "version": "1.8.4",
3
+ "version": "1.8.11",
4
4
  "description": "The High-Performance Hybrid HTTP Runtime for Node.js. Built for extreme concurrency, request fusion, and zero-overhead scaling.",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -14,6 +14,15 @@
14
14
  "bin": {
15
15
  "qhttpx": "./dist/src/cli/index.js"
16
16
  },
17
+ "files": [
18
+ "dist",
19
+ "src/native",
20
+ "binding.gyp",
21
+ "README.md",
22
+ "LICENSE",
23
+ "CHANGELOG.md",
24
+ "docs"
25
+ ],
17
26
  "directories": {
18
27
  "doc": "docs"
19
28
  },
@@ -67,6 +76,7 @@
67
76
  "@typescript-eslint/eslint-plugin": "^8.53.0",
68
77
  "@typescript-eslint/parser": "^8.53.0",
69
78
  "autocannon": "^8.0.0",
79
+ "dotenv": "^17.2.3",
70
80
  "eslint": "^9.39.2",
71
81
  "eslint-config-prettier": "^10.1.8",
72
82
  "eslint-plugin-prettier": "^5.5.5",
@@ -81,6 +91,7 @@
81
91
  "better-sqlite3": "^12.6.2",
82
92
  "busboy": "^1.6.0",
83
93
  "fast-json-stringify": "^5.15.1",
94
+ "node-addon-api": "^8.5.0",
84
95
  "pino": "^10.2.0",
85
96
  "pino-pretty": "^13.1.3",
86
97
  "quantam-async": "^0.1.1",
@@ -9,10 +9,9 @@ function runAutocannon(url) {
9
9
  return new Promise((resolve, reject) => {
10
10
  const instance = (0, autocannon_1.default)({
11
11
  url,
12
- amount: 10000,
13
- connections: 10000,
14
- pipelining: 1,
15
- duration: 10,
12
+ connections: 100,
13
+ pipelining: 10,
14
+ duration: 40,
16
15
  }, (err, result) => {
17
16
  if (err) {
18
17
  reject(err);
@@ -37,6 +36,9 @@ async function run() {
37
36
  });
38
37
  const { port } = await app.listen(0, '127.0.0.1');
39
38
  const url = `http://127.0.0.1:${port}/json`;
39
+ console.log('Running warmup (1/2)...');
40
+ await runAutocannon(url);
41
+ console.log('Running benchmark (2/2)...');
40
42
  const result = await runAutocannon(url);
41
43
  autocannon_1.default.printResult(result);
42
44
  const totalRequests = result.requests.total;