qhttpx 2.1.0 → 2.3.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 (267) hide show
  1. package/LICENSE +201 -21
  2. package/README.md +117 -221
  3. package/dist/chunk-QW72SEAS.mjs +98 -0
  4. package/dist/{src/cli/index.d.ts → cli.d.mts} +0 -1
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +287 -0
  7. package/dist/cli.mjs +209 -0
  8. package/dist/index.d.mts +433 -0
  9. package/dist/index.d.ts +433 -0
  10. package/dist/index.js +1955 -0
  11. package/dist/index.mjs +1863 -0
  12. package/dist/qhttpx-core-new.linux-x64-gnu.node +0 -0
  13. package/dist/qhttpx-core-new.node +0 -0
  14. package/dist/qhttpx-core-new.win32-x64-msvc.node +0 -0
  15. package/examples/benchmark.ts +67 -0
  16. package/examples/body_demo.ts +32 -0
  17. package/examples/chat_client.ts +36 -0
  18. package/examples/chat_demo.ts +41 -0
  19. package/examples/cluster_demo.ts +26 -0
  20. package/examples/cors_demo.ts +25 -0
  21. package/examples/db_auth_demo.ts +66 -0
  22. package/examples/demo.ts +52 -0
  23. package/examples/headers_demo.ts +24 -0
  24. package/examples/hello.ts +7 -0
  25. package/examples/http2_demo.ts +52 -0
  26. package/examples/magic-dev.ts +15 -0
  27. package/examples/middleware_demo.ts +34 -0
  28. package/examples/mongo_demo.ts +40 -0
  29. package/examples/native_policy_demo.ts +33 -0
  30. package/examples/observability_demo.ts +24 -0
  31. package/examples/public/1mb.dat +1 -0
  32. package/examples/query_demo.ts +29 -0
  33. package/examples/response_demo.ts +21 -0
  34. package/examples/routing_demo.ts +24 -0
  35. package/examples/server.ts +51 -0
  36. package/examples/static_demo.ts +29 -0
  37. package/examples/test_middleware_client.ts +33 -0
  38. package/examples/test_query_client.ts +34 -0
  39. package/examples/test_response_client.ts +30 -0
  40. package/examples/tls_demo.ts +32 -0
  41. package/examples/upload_demo.ts +43 -0
  42. package/examples/uploads/test.txt +1 -0
  43. package/examples/verify_upload.ts +69 -0
  44. package/examples/ws_client.ts +26 -0
  45. package/examples/ws_demo.ts +21 -0
  46. package/package.json +65 -81
  47. package/CHANGELOG.md +0 -285
  48. package/dist/examples/api-server.d.ts +0 -1
  49. package/dist/examples/api-server.js +0 -80
  50. package/dist/examples/basic.d.ts +0 -1
  51. package/dist/examples/basic.js +0 -9
  52. package/dist/examples/compression.d.ts +0 -1
  53. package/dist/examples/compression.js +0 -15
  54. package/dist/examples/cors.d.ts +0 -1
  55. package/dist/examples/cors.js +0 -18
  56. package/dist/examples/errors.d.ts +0 -1
  57. package/dist/examples/errors.js +0 -26
  58. package/dist/examples/file-upload.d.ts +0 -1
  59. package/dist/examples/file-upload.js +0 -22
  60. package/dist/examples/fusion.d.ts +0 -1
  61. package/dist/examples/fusion.js +0 -21
  62. package/dist/examples/rate-limiting.d.ts +0 -1
  63. package/dist/examples/rate-limiting.js +0 -17
  64. package/dist/examples/validation.d.ts +0 -1
  65. package/dist/examples/validation.js +0 -22
  66. package/dist/examples/websockets.d.ts +0 -1
  67. package/dist/examples/websockets.js +0 -19
  68. package/dist/package.json +0 -107
  69. package/dist/src/benchmarks/quantam-users.d.ts +0 -1
  70. package/dist/src/benchmarks/quantam-users.js +0 -56
  71. package/dist/src/benchmarks/quick-bench.d.ts +0 -1
  72. package/dist/src/benchmarks/quick-bench.js +0 -57
  73. package/dist/src/benchmarks/simple-json.d.ts +0 -1
  74. package/dist/src/benchmarks/simple-json.js +0 -171
  75. package/dist/src/benchmarks/ultra-mode.d.ts +0 -1
  76. package/dist/src/benchmarks/ultra-mode.js +0 -64
  77. package/dist/src/cli/index.js +0 -222
  78. package/dist/src/client/index.d.ts +0 -17
  79. package/dist/src/client/index.js +0 -72
  80. package/dist/src/core/batch.d.ts +0 -24
  81. package/dist/src/core/batch.js +0 -97
  82. package/dist/src/core/body-parser.d.ts +0 -15
  83. package/dist/src/core/body-parser.js +0 -121
  84. package/dist/src/core/buffer-pool.d.ts +0 -41
  85. package/dist/src/core/buffer-pool.js +0 -70
  86. package/dist/src/core/config.d.ts +0 -7
  87. package/dist/src/core/config.js +0 -50
  88. package/dist/src/core/context-pool.d.ts +0 -12
  89. package/dist/src/core/context-pool.js +0 -34
  90. package/dist/src/core/errors.d.ts +0 -34
  91. package/dist/src/core/errors.js +0 -70
  92. package/dist/src/core/fusion.d.ts +0 -20
  93. package/dist/src/core/fusion.js +0 -191
  94. package/dist/src/core/logger.d.ts +0 -22
  95. package/dist/src/core/logger.js +0 -49
  96. package/dist/src/core/metrics.d.ts +0 -50
  97. package/dist/src/core/metrics.js +0 -123
  98. package/dist/src/core/resources.d.ts +0 -9
  99. package/dist/src/core/resources.js +0 -25
  100. package/dist/src/core/scheduler.d.ts +0 -38
  101. package/dist/src/core/scheduler.js +0 -126
  102. package/dist/src/core/scope.d.ts +0 -41
  103. package/dist/src/core/scope.js +0 -107
  104. package/dist/src/core/serializer.d.ts +0 -10
  105. package/dist/src/core/serializer.js +0 -82
  106. package/dist/src/core/server.d.ts +0 -179
  107. package/dist/src/core/server.js +0 -1511
  108. package/dist/src/core/stream.d.ts +0 -15
  109. package/dist/src/core/stream.js +0 -71
  110. package/dist/src/core/tasks.d.ts +0 -29
  111. package/dist/src/core/tasks.js +0 -87
  112. package/dist/src/core/timer.d.ts +0 -11
  113. package/dist/src/core/timer.js +0 -29
  114. package/dist/src/core/types.d.ts +0 -225
  115. package/dist/src/core/types.js +0 -19
  116. package/dist/src/core/websocket.d.ts +0 -25
  117. package/dist/src/core/websocket.js +0 -86
  118. package/dist/src/core/worker-queue.d.ts +0 -41
  119. package/dist/src/core/worker-queue.js +0 -73
  120. package/dist/src/database/adapters/memory.d.ts +0 -21
  121. package/dist/src/database/adapters/memory.js +0 -90
  122. package/dist/src/database/adapters/mongo.d.ts +0 -11
  123. package/dist/src/database/adapters/mongo.js +0 -141
  124. package/dist/src/database/adapters/postgres.d.ts +0 -10
  125. package/dist/src/database/adapters/postgres.js +0 -111
  126. package/dist/src/database/adapters/sqlite.d.ts +0 -10
  127. package/dist/src/database/adapters/sqlite.js +0 -42
  128. package/dist/src/database/coalescer.d.ts +0 -14
  129. package/dist/src/database/coalescer.js +0 -134
  130. package/dist/src/database/manager.d.ts +0 -35
  131. package/dist/src/database/manager.js +0 -87
  132. package/dist/src/database/types.d.ts +0 -20
  133. package/dist/src/database/types.js +0 -2
  134. package/dist/src/index.d.ts +0 -52
  135. package/dist/src/index.js +0 -92
  136. package/dist/src/middleware/compression.d.ts +0 -2
  137. package/dist/src/middleware/compression.js +0 -133
  138. package/dist/src/middleware/cors.d.ts +0 -2
  139. package/dist/src/middleware/cors.js +0 -66
  140. package/dist/src/middleware/presets.d.ts +0 -15
  141. package/dist/src/middleware/presets.js +0 -52
  142. package/dist/src/middleware/rate-limit.d.ts +0 -14
  143. package/dist/src/middleware/rate-limit.js +0 -83
  144. package/dist/src/middleware/security.d.ts +0 -10
  145. package/dist/src/middleware/security.js +0 -74
  146. package/dist/src/middleware/static.d.ts +0 -11
  147. package/dist/src/middleware/static.js +0 -191
  148. package/dist/src/openapi/generator.d.ts +0 -19
  149. package/dist/src/openapi/generator.js +0 -149
  150. package/dist/src/router/radix-router.d.ts +0 -18
  151. package/dist/src/router/radix-router.js +0 -89
  152. package/dist/src/router/radix-tree.d.ts +0 -21
  153. package/dist/src/router/radix-tree.js +0 -175
  154. package/dist/src/router/router.d.ts +0 -37
  155. package/dist/src/router/router.js +0 -203
  156. package/dist/src/testing/index.d.ts +0 -25
  157. package/dist/src/testing/index.js +0 -84
  158. package/dist/src/utils/cookies.d.ts +0 -3
  159. package/dist/src/utils/cookies.js +0 -59
  160. package/dist/src/utils/logger.d.ts +0 -2
  161. package/dist/src/utils/logger.js +0 -45
  162. package/dist/src/utils/signals.d.ts +0 -6
  163. package/dist/src/utils/signals.js +0 -31
  164. package/dist/src/utils/sse.d.ts +0 -6
  165. package/dist/src/utils/sse.js +0 -32
  166. package/dist/src/validation/index.d.ts +0 -3
  167. package/dist/src/validation/index.js +0 -19
  168. package/dist/src/validation/simple.d.ts +0 -5
  169. package/dist/src/validation/simple.js +0 -102
  170. package/dist/src/validation/types.d.ts +0 -32
  171. package/dist/src/validation/types.js +0 -12
  172. package/dist/src/validation/zod.d.ts +0 -4
  173. package/dist/src/validation/zod.js +0 -18
  174. package/dist/src/views/index.d.ts +0 -1
  175. package/dist/src/views/index.js +0 -17
  176. package/dist/src/views/types.d.ts +0 -3
  177. package/dist/src/views/types.js +0 -2
  178. package/dist/tests/adapters.test.d.ts +0 -1
  179. package/dist/tests/adapters.test.js +0 -106
  180. package/dist/tests/batch.test.d.ts +0 -1
  181. package/dist/tests/batch.test.js +0 -117
  182. package/dist/tests/body-parser.test.d.ts +0 -1
  183. package/dist/tests/body-parser.test.js +0 -52
  184. package/dist/tests/compression-sse.test.d.ts +0 -1
  185. package/dist/tests/compression-sse.test.js +0 -87
  186. package/dist/tests/cookies.test.d.ts +0 -1
  187. package/dist/tests/cookies.test.js +0 -63
  188. package/dist/tests/cors.test.d.ts +0 -1
  189. package/dist/tests/cors.test.js +0 -55
  190. package/dist/tests/database.test.d.ts +0 -1
  191. package/dist/tests/database.test.js +0 -80
  192. package/dist/tests/dx.test.d.ts +0 -1
  193. package/dist/tests/dx.test.js +0 -114
  194. package/dist/tests/ecosystem.test.d.ts +0 -1
  195. package/dist/tests/ecosystem.test.js +0 -133
  196. package/dist/tests/features.test.d.ts +0 -1
  197. package/dist/tests/features.test.js +0 -47
  198. package/dist/tests/fusion.test.d.ts +0 -1
  199. package/dist/tests/fusion.test.js +0 -92
  200. package/dist/tests/http-basic.test.d.ts +0 -1
  201. package/dist/tests/http-basic.test.js +0 -124
  202. package/dist/tests/logger.test.d.ts +0 -1
  203. package/dist/tests/logger.test.js +0 -33
  204. package/dist/tests/middleware.test.d.ts +0 -1
  205. package/dist/tests/middleware.test.js +0 -109
  206. package/dist/tests/observability.test.d.ts +0 -1
  207. package/dist/tests/observability.test.js +0 -59
  208. package/dist/tests/openapi.test.d.ts +0 -1
  209. package/dist/tests/openapi.test.js +0 -64
  210. package/dist/tests/plugin.test.d.ts +0 -1
  211. package/dist/tests/plugin.test.js +0 -65
  212. package/dist/tests/plugins.test.d.ts +0 -1
  213. package/dist/tests/plugins.test.js +0 -71
  214. package/dist/tests/rate-limit.test.d.ts +0 -1
  215. package/dist/tests/rate-limit.test.js +0 -77
  216. package/dist/tests/resources.test.d.ts +0 -1
  217. package/dist/tests/resources.test.js +0 -47
  218. package/dist/tests/scheduler.test.d.ts +0 -1
  219. package/dist/tests/scheduler.test.js +0 -46
  220. package/dist/tests/schema-routes.test.d.ts +0 -1
  221. package/dist/tests/schema-routes.test.js +0 -79
  222. package/dist/tests/security.test.d.ts +0 -1
  223. package/dist/tests/security.test.js +0 -83
  224. package/dist/tests/server-db.test.d.ts +0 -1
  225. package/dist/tests/server-db.test.js +0 -72
  226. package/dist/tests/smoke.test.d.ts +0 -1
  227. package/dist/tests/smoke.test.js +0 -10
  228. package/dist/tests/sqlite-fusion.test.d.ts +0 -1
  229. package/dist/tests/sqlite-fusion.test.js +0 -92
  230. package/dist/tests/static.test.d.ts +0 -1
  231. package/dist/tests/static.test.js +0 -102
  232. package/dist/tests/stream.test.d.ts +0 -1
  233. package/dist/tests/stream.test.js +0 -44
  234. package/dist/tests/task-metrics.test.d.ts +0 -1
  235. package/dist/tests/task-metrics.test.js +0 -53
  236. package/dist/tests/tasks.test.d.ts +0 -1
  237. package/dist/tests/tasks.test.js +0 -62
  238. package/dist/tests/testing.test.d.ts +0 -1
  239. package/dist/tests/testing.test.js +0 -47
  240. package/dist/tests/validation.test.d.ts +0 -1
  241. package/dist/tests/validation.test.js +0 -107
  242. package/dist/tests/websocket.test.d.ts +0 -1
  243. package/dist/tests/websocket.test.js +0 -146
  244. package/dist/vitest.config.d.ts +0 -2
  245. package/dist/vitest.config.js +0 -9
  246. package/docs/AEGIS.md +0 -91
  247. package/docs/API_REFERENCE.md +0 -749
  248. package/docs/BENCHMARKS.md +0 -39
  249. package/docs/CAPABILITIES.md +0 -70
  250. package/docs/CLI.md +0 -43
  251. package/docs/DATABASE.md +0 -142
  252. package/docs/ECOSYSTEM.md +0 -146
  253. package/docs/ERRORS.md +0 -112
  254. package/docs/FUSION.md +0 -87
  255. package/docs/MIDDLEWARE.md +0 -65
  256. package/docs/MIGRATION_1.9_TO_2.0.md +0 -495
  257. package/docs/NEXT_STEPS.md +0 -99
  258. package/docs/OPENAPI.md +0 -99
  259. package/docs/PLUGINS.md +0 -59
  260. package/docs/PRODUCTION_DEPLOYMENT.md +0 -798
  261. package/docs/REAL_WORLD_EXAMPLES.md +0 -109
  262. package/docs/ROADMAP.md +0 -366
  263. package/docs/ROUTING.md +0 -78
  264. package/docs/SECURITY.md +0 -876
  265. package/docs/STATIC.md +0 -61
  266. package/docs/VALIDATION.md +0 -114
  267. package/docs/WEBSOCKETS.md +0 -76
