qhttpx 1.8.5 → 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 +52 -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 +11 -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 +389 -261
  32. package/dist/src/core/types.d.ts +37 -0
  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 +11 -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 -1234
  93. package/src/core/stream.ts +0 -111
  94. package/src/core/tasks.ts +0 -138
  95. package/src/core/types.ts +0 -192
  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
@@ -142,26 +142,29 @@ function runNew(projectName) {
142
142
  const pkgJson = {
143
143
  name: projectName,
144
144
  version: '0.0.1',
145
+ type: 'module',
145
146
  scripts: {
146
147
  dev: 'qhttpx dev src/index.ts',
147
148
  start: 'qhttpx start dist/index.js',
148
149
  build: 'tsc'
149
150
  },
150
151
  dependencies: {
151
- 'qhttpx': '^1.0.0'
152
+ 'qhttpx': '^1.8.6',
153
+ 'dotenv': '^16.4.1'
152
154
  },
153
155
  devDependencies: {
154
- 'typescript': '^5.0.0',
155
- '@types/node': '^20.0.0',
156
- 'tsx': '^4.0.0'
156
+ 'typescript': '^5.3.3',
157
+ '@types/node': '^20.11.16',
158
+ 'tsx': '^4.7.0'
157
159
  }
158
160
  };
159
161
  fs_1.default.writeFileSync(path_1.default.join(projectDir, 'package.json'), JSON.stringify(pkgJson, null, 2));
160
162
  // tsconfig.json
161
163
  const tsConfig = {
162
164
  compilerOptions: {
163
- target: 'ES2020',
164
- module: 'commonjs',
165
+ target: 'ES2022',
166
+ module: 'Node16',
167
+ moduleResolution: 'Node16',
165
168
  rootDir: 'src',
166
169
  outDir: 'dist',
167
170
  strict: true,
@@ -174,15 +177,34 @@ function runNew(projectName) {
174
177
  fs_1.default.writeFileSync(path_1.default.join(projectDir, 'tsconfig.json'), JSON.stringify(tsConfig, null, 2));
175
178
  // src/index.ts
176
179
  const indexTs = `import { createHttpApp } from 'qhttpx';
180
+ import 'dotenv/config';
177
181
 
178
- const app = createHttpApp();
182
+ const app = createHttpApp({
183
+ // ⚡ Performance: Auto-coalesce duplicate requests
184
+ enableRequestFusion: true,
179
185
 
180
- app.get('/', (ctx) => {
181
- ctx.json({ message: 'Hello from QHTTPX!' });
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
+ });
182
204
  });
183
205
 
184
- app.listen(3000).then(({ port }) => {
185
- console.log(\`Server running on port \${port}\`);
206
+ app.listen(Number(process.env.PORT) || 3000, () => {
207
+ console.log(\`Server running on http://localhost:\${process.env.PORT || 3000}\`);
186
208
  });
187
209
  `;
188
210
  fs_1.default.writeFileSync(path_1.default.join(projectDir, 'src', 'index.ts'), indexTs);
@@ -0,0 +1,34 @@
1
+ import { HttpError } from './types';
2
+ export declare class BadRequestException extends HttpError {
3
+ constructor(message?: string, details?: unknown);
4
+ }
5
+ export declare class UnauthorizedException extends HttpError {
6
+ constructor(message?: string, details?: unknown);
7
+ }
8
+ export declare class ForbiddenException extends HttpError {
9
+ constructor(message?: string, details?: unknown);
10
+ }
11
+ export declare class NotFoundException extends HttpError {
12
+ constructor(message?: string, details?: unknown);
13
+ }
14
+ export declare class MethodNotAllowedException extends HttpError {
15
+ constructor(message?: string, details?: unknown);
16
+ }
17
+ export declare class ConflictException extends HttpError {
18
+ constructor(message?: string, details?: unknown);
19
+ }
20
+ export declare class PayloadTooLargeException extends HttpError {
21
+ constructor(message?: string, details?: unknown);
22
+ }
23
+ export declare class UnsupportedMediaTypeException extends HttpError {
24
+ constructor(message?: string, details?: unknown);
25
+ }
26
+ export declare class TooManyRequestsException extends HttpError {
27
+ constructor(message?: string, details?: unknown);
28
+ }
29
+ export declare class InternalServerErrorException extends HttpError {
30
+ constructor(message?: string, details?: unknown);
31
+ }
32
+ export declare class ServiceUnavailableException extends HttpError {
33
+ constructor(message?: string, details?: unknown);
34
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ServiceUnavailableException = exports.InternalServerErrorException = exports.TooManyRequestsException = exports.UnsupportedMediaTypeException = exports.PayloadTooLargeException = exports.ConflictException = exports.MethodNotAllowedException = exports.NotFoundException = exports.ForbiddenException = exports.UnauthorizedException = exports.BadRequestException = void 0;
4
+ const types_1 = require("./types");
5
+ class BadRequestException extends types_1.HttpError {
6
+ constructor(message = 'Bad Request', details) {
7
+ super(400, message, { code: 'BAD_REQUEST', details });
8
+ }
9
+ }
10
+ exports.BadRequestException = BadRequestException;
11
+ class UnauthorizedException extends types_1.HttpError {
12
+ constructor(message = 'Unauthorized', details) {
13
+ super(401, message, { code: 'UNAUTHORIZED', details });
14
+ }
15
+ }
16
+ exports.UnauthorizedException = UnauthorizedException;
17
+ class ForbiddenException extends types_1.HttpError {
18
+ constructor(message = 'Forbidden', details) {
19
+ super(403, message, { code: 'FORBIDDEN', details });
20
+ }
21
+ }
22
+ exports.ForbiddenException = ForbiddenException;
23
+ class NotFoundException extends types_1.HttpError {
24
+ constructor(message = 'Not Found', details) {
25
+ super(404, message, { code: 'NOT_FOUND', details });
26
+ }
27
+ }
28
+ exports.NotFoundException = NotFoundException;
29
+ class MethodNotAllowedException extends types_1.HttpError {
30
+ constructor(message = 'Method Not Allowed', details) {
31
+ super(405, message, { code: 'METHOD_NOT_ALLOWED', details });
32
+ }
33
+ }
34
+ exports.MethodNotAllowedException = MethodNotAllowedException;
35
+ class ConflictException extends types_1.HttpError {
36
+ constructor(message = 'Conflict', details) {
37
+ super(409, message, { code: 'CONFLICT', details });
38
+ }
39
+ }
40
+ exports.ConflictException = ConflictException;
41
+ class PayloadTooLargeException extends types_1.HttpError {
42
+ constructor(message = 'Payload Too Large', details) {
43
+ super(413, message, { code: 'PAYLOAD_TOO_LARGE', details });
44
+ }
45
+ }
46
+ exports.PayloadTooLargeException = PayloadTooLargeException;
47
+ class UnsupportedMediaTypeException extends types_1.HttpError {
48
+ constructor(message = 'Unsupported Media Type', details) {
49
+ super(415, message, { code: 'UNSUPPORTED_MEDIA_TYPE', details });
50
+ }
51
+ }
52
+ exports.UnsupportedMediaTypeException = UnsupportedMediaTypeException;
53
+ class TooManyRequestsException extends types_1.HttpError {
54
+ constructor(message = 'Too Many Requests', details) {
55
+ super(429, message, { code: 'TOO_MANY_REQUESTS', details });
56
+ }
57
+ }
58
+ exports.TooManyRequestsException = TooManyRequestsException;
59
+ class InternalServerErrorException extends types_1.HttpError {
60
+ constructor(message = 'Internal Server Error', details) {
61
+ super(500, message, { code: 'INTERNAL_SERVER_ERROR', details });
62
+ }
63
+ }
64
+ exports.InternalServerErrorException = InternalServerErrorException;
65
+ class ServiceUnavailableException extends types_1.HttpError {
66
+ constructor(message = 'Service Unavailable', details) {
67
+ super(503, message, { code: 'SERVICE_UNAVAILABLE', details });
68
+ }
69
+ }
70
+ exports.ServiceUnavailableException = ServiceUnavailableException;
@@ -0,0 +1,11 @@
1
+ import net from 'net';
2
+ import { QHTTPX } from './server';
3
+ export declare class NativeAdapter {
4
+ private app;
5
+ private nativeServer;
6
+ private responsePool;
7
+ constructor(app: QHTTPX);
8
+ listen(port: number, cb?: () => void): net.Server | Promise<{
9
+ port: number;
10
+ }>;
11
+ }
@@ -0,0 +1,211 @@
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
+ exports.NativeAdapter = void 0;
7
+ const net_1 = __importDefault(require("net"));
8
+ const stream_1 = require("stream");
9
+ const native_1 = require("../native");
10
+ class MockIncomingMessage extends stream_1.Readable {
11
+ constructor(socket, method, url, headers) {
12
+ super();
13
+ this.httpVersion = '1.1';
14
+ this.socket = socket;
15
+ this.method = method;
16
+ this.url = url;
17
+ this.headers = headers;
18
+ }
19
+ _read() {
20
+ // No-op, data is pushed manually
21
+ }
22
+ }
23
+ class MockServerResponse extends stream_1.Writable {
24
+ constructor(socket, nativeServer) {
25
+ super();
26
+ this.statusCode = 200;
27
+ this.headersSent = false;
28
+ this.headers = {};
29
+ this.socket = socket;
30
+ this.nativeServer = nativeServer;
31
+ }
32
+ setHeader(name, value) {
33
+ this.headers[name.toLowerCase()] = value;
34
+ return this;
35
+ }
36
+ getHeader(name) {
37
+ return this.headers[name.toLowerCase()];
38
+ }
39
+ getHeaders() {
40
+ return { ...this.headers };
41
+ }
42
+ hasHeader(name) {
43
+ return Object.prototype.hasOwnProperty.call(this.headers, name.toLowerCase());
44
+ }
45
+ removeHeader(name) {
46
+ delete this.headers[name.toLowerCase()];
47
+ }
48
+ writeHead(statusCode, headers) {
49
+ this.statusCode = statusCode;
50
+ if (headers) {
51
+ for (const key in headers) {
52
+ this.setHeader(key, headers[key]);
53
+ }
54
+ }
55
+ return this;
56
+ }
57
+ reset(socket) {
58
+ this.socket = socket;
59
+ this.statusCode = 200;
60
+ this.headersSent = false;
61
+ this.headers = {};
62
+ this.removeAllListeners();
63
+ }
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ _write(chunk, encoding, callback) {
66
+ if (!this.headersSent) {
67
+ this.sendHeaders();
68
+ }
69
+ this.socket.write(chunk, encoding, callback);
70
+ }
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ end(arg1, arg2, arg3) {
73
+ if (arg1 && typeof arg1 !== 'function') {
74
+ if (!this.headersSent) {
75
+ // Optimization: Use native createResponse / createJSONResponse if possible
76
+ try {
77
+ let respBuffer;
78
+ // Check for JSON object (not buffer/string)
79
+ if (typeof arg1 === 'object' && !Buffer.isBuffer(arg1)) {
80
+ respBuffer = this.nativeServer.createJSONResponse(arg1);
81
+ }
82
+ else {
83
+ const body = arg1;
84
+ const headers = {};
85
+ for (const k in this.headers) {
86
+ const v = this.headers[k];
87
+ headers[k] = Array.isArray(v) ? v.join(', ') : String(v);
88
+ }
89
+ respBuffer = this.nativeServer.createResponse(this.statusCode, headers, body);
90
+ }
91
+ // Try direct writeResponse if FD is available
92
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
93
+ const fd = this.socket._handle?.fd;
94
+ if (typeof fd === 'number' && fd >= 0) {
95
+ this.nativeServer.writeResponse(fd, [respBuffer]);
96
+ }
97
+ else {
98
+ this.socket.write(respBuffer);
99
+ }
100
+ this.headersSent = true;
101
+ if (arg2 && typeof arg2 === 'function')
102
+ arg2();
103
+ else if (arg3 && typeof arg3 === 'function')
104
+ arg3();
105
+ return this;
106
+ }
107
+ catch {
108
+ // Fallback
109
+ }
110
+ }
111
+ this.write(arg1, arg2);
112
+ }
113
+ if (!this.headersSent) {
114
+ this.sendHeaders();
115
+ }
116
+ super.end();
117
+ if (arg1 && typeof arg1 === 'function')
118
+ arg1();
119
+ else if (arg2 && typeof arg2 === 'function')
120
+ arg2();
121
+ else if (arg3 && typeof arg3 === 'function')
122
+ arg3();
123
+ return this;
124
+ }
125
+ sendHeaders() {
126
+ let head = `HTTP/1.1 ${this.statusCode} OK\r\n`; // Status msg todo
127
+ for (const key in this.headers) {
128
+ const val = this.headers[key];
129
+ if (Array.isArray(val)) {
130
+ for (const v of val) {
131
+ head += `${key}: ${v}\r\n`;
132
+ }
133
+ }
134
+ else {
135
+ head += `${key}: ${val}\r\n`;
136
+ }
137
+ }
138
+ head += '\r\n';
139
+ this.socket.write(head);
140
+ this.headersSent = true;
141
+ }
142
+ }
143
+ class MockResponsePool {
144
+ constructor(nativeServer) {
145
+ this.pool = [];
146
+ this.nativeServer = nativeServer;
147
+ }
148
+ acquire(socket) {
149
+ const res = this.pool.pop();
150
+ if (res) {
151
+ res.reset(socket);
152
+ return res;
153
+ }
154
+ return new MockServerResponse(socket, this.nativeServer);
155
+ }
156
+ release(res) {
157
+ // Simple cap to prevent memory leak if something goes wrong
158
+ if (this.pool.length < 2000) {
159
+ this.pool.push(res);
160
+ }
161
+ }
162
+ }
163
+ class NativeAdapter {
164
+ constructor(app) {
165
+ this.app = app;
166
+ this.nativeServer = new native_1.NativeServer();
167
+ this.responsePool = new MockResponsePool(this.nativeServer);
168
+ }
169
+ listen(port, cb) {
170
+ if (!this.nativeServer.isAvailable) {
171
+ console.warn('Native server not available, falling back to Node.js HTTP');
172
+ return this.app.listen(port, cb);
173
+ }
174
+ const server = net_1.default.createServer((socket) => {
175
+ let buffer = Buffer.alloc(0);
176
+ socket.on('data', (chunk) => {
177
+ buffer = buffer.length === 0 ? chunk : Buffer.concat([buffer, chunk]);
178
+ // Try parsing
179
+ const res = this.nativeServer.parse(buffer);
180
+ if (res) {
181
+ // Parsed successfully
182
+ const req = new MockIncomingMessage(socket, res.method, res.path, res.headers);
183
+ const response = this.responsePool.acquire(socket);
184
+ response.on('finish', () => {
185
+ this.responsePool.release(response);
186
+ });
187
+ // Push body if any
188
+ if (res.bodyOffset < buffer.length) {
189
+ req.push(buffer.slice(res.bodyOffset));
190
+ }
191
+ req.push(null); // End of body (assuming single packet for now or content-length handling needed for real impl)
192
+ // Reset buffer for pipelining support (not implemented here, assuming connection: close or one req per packet for simplicity)
193
+ buffer = Buffer.alloc(0);
194
+ // Dispatch to QHTTPX
195
+ this.app.handleRequest(req, response);
196
+ }
197
+ else if (res === null) {
198
+ // Error
199
+ socket.destroy();
200
+ }
201
+ // else undefined -> partial, wait for more data
202
+ });
203
+ socket.on('error', () => {
204
+ // console.error(err);
205
+ });
206
+ });
207
+ server.listen(port, cb);
208
+ return server;
209
+ }
210
+ }
211
+ exports.NativeAdapter = NativeAdapter;
@@ -1,9 +1,53 @@
1
- import http from 'http';
1
+ import http, { IncomingMessage, ServerResponse, IncomingHttpHeaders } from 'http';
2
+ import { URL } from 'url';
2
3
  import { WebSocketManager } from './websocket';
4
+ import { Validator } from '../validation/types';
3
5
  import { OpenAPIOptions } from '../openapi/generator';
4
- import { HTTPMethod, QHTTPXErrorHandler, QHTTPXHandler, QHTTPXMethodNotAllowedHandler, QHTTPXMiddleware, QHTTPXNotFoundHandler, QHTTPXOptions, QHTTPXRouteOptions, QHTTPXPlugin, QHTTPXPluginOptions } from './types';
6
+ import { HTTPMethod, QHTTPXContext, QHTTPXErrorHandler, QHTTPXHandler, QHTTPXMethodNotAllowedHandler, QHTTPXMiddleware, QHTTPXNotFoundHandler, QHTTPXOptions, QHTTPXRouteOptions, QHTTPXPlugin, QHTTPXPluginOptions, CookieOptions, QHTTPXFile } from './types';
5
7
  import { Logger } from './logger';
8
+ export declare class QHTTPXContextImpl implements QHTTPXContext {
9
+ req: IncomingMessage;
10
+ res: ServerResponse;
11
+ headers: IncomingHttpHeaders;
12
+ method: HTTPMethod;
13
+ params: Record<string, string>;
14
+ query: Record<string, string | string[]>;
15
+ body: unknown;
16
+ files?: Record<string, QHTTPXFile | QHTTPXFile[]>;
17
+ cookies: Record<string, string>;
18
+ private _state;
19
+ requestId: string | undefined;
20
+ requestStart: number | undefined;
21
+ serializer?: (value: unknown) => string;
22
+ disableAutoEnd?: boolean;
23
+ path: string;
24
+ error?: Error;
25
+ next?: () => Promise<void>;
26
+ private _url;
27
+ private _ip;
28
+ private _app;
29
+ private _appJsonSerializer;
30
+ constructor(app: QHTTPX);
31
+ get bufferPool(): any;
32
+ get db(): any;
33
+ get state(): Record<string, unknown>;
34
+ set state(v: Record<string, unknown>);
35
+ get ip(): string;
36
+ set ip(v: string);
37
+ get url(): URL;
38
+ set url(v: URL);
39
+ json(payload: unknown, status?: number): void;
40
+ send(payload: string | Buffer, status?: number): void;
41
+ html(payload: string, status?: number): void;
42
+ redirect(url: string, status?: number): void;
43
+ setCookie(name: string, value: string, options: CookieOptions | undefined): void;
44
+ render(view: string, locals?: Record<string, unknown>): Promise<void>;
45
+ validate<T>(schema: unknown, data?: unknown): Promise<T>;
46
+ reset(): void;
47
+ }
6
48
  export declare class QHTTPX {
49
+ private static readonly EMPTY_PARAMS;
50
+ private static readonly EMPTY_MATCH;
7
51
  private readonly options;
8
52
  private readonly server;
9
53
  readonly logger: Logger;
@@ -24,11 +68,13 @@ export declare class QHTTPX {
24
68
  private readonly onBeforeShutdownHooks;
25
69
  private readonly onShutdownHooks;
26
70
  private nextRequestId;
71
+ private requestCounter;
27
72
  private readonly wsManager;
28
73
  private readonly ultraMode;
29
74
  private readonly batchExecutor?;
30
75
  private readonly fusion?;
31
- private readonly validator;
76
+ readonly validator: Validator;
77
+ private readonly poolLimit;
32
78
  constructor(options?: QHTTPXOptions);
33
79
  get serverInstance(): http.Server;
34
80
  get websocket(): WebSocketManager;
@@ -82,7 +128,9 @@ export declare class QHTTPX {
82
128
  private createContext;
83
129
  private acquireContext;
84
130
  private releaseContext;
85
- private handleRequest;
131
+ private handleNoMatch;
132
+ handleRequest(req: IncomingMessage, res: ServerResponse): void;
133
+ private dispatch;
86
134
  private handleUpgrade;
87
135
  private runLifecycleHooks;
88
136
  private handleError;