qhttpx 1.8.12 → 1.9.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 (206) hide show
  1. package/package.json +12 -3
  2. package/prebuilds/darwin-arm64/qhttpx.node +0 -0
  3. package/prebuilds/linux-x64/qhttpx.node +0 -0
  4. package/prebuilds/win32-x64/qhttpx.node +0 -0
  5. package/src/native/index.ts +104 -24
  6. package/src/native/picohttpparser.h +5 -0
  7. package/src/native/server.cc +2 -0
  8. package/dist/examples/api-server.d.ts +0 -1
  9. package/dist/examples/api-server.js +0 -77
  10. package/dist/examples/basic.d.ts +0 -1
  11. package/dist/examples/basic.js +0 -10
  12. package/dist/examples/compression.d.ts +0 -1
  13. package/dist/examples/compression.js +0 -17
  14. package/dist/examples/cors.d.ts +0 -1
  15. package/dist/examples/cors.js +0 -19
  16. package/dist/examples/errors.d.ts +0 -1
  17. package/dist/examples/errors.js +0 -25
  18. package/dist/examples/file-upload.d.ts +0 -1
  19. package/dist/examples/file-upload.js +0 -24
  20. package/dist/examples/fusion.d.ts +0 -1
  21. package/dist/examples/fusion.js +0 -21
  22. package/dist/examples/rate-limiting.d.ts +0 -1
  23. package/dist/examples/rate-limiting.js +0 -17
  24. package/dist/examples/validation.d.ts +0 -1
  25. package/dist/examples/validation.js +0 -23
  26. package/dist/examples/websockets.d.ts +0 -1
  27. package/dist/examples/websockets.js +0 -20
  28. package/dist/package.json +0 -101
  29. package/dist/src/benchmarks/quantam-users.d.ts +0 -1
  30. package/dist/src/benchmarks/quantam-users.js +0 -56
  31. package/dist/src/benchmarks/simple-json.d.ts +0 -1
  32. package/dist/src/benchmarks/simple-json.js +0 -60
  33. package/dist/src/benchmarks/ultra-mode.d.ts +0 -1
  34. package/dist/src/benchmarks/ultra-mode.js +0 -94
  35. package/dist/src/cli/index.d.ts +0 -2
  36. package/dist/src/cli/index.js +0 -222
  37. package/dist/src/client/index.d.ts +0 -17
  38. package/dist/src/client/index.js +0 -72
  39. package/dist/src/core/batch.d.ts +0 -24
  40. package/dist/src/core/batch.js +0 -97
  41. package/dist/src/core/body-parser.d.ts +0 -15
  42. package/dist/src/core/body-parser.js +0 -121
  43. package/dist/src/core/buffer-pool.d.ts +0 -41
  44. package/dist/src/core/buffer-pool.js +0 -70
  45. package/dist/src/core/config.d.ts +0 -7
  46. package/dist/src/core/config.js +0 -50
  47. package/dist/src/core/errors.d.ts +0 -34
  48. package/dist/src/core/errors.js +0 -70
  49. package/dist/src/core/fusion.d.ts +0 -14
  50. package/dist/src/core/fusion.js +0 -183
  51. package/dist/src/core/logger.d.ts +0 -22
  52. package/dist/src/core/logger.js +0 -49
  53. package/dist/src/core/metrics.d.ts +0 -45
  54. package/dist/src/core/metrics.js +0 -111
  55. package/dist/src/core/native-adapter.d.ts +0 -11
  56. package/dist/src/core/native-adapter.js +0 -211
  57. package/dist/src/core/resources.d.ts +0 -9
  58. package/dist/src/core/resources.js +0 -25
  59. package/dist/src/core/scheduler.d.ts +0 -34
  60. package/dist/src/core/scheduler.js +0 -85
  61. package/dist/src/core/scope.d.ts +0 -26
  62. package/dist/src/core/scope.js +0 -68
  63. package/dist/src/core/serializer.d.ts +0 -10
  64. package/dist/src/core/serializer.js +0 -44
  65. package/dist/src/core/server.d.ts +0 -138
  66. package/dist/src/core/server.js +0 -1082
  67. package/dist/src/core/stream.d.ts +0 -15
  68. package/dist/src/core/stream.js +0 -71
  69. package/dist/src/core/tasks.d.ts +0 -29
  70. package/dist/src/core/tasks.js +0 -87
  71. package/dist/src/core/types.d.ts +0 -173
  72. package/dist/src/core/types.js +0 -19
  73. package/dist/src/core/websocket.d.ts +0 -25
  74. package/dist/src/core/websocket.js +0 -86
  75. package/dist/src/core/worker-queue.d.ts +0 -41
  76. package/dist/src/core/worker-queue.js +0 -73
  77. package/dist/src/database/adapters/memory.d.ts +0 -21
  78. package/dist/src/database/adapters/memory.js +0 -90
  79. package/dist/src/database/adapters/mongo.d.ts +0 -11
  80. package/dist/src/database/adapters/mongo.js +0 -141
  81. package/dist/src/database/adapters/postgres.d.ts +0 -10
  82. package/dist/src/database/adapters/postgres.js +0 -111
  83. package/dist/src/database/adapters/sqlite.d.ts +0 -10
  84. package/dist/src/database/adapters/sqlite.js +0 -42
  85. package/dist/src/database/coalescer.d.ts +0 -14
  86. package/dist/src/database/coalescer.js +0 -134
  87. package/dist/src/database/manager.d.ts +0 -35
  88. package/dist/src/database/manager.js +0 -87
  89. package/dist/src/database/types.d.ts +0 -20
  90. package/dist/src/database/types.js +0 -2
  91. package/dist/src/index.d.ts +0 -50
  92. package/dist/src/index.js +0 -91
  93. package/dist/src/middleware/compression.d.ts +0 -2
  94. package/dist/src/middleware/compression.js +0 -133
  95. package/dist/src/middleware/cors.d.ts +0 -2
  96. package/dist/src/middleware/cors.js +0 -66
  97. package/dist/src/middleware/presets.d.ts +0 -16
  98. package/dist/src/middleware/presets.js +0 -52
  99. package/dist/src/middleware/rate-limit.d.ts +0 -14
  100. package/dist/src/middleware/rate-limit.js +0 -83
  101. package/dist/src/middleware/security.d.ts +0 -21
  102. package/dist/src/middleware/security.js +0 -69
  103. package/dist/src/middleware/static.d.ts +0 -11
  104. package/dist/src/middleware/static.js +0 -191
  105. package/dist/src/native/index.d.ts +0 -29
  106. package/dist/src/native/index.js +0 -64
  107. package/dist/src/openapi/generator.d.ts +0 -19
  108. package/dist/src/openapi/generator.js +0 -149
  109. package/dist/src/router/radix-router.d.ts +0 -18
  110. package/dist/src/router/radix-router.js +0 -89
  111. package/dist/src/router/radix-tree.d.ts +0 -18
  112. package/dist/src/router/radix-tree.js +0 -131
  113. package/dist/src/router/router.d.ts +0 -34
  114. package/dist/src/router/router.js +0 -186
  115. package/dist/src/testing/index.d.ts +0 -25
  116. package/dist/src/testing/index.js +0 -84
  117. package/dist/src/utils/cookies.d.ts +0 -3
  118. package/dist/src/utils/cookies.js +0 -59
  119. package/dist/src/utils/logger.d.ts +0 -12
  120. package/dist/src/utils/logger.js +0 -45
  121. package/dist/src/utils/signals.d.ts +0 -6
  122. package/dist/src/utils/signals.js +0 -31
  123. package/dist/src/utils/sse.d.ts +0 -6
  124. package/dist/src/utils/sse.js +0 -32
  125. package/dist/src/validation/index.d.ts +0 -3
  126. package/dist/src/validation/index.js +0 -19
  127. package/dist/src/validation/simple.d.ts +0 -5
  128. package/dist/src/validation/simple.js +0 -102
  129. package/dist/src/validation/types.d.ts +0 -32
  130. package/dist/src/validation/types.js +0 -12
  131. package/dist/src/validation/zod.d.ts +0 -4
  132. package/dist/src/validation/zod.js +0 -18
  133. package/dist/src/views/index.d.ts +0 -1
  134. package/dist/src/views/index.js +0 -17
  135. package/dist/src/views/types.d.ts +0 -3
  136. package/dist/src/views/types.js +0 -2
  137. package/dist/tests/adapters.test.d.ts +0 -1
  138. package/dist/tests/adapters.test.js +0 -106
  139. package/dist/tests/batch.test.d.ts +0 -1
  140. package/dist/tests/batch.test.js +0 -117
  141. package/dist/tests/body-parser.test.d.ts +0 -1
  142. package/dist/tests/body-parser.test.js +0 -52
  143. package/dist/tests/compression-sse.test.d.ts +0 -1
  144. package/dist/tests/compression-sse.test.js +0 -87
  145. package/dist/tests/cookies.test.d.ts +0 -1
  146. package/dist/tests/cookies.test.js +0 -63
  147. package/dist/tests/cors.test.d.ts +0 -1
  148. package/dist/tests/cors.test.js +0 -55
  149. package/dist/tests/database.test.d.ts +0 -1
  150. package/dist/tests/database.test.js +0 -80
  151. package/dist/tests/dx.test.d.ts +0 -1
  152. package/dist/tests/dx.test.js +0 -114
  153. package/dist/tests/ecosystem.test.d.ts +0 -1
  154. package/dist/tests/ecosystem.test.js +0 -133
  155. package/dist/tests/features.test.d.ts +0 -1
  156. package/dist/tests/features.test.js +0 -47
  157. package/dist/tests/fusion.test.d.ts +0 -1
  158. package/dist/tests/fusion.test.js +0 -92
  159. package/dist/tests/http-basic.test.d.ts +0 -1
  160. package/dist/tests/http-basic.test.js +0 -124
  161. package/dist/tests/logger.test.d.ts +0 -1
  162. package/dist/tests/logger.test.js +0 -33
  163. package/dist/tests/middleware.test.d.ts +0 -1
  164. package/dist/tests/middleware.test.js +0 -109
  165. package/dist/tests/native-adapter.test.d.ts +0 -1
  166. package/dist/tests/native-adapter.test.js +0 -71
  167. package/dist/tests/observability.test.d.ts +0 -1
  168. package/dist/tests/observability.test.js +0 -59
  169. package/dist/tests/openapi.test.d.ts +0 -1
  170. package/dist/tests/openapi.test.js +0 -64
  171. package/dist/tests/plugin.test.d.ts +0 -1
  172. package/dist/tests/plugin.test.js +0 -65
  173. package/dist/tests/plugins.test.d.ts +0 -1
  174. package/dist/tests/plugins.test.js +0 -71
  175. package/dist/tests/rate-limit.test.d.ts +0 -1
  176. package/dist/tests/rate-limit.test.js +0 -77
  177. package/dist/tests/resources.test.d.ts +0 -1
  178. package/dist/tests/resources.test.js +0 -47
  179. package/dist/tests/scheduler.test.d.ts +0 -1
  180. package/dist/tests/scheduler.test.js +0 -46
  181. package/dist/tests/schema-routes.test.d.ts +0 -1
  182. package/dist/tests/schema-routes.test.js +0 -77
  183. package/dist/tests/security.test.d.ts +0 -1
  184. package/dist/tests/security.test.js +0 -83
  185. package/dist/tests/server-db.test.d.ts +0 -1
  186. package/dist/tests/server-db.test.js +0 -72
  187. package/dist/tests/smoke.test.d.ts +0 -1
  188. package/dist/tests/smoke.test.js +0 -10
  189. package/dist/tests/sqlite-fusion.test.d.ts +0 -1
  190. package/dist/tests/sqlite-fusion.test.js +0 -92
  191. package/dist/tests/static.test.d.ts +0 -1
  192. package/dist/tests/static.test.js +0 -102
  193. package/dist/tests/stream.test.d.ts +0 -1
  194. package/dist/tests/stream.test.js +0 -44
  195. package/dist/tests/task-metrics.test.d.ts +0 -1
  196. package/dist/tests/task-metrics.test.js +0 -53
  197. package/dist/tests/tasks.test.d.ts +0 -1
  198. package/dist/tests/tasks.test.js +0 -62
  199. package/dist/tests/testing.test.d.ts +0 -1
  200. package/dist/tests/testing.test.js +0 -47
  201. package/dist/tests/validation.test.d.ts +0 -1
  202. package/dist/tests/validation.test.js +0 -107
  203. package/dist/tests/websocket.test.d.ts +0 -1
  204. package/dist/tests/websocket.test.js +0 -146
  205. package/dist/vitest.config.d.ts +0 -2
  206. package/dist/vitest.config.js +0 -9
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "qhttpx",
3
- "version": "1.8.12",
4
- "description": "The High-Performance Hybrid HTTP Runtime for Node.js. Built for extreme concurrency, request fusion, and zero-overhead scaling.",
3
+ "version": "1.9.0",
4
+ "description": "The Ultra-Fast HTTP Framework for Node.js",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
7
7
  "exports": {
@@ -17,6 +17,8 @@
17
17
  "files": [
18
18
  "dist",
19
19
  "src/native",
20
+ "prebuilds",
21
+ "scripts",
20
22
  "binding.gyp",
21
23
  "README.md",
22
24
  "LICENSE",
@@ -27,6 +29,7 @@
27
29
  "doc": "docs"
28
30
  },
29
31
  "scripts": {
32
+ "prebuild": "prebuildify --napi --strip",
30
33
  "build": "tsc -p tsconfig.json",
31
34
  "lint": "eslint src tests --ext .ts",
32
35
  "test": "vitest run",
@@ -63,6 +66,10 @@
63
66
  ],
64
67
  "author": "Quantam Open Source",
65
68
  "license": "MIT",
69
+ "repository": {
70
+ "type": "git",
71
+ "url": "https://github.com/Quantam-Open-Source/qhttpx"
72
+ },
66
73
  "type": "commonjs",
67
74
  "devDependencies": {
68
75
  "@types/autocannon": "^7.12.7",
@@ -81,7 +88,9 @@
81
88
  "eslint-config-prettier": "^10.1.8",
82
89
  "eslint-plugin-prettier": "^5.5.5",
83
90
  "mongodb": "^7.0.0",
91
+ "node-addon-api": "^8.5.0",
84
92
  "pg": "^8.17.1",
93
+ "prebuildify": "^6.0.1",
85
94
  "prettier": "^3.8.0",
86
95
  "tsx": "^4.21.0",
87
96
  "typescript": "^5.9.3",
@@ -91,7 +100,7 @@
91
100
  "better-sqlite3": "^12.6.2",
92
101
  "busboy": "^1.6.0",
93
102
  "fast-json-stringify": "^5.15.1",
94
- "node-addon-api": "^8.5.0",
103
+ "node-gyp-build": "^4.8.4",
95
104
  "pino": "^10.2.0",
96
105
  "pino-pretty": "^13.1.3",
97
106
  "quantam-async": "^0.1.1",
Binary file
Binary file
@@ -1,4 +1,9 @@
1
+ import path from 'path';
2
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
3
+ const loadBinding = require('node-gyp-build');
1
4
 
5
+ // EXPECTED ABI VERSION
6
+ const EXPECTED_ABI = 1;
2
7
 
3
8
  export interface NativeServerBinding {
4
9
  parse(buffer: Buffer): {
@@ -17,23 +22,24 @@ export interface NativeServerBinding {
17
22
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
23
  let nativeBinding: any = null;
19
24
 
20
- // Use try/catch with module.createRequire if import.meta is not available in some build targets
21
- // However, since we are in a TS module that might be commonjs or esm
22
- // We'll use a safer approach for require
23
25
  try {
24
- const req = require;
26
+ // Look for prebuilds or built binary in root
27
+ const rootDir = __dirname.includes('dist')
28
+ ? path.join(__dirname, '..', '..', '..')
29
+ : path.join(__dirname, '..', '..');
30
+
31
+ const binding = loadBinding(rootDir);
25
32
 
26
- try {
27
- nativeBinding = req('../../build/Release/qhttpx_native.node');
28
- } catch {
29
- try {
30
- nativeBinding = req('../../build/Debug/qhttpx_native.node');
31
- } catch {
32
- // Ignored
33
- }
33
+ // 5. Version lock the ABI
34
+ if (binding && binding.abi === EXPECTED_ABI) {
35
+ nativeBinding = binding;
36
+ } else if (binding) {
37
+ // Version mismatch - disable native
38
+ // console.warn(`QHTTPX: Native ABI mismatch (Expected: ${EXPECTED_ABI}, Got: ${binding.abi}). Falling back to JS.`);
39
+ nativeBinding = null;
34
40
  }
35
41
  } catch {
36
- // Ignored
42
+ // Graceful fallback to JS implementation
37
43
  }
38
44
 
39
45
  export class NativeServer {
@@ -41,7 +47,11 @@ export class NativeServer {
41
47
 
42
48
  constructor() {
43
49
  if (nativeBinding && nativeBinding.NativeServer) {
44
- this.binding = new nativeBinding.NativeServer();
50
+ try {
51
+ this.binding = new nativeBinding.NativeServer();
52
+ } catch {
53
+ this.binding = null;
54
+ }
45
55
  } else {
46
56
  this.binding = null;
47
57
  }
@@ -51,28 +61,98 @@ export class NativeServer {
51
61
  return this.binding !== null;
52
62
  }
53
63
 
64
+ // 4. Guard every native call
54
65
  public parse(buffer: Buffer) {
55
- if (!this.binding) throw new Error('Native bindings not available');
56
- return this.binding.parse(buffer);
66
+ if (this.binding) {
67
+ try {
68
+ return this.binding.parse(buffer);
69
+ } catch {
70
+ this.disableNative();
71
+ }
72
+ }
73
+ // Fallback: If native parse fails, we return null.
74
+ // The NativeAdapter will see null and might close the connection or handle error.
75
+ // We cannot easily implement a full HTTP parser in JS here without adding dependencies.
76
+ // But since NativeAdapter falls back to http.Server if !isAvailable,
77
+ // disabling native here ensures subsequent requests use the safe path.
78
+ return null;
57
79
  }
58
80
 
59
81
  public createResponse(statusCode: number, headers: Record<string, string>, body?: string | Buffer) {
60
- if (!this.binding) throw new Error('Native bindings not available');
61
- return this.binding.createResponse(statusCode, headers, body);
82
+ if (this.binding) {
83
+ try {
84
+ return this.binding.createResponse(statusCode, headers, body);
85
+ } catch {
86
+ this.disableNative();
87
+ }
88
+ }
89
+ return this.jsCreateResponse(statusCode, headers, body);
62
90
  }
63
91
 
64
92
  public createJSONResponse(obj: unknown) {
65
- if (!this.binding) throw new Error('Native bindings not available');
66
- return this.binding.createJSONResponse(obj);
93
+ if (this.binding) {
94
+ try {
95
+ return this.binding.createJSONResponse(obj);
96
+ } catch {
97
+ this.disableNative();
98
+ }
99
+ }
100
+ // Fallback: Use JSON.stringify + Buffer
101
+ return this.jsCreateJSONResponse(obj);
67
102
  }
68
103
 
69
104
  public writeResponse(fd: number, chunks: (Buffer | string)[]) {
70
- if (!this.binding) throw new Error('Native bindings not available');
71
- return this.binding.writeResponse(fd, chunks);
105
+ if (this.binding) {
106
+ try {
107
+ return this.binding.writeResponse(fd, chunks);
108
+ } catch {
109
+ this.disableNative();
110
+ }
111
+ }
112
+ // No JS fallback for raw FD writes (requires net.Socket usually)
113
+ // The caller (NativeAdapter) should handle this by using socket.write()
114
+ // We throw here so caller knows to use fallback
115
+ throw new Error('Native writeResponse not available');
72
116
  }
73
117
 
74
118
  public setCPUAffinity(cpuId: number) {
75
- if (!this.binding) throw new Error('Native bindings not available');
76
- return this.binding.setCPUAffinity(cpuId);
119
+ if (this.binding) {
120
+ try {
121
+ return this.binding.setCPUAffinity(cpuId);
122
+ } catch {
123
+ this.disableNative();
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+
129
+ private disableNative() {
130
+ this.binding = null;
131
+ // console.warn('QHTTPX: Native module disabled due to error. Falling back to JS.');
132
+ }
133
+
134
+ // --- JS Fallbacks ---
135
+
136
+ private jsCreateResponse(statusCode: number, headers: Record<string, string>, body?: string | Buffer): Buffer {
137
+ const statusMessage = statusCode === 200 ? 'OK' : 'Unknown'; // Simplified
138
+ let head = `HTTP/1.1 ${statusCode} ${statusMessage}\r\n`;
139
+ for (const [key, value] of Object.entries(headers)) {
140
+ head += `${key}: ${value}\r\n`;
141
+ }
142
+ head += '\r\n';
143
+
144
+ const headBuf = Buffer.from(head);
145
+ if (body) {
146
+ const bodyBuf = Buffer.isBuffer(body) ? body : Buffer.from(body);
147
+ return Buffer.concat([headBuf, bodyBuf]);
148
+ }
149
+ return headBuf;
150
+ }
151
+
152
+ private jsCreateJSONResponse(obj: unknown): Buffer {
153
+ const json = JSON.stringify(obj);
154
+ const contentLen = Buffer.byteLength(json);
155
+ const head = `HTTP/1.1 200 OK\r\nContent-Type: application/json\r\nContent-Length: ${contentLen}\r\n\r\n`;
156
+ return Buffer.concat([Buffer.from(head), Buffer.from(json)]);
77
157
  }
78
158
  }
@@ -30,6 +30,11 @@
30
30
 
31
31
  #include <sys/types.h>
32
32
 
33
+ #ifdef _WIN32
34
+ #include <BaseTsd.h>
35
+ typedef SSIZE_T ssize_t;
36
+ #endif
37
+
33
38
  #ifdef __cplusplus
34
39
  extern "C" {
35
40
  #endif
@@ -26,6 +26,8 @@ Napi::Object NativeServer::Init(Napi::Env env, Napi::Object exports) {
26
26
  env.SetInstanceData(constructor);
27
27
 
28
28
  exports.Set("NativeServer", func);
29
+ // Version Lock: Expose ABI version
30
+ exports.Set("abi", Napi::Number::New(env, 1));
29
31
  return exports;
30
32
  }
31
33
 
@@ -1 +0,0 @@
1
- export {};
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const index_1 = require("../src/index");
4
- const dotenv_1 = require("dotenv");
5
- // Load .env
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
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)
18
- });
19
- // 2. Global Middleware (Logging is built-in by default)
20
- // No manual app.use(rateLimit(...)) needed!
21
- // 3. Validation Schema
22
- const UserSchema = {
23
- body: {
24
- type: 'object',
25
- required: ['name', 'role'],
26
- properties: { name: { type: 'string' }, role: { type: 'string' } }
27
- }
28
- };
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 }) => {
38
- // Body is already validated and typed here
39
- json({ created: true, user: body }, 201);
40
- });
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)
50
- app.post('/upload', ({ files, json }) => {
51
- if (!files?.doc)
52
- return json({ error: 'No file' }, 400);
53
- const doc = Array.isArray(files.doc) ? files.doc[0] : files.doc;
54
- json({ filename: doc.filename, size: doc.size });
55
- });
56
- // 📡 WebSockets (Pub/Sub)
57
- app.upgrade('/chat', (ws) => {
58
- ws.join('general'); // Auto-join room
59
- ws.on('message', (msg) => {
60
- // Broadcast to room
61
- app.websocket.to('general').emit(`Echo: ${msg}`);
62
- });
63
- });
64
- // 5. Unified Error Handling
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
- }
73
- console.error(error); // Log internal error
74
- json({ error: 'Internal Server Error', handled: true }, 500);
75
- });
76
- // 6. Start Server
77
- app.listen(3000, () => console.log('🚀 Server running on http://localhost:3000'));
@@ -1 +0,0 @@
1
- export {};
@@ -1,10 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,17 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,19 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,25 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,24 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,21 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,17 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,23 +0,0 @@
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
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,20 +0,0 @@
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 DELETED
@@ -1,101 +0,0 @@
1
- {
2
- "name": "qhttpx",
3
- "version": "1.8.12",
4
- "description": "The High-Performance Hybrid HTTP Runtime for Node.js. Built for extreme concurrency, request fusion, and zero-overhead scaling.",
5
- "main": "dist/src/index.js",
6
- "types": "dist/src/index.d.ts",
7
- "exports": {
8
- ".": {
9
- "types": "./dist/src/index.d.ts",
10
- "require": "./dist/src/index.js",
11
- "default": "./dist/src/index.js"
12
- }
13
- },
14
- "bin": {
15
- "qhttpx": "./dist/src/cli/index.js"
16
- },
17
- "files": [
18
- "dist",
19
- "src/native",
20
- "binding.gyp",
21
- "README.md",
22
- "LICENSE",
23
- "CHANGELOG.md",
24
- "docs"
25
- ],
26
- "directories": {
27
- "doc": "docs"
28
- },
29
- "scripts": {
30
- "build": "tsc -p tsconfig.json",
31
- "lint": "eslint src tests --ext .ts",
32
- "test": "vitest run",
33
- "example": "npx tsx examples/api-server.ts",
34
- "bench": "npm run build && node dist/src/benchmarks/simple-json.js",
35
- "bench:quantam": "npm run build && node dist/src/benchmarks/quantam-users.js",
36
- "bench:ultra": "npm run build && node dist/src/benchmarks/ultra-mode.js"
37
- },
38
- "keywords": [
39
- "http",
40
- "server",
41
- "web",
42
- "framework",
43
- "typescript",
44
- "fast",
45
- "performance",
46
- "high-performance",
47
- "async",
48
- "concurrency",
49
- "request-fusion",
50
- "coalescing",
51
- "middleware",
52
- "websocket",
53
- "sse",
54
- "rate-limit",
55
- "rest",
56
- "api",
57
- "json",
58
- "router",
59
- "radix-tree",
60
- "scheduler",
61
- "ultra-fast",
62
- "nodejs"
63
- ],
64
- "author": "Quantam Open Source",
65
- "license": "MIT",
66
- "type": "commonjs",
67
- "devDependencies": {
68
- "@types/autocannon": "^7.12.7",
69
- "@types/better-sqlite3": "^7.6.13",
70
- "@types/busboy": "^1.5.4",
71
- "@types/ioredis": "^4.28.10",
72
- "@types/mongodb": "^4.0.6",
73
- "@types/node": "^25.0.9",
74
- "@types/pg": "^8.16.0",
75
- "@types/ws": "^8.18.1",
76
- "@typescript-eslint/eslint-plugin": "^8.53.0",
77
- "@typescript-eslint/parser": "^8.53.0",
78
- "autocannon": "^8.0.0",
79
- "dotenv": "^17.2.3",
80
- "eslint": "^9.39.2",
81
- "eslint-config-prettier": "^10.1.8",
82
- "eslint-plugin-prettier": "^5.5.5",
83
- "mongodb": "^7.0.0",
84
- "pg": "^8.17.1",
85
- "prettier": "^3.8.0",
86
- "tsx": "^4.21.0",
87
- "typescript": "^5.9.3",
88
- "vitest": "^4.0.17"
89
- },
90
- "dependencies": {
91
- "better-sqlite3": "^12.6.2",
92
- "busboy": "^1.6.0",
93
- "fast-json-stringify": "^5.15.1",
94
- "node-addon-api": "^8.5.0",
95
- "pino": "^10.2.0",
96
- "pino-pretty": "^13.1.3",
97
- "quantam-async": "^0.1.1",
98
- "ws": "^8.19.0",
99
- "zod": "^4.3.5"
100
- }
101
- }
@@ -1 +0,0 @@
1
- export {};