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
@@ -1,109 +0,0 @@
1
- # Real World Usage Examples
2
-
3
- Here is how QHTTPX looks in a production application.
4
-
5
- ## 1. The Entry Point (`src/index.ts`)
6
-
7
- Clean setup with built-in clustering and rate limiting.
8
-
9
- ```typescript
10
- import { createHttpApp } from 'qhttpx';
11
- import { rateLimit } from 'qhttpx/middleware';
12
-
13
- const app = createHttpApp({
14
- // Enable built-in request coalescing for high traffic
15
- enableRequestFusion: true,
16
- // Auto-scale to CPU cores
17
- workers: 'auto'
18
- });
19
-
20
- // Global Rate Limiter (Aegis)
21
- app.use(rateLimit({
22
- windowMs: 60 * 1000,
23
- max: 1000,
24
- keyGenerator: (req) => req.headers['x-api-key'] || req.ip
25
- }));
26
-
27
- // Start server
28
- app.listen(3000).then(({ port }) => {
29
- console.log(`🚀 Server running on port ${port}`);
30
- });
31
- ```
32
-
33
- ## 2. Modular Features (`src/modules/users.ts`)
34
-
35
- Using the Plugin System to organize code.
36
-
37
- ```typescript
38
- import { QHTTPXPlugin, QHTTPXScope } from 'qhttpx';
39
-
40
- export const userModule: QHTTPXPlugin = async (scope: QHTTPXScope) => {
41
-
42
- // GET /api/v1/users/:id
43
- scope.get('/:id', async (ctx) => {
44
- const userId = ctx.params.id;
45
- // Auto-fused database query
46
- const user = await ctx.db.query('SELECT * FROM users WHERE id = ?', [userId]);
47
-
48
- if (!user) return ctx.notFound();
49
- ctx.json(user);
50
- });
51
-
52
- // POST /api/v1/users
53
- scope.post('/', async (ctx) => {
54
- // Built-in validation
55
- const body = await ctx.validate({
56
- email: 'string|required',
57
- age: 'number|min:18'
58
- });
59
-
60
- // ... save user logic
61
- ctx.json({ success: true });
62
- });
63
- };
64
- ```
65
-
66
- ## 3. Registering Modules (`src/app.ts`)
67
-
68
- Bringing it all together with prefixes.
69
-
70
- ```typescript
71
- import { userModule } from './modules/users';
72
- import { authModule } from './modules/auth';
73
-
74
- // Register plugins with prefixes
75
- await app.register(userModule, { prefix: '/api/v1/users' });
76
- await app.register(authModule, { prefix: '/api/v1/auth' });
77
- ```
78
-
79
- ## 4. High-Performance Query Fusion
80
-
81
- How the fusion engine simplifies code while boosting performance.
82
-
83
- ```typescript
84
- // In your controller/handler:
85
- // You write simple queries:
86
- const user = await db.query('SELECT * FROM users WHERE id = ?', [1]);
87
-
88
- // QHTTPX automatically batches them into:
89
- // SELECT * FROM users WHERE id IN (1, 2, 3, ...)
90
- // And distributes the results back to each request.
91
- ```
92
-
93
- ## 5. Middleware & Guards
94
-
95
- Protecting routes is simple.
96
-
97
- ```typescript
98
- const adminGuard = (ctx, next) => {
99
- if (ctx.req.headers['x-role'] !== 'admin') {
100
- return ctx.status(403).json({ error: 'Forbidden' });
101
- }
102
- return next();
103
- };
104
-
105
- // Apply to specific route
106
- app.delete('/db/drop', adminGuard, (ctx) => {
107
- // ...
108
- });
109
- ```
package/docs/ROADMAP.md DELETED
@@ -1,366 +0,0 @@
1
- # QHTTPX Roadmap
2
-
3
- ## Overview
4
-
5
- QHTTPX is evolving toward a **lightweight, composable runtime** that prioritizes structural efficiency over microbenchmarks. Each phase targets a specific bottleneck in the HTTP request path, guided by the principle: *lighter core, more powerful abstractions*.
6
-
7
- ---
8
-
9
- ## Current State: v0.1
10
-
11
- ### Phase 1 – Hot-path Allocations ✅
12
-
13
- **Status: Implemented and Preallocated**
14
-
15
- #### Context Pooling
16
- - `contextPool: QHTTPXContext[]` preallocates up to `maxConcurrency` contexts at startup
17
- - `acquireContext()` pulls from pool and resets fields
18
- - `releaseContext()` cleans and returns to pool
19
- - **Effect**: No new context allocations under normal load; stable object shapes for hidden-class optimization
20
-
21
- #### Buffer Reuse
22
- - Engine supports pluggable `jsonSerializer?: (value: unknown) => string | Buffer`
23
- - Apps can precompile response buffers (e.g., health checks, metrics)
24
- - Benchmarks demonstrate zero-allocation JSON on hot paths
25
- - **Effect**: Users can achieve static buffer responses; mechanism generalizable
26
-
27
- #### Outcome
28
- - GC pauses reduced; p99 latencies stabilized
29
- - Foundation for buffer pools and serialization optimization
30
-
31
- ---
32
-
33
- ### Phase 2 – Routing (Partial) ⚠️
34
-
35
- **Status: Functional but Not Optimized**
36
-
37
- #### Current Implementation
38
- - Simple `RouteDefinition[]` list
39
- - Linear scan per HTTP method
40
- - Per-request normalization: `path.split('/')`, then segment matching
41
-
42
- #### What's Missing
43
- - No per-method route buckets (still scans all routes regardless of method)
44
- - No freeze-on-boot design (routes can be added/modified at any time)
45
- - No compiled/flattened structure (no radix tree, no array indices)
46
- - Per-request overhead: string splits, object allocations in match logic
47
-
48
- ---
49
-
50
- ### Phase 3 – Zero-cost Middleware ✅
51
-
52
- **Status: Implemented (Lighter Pipeline)**
53
-
54
- #### Pipeline Flattening
55
- - Removed per-request stack copy combining middlewares + route handler
56
- - Route handler no longer wrapped as extra middleware
57
- - Simple Koa-compatible dispatch loop: `middlewares[i](ctx, next)`
58
- - **Effect**: Fewer allocations; maintains familiar middleware API
59
-
60
- #### What's Not Yet Done
61
- - No precompiled runner (still dynamically dispatches through middleware chain)
62
- - Could evolve to single-loop execution with inlined middleware logic
63
-
64
- ---
65
-
66
- ### Phase 4 – Serialization (Partial) ✅
67
-
68
- **Status: Pluggable Hook Available**
69
-
70
- - Engine supports custom `jsonSerializer` at options level
71
- - Hot paths can use prebuilt Buffers
72
- - Mechanism ready for future schema compilers (e.g., fast-json-stringify style)
73
-
74
- #### What's Not Yet Done
75
- - No built-in schema compiler integration
76
- - No automatic path detection (e.g., `/health` → static buffer)
77
- - General buffer pools (small/medium/large) not yet part of runtime
78
-
79
- ---
80
-
81
- ### Phase 5+ – Scheduler & Runtime
82
-
83
- **Status: Skeleton Present**
84
-
85
- - `Scheduler` class with concurrency model
86
- - `TaskEngine` for background tasks
87
- - **Not yet**: Per-worker queues, work-stealing, lock-free primitives
88
-
89
- ---
90
-
91
- ## v0.2: Focus on Router & Consolidation
92
-
93
- ### Goals
94
- 1. **Make routing lazy-safe and indexable**: Support per-method buckets and freeze-on-boot design
95
- 2. **Improve measurability**: Track what v0.1 achieved; establish baselines for v0.2 improvements
96
- 3. **Maintain backward compatibility**: Existing API surface unchanged
97
-
98
- ### Scope
99
-
100
- #### 1. Router Optimization – Frozen, Per-Method Buckets
101
- **Deliverable**: `router.ts` refactor
102
-
103
- - **Step 1**: Reorganize routes internally into per-method buckets
104
- - `routes: { GET: RouteDefinition[], POST: RouteDefinition[], ... }`
105
- - Reduce scan loop overhead by method-specific lookups
106
-
107
- - **Step 2**: Introduce freeze-on-boot pattern
108
- - After `listen()` is called, warn (or optionally error) on new route registrations
109
- - Document that routes must be registered before server start
110
-
111
- - **Step 3**: Prebuild derived structures
112
- - Static routes table (path → handler, no params)
113
- - Parameterized routes list (faster fallback for `/foo/:id` patterns)
114
- - Prepare for radix compilation in v0.3
115
-
116
- **Why v0.2**: Routing is a bottleneck on every request. Fixing it early unlocks measurable gains and clearer architecture for v0.3's radix tree.
117
-
118
- **Risk**: Low. Public API unchanged; internals reorganized.
119
-
120
- ---
121
-
122
- #### 2. Buffer Pools (Optional, If Time)
123
- **Deliverable**: Internal buffer pool API
124
-
125
- - Small/medium/large pools for response bodies
126
- - Available to engine and future plugins
127
- - Keep mechanism simple: leak-proof, no external memory pressure
128
-
129
- **Why optional**: Nice-to-have for future buffer reuse. Can ship in v0.2 if implementation is lightweight; defer to v0.3 if it adds complexity.
130
-
131
- ---
132
-
133
- #### 3. Documentation & Baselines
134
- **Deliverable**: Updated `docs/`
135
-
136
- - Clarify v0.1 achievements (context pooling, pipeline flattening, pluggable JSON)
137
- - Benchmark baseline for v0.2 router changes
138
- - Explain freezing pattern and its implications for startup/shutdown
139
-
140
- ---
141
-
142
- ### Out of Scope for v0.2
143
- - Radix tree implementation (defer to v0.3)
144
- - Precompiled middleware runner (v0.3+)
145
- - Scheduler work-stealing (v0.5+)
146
- - Built-in schema compiler (v0.3+)
147
-
148
- ---
149
-
150
- ## v0.3: Radix Router & Middleware Compilation
151
-
152
- ### Goals
153
- 1. **Flatten routing further**: Build radix tree at boot, match in tight loop
154
- 2. **Precompile middleware chains**: Remove per-request dispatch overhead
155
- 3. **Introduce buffer pools formally**: General-purpose pooling for response bodies
156
-
157
- ### Scope
158
-
159
- #### 1. Radix Router
160
- - Build tree structure at `listen()` time
161
- - Flatten into arrays: `{ charCode, childIndex, handlerIndex, paramKeyIndex }`
162
- - Match becomes a tight loop with zero allocations
163
- - Support param extraction and wildcard routes
164
-
165
- #### 2. Middleware Precompilation
166
- - When `use()` or routes are registered, compile a single runner function
167
- - Runner is array of middleware + final handler, executed in simple loop
168
- - Maintains Koa semantics, removes dispatch overhead
169
-
170
- #### 3. Buffer Pools Formalized
171
- - Integrate into `server.ts` as standard pools (S/M/L)
172
- - Make available to route handlers via context
173
- - Document pool semantics (request-scoped resets)
174
-
175
- ---
176
-
177
- ## v0.5: Scheduler & Lock-Free Queues
178
-
179
- ### Goals
180
- 1. **Per-worker concurrency**: Ring buffers, per-core task queues
181
- 2. **Work-stealing**: Tasks move to idle cores
182
- 3. **Unified HTTP + Task scheduling**: Same primitives, different priorities
183
-
184
- ### Scope
185
- - Refactor `scheduler.ts` and `tasks.ts`
186
- - Introduce lock-free work queues
187
- - Integrate with existing concurrency model
188
-
189
- ---
190
-
191
- ## Key Principles (All Phases)
192
-
193
- 1. **Lighter, not faster**: Optimize structure, not just throughput
194
- 2. **Backward compatible**: Public API stays stable across minor versions
195
- 3. **Measurable**: Baseline before, measure after, document gains
196
- 4. **Composable**: Each phase builds on previous; no regressions
197
- 5. **No benchmark chasing**: Focus on real bottlenecks (allocation, dispatch, lookup)
198
-
199
- ---
200
-
201
- ## Success Criteria
202
-
203
- ### v0.2
204
- - [ ] Router per-method buckets implemented
205
- - [ ] Freeze-on-boot pattern enforced
206
- - [ ] Derived structures (static/param routes) prebuild correctly
207
- - [ ] Tests pass; backward compatibility verified
208
- - [ ] Baseline benchmarks established (context pooling, pipeline, router latency)
209
-
210
- ### v0.3
211
- - [ ] Radix tree built at boot; match is tight loop
212
- - [ ] Middleware chain precompiled; no per-request dispatch
213
- - [ ] Buffer pools integrated into `server.ts`
214
- - [ ] P50/P99 latencies improve measurably vs v0.2
215
- - [ ] Public API unchanged
216
-
217
- ### v0.5
218
- - [ ] Scheduler supports per-worker queues
219
- - [ ] Work-stealing implemented and tested
220
- - [ ] HTTP and task scheduling unified under same primitives
221
- - [ ] System handles burst loads better (work moves to idle cores)
222
-
223
- ---
224
-
225
- ## Next Steps
226
-
227
- 1. **Immediate**: Start v0.2 router refactor (per-method buckets, freeze pattern)
228
- 2. **Parallel**: Update benchmarks to track v0.2 improvements
229
- 3. **Document**: Clarify startup/shutdown semantics with frozen routes
230
-
231
- ---
232
-
233
- ## Framework & Production Roadmap
234
-
235
- This section focuses on framework-level features: production readiness, observability, safety, and capabilities that differentiate QHTTPX from frameworks like Express and Fastify.
236
-
237
- ### v0.4 – Production Framework Essentials ✅
238
-
239
- **Status: Implemented**
240
-
241
- **Goals**
242
-
243
- - Make behavior predictable in real services (errors, shutdown, config).
244
- - Provide first-class observability and safety, not just hot-path speed.
245
- - Keep the core small and composable.
246
-
247
- **Scope**
248
-
249
- 1. **Error Handling & HTTP Error Model**
250
- - Introduce an `HttpError` type with `status`, `code`, `details`.
251
- - Add an opt-in global error middleware:
252
- - Catches thrown errors from handlers/middlewares.
253
- - Maps `HttpError` to consistent JSON or text responses.
254
- - Hides internal errors behind a generic 500 except in development.
255
- - Provide helpers to register custom 404 and 405 handlers instead of hardcoded text responses.
256
-
257
- 2. **Configuration & Environment Handling**
258
- - Clarify how `QHTTPXOptions` is used for runtime configuration.
259
- - Provide a recommended pattern for constructing `QHTTPX` instances from environment variables.
260
- - Optionally expose a small `loadConfig({ env, defaults })` helper to centralize configuration parsing and validation.
261
-
262
- 3. **Graceful Shutdown & Lifecycle Hooks**
263
- - Add lifecycle hooks on the `QHTTPX` instance, such as `onStart`, `onShutdown`, `onBeforeShutdown`.
264
- - Implement graceful shutdown:
265
- - Stop accepting new connections.
266
- - Let in-flight requests complete up to a configurable timeout.
267
- - Flush metrics and background tasks before process exit.
268
- - Provide a helper to wire process signals, e.g. `attachSignalHandlers(app, { signals: ['SIGINT', 'SIGTERM'] })`.
269
-
270
- 4. **Observability & Request Identity**
271
- - Extend metrics and logger support with optional request ID correlation:
272
- - Generate a `x-request-id` when missing.
273
- - Expose the request ID on the context and in log entries/metrics.
274
- - Add a minimal interface for integrating external tracers (e.g., OpenTelemetry) without coupling QHTTPX to specific libraries.
275
- - Promote a structured logging example (JSON sink) as the recommended production default.
276
-
277
- 5. **Security Baseline Pack**
278
- - Combine CORS and security headers middlewares into a recommended preset:
279
- - `createSecureDefaults({ cors, csp, hsts, ... })` returning a set of middlewares.
280
- - Add a simple rate-limiting middleware (token bucket per IP or identifier) with pluggable storage, starting with in-memory.
281
- - Extend `readBody` handling to enforce a `maxBodyBytes` option and return 413 on oversized requests.
282
-
283
- 6. **Testing Utilities**
284
- - Provide a lightweight testing helper:
285
- - `createTestClient(app: QHTTPX)` to start the server on a random port.
286
- - `client.request({ method, path, body, headers })` for integration tests.
287
- - Ensure it works smoothly with Vitest and document recommended test patterns.
288
-
289
- ---
290
-
291
- ### v0.6 – Differentiating Features vs Fastify/Express
292
-
293
- **Goals**
294
-
295
- - Turn QHTTPX into a resource-aware HTTP runtime, not just a router.
296
- - Offer built-in quality-of-service and safety mechanisms.
297
- - Leverage existing scheduler, task engine, and metrics as first-class features.
298
-
299
- **Scope**
300
-
301
- 1. **Unified HTTP + Background Task Runtime**
302
- - Elevate the existing `TaskEngine` and `Scheduler` into a core story:
303
- - Clear API to register tasks tied to the application lifecycle.
304
- - Expose task metrics (queue depths, retries, failures) via `/__qhttpx/metrics`.
305
- - Introduce simple task priority classes (e.g., high vs low priority queues).
306
-
307
- 2. **Resource-Aware Admission Control**
308
- - Extend resource checks beyond RSS to include:
309
- - In-flight requests.
310
- - Scheduler queue sizes.
311
- - Latency metrics (e.g., p99).
312
- - Introduce a load shedding mechanism:
313
- - Optionally classify routes as "critical" or "best-effort".
314
- - Shed lower-priority requests under high load (returning 503).
315
-
316
- 3. **Latency Budgets & SLO-Aware Routing**
317
- - Allow per-route or per-group latency budgets (e.g., `100ms`).
318
- - Track budget violations and optionally:
319
- - Reject or degrade noncritical routes.
320
- - Provide simple SLO classes such as `critical`, `standard`, `background`.
321
-
322
- 4. **Concurrency & Priority Classes for Requests**
323
- - Build on `SchedulerOptions` and per-worker queues:
324
- - Annotate routes with priority and map them to worker queues.
325
- - Route latency-sensitive paths to high-priority queues and batch/admin endpoints to lower-priority queues.
326
-
327
- 5. **First-Class Streaming & SSE Patterns**
328
- - Promote existing SSE and streaming helpers into a "live services" story:
329
- - Provide patterns for broadcasting events to many SSE clients.
330
- - Ensure backpressure-aware file and data streaming.
331
- - Integrate connection counts and streaming durations into metrics.
332
-
333
- 6. **Introspectable Runtime**
334
- - Extend `/__qhttpx/metrics` and related endpoints to expose:
335
- - Per-worker queue statistics.
336
- - Task engine statistics (registered tasks, pending retries).
337
- - Router statistics (route counts, frozen state).
338
- - Optionally add `/__qhttpx/runtime` for a JSON summary of runtime state (excluding secrets).
339
-
340
- ---
341
-
342
- ### v0.8 – Developer Experience & Ergonomics
343
-
344
- **Goals**
345
-
346
- - Improve ergonomics without bloating the core engine.
347
- - Provide opinionated presets that are still decomposable into primitives.
348
-
349
- **Scope**
350
-
351
- 1. **Routing Ergonomics**
352
- - Add route builders such as `app.route('/users/:id')` to group methods.
353
- - Provide a typed helper layer for TypeScript users:
354
- - Wrap `QHTTPXHandler` with generics for params, query, body, and response types.
355
-
356
- 2. **Preset Stacks**
357
- - "API preset":
358
- - JSON responses, CORS, logger, metrics, error handler, security headers, and size limits.
359
- - "Static site + API preset":
360
- - Adds static middleware with recommended settings on top of the API preset.
361
- - Implement presets as thin helpers that call `app.use(...)` with existing middlewares.
362
-
363
- 3. **CLI (Optional)**
364
- - Introduce a minimal CLI to scaffold starter projects:
365
- - Example app with `/health`, `/metrics`, SSE example, a background task, and basic tests.
366
- - Keep the CLI small and optional so QHTTPX remains primarily a runtime and library.
package/docs/ROUTING.md DELETED
@@ -1,78 +0,0 @@
1
- # Routing
2
-
3
- QHTTPX employs a high-performance **Dual-Strategy Router** optimized for real-world usage patterns.
4
-
5
- 1. **Static Routes**: Uses a JavaScript `Map` for **O(1)** instant lookup, regardless of how many routes you have.
6
- 2. **Dynamic Routes**: Uses **Pre-compiled Regex** patterns, compiled once at startup (during the `freeze` phase), ensuring zero parsing overhead during requests.
7
-
8
- This hybrid approach outperforms traditional Radix Tree implementations for static paths while maintaining flexibility for dynamic parameters.
9
-
10
- ## Basic Routing
11
-
12
- Supported methods: `get`, `post`, `put`, `delete`, `patch`, `options`, `head`.
13
-
14
- ```typescript
15
- app.get('/', (ctx) => {
16
- return { hello: 'world' };
17
- });
18
-
19
- app.post('/items', (ctx) => {
20
- // ...
21
- return { status: 'created' }; // Auto-201
22
- });
23
- ```
24
-
25
- ## Route Parameters
26
-
27
- Capture dynamic segments of the URL using colons (`:`).
28
-
29
- ```typescript
30
- app.get('/users/:id', (ctx) => {
31
- const { id } = ctx.params;
32
- return { userId: id };
33
- });
34
-
35
- // Multiple parameters
36
- app.get('/posts/:year/:month/:slug', (ctx) => {
37
- const { year, month, slug } = ctx.params;
38
- // ...
39
- });
40
- ```
41
-
42
- ## Wildcards
43
-
44
- Match everything following a path using `*`.
45
-
46
- ```typescript
47
- // Matches /files/image.png, /files/docs/report.pdf, etc.
48
- app.get('/files/*', (ctx) => {
49
- const path = ctx.params['*']; // "image.png"
50
- // ...
51
- });
52
- ```
53
-
54
- ## Route Destructuring
55
-
56
- The handler context can be destructured for cleaner code:
57
-
58
- ```typescript
59
- app.get('/search', ({ query }) => {
60
- const { q } = query;
61
- return { results: performSearch(q) };
62
- });
63
- ```
64
-
65
- ## Scoped Routes (Plugins)
66
-
67
- Use plugins to create route groups with prefixes. The `plugin` helper makes this easy.
68
-
69
- ```typescript
70
- import { plugin } from 'qhttpx';
71
-
72
- const apiV1 = plugin(async (app) => {
73
- app.get('/users', () => { ... }); // Becomes /api/v1/users
74
- app.get('/posts', () => { ... }); // Becomes /api/v1/posts
75
- });
76
-
77
- app.routes('/api/v1', apiV1);
78
- ```