package/dist/package.json DELETED
@@ -1,107 +0,0 @@
1
- {
2
- "name": "qhttpx",
3
- "version": "2.1.0",
4
- "gypfile": false,
5
- "description": "The Ultra-Fast HTTP Framework for Node.js",
6
- "main": "dist/src/index.js",
7
- "types": "dist/src/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/src/index.d.ts",
11
- "require": "./dist/src/index.js",
12
- "default": "./dist/src/index.js"
13
- }
14
- },
15
- "bin": {
16
- "qhttpx": "./dist/src/cli/index.js"
17
- },
18
- "files": [
19
- "dist",
20
- "scripts",
21
- "README.md",
22
- "LICENSE",
23
- "CHANGELOG.md",
24
- "docs"
25
- ],
26
- "directories": {
27
- "doc": "docs"
28
- },
29
- "scripts": {
30
- "prepublishOnly": "npm run build",
31
- "build": "tsc -p tsconfig.json",
32
- "lint": "eslint src tests --ext .ts",
33
- "test": "vitest run",
34
- "example": "npx tsx examples/api-server.ts",
35
- "bench": "npm run build && node dist/src/benchmarks/simple-json.js",
36
- "bench:quantam": "npm run build && node dist/src/benchmarks/quantam-users.js",
37
- "bench:ultra": "npm run build && node dist/src/benchmarks/ultra-mode.js"
38
- },
39
- "keywords": [
40
- "http",
41
- "server",
42
- "web",
43
- "framework",
44
- "typescript",
45
- "fast",
46
- "performance",
47
- "high-performance",
48
- "async",
49
- "concurrency",
50
- "request-fusion",
51
- "coalescing",
52
- "middleware",
53
- "websocket",
54
- "sse",
55
- "rate-limit",
56
- "rest",
57
- "api",
58
- "json",
59
- "router",
60
- "radix-tree",
61
- "scheduler",
62
- "ultra-fast",
63
- "nodejs"
64
- ],
65
- "author": "Quantam Open Source",
66
- "license": "MIT",
67
- "repository": {
68
- "type": "git",
69
- "url": "https://github.com/Quantam-Open-Source/qhttpx"
70
- },
71
- "homepage": "https://qhttpx.gridrr.com",
72
- "type": "commonjs",
73
- "devDependencies": {
74
- "@types/autocannon": "^7.12.7",
75
- "@types/better-sqlite3": "^7.6.13",
76
- "@types/busboy": "^1.5.4",
77
- "@types/ioredis": "^4.28.10",
78
- "@types/mongodb": "^4.0.6",
79
- "@types/node": "^25.0.9",
80
- "@types/pg": "^8.16.0",
81
- "@types/ws": "^8.18.1",
82
- "@typescript-eslint/eslint-plugin": "^8.53.0",
83
- "@typescript-eslint/parser": "^8.53.0",
84
- "autocannon": "^8.0.0",
85
- "dotenv": "^17.2.3",
86
- "eslint": "^9.39.2",
87
- "eslint-config-prettier": "^10.1.8",
88
- "eslint-plugin-prettier": "^5.5.5",
89
- "mongodb": "^7.0.0",
90
- "pg": "^8.17.1",
91
- "prettier": "^3.8.0",
92
- "tsx": "^4.21.0",
93
- "typescript": "^5.9.3",
94
- "vitest": "^4.0.17"
95
- },
96
- "dependencies": {
97
- "better-sqlite3": "^12.6.2",
98
- "busboy": "^1.6.0",
99
- "fast-json-stringify": "^5.15.1",
100
- "fastify": "^5.7.1",
101
- "pino": "^10.2.0",
102
- "pino-pretty": "^13.1.3",
103
- "quantam-async": "^0.1.1",
104
- "ws": "^8.19.0",
105
- "zod": "^4.3.5"
106
- }
107
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const quantam_async_1 = require("quantam-async");
4
- const index_1 = require("../index");
5
- async function run() {
6
- const app = new index_1.QHTTPX({
7
- maxConcurrency: 512,
8
- requestTimeoutMs: 10000,
9
- });
10
- app.get('/json', ({ json }) => {
11
- json({ message: 'hello from qhttpx' });
12
- });
13
- const { port } = await app.listen(0, '127.0.0.1');
14
- const url = `http://127.0.0.1:${port}/json`;
15
- const requestsPerUser = 10;
16
- const userCount = 10000;
17
- const maxConcurrentUsers = 1000;
18
- const flow = (0, quantam_async_1.quantam)()
19
- .name('user-flow')
20
- .step(async (userId) => {
21
- for (let i = 0; i < requestsPerUser; i += 1) {
22
- const response = await fetch(url);
23
- if (!response.ok) {
24
- throw new Error(`user ${userId} request ${i} failed with status ${response.status}`);
25
- }
26
- await response.text();
27
- }
28
- return userId;
29
- })
30
- .retry(3, 50)
31
- .timeout(30000);
32
- const inputs = [];
33
- for (let i = 0; i < userCount; i += 1) {
34
- inputs.push(i);
35
- }
36
- const start = Date.now();
37
- try {
38
- await flow.runMany(inputs, {
39
- concurrency: maxConcurrentUsers,
40
- });
41
- }
42
- catch (err) {
43
- console.error('Quantam runMany error', err);
44
- }
45
- const durationSec = (Date.now() - start) / 1000;
46
- const totalRequests = userCount * requestsPerUser;
47
- const rps = totalRequests / durationSec;
48
- console.log(`Quantam bench: users=${userCount}, requestsPerUser=${requestsPerUser}, ` +
49
- `totalRequests=${totalRequests}, duration=${durationSec.toFixed(2)}s, rps=${rps.toFixed(0)}, concurrency=${maxConcurrentUsers}`);
50
- await app.close();
51
- process.exit(0);
52
- }
53
- run().catch((err) => {
54
- console.error(err);
55
- process.exit(1);
56
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,57 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,171 +0,0 @@
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 fastify_1 = __importDefault(require("fastify"));
8
- const index_1 = require("../index");
9
- // ============================================
10
- // NUCLEAR OPTIMIZATION #1: Pre-built Response
11
- // ============================================
12
- // We now use the framework's built-in staticResponse optimization
13
- const STATIC_JSON_RESPONSE = { message: 'hello from qhttpx' };
14
- // Real-world pipelining (10 = realistic for high-performance benchmarks)
15
- function runAutocannon(url, options) {
16
- return new Promise((resolve, reject) => {
17
- const instance = (0, autocannon_1.default)({
18
- url,
19
- connections: 100,
20
- pipelining: options?.pipelining ?? 10, // ✅ Config: 10
21
- duration: 40,
22
- }, (err, result) => {
23
- if (err) {
24
- reject(err);
25
- return;
26
- }
27
- resolve(result);
28
- });
29
- instance.on('error', (err) => {
30
- reject(err);
31
- });
32
- });
33
- }
34
- async function benchmarkQHTTPX() {
35
- console.log('\n' + '='.repeat(60));
36
- console.log('BENCHMARKING QHTTPX (Nuclear Optimized)');
37
- console.log('='.repeat(60));
38
- const app = new index_1.QHTTPX({
39
- maxConcurrency: 2000,
40
- metricsEnabled: false,
41
- performanceMode: 'default',
42
- });
43
- // ============================================
44
- // NUCLEAR OPTIMIZATION #2: Use pre-built buffer
45
- // ============================================
46
- // Sync handler using pre-built response (fastest possible)
47
- app.get('/json', ({ json }) => {
48
- // This handler will be optimized away by staticResponse option
49
- // But we provide a fallback using the new destructuring style
50
- json(STATIC_JSON_RESPONSE);
51
- }, {
52
- staticResponse: STATIC_JSON_RESPONSE
53
- });
54
- const { port } = await app.listen(0, '127.0.0.1');
55
- const url = `http://127.0.0.1:${port}/json`;
56
- console.log('\nWarmup run (1/3)...');
57
- await runAutocannon(url);
58
- console.log('Benchmark run 1 (2/3)...');
59
- const result1 = await runAutocannon(url);
60
- console.log('Benchmark run 2 (3/3)...');
61
- const result2 = await runAutocannon(url);
62
- // Use average of two runs
63
- const avgRps = (result1.requests.average + result2.requests.average) / 2;
64
- const avgP99 = (result1.latency.p99 + result2.latency.p99) / 2;
65
- const totalRequests = result2.requests.total;
66
- console.log(`\n📊 QHTTPX Results (Pipelining=${result2.pipelining}):`);
67
- console.log(` Total Requests: ${totalRequests}`);
68
- console.log(` Avg Req/sec: ${avgRps.toFixed(0)}`);
69
- console.log(` P99 Latency: ${avgP99.toFixed(1)}ms`);
70
- console.log(` Connections: ${result2.connections}`);
71
- console.log(` Pipelining: ${result2.pipelining}`);
72
- await app.close();
73
- return {
74
- name: 'QHTTPX',
75
- totalRequests,
76
- avgRps,
77
- p99: avgP99,
78
- };
79
- }
80
- async function benchmarkFastify() {
81
- console.log('\n' + '='.repeat(60));
82
- console.log('BENCHMARKING FASTIFY (Reference)');
83
- console.log('='.repeat(60));
84
- const fastify = (0, fastify_1.default)({
85
- logger: false,
86
- });
87
- // Fastify with standard async handler
88
- fastify.get('/json', async () => {
89
- return { message: 'hello from fastify' };
90
- });
91
- await fastify.listen({ port: 0, host: '127.0.0.1' });
92
- const address = fastify.server.address();
93
- const port = typeof address === 'string' ? 3001 : address.port;
94
- const url = `http://127.0.0.1:${port}/json`;
95
- console.log('\nWarmup run (1/3)...');
96
- await runAutocannon(url);
97
- console.log('Benchmark run 1 (2/3)...');
98
- const result1 = await runAutocannon(url);
99
- console.log('Benchmark run 2 (3/3)...');
100
- const result2 = await runAutocannon(url);
101
- // Use average of two runs
102
- const avgRps = (result1.requests.average + result2.requests.average) / 2;
103
- const avgP99 = (result1.latency.p99 + result2.latency.p99) / 2;
104
- const totalRequests = result2.requests.total;
105
- console.log(`\n📊 Fastify Results (Pipelining=${result2.pipelining}):`);
106
- console.log(` Total Requests: ${totalRequests}`);
107
- console.log(` Avg Req/sec: ${avgRps.toFixed(0)}`);
108
- console.log(` P99 Latency: ${avgP99.toFixed(1)}ms`);
109
- console.log(` Connections: ${result2.connections}`);
110
- console.log(` Pipelining: ${result2.pipelining}`);
111
- await fastify.close();
112
- return {
113
- name: 'Fastify',
114
- totalRequests,
115
- avgRps,
116
- p99: avgP99,
117
- };
118
- }
119
- async function run() {
120
- console.log('\n🚀 Starting Performance Comparison Benchmark');
121
- console.log('Target: Beat Fastify (70K-90K req/s on 4-core, 120K+ on 8-core)');
122
- const results = [];
123
- try {
124
- const qhttpxResult = await benchmarkQHTTPX();
125
- results.push(qhttpxResult);
126
- const fastifyResult = await benchmarkFastify();
127
- results.push(fastifyResult);
128
- // Summary comparison
129
- console.log('\n' + '='.repeat(60));
130
- console.log('BENCHMARK SUMMARY');
131
- console.log('='.repeat(60));
132
- const qhttpx = results.find((r) => r.name === 'QHTTPX');
133
- const fastify = results.find((r) => r.name === 'Fastify');
134
- console.log(`\n📈 Requests/sec:`);
135
- console.log(` QHTTPX: ${qhttpx.avgRps.toFixed(0)} req/sec`);
136
- console.log(` Fastify: ${fastify.avgRps.toFixed(0)} req/sec`);
137
- const improvement = ((qhttpx.avgRps - fastify.avgRps) / fastify.avgRps * 100).toFixed(1);
138
- console.log(` ${improvement}% ${qhttpx.avgRps > fastify.avgRps ? 'FASTER ✓' : 'slower'}`);
139
- console.log(`\n⏱️ P99 Latency:`);
140
- console.log(` QHTTPX: ${qhttpx.p99.toFixed(1)}ms`);
141
- console.log(` Fastify: ${fastify.p99.toFixed(1)}ms`);
142
- console.log(`\n✅ Architecture Improvements:`);
143
- console.log(` • Static routes: O(1) Map lookup (vs Radix tree O(log n))`);
144
- console.log(` • Dynamic routes: Pre-compiled regex patterns`);
145
- console.log(` • Single code path: No mode branching`);
146
- console.log(` • Sync handlers: No async/Promise overhead`);
147
- console.log(` • Context pooling: Zero allocations per request`);
148
- console.log(` • Pre-built responses: No JSON serialization`);
149
- console.log(`\n✅ Nuclear Optimizations Applied:`);
150
- console.log(` • Pre-built Buffer response (compiled once)`);
151
- console.log(` • Pipelining: 10 (High performance config)`);
152
- console.log(` • No middleware overhead`);
153
- console.log(` • Direct res.end() (no abstractions)`);
154
- console.log(` • Server performance tuning enabled`);
155
- console.log(` • Multiple runs averaged (stable results)`);
156
- console.log('\n' + '='.repeat(60));
157
- console.log('📚 Optimizations Used:');
158
- console.log(' From: Architecture Revamp.md');
159
- console.log(' From: revamp2.md nuclear optimizations');
160
- console.log('='.repeat(60) + '\n');
161
- }
162
- catch (err) {
163
- console.error('Benchmark error:', err);
164
- process.exit(1);
165
- }
166
- process.exit(0);
167
- }
168
- run().catch((err) => {
169
- console.error(err);
170
- process.exit(1);
171
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,64 +0,0 @@
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
- async function runAutocannon(name, url) {
9
- const result = await (0, autocannon_1.default)({
10
- url,
11
- connections: 200,
12
- pipelining: 10,
13
- duration: 10,
14
- });
15
- const total = result.requests.total;
16
- const sent = result.requests.sent;
17
- const rps = result.requests.average;
18
- const p99 = result.latency.p99;
19
- console.log(`${name} bench: total=${total} (sent=${sent}) req, ` +
20
- `${rps.toFixed(0)} req/sec, p99=${p99.toFixed(1)}ms, connections=${result.connections}, pipelining=${result.pipelining}`);
21
- return {
22
- name,
23
- total,
24
- sent,
25
- rps,
26
- p99,
27
- };
28
- }
29
- async function startQHTTPXDefault() {
30
- const payloadBuffer = Buffer.from(JSON.stringify({ message: 'hello from qhttpx' }));
31
- const app = new index_1.QHTTPX({
32
- maxConcurrency: 1024,
33
- metricsEnabled: false,
34
- performanceMode: 'default',
35
- jsonSerializer: () => payloadBuffer,
36
- });
37
- app.get('/json', ({ json }) => {
38
- json({ message: 'hello from qhttpx' });
39
- });
40
- const { port } = await app.listen(0, '127.0.0.1');
41
- const url = `http://127.0.0.1:${port}/json`;
42
- return { app, url };
43
- }
44
- async function run() {
45
- const results = [];
46
- console.log('=== QHTTPX Default Mode (Optimized) ===');
47
- const defaultMode = await startQHTTPXDefault();
48
- try {
49
- const r = await runAutocannon('QHTTPX-Default', defaultMode.url);
50
- results.push(r);
51
- }
52
- finally {
53
- await defaultMode.app.close();
54
- }
55
- console.log('\n=== Summary ===');
56
- for (const r of results) {
57
- console.log(`${r.name}: ${r.rps.toFixed(0)} req/sec, p99=${r.p99.toFixed(1)}ms, total=${r.total}`);
58
- }
59
- process.exit(0);
60
- }
61
- run().catch((err) => {
62
- console.error(err);
63
- process.exit(1);
64
- });
@@ -1,222 +0,0 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const child_process_1 = require("child_process");
8
- const cluster_1 = __importDefault(require("cluster"));
9
- const os_1 = __importDefault(require("os"));
10
- const path_1 = __importDefault(require("path"));
11
- const fs_1 = __importDefault(require("fs"));
12
- const args = process.argv.slice(2);
13
- const command = args[0];
14
- if (!command) {
15
- printHelp();
16
- process.exit(1);
17
- }
18
- const targetFile = args[1];
19
- if (command === 'start') {
20
- if (!targetFile) {
21
- console.error('Error: Please provide an entry file (e.g., qhttpx start dist/index.js)');
22
- process.exit(1);
23
- }
24
- runStart(targetFile);
25
- }
26
- else if (command === 'dev') {
27
- if (!targetFile) {
28
- console.error('Error: Please provide an entry file (e.g., qhttpx dev src/index.ts)');
29
- process.exit(1);
30
- }
31
- runDev(targetFile);
32
- }
33
- else if (command === 'new') {
34
- if (!targetFile) {
35
- console.error('Error: Please provide a project name (e.g., qhttpx new my-app)');
36
- process.exit(1);
37
- }
38
- runNew(targetFile);
39
- }
40
- else {
41
- console.error(`Unknown command: ${command}`);
42
- printHelp();
43
- process.exit(1);
44
- }
45
- function printHelp() {
46
- console.log('Usage: qhttpx <command> [options]');
47
- console.log('Commands:');
48
- console.log(' start <file> Run in production cluster mode (Node.js)');
49
- console.log(' dev <file> Run in development mode with hot reload (tsx)');
50
- console.log(' new <name> Create a new QHTTPX project');
51
- }
52
- function runStart(entry) {
53
- const absoluteEntry = path_1.default.resolve(process.cwd(), entry);
54
- if (cluster_1.default.isPrimary) {
55
- const numCPUs = os_1.default.cpus().length;
56
- console.log(`[QCLI] 🚀 Starting Cluster Mode`);
57
- console.log(`[QCLI] 📂 Entry: ${absoluteEntry}`);
58
- console.log(`[QCLI] 💻 Workers: ${numCPUs}`);
59
- for (let i = 0; i < numCPUs; i++) {
60
- cluster_1.default.fork();
61
- }
62
- cluster_1.default.on('exit', (worker) => {
63
- console.log(`[QCLI] 💀 Worker ${worker.process.pid} died. Restarting...`);
64
- cluster_1.default.fork();
65
- });
66
- }
67
- else {
68
- try {
69
- // eslint-disable-next-line @typescript-eslint/no-require-imports
70
- require(absoluteEntry);
71
- }
72
- catch (err) {
73
- console.error(`[QCLI] Failed to load entry file: ${absoluteEntry}`);
74
- console.error(err);
75
- process.exit(1);
76
- }
77
- }
78
- }
79
- function runDev(entry) {
80
- const absoluteEntry = path_1.default.resolve(process.cwd(), entry);
81
- console.log(`[QCLI] 🛠️ Starting Dev Mode`);
82
- console.log(`[QCLI] 📂 Entry: ${absoluteEntry}`);
83
- let child = null;
84
- const startChild = () => {
85
- // Use tsx for dev execution
86
- child = (0, child_process_1.spawn)('npx', ['tsx', absoluteEntry], {
87
- stdio: 'inherit',
88
- shell: true,
89
- cwd: process.cwd()
90
- });
91
- child.on('close', (code) => {
92
- if (code !== 0 && code !== null) {
93
- console.log(`[QCLI] App crashed (code ${code}). Waiting for changes...`);
94
- }
95
- });
96
- };
97
- const restartChild = () => {
98
- if (child) {
99
- console.log('[QCLI] 🔄 File changed. Restarting...');
100
- // On Windows, killing a shell-spawned process is tricky.
101
- // But 'child.kill()' usually works for the handle.
102
- // For deeper tree killing, we might need a library, but let's try standard kill.
103
- child.kill();
104
- child = null;
105
- }
106
- startChild();
107
- };
108
- startChild();
109
- // Watcher
110
- let debounceTimer;
111
- const watchDir = path_1.default.dirname(absoluteEntry); // Watch the directory of the entry file (usually src)
112
- console.log(`[QCLI] 👀 Watching: ${watchDir}`);
113
- // Recursive watch is platform dependent, but 'recursive: true' works on Windows/macOS
114
- try {
115
- fs_1.default.watch(watchDir, { recursive: true }, (eventType, filename) => {
116
- if (!filename)
117
- return;
118
- // Ignore node_modules and .git
119
- if (filename.includes('node_modules') || filename.includes('.git'))
120
- return;
121
- clearTimeout(debounceTimer);
122
- debounceTimer = setTimeout(() => {
123
- restartChild();
124
- }, 200); // 200ms debounce
125
- });
126
- }
127
- catch {
128
- console.warn('[QCLI] Recursive watch not supported or failed. Falling back to simple watch.');
129
- // Fallback or just fail gracefully
130
- }
131
- }
132
- function runNew(projectName) {
133
- const projectDir = path_1.default.resolve(process.cwd(), projectName);
134
- if (fs_1.default.existsSync(projectDir)) {
135
- console.error(`Error: Directory ${projectName} already exists.`);
136
- process.exit(1);
137
- }
138
- console.log(`[QCLI] ✨ Creating new QHTTPX project in ${projectName}...`);
139
- fs_1.default.mkdirSync(projectDir);
140
- fs_1.default.mkdirSync(path_1.default.join(projectDir, 'src'));
141
- // package.json
142
- const pkgJson = {
143
- name: projectName,
144
- version: '0.0.1',
145
- type: 'module',
146
- scripts: {
147
- dev: 'qhttpx dev src/index.ts',
148
- start: 'qhttpx start dist/index.js',
149
- build: 'tsc'
150
- },
151
- dependencies: {
152
- 'qhttpx': '^1.8.6',
153
- 'dotenv': '^16.4.1'
154
- },
155
- devDependencies: {
156
- 'typescript': '^5.3.3',
157
- '@types/node': '^20.11.16',
158
- 'tsx': '^4.7.0'
159
- }
160
- };
161
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
162
- // tsconfig.json
163
- const tsConfig = {
164
- compilerOptions: {
165
- target: 'ES2022',
166
- module: 'Node16',
167
- moduleResolution: 'Node16',
168
- rootDir: 'src',
169
- outDir: 'dist',
170
- strict: true,
171
- esModuleInterop: true,
172
- skipLibCheck: true,
173
- forceConsistentCasingInFileNames: true
174
- },
175
- include: ['src']
176
- };
177
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
178
- // src/index.ts
179
- const indexTs = `import { createHttpApp } from 'qhttpx';
180
- import 'dotenv/config';
181
-
182
- const app = createHttpApp({
183
- // ⚡ Performance: Auto-coalesce duplicate requests
184
- enableRequestFusion: true,
185
-
186
- // 🛡️ Security: Built-in CORS & Rate Limiting
187
- cors: true,
188
- rateLimit: {
189
- windowMs: 15 * 60 * 1000, // 15 min
190
- max: 100, // 100 reqs per IP
191
- trustProxy: true
192
- },
193
-
194
- // 🗜️ Optimization: Gzip/Brotli compression
195
- compression: true
196
- });
197
-
198
- app.get('/', ({ json }) => {
199
- json({
200
- message: 'Welcome to QHTTPX 🚀',
201
- status: 'online',
202
- timestamp: Date.now()
203
- });
204
- });
205
-
206
- app.listen(Number(process.env.PORT) || 3000, () => {
207
- console.log(\`Server running on http://localhost:\${process.env.PORT || 3000}\`);
208
- });
209
- `;
210
- fs_1.default.writeFileSync(path_1.default.join(projectDir, 'src', 'index.ts'), indexTs);
211
- // .gitignore
212
- const gitignore = `node_modules
213
- dist
214
- .env
215
- `;
216
- fs_1.default.writeFileSync(path_1.default.join(projectDir, '.gitignore'), gitignore);
217
- console.log(`[QCLI] ✅ Project created successfully!`);
218
- console.log(`\nNext steps:`);
219
- console.log(` cd ${projectName}`);
220
- console.log(` npm install`);
221
- console.log(` npm run dev`);
222
- }