qhttpx 1.9.3 → 2.0.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 (98) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +17 -12
  3. package/dist/examples/api-server.js +38 -35
  4. package/dist/examples/basic.js +3 -4
  5. package/dist/examples/compression.js +6 -8
  6. package/dist/examples/cors.js +5 -6
  7. package/dist/examples/errors.js +12 -11
  8. package/dist/examples/file-upload.js +4 -6
  9. package/dist/examples/fusion.js +6 -6
  10. package/dist/examples/rate-limiting.js +10 -10
  11. package/dist/examples/validation.js +5 -6
  12. package/dist/examples/websockets.js +3 -4
  13. package/dist/package.json +3 -8
  14. package/dist/src/benchmarks/quantam-users.js +2 -2
  15. package/dist/src/benchmarks/quick-bench.js +57 -0
  16. package/dist/src/benchmarks/simple-json.js +133 -22
  17. package/dist/src/benchmarks/ultra-mode.js +8 -38
  18. package/dist/src/core/context-pool.d.ts +12 -0
  19. package/dist/src/core/context-pool.js +34 -0
  20. package/dist/src/core/fusion.js +0 -2
  21. package/dist/src/core/metrics.d.ts +1 -0
  22. package/dist/src/core/metrics.js +3 -0
  23. package/dist/src/core/scheduler.d.ts +4 -0
  24. package/dist/src/core/scheduler.js +75 -34
  25. package/dist/src/core/scope.d.ts +23 -8
  26. package/dist/src/core/scope.js +53 -14
  27. package/dist/src/core/serializer.d.ts +1 -1
  28. package/dist/src/core/serializer.js +45 -7
  29. package/dist/src/core/server.d.ts +51 -10
  30. package/dist/src/core/server.js +695 -259
  31. package/dist/src/core/timer.d.ts +11 -0
  32. package/dist/src/core/timer.js +29 -0
  33. package/dist/src/core/types.d.ts +64 -12
  34. package/dist/src/core/types.js +6 -6
  35. package/dist/src/index.d.ts +6 -4
  36. package/dist/src/index.js +19 -18
  37. package/dist/src/middleware/presets.d.ts +1 -2
  38. package/dist/src/middleware/presets.js +1 -1
  39. package/dist/src/middleware/security.d.ts +2 -13
  40. package/dist/src/middleware/security.js +6 -1
  41. package/dist/src/router/radix-tree.d.ts +5 -2
  42. package/dist/src/router/radix-tree.js +58 -14
  43. package/dist/src/router/router.d.ts +5 -2
  44. package/dist/src/router/router.js +80 -63
  45. package/dist/src/utils/logger.d.ts +1 -11
  46. package/dist/tests/fusion.test.js +4 -4
  47. package/dist/tests/rate-limit.test.js +2 -2
  48. package/dist/tests/schema-routes.test.js +3 -1
  49. package/docs/AEGIS.md +18 -28
  50. package/docs/BENCHMARKS.md +8 -6
  51. package/docs/DATABASE.md +4 -4
  52. package/docs/MIDDLEWARE.md +3 -3
  53. package/docs/ROUTING.md +21 -13
  54. package/docs/VALIDATION.md +9 -31
  55. package/package.json +3 -8
  56. package/binding.gyp +0 -18
  57. package/dist/src/benchmarks/compare-frameworks.js +0 -119
  58. package/dist/src/benchmarks/compare.js +0 -288
  59. package/dist/src/buffer-pool.js +0 -70
  60. package/dist/src/config.js +0 -50
  61. package/dist/src/cookies.js +0 -59
  62. package/dist/src/core/native-adapter.d.ts +0 -11
  63. package/dist/src/core/native-adapter.js +0 -211
  64. package/dist/src/cors.js +0 -66
  65. package/dist/src/logger.js +0 -45
  66. package/dist/src/metrics.js +0 -111
  67. package/dist/src/native/index.d.ts +0 -32
  68. package/dist/src/native/index.js +0 -141
  69. package/dist/src/presets.js +0 -33
  70. package/dist/src/radix-router.js +0 -89
  71. package/dist/src/radix-tree.js +0 -81
  72. package/dist/src/resources.js +0 -25
  73. package/dist/src/router.js +0 -138
  74. package/dist/src/scheduler.js +0 -85
  75. package/dist/src/security.js +0 -69
  76. package/dist/src/server.js +0 -685
  77. package/dist/src/signals.js +0 -31
  78. package/dist/src/static.js +0 -107
  79. package/dist/src/stream.js +0 -71
  80. package/dist/src/tasks.js +0 -87
  81. package/dist/src/testing.js +0 -40
  82. package/dist/src/types.js +0 -19
  83. package/dist/src/utils/testing.js +0 -40
  84. package/dist/src/worker-queue.js +0 -73
  85. package/dist/tests/native-adapter.test.d.ts +0 -1
  86. package/dist/tests/native-adapter.test.js +0 -71
  87. package/prebuilds/darwin-arm64/qhttpx.node +0 -0
  88. package/prebuilds/linux-x64/qhttpx.node +0 -0
  89. package/prebuilds/win32-x64/qhttpx.node +0 -0
  90. package/scripts/install-native.js +0 -26
  91. package/src/native/README.md +0 -31
  92. package/src/native/addon.cc +0 -8
  93. package/src/native/index.ts +0 -158
  94. package/src/native/picohttpparser.c +0 -608
  95. package/src/native/picohttpparser.h +0 -76
  96. package/src/native/server.cc +0 -264
  97. package/src/native/server.h +0 -30
  98. /package/dist/src/benchmarks/{compare.d.ts → quick-bench.d.ts} +0 -0
@@ -1,119 +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 express_1 = __importDefault(require("express"));
9
- const index_1 = require("../index");
10
- async function runAutocannon(name, url) {
11
- const result = await (0, autocannon_1.default)({
12
- url,
13
- connections: 200,
14
- pipelining: 10,
15
- duration: 10,
16
- });
17
- const total = result.requests.total;
18
- const sent = result.requests.sent;
19
- const rps = result.requests.average;
20
- const p99 = result.latency.p99;
21
- console.log(`${name} bench: total=${total} (sent=${sent}) req, ` +
22
- `${rps.toFixed(0)} req/sec, p99=${p99.toFixed(1)}ms, connections=${result.connections}, pipelining=${result.pipelining}`);
23
- return {
24
- name,
25
- total,
26
- sent,
27
- rps,
28
- p99,
29
- };
30
- }
31
- async function startQHTTPX() {
32
- const payloadBuffer = Buffer.from(JSON.stringify({ message: 'hello from qhttpx' }));
33
- const app = new index_1.QHTTPX({
34
- maxConcurrency: 1024,
35
- metricsEnabled: false,
36
- jsonSerializer: () => payloadBuffer,
37
- });
38
- app.get('/json', (ctx) => {
39
- ctx.json({ message: 'hello from qhttpx' });
40
- });
41
- const { port } = await app.listen(0, '127.0.0.1');
42
- const url = `http://127.0.0.1:${port}/json`;
43
- return { app, url };
44
- }
45
- async function startFastify() {
46
- const app = (0, fastify_1.default)();
47
- app.get('/json', async () => {
48
- return { message: 'hello from fastify' };
49
- });
50
- await app.listen({ port: 0, host: '127.0.0.1' });
51
- const address = app.server.address();
52
- if (!address || typeof address === 'string') {
53
- throw new Error('Fastify address not available');
54
- }
55
- const url = `http://127.0.0.1:${address.port}/json`;
56
- return { app, url };
57
- }
58
- async function startExpress() {
59
- const app = (0, express_1.default)();
60
- app.get('/json', (_req, res) => {
61
- res.json({ message: 'hello from express' });
62
- });
63
- const server = await new Promise((resolve) => {
64
- const s = app.listen(0, '127.0.0.1', () => {
65
- resolve(s);
66
- });
67
- });
68
- const address = server.address();
69
- if (!address || typeof address === 'string') {
70
- throw new Error('Express address not available');
71
- }
72
- const url = `http://127.0.0.1:${address.port}/json`;
73
- return { app, url, server };
74
- }
75
- async function run() {
76
- const results = [];
77
- const qhttpx = await startQHTTPX();
78
- try {
79
- const r = await runAutocannon('QHTTPX', qhttpx.url);
80
- results.push(r);
81
- }
82
- finally {
83
- await qhttpx.app.close();
84
- }
85
- const fast = await startFastify();
86
- try {
87
- const r = await runAutocannon('Fastify', fast.url);
88
- results.push(r);
89
- }
90
- finally {
91
- await fast.app.close();
92
- }
93
- const exp = await startExpress();
94
- try {
95
- const r = await runAutocannon('Express', exp.url);
96
- results.push(r);
97
- }
98
- finally {
99
- await new Promise((resolve, reject) => {
100
- exp.server.close((err) => {
101
- if (err) {
102
- reject(err);
103
- }
104
- else {
105
- resolve();
106
- }
107
- });
108
- });
109
- }
110
- console.log('\nSummary:');
111
- for (const r of results) {
112
- console.log(`${r.name}: ${r.rps.toFixed(0)} req/sec, p99=${r.p99.toFixed(1)}ms, total=${r.total}`);
113
- }
114
- process.exit(0);
115
- }
116
- run().catch((err) => {
117
- console.error(err);
118
- process.exit(1);
119
- });
@@ -1,288 +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
- const fastify_1 = __importDefault(require("fastify"));
9
- const express_1 = __importDefault(require("express"));
10
- const hono_1 = require("hono");
11
- const node_server_1 = require("@hono/node-server");
12
- const koa_1 = __importDefault(require("koa"));
13
- const polka_1 = __importDefault(require("polka"));
14
- const http_1 = __importDefault(require("http"));
15
- const PORT = 3000;
16
- const DURATION = 300; // Testing duration
17
- const CONNECTIONS = 500; // Connections
18
- const PIPELINING = 20; // Request pipelining
19
- const results = [];
20
- function printProgress(name, timeLeft, total) {
21
- const percent = Math.max(0, Math.min(100, Math.round(((total - timeLeft) / total) * 100)));
22
- const barLength = 30;
23
- const filled = Math.round((barLength * percent) / 100);
24
- const bar = '█'.repeat(filled) + '░'.repeat(barLength - filled);
25
- // Clear line and move cursor to start
26
- process.stdout.clearLine(0);
27
- process.stdout.cursorTo(0);
28
- process.stdout.write(`${name} [${bar}] ${percent}% | Time Left: ${timeLeft}s`);
29
- }
30
- const frameworks = [
31
- {
32
- name: 'QHTTPX (Native)',
33
- control: () => {
34
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
- let app;
36
- return {
37
- start: async () => {
38
- return new Promise((resolve) => {
39
- app = (0, index_1.createHttpApp)();
40
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- app.get('/', ({ json }) => json({ hello: 'world' }));
42
- app.listen(PORT, () => resolve());
43
- });
44
- },
45
- stop: async () => {
46
- await app.close();
47
- },
48
- };
49
- },
50
- },
51
- {
52
- name: 'Fastify',
53
- control: () => {
54
- const app = (0, fastify_1.default)();
55
- app.get('/', async () => ({ hello: 'world' }));
56
- return {
57
- start: async () => {
58
- await app.listen({ port: PORT });
59
- },
60
- stop: async () => {
61
- await app.close();
62
- },
63
- };
64
- },
65
- },
66
- {
67
- name: 'Hono (Node)',
68
- control: () => {
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
- let server;
71
- return {
72
- start: async () => {
73
- const app = new hono_1.Hono();
74
- app.get('/', (c) => c.json({ hello: 'world' }));
75
- return new Promise((resolve, reject) => {
76
- try {
77
- server = (0, node_server_1.serve)({ fetch: app.fetch, port: PORT }, () => resolve());
78
- server.on('error', reject);
79
- }
80
- catch (e) {
81
- reject(e);
82
- }
83
- });
84
- },
85
- stop: async () => {
86
- return new Promise((resolve) => {
87
- if (server && typeof server.close === 'function') {
88
- server.removeAllListeners('error');
89
- server.close(() => resolve());
90
- }
91
- else {
92
- resolve();
93
- }
94
- });
95
- },
96
- };
97
- },
98
- },
99
- {
100
- name: 'Express',
101
- control: () => {
102
- let server;
103
- return {
104
- start: async () => {
105
- return new Promise((resolve) => {
106
- const app = (0, express_1.default)();
107
- app.disable('etag');
108
- app.disable('x-powered-by');
109
- app.get('/', (req, res) => res.json({ hello: 'world' }));
110
- server = app.listen(PORT, () => resolve());
111
- });
112
- },
113
- stop: async () => {
114
- return new Promise((resolve) => {
115
- server.close(() => resolve());
116
- });
117
- },
118
- };
119
- },
120
- },
121
- {
122
- name: 'Koa',
123
- control: () => {
124
- let server;
125
- return {
126
- start: async () => {
127
- return new Promise((resolve) => {
128
- const app = new koa_1.default();
129
- app.use((ctx) => {
130
- ctx.body = { hello: 'world' };
131
- });
132
- server = app.listen(PORT, () => resolve());
133
- });
134
- },
135
- stop: async () => {
136
- return new Promise((resolve) => {
137
- server.close(() => resolve());
138
- });
139
- },
140
- };
141
- },
142
- },
143
- {
144
- name: 'Polka',
145
- control: () => {
146
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
- let server;
148
- return {
149
- start: async () => {
150
- return new Promise((resolve) => {
151
- const app = (0, polka_1.default)();
152
- app.get('/', (req, res) => {
153
- res.setHeader('Content-Type', 'application/json');
154
- res.end(JSON.stringify({ hello: 'world' }));
155
- });
156
- server = app.listen(PORT, () => resolve());
157
- });
158
- },
159
- stop: async () => {
160
- return new Promise((resolve) => {
161
- server.server.close(() => resolve());
162
- });
163
- },
164
- };
165
- },
166
- },
167
- {
168
- name: 'Restify',
169
- control: () => {
170
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
171
- let server;
172
- return {
173
- start: async () => {
174
- return new Promise((resolve, reject) => {
175
- try {
176
- // eslint-disable-next-line @typescript-eslint/no-require-imports
177
- const restify = require('restify');
178
- server = restify.createServer();
179
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
180
- server.get('/', (req, res, next) => {
181
- res.send({ hello: 'world' });
182
- next();
183
- });
184
- server.listen(PORT, () => resolve());
185
- }
186
- catch (e) {
187
- reject(e);
188
- }
189
- });
190
- },
191
- stop: async () => {
192
- return new Promise((resolve) => {
193
- if (server)
194
- server.close(() => resolve());
195
- else
196
- resolve();
197
- });
198
- },
199
- };
200
- },
201
- },
202
- {
203
- name: 'Node Native',
204
- control: () => {
205
- let server;
206
- return {
207
- start: async () => {
208
- return new Promise((resolve) => {
209
- server = http_1.default.createServer((req, res) => {
210
- res.setHeader('Content-Type', 'application/json');
211
- res.end(JSON.stringify({ hello: 'world' }));
212
- });
213
- server.listen(PORT, () => resolve());
214
- });
215
- },
216
- stop: async () => {
217
- return new Promise((resolve) => {
218
- server.close(() => resolve());
219
- });
220
- },
221
- };
222
- },
223
- },
224
- ];
225
- async function run() {
226
- const origLog = console.log;
227
- const origError = console.error;
228
- const origWarn = console.warn;
229
- origLog(`\nStarting Benchmark Comparison`);
230
- origLog(`Duration: ${DURATION}s | Connections: ${CONNECTIONS}\n`);
231
- for (const fw of frameworks) {
232
- origLog(`Preparing ${fw.name}...`);
233
- const ctrl = fw.control();
234
- try {
235
- await ctrl.start();
236
- // Wait for server to be fully ready
237
- await new Promise((r) => setTimeout(r, 500));
238
- const startTime = Date.now();
239
- const interval = setInterval(() => {
240
- const elapsed = (Date.now() - startTime) / 1000;
241
- const timeLeft = Math.max(0, Math.round(DURATION - elapsed));
242
- printProgress(fw.name, timeLeft, DURATION);
243
- }, 200);
244
- // Suppress autocannon logs
245
- console.log = () => { };
246
- console.error = () => { };
247
- console.warn = () => { };
248
- const result = await (0, autocannon_1.default)({
249
- url: `http://localhost:${PORT}`,
250
- connections: CONNECTIONS,
251
- pipelining: PIPELINING,
252
- duration: DURATION,
253
- });
254
- console.log = origLog;
255
- console.error = origError;
256
- console.warn = origWarn;
257
- clearInterval(interval);
258
- printProgress(fw.name, 0, DURATION);
259
- origLog('\n');
260
- results.push({
261
- name: fw.name,
262
- reqs: result.requests.average,
263
- latency: result.latency.average,
264
- p50: result.latency.p50,
265
- p90: result.latency.p90,
266
- p99: result.latency.p99,
267
- max: result.latency.max,
268
- throughput: (result.throughput.average / 1024 / 1024).toFixed(2),
269
- });
270
- await ctrl.stop();
271
- }
272
- catch (err) {
273
- console.log = origLog;
274
- console.error = origError;
275
- console.warn = origWarn;
276
- origError(`Error benchmarking ${fw.name}:`, err);
277
- try {
278
- await ctrl.stop();
279
- }
280
- catch { }
281
- }
282
- // Cool down - allow time for port to be released
283
- await new Promise((r) => setTimeout(r, 3000));
284
- }
285
- origLog('\n--- Final Results ---');
286
- console.table(results.sort((a, b) => b.reqs - a.reqs));
287
- }
288
- run().catch(console.error);
@@ -1,70 +0,0 @@
1
- "use strict";
2
- /**
3
- * Buffer pool for response bodies (small, medium, large).
4
- * Reuses allocated buffers to reduce GC pressure.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.BufferPool = void 0;
8
- class BufferPool {
9
- constructor(config = {}) {
10
- this.smallBuffers = [];
11
- this.mediumBuffers = [];
12
- this.largeBuffers = [];
13
- this.smallSize = config.smallSize ?? 4096; // 4KB
14
- this.mediumSize = config.mediumSize ?? 65536; // 64KB
15
- this.largeSize = config.largeSize ?? 262144; // 256KB
16
- this.smallPoolSize = config.smallPoolSize ?? 32;
17
- this.mediumPoolSize = config.mediumPoolSize ?? 8;
18
- this.largePoolSize = config.largePoolSize ?? 2;
19
- // Preallocate buffers
20
- for (let i = 0; i < this.smallPoolSize; i += 1) {
21
- this.smallBuffers.push(Buffer.allocUnsafe(this.smallSize));
22
- }
23
- for (let i = 0; i < this.mediumPoolSize; i += 1) {
24
- this.mediumBuffers.push(Buffer.allocUnsafe(this.mediumSize));
25
- }
26
- for (let i = 0; i < this.largePoolSize; i += 1) {
27
- this.largeBuffers.push(Buffer.allocUnsafe(this.largeSize));
28
- }
29
- }
30
- /**
31
- * Acquire a buffer suitable for the given size.
32
- * Returns a buffer from the appropriate pool.
33
- */
34
- acquire(size) {
35
- if (size <= this.smallSize) {
36
- return this.smallBuffers.pop() || Buffer.allocUnsafe(this.smallSize);
37
- }
38
- if (size <= this.mediumSize) {
39
- return this.mediumBuffers.pop() || Buffer.allocUnsafe(this.mediumSize);
40
- }
41
- return this.largeBuffers.pop() || Buffer.allocUnsafe(this.largeSize);
42
- }
43
- /**
44
- * Release a buffer back to the appropriate pool.
45
- */
46
- release(buffer) {
47
- if (buffer.length === this.smallSize && this.smallBuffers.length < this.smallPoolSize) {
48
- this.smallBuffers.push(buffer);
49
- }
50
- else if (buffer.length === this.mediumSize &&
51
- this.mediumBuffers.length < this.mediumPoolSize) {
52
- this.mediumBuffers.push(buffer);
53
- }
54
- else if (buffer.length === this.largeSize &&
55
- this.largeBuffers.length < this.largePoolSize) {
56
- this.largeBuffers.push(buffer);
57
- }
58
- }
59
- /**
60
- * Get the number of available buffers in each pool.
61
- */
62
- getPoolStatus() {
63
- return {
64
- small: this.smallBuffers.length,
65
- medium: this.mediumBuffers.length,
66
- large: this.largeBuffers.length,
67
- };
68
- }
69
- }
70
- exports.BufferPool = BufferPool;
@@ -1,50 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadConfig = loadConfig;
4
- function loadConfig(options = {}) {
5
- const env = options.env ?? process.env;
6
- const defaults = options.defaults ?? {};
7
- const prefix = options.prefix ?? 'QHTTPX_';
8
- const getNumber = (key) => {
9
- const value = env[prefix + key];
10
- if (!value) {
11
- return undefined;
12
- }
13
- const n = Number(value);
14
- if (!Number.isFinite(n) || n <= 0) {
15
- return undefined;
16
- }
17
- return n;
18
- };
19
- const getBoolean = (key) => {
20
- const value = env[prefix + key];
21
- if (!value) {
22
- return undefined;
23
- }
24
- const lower = value.toLowerCase();
25
- if (lower === 'true' || lower === '1') {
26
- return true;
27
- }
28
- if (lower === 'false' || lower === '0') {
29
- return false;
30
- }
31
- return undefined;
32
- };
33
- const maxConcurrency = getNumber('MAX_CONCURRENCY');
34
- const requestTimeoutMs = getNumber('REQUEST_TIMEOUT_MS');
35
- const maxMemoryBytes = getNumber('MAX_MEMORY_BYTES');
36
- const maxBodyBytes = getNumber('MAX_BODY_BYTES');
37
- const keepAliveTimeoutMs = getNumber('KEEP_ALIVE_TIMEOUT_MS');
38
- const headersTimeoutMs = getNumber('HEADERS_TIMEOUT_MS');
39
- const metricsEnabled = getBoolean('METRICS_ENABLED');
40
- return {
41
- ...defaults,
42
- maxConcurrency: maxConcurrency ?? defaults.maxConcurrency,
43
- requestTimeoutMs: requestTimeoutMs ?? defaults.requestTimeoutMs,
44
- maxMemoryBytes: maxMemoryBytes ?? defaults.maxMemoryBytes,
45
- maxBodyBytes: maxBodyBytes ?? defaults.maxBodyBytes,
46
- keepAliveTimeoutMs: keepAliveTimeoutMs ?? defaults.keepAliveTimeoutMs,
47
- headersTimeoutMs: headersTimeoutMs ?? defaults.headersTimeoutMs,
48
- metricsEnabled: metricsEnabled ?? defaults.metricsEnabled,
49
- };
50
- }
@@ -1,59 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseCookies = parseCookies;
4
- exports.serializeCookie = serializeCookie;
5
- function parseCookies(header) {
6
- const list = {};
7
- if (!header) {
8
- return list;
9
- }
10
- header.split(';').forEach((cookie) => {
11
- const parts = cookie.split('=');
12
- const name = parts.shift()?.trim();
13
- if (name) {
14
- const value = parts.join('=');
15
- list[name] = decodeURIComponent(value);
16
- }
17
- });
18
- return list;
19
- }
20
- function serializeCookie(name, value, options = {}) {
21
- let str = `${name}=${encodeURIComponent(value)}`;
22
- if (options.maxAge) {
23
- str += `; Max-Age=${Math.floor(options.maxAge)}`;
24
- }
25
- if (options.domain) {
26
- str += `; Domain=${options.domain}`;
27
- }
28
- if (options.path) {
29
- str += `; Path=${options.path}`;
30
- }
31
- else {
32
- str += '; Path=/';
33
- }
34
- if (options.expires) {
35
- str += `; Expires=${options.expires.toUTCString()}`;
36
- }
37
- if (options.httpOnly) {
38
- str += '; HttpOnly';
39
- }
40
- if (options.secure) {
41
- str += '; Secure';
42
- }
43
- if (options.sameSite) {
44
- switch (options.sameSite) {
45
- case 'lax':
46
- str += '; SameSite=Lax';
47
- break;
48
- case 'strict':
49
- str += '; SameSite=Strict';
50
- break;
51
- case 'none':
52
- str += '; SameSite=None';
53
- break;
54
- default:
55
- break;
56
- }
57
- }
58
- return str;
59
- }
@@ -1,11 +0,0 @@
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
- }