qhttpx 2.0.0 → 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.
- package/README.md +15 -27
- package/dist/package.json +1 -1
- package/dist/src/core/metrics.d.ts +2 -1
- package/dist/src/core/metrics.js +9 -6
- package/dist/src/core/server.js +1 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,10 +45,10 @@ Most Node.js frameworks rely on the event loop blindly. QHTTPX introduces a **Co
|
|
|
45
45
|
|
|
46
46
|
| Feature | **QHTTPX** | Fastify | Express | Hono |
|
|
47
47
|
| :--- | :---: | :---: | :---: | :---: |
|
|
48
|
-
| **Core Runtime** | **⚡
|
|
48
|
+
| **Core Runtime** | **⚡ Pure TypeScript** | JS | JS | JS |
|
|
49
49
|
| **Request Fusion** | **✅ Native** | ❌ | ❌ | ❌ |
|
|
50
50
|
| **DDoS Protection** | **✅ Built-in (Aegis)** | ❌ | ❌ | ❌ |
|
|
51
|
-
| **JSON Serialization** | **✅
|
|
51
|
+
| **JSON Serialization** | **✅ Optimized Fast-Path** | Schema-based | Slow | Slow |
|
|
52
52
|
| **Concurrency Model** | **✅ Async Scheduler** | Event Loop | Event Loop | Event Loop |
|
|
53
53
|
| **Rate Limiting** | **✅ Zero-Overhead** | Plugin | Middleware | Middleware |
|
|
54
54
|
| **Routing Algorithm** | **✅ Optimized Radix** | Radix Tree | Linear/Regex | RegExp/Trie |
|
|
@@ -188,24 +188,26 @@ app.start(3000).then(() => console.log('Running on http://localhost:3000'));
|
|
|
188
188
|
|
|
189
189
|
Run with: `node index.js`
|
|
190
190
|
|
|
191
|
-
### 3. The
|
|
192
|
-
|
|
193
|
-
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.
|
|
194
193
|
|
|
195
194
|
```typescript
|
|
196
|
-
import {
|
|
195
|
+
import { app } from 'qhttpx';
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
});
|
|
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 });
|
|
202
201
|
|
|
203
|
-
app.get(
|
|
204
|
-
|
|
205
|
-
return
|
|
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');
|
|
206
205
|
});
|
|
206
|
+
|
|
207
|
+
app.start(3000);
|
|
207
208
|
```
|
|
208
209
|
|
|
210
|
+
|
|
209
211
|
---
|
|
210
212
|
|
|
211
213
|
## 📚 Documentation
|
|
@@ -223,21 +225,7 @@ Detailed guides for every feature of QHTTPX:
|
|
|
223
225
|
|
|
224
226
|
---
|
|
225
227
|
|
|
226
|
-
## 📊 Benchmarks
|
|
227
|
-
|
|
228
|
-
Benchmarks comparing **QHTTPX v1.8.6** against popular Node.js frameworks.
|
|
229
|
-
*(Run on local environment: Windows, 100 connections, 10 pipelining, 40s duration. Average of 2 runs, taking the second result.)*
|
|
230
|
-
|
|
231
|
-
| Framework | Req/Sec | Latency (Avg) | Throughput |
|
|
232
|
-
| :--- | :--- | :--- | :--- |
|
|
233
|
-
| **Fastify** | 16,050 | 256.78 ms | 3.00 Mb/s |
|
|
234
|
-
| **QHTTPX** | **14,179** | **291.13 ms** | **3.02 Mb/s** |
|
|
235
|
-
| **Hono** | 14,176 | 294.09 ms | 2.43 Mb/s |
|
|
236
|
-
| **Express** | 10,450 | 407.12 ms | 1.94 Mb/s |
|
|
237
228
|
|
|
238
|
-
> **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.
|
|
239
|
-
|
|
240
|
-
---
|
|
241
229
|
|
|
242
230
|
## 🤝 Ecosystem Compatibility
|
|
243
231
|
|
package/dist/package.json
CHANGED
|
@@ -29,7 +29,7 @@ export declare class Metrics {
|
|
|
29
29
|
private readonly fusion?;
|
|
30
30
|
private readonly latencies;
|
|
31
31
|
private readonly maxLatencies;
|
|
32
|
-
private
|
|
32
|
+
private _enabled;
|
|
33
33
|
private totalRequests;
|
|
34
34
|
private inFlightRequests;
|
|
35
35
|
private totalErrors;
|
|
@@ -39,6 +39,7 @@ export declare class Metrics {
|
|
|
39
39
|
enabled?: boolean;
|
|
40
40
|
}, taskEngine?: TaskEngine, fusion?: RequestFusion);
|
|
41
41
|
get isEnabled(): boolean;
|
|
42
|
+
setEnabled(value: boolean): void;
|
|
42
43
|
onRequestStart(): void;
|
|
43
44
|
onRequestEnd(durationMs: number, statusCode: number): void;
|
|
44
45
|
onTimeout(): void;
|
package/dist/src/core/metrics.js
CHANGED
|
@@ -12,19 +12,22 @@ class Metrics {
|
|
|
12
12
|
this.taskEngine = taskEngine;
|
|
13
13
|
this.fusion = fusion;
|
|
14
14
|
this.maxLatencies = options.maxLatencies ?? 1000;
|
|
15
|
-
this.
|
|
15
|
+
this._enabled = options.enabled ?? true;
|
|
16
16
|
}
|
|
17
17
|
get isEnabled() {
|
|
18
|
-
return this.
|
|
18
|
+
return this._enabled;
|
|
19
|
+
}
|
|
20
|
+
setEnabled(value) {
|
|
21
|
+
this._enabled = value;
|
|
19
22
|
}
|
|
20
23
|
onRequestStart() {
|
|
21
|
-
if (!this.
|
|
24
|
+
if (!this._enabled) {
|
|
22
25
|
return;
|
|
23
26
|
}
|
|
24
27
|
this.inFlightRequests += 1;
|
|
25
28
|
}
|
|
26
29
|
onRequestEnd(durationMs, statusCode) {
|
|
27
|
-
if (!this.
|
|
30
|
+
if (!this._enabled) {
|
|
28
31
|
return;
|
|
29
32
|
}
|
|
30
33
|
this.totalRequests += 1;
|
|
@@ -37,7 +40,7 @@ class Metrics {
|
|
|
37
40
|
this.recordLatency(durationMs);
|
|
38
41
|
}
|
|
39
42
|
onTimeout() {
|
|
40
|
-
if (!this.
|
|
43
|
+
if (!this._enabled) {
|
|
41
44
|
return;
|
|
42
45
|
}
|
|
43
46
|
this.totalTimeouts += 1;
|
|
@@ -74,7 +77,7 @@ class Metrics {
|
|
|
74
77
|
};
|
|
75
78
|
}
|
|
76
79
|
recordLatency(durationMs) {
|
|
77
|
-
if (!this.
|
|
80
|
+
if (!this._enabled) {
|
|
78
81
|
return;
|
|
79
82
|
}
|
|
80
83
|
if (!Number.isFinite(durationMs) || durationMs < 0) {
|
package/dist/src/core/server.js
CHANGED
|
@@ -1033,14 +1033,7 @@ class QHTTPX {
|
|
|
1033
1033
|
}
|
|
1034
1034
|
metrics(enable = true) {
|
|
1035
1035
|
this.options.metricsEnabled = enable;
|
|
1036
|
-
|
|
1037
|
-
// The Metrics class is initialized in constructor.
|
|
1038
|
-
// We might need to update the metrics instance.
|
|
1039
|
-
// But looking at Metrics class, it takes options in constructor.
|
|
1040
|
-
// However, we can probably update the internal state if needed.
|
|
1041
|
-
// For now, let's assume setting options is enough or we might need to expose a method on Metrics.
|
|
1042
|
-
// Re-initializing metrics might be complex.
|
|
1043
|
-
// Let's assume the user calls this before start.
|
|
1036
|
+
this._metrics.setEnabled(enable);
|
|
1044
1037
|
return this;
|
|
1045
1038
|
}
|
|
1046
1039
|
error(status, message, details) {
|