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,73 +0,0 @@
1
- "use strict";
2
- /**
3
- * Lock-free (or lock-minimal) work queue for per-worker task distribution.
4
- * Uses a simple ring buffer for high throughput.
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.WorkerQueue = void 0;
8
- class WorkerQueue {
9
- constructor(capacity = 1024) {
10
- this.writeIndex = 0;
11
- this.readIndex = 0;
12
- this.size = 0;
13
- if (capacity <= 0 || !Number.isInteger(capacity)) {
14
- throw new Error('Capacity must be a positive integer');
15
- }
16
- // Ensure capacity is a power of 2 for efficient modulo with bitmask
17
- this.capacity = Math.pow(2, Math.ceil(Math.log2(capacity)));
18
- this.buffer = new Array(this.capacity);
19
- }
20
- /**
21
- * Enqueue a work item. Returns true if successful, false if queue is full.
22
- */
23
- enqueue(item) {
24
- if (this.size >= this.capacity) {
25
- return false;
26
- }
27
- this.buffer[this.writeIndex] = item;
28
- this.writeIndex = (this.writeIndex + 1) & (this.capacity - 1);
29
- this.size += 1;
30
- return true;
31
- }
32
- /**
33
- * Dequeue a work item. Returns undefined if queue is empty.
34
- */
35
- dequeue() {
36
- if (this.size <= 0) {
37
- return undefined;
38
- }
39
- const item = this.buffer[this.readIndex];
40
- this.buffer[this.readIndex] = undefined;
41
- this.readIndex = (this.readIndex + 1) & (this.capacity - 1);
42
- this.size -= 1;
43
- return item;
44
- }
45
- /**
46
- * Peek at the next item without removing it.
47
- */
48
- peek() {
49
- if (this.size <= 0) {
50
- return undefined;
51
- }
52
- return this.buffer[this.readIndex];
53
- }
54
- /**
55
- * Check if the queue is empty.
56
- */
57
- isEmpty() {
58
- return this.size === 0;
59
- }
60
- /**
61
- * Get the current size of the queue.
62
- */
63
- getSize() {
64
- return this.size;
65
- }
66
- /**
67
- * Get the capacity of the queue.
68
- */
69
- getCapacity() {
70
- return this.capacity;
71
- }
72
- }
73
- exports.WorkerQueue = WorkerQueue;
@@ -1,21 +0,0 @@
1
- import { DatabaseAdapter, DatabaseConfig } from '../types';
2
- export declare class MemoryAdapter implements DatabaseAdapter {
3
- private config;
4
- private connected;
5
- private collections;
6
- constructor(config: DatabaseConfig);
7
- connect(): Promise<void>;
8
- disconnect(): Promise<void>;
9
- isConnected(): boolean;
10
- /**
11
- * Execute a query against the in-memory database
12
- * @param query Object specifying collection, action, and parameters
13
- * @example
14
- * // Find
15
- * query({ collection: 'users', action: 'find', filter: { id: 1 } })
16
- * // Insert
17
- * query({ collection: 'users', action: 'insert', data: { name: 'Alice' } })
18
- */
19
- query<T = any>(query: any): Promise<T>;
20
- private matches;
21
- }
@@ -1,90 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MemoryAdapter = void 0;
4
- class MemoryAdapter {
5
- constructor(config) {
6
- this.config = config;
7
- this.connected = false;
8
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
- this.collections = new Map();
10
- }
11
- async connect() {
12
- // Simulate connection delay
13
- await new Promise(resolve => setTimeout(resolve, 100));
14
- this.connected = true;
15
- }
16
- async disconnect() {
17
- this.connected = false;
18
- this.collections.clear();
19
- }
20
- isConnected() {
21
- return this.connected;
22
- }
23
- /**
24
- * Execute a query against the in-memory database
25
- * @param query Object specifying collection, action, and parameters
26
- * @example
27
- * // Find
28
- * query({ collection: 'users', action: 'find', filter: { id: 1 } })
29
- * // Insert
30
- * query({ collection: 'users', action: 'insert', data: { name: 'Alice' } })
31
- */
32
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
- async query(query) {
34
- if (!this.connected) {
35
- throw new Error('Database not connected');
36
- }
37
- const { collection, action, data, filter } = query;
38
- if (!collection || !action) {
39
- throw new Error('Query must specify collection and action');
40
- }
41
- if (!this.collections.has(collection)) {
42
- this.collections.set(collection, []);
43
- }
44
- const store = this.collections.get(collection);
45
- switch (action) {
46
- case 'find':
47
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
- if (!filter)
49
- return store;
50
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
- return store.filter(item => this.matches(item, filter));
52
- case 'findOne':
53
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
54
- if (!filter)
55
- return store[0];
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
- return store.find(item => this.matches(item, filter));
58
- case 'insert':
59
- const newItem = { id: Date.now(), ...data };
60
- store.push(newItem);
61
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
- return newItem;
63
- case 'update':
64
- let updatedCount = 0;
65
- store.forEach((item, index) => {
66
- if (this.matches(item, filter)) {
67
- store[index] = { ...item, ...data };
68
- updatedCount++;
69
- }
70
- });
71
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
- return updatedCount;
73
- case 'delete':
74
- const initialLength = store.length;
75
- const newStore = store.filter(item => !this.matches(item, filter));
76
- this.collections.set(collection, newStore);
77
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
- return (initialLength - newStore.length);
79
- default:
80
- throw new Error(`Unknown action: ${action}`);
81
- }
82
- }
83
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
- matches(item, filter) {
85
- if (!filter)
86
- return true;
87
- return Object.entries(filter).every(([key, value]) => item[key] === value);
88
- }
89
- }
90
- exports.MemoryAdapter = MemoryAdapter;
@@ -1,11 +0,0 @@
1
- import { DatabaseAdapter, DatabaseConfig } from '../types';
2
- export declare class MongoAdapter implements DatabaseAdapter {
3
- private client;
4
- private db;
5
- private config;
6
- constructor(config: DatabaseConfig);
7
- connect(): Promise<void>;
8
- disconnect(): Promise<void>;
9
- query<T = any>(query: string | object, params?: any[]): Promise<T>;
10
- isConnected(): boolean;
11
- }
@@ -1,141 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.MongoAdapter = void 0;
37
- class MongoAdapter {
38
- constructor(config) {
39
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
- this.client = null;
41
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
- this.db = null;
43
- this.config = config;
44
- }
45
- async connect() {
46
- if (this.client)
47
- return;
48
- try {
49
- const mongodb = await Promise.resolve().then(() => __importStar(require('mongodb')));
50
- const { MongoClient } = mongodb.default || mongodb;
51
- const url = this.config.url || `mongodb://${this.config.host || 'localhost'}:${this.config.port || 27017}`;
52
- this.client = new MongoClient(url, {
53
- auth: this.config.username ? {
54
- username: this.config.username,
55
- password: this.config.password
56
- } : undefined,
57
- ...this.config.options
58
- });
59
- await this.client.connect();
60
- this.db = this.client.db(this.config.database);
61
- }
62
- catch (err) {
63
- if (err.message.includes('Cannot find module')) {
64
- throw new Error('MongoDB driver not found. Please run: npm install mongodb');
65
- }
66
- throw err;
67
- }
68
- }
69
- async disconnect() {
70
- if (this.client) {
71
- await this.client.close();
72
- this.client = null;
73
- this.db = null;
74
- }
75
- }
76
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
- async query(query, params) {
78
- if (!this.db) {
79
- throw new Error('Database not connected');
80
- }
81
- // MongoDB "query" is usually a collection.find() or similar.
82
- // We need a convention here.
83
- // Convention: query is a JSON object with { collection: 'name', action: 'find', filter: {}, ... }
84
- // OR: query is just the collection name, and params[0] is the operation?
85
- // Let's go with a structured object for maximum flexibility if passed as object.
86
- // If query is string, maybe it's just collection name?
87
- // Let's support a simple object-based API:
88
- // db.query({ collection: 'users', action: 'find', filter: { id: 1 } })
89
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
90
- let op = query;
91
- if (typeof query === 'string') {
92
- // Fallback or simple format?
93
- // Maybe "users.find" ?
94
- const parts = query.split('.');
95
- if (parts.length >= 2) {
96
- op = {
97
- collection: parts[0],
98
- action: parts[1],
99
- filter: params?.[0]
100
- };
101
- }
102
- else {
103
- throw new Error('Invalid MongoDB query format. Use object or "collection.action" string.');
104
- }
105
- }
106
- const collection = this.db.collection(op.collection);
107
- switch (op.action) {
108
- case 'find':
109
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
- const cursor = collection.find(op.filter || {});
111
- if (op.limit)
112
- cursor.limit(op.limit);
113
- if (op.skip)
114
- cursor.skip(op.skip);
115
- return (await cursor.toArray());
116
- case 'findOne':
117
- return (await collection.findOne(op.filter || {}));
118
- case 'insertOne':
119
- return (await collection.insertOne(op.doc || params?.[0]));
120
- case 'insertMany':
121
- return (await collection.insertMany(op.docs || params?.[0]));
122
- case 'updateOne':
123
- return (await collection.updateOne(op.filter, op.update || params?.[1]));
124
- case 'updateMany':
125
- return (await collection.updateMany(op.filter, op.update || params?.[1]));
126
- case 'deleteOne':
127
- return (await collection.deleteOne(op.filter));
128
- case 'deleteMany':
129
- return (await collection.deleteMany(op.filter));
130
- case 'aggregate':
131
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
132
- return (await collection.aggregate((op.pipeline || params)).toArray());
133
- default:
134
- throw new Error(`Unsupported MongoDB action: ${op.action}`);
135
- }
136
- }
137
- isConnected() {
138
- return this.client !== null;
139
- }
140
- }
141
- exports.MongoAdapter = MongoAdapter;
@@ -1,10 +0,0 @@
1
- import { DatabaseAdapter, DatabaseConfig } from '../types';
2
- export declare class PostgresAdapter implements DatabaseAdapter {
3
- private pool;
4
- private config;
5
- constructor(config: DatabaseConfig);
6
- connect(): Promise<void>;
7
- disconnect(): Promise<void>;
8
- query<T = any>(sql: string, params?: any[]): Promise<T>;
9
- isConnected(): boolean;
10
- }
@@ -1,111 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.PostgresAdapter = void 0;
37
- class PostgresAdapter {
38
- constructor(config) {
39
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
- this.pool = null;
41
- this.config = config;
42
- }
43
- async connect() {
44
- if (this.pool)
45
- return;
46
- try {
47
- // Dynamic import
48
- const pg = await Promise.resolve().then(() => __importStar(require('pg')));
49
- const { Pool } = pg.default || pg;
50
- this.pool = new Pool({
51
- host: this.config.host,
52
- port: this.config.port || 5432,
53
- user: this.config.username,
54
- password: this.config.password,
55
- database: this.config.database,
56
- // Postgres-specific options can be passed via config.options
57
- ...this.config.options
58
- });
59
- // Verify connection
60
- const client = await this.pool.connect();
61
- client.release();
62
- }
63
- catch (err) {
64
- if (err.message.includes('Cannot find module')) {
65
- throw new Error('PostgreSQL driver not found. Please run: npm install pg');
66
- }
67
- throw err;
68
- }
69
- }
70
- async disconnect() {
71
- if (this.pool) {
72
- await this.pool.end();
73
- this.pool = null;
74
- }
75
- }
76
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
- async query(sql, params) {
78
- if (!this.pool) {
79
- throw new Error('Database not connected');
80
- }
81
- try {
82
- // pg supports parameterized queries using $1, $2, etc.
83
- // But our Coalescer might be sending '?' if it's generic.
84
- // If the user writes 'SELECT * FROM users WHERE id = $1', that's fine.
85
- // If they write '?', we might need to convert it?
86
- // For now, we assume the user provides SQL compatible with the underlying driver.
87
- // Or we could implement a simple '?' -> '$n' converter if we want to standardize.
88
- // Standardizing is better for the generic "engine" feel.
89
- if (sql.includes('?')) {
90
- let i = 1;
91
- sql = sql.replace(/\?/g, () => `$${i++}`);
92
- }
93
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
- const result = await this.pool.query(sql, params);
95
- // Return rows for SELECT, or result meta for others?
96
- // Our interface implies T.
97
- // Usually users expect rows array for SELECT.
98
- if (result.command === 'SELECT' || result.command === 'INSERT' && result.rows.length > 0) {
99
- return result.rows;
100
- }
101
- return result;
102
- }
103
- catch (err) {
104
- throw err;
105
- }
106
- }
107
- isConnected() {
108
- return this.pool !== null && !this.pool.ended;
109
- }
110
- }
111
- exports.PostgresAdapter = PostgresAdapter;
@@ -1,10 +0,0 @@
1
- import { DatabaseAdapter, DatabaseConfig } from '../types';
2
- export declare class SQLiteAdapter implements DatabaseAdapter {
3
- private db;
4
- private config;
5
- constructor(config: DatabaseConfig);
6
- connect(): Promise<void>;
7
- disconnect(): Promise<void>;
8
- query<T = any>(sql: string, params?: any[]): Promise<T>;
9
- isConnected(): boolean;
10
- }
@@ -1,42 +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
- exports.SQLiteAdapter = void 0;
7
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
8
- class SQLiteAdapter {
9
- constructor(config) {
10
- this.db = null;
11
- this.config = config;
12
- }
13
- async connect() {
14
- const filename = this.config.database || ':memory:';
15
- this.db = new better_sqlite3_1.default(filename, this.config.options);
16
- }
17
- async disconnect() {
18
- if (this.db) {
19
- this.db.close();
20
- this.db = null;
21
- }
22
- }
23
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
- async query(sql, params) {
25
- if (!this.db) {
26
- throw new Error('Database not connected');
27
- }
28
- const stmt = this.db.prepare(sql);
29
- // better-sqlite3 handles '?' params automatically
30
- // Determine if it's a read or write operation
31
- if (sql.trim().toLowerCase().startsWith('select')) {
32
- return stmt.all(params || []);
33
- }
34
- else {
35
- return stmt.run(params || []);
36
- }
37
- }
38
- isConnected() {
39
- return this.db !== null && this.db.open;
40
- }
41
- }
42
- exports.SQLiteAdapter = SQLiteAdapter;
@@ -1,14 +0,0 @@
1
- import { DatabaseAdapter } from './types';
2
- export declare class QueryCoalescer<T = unknown> {
3
- private pending;
4
- private timeout;
5
- private readonly adapter;
6
- constructor(adapter: DatabaseAdapter);
7
- /**
8
- * Intercepts a query and attempts to coalesce it with others.
9
- * Only supports simple queries of the form "SELECT ... WHERE col = ?" for now.
10
- */
11
- query(query: string, params?: unknown[]): Promise<T>;
12
- private scheduleFlush;
13
- private flush;
14
- }
@@ -1,134 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.QueryCoalescer = void 0;
4
- // eslint-enable @typescript-eslint/no-explicit-any
5
- class QueryCoalescer {
6
- constructor(adapter) {
7
- this.pending = new Map();
8
- this.timeout = null;
9
- this.adapter = adapter;
10
- }
11
- /**
12
- * Intercepts a query and attempts to coalesce it with others.
13
- * Only supports simple queries of the form "SELECT ... WHERE col = ?" for now.
14
- */
15
- async query(query, params) {
16
- // Basic check for coalescing eligibility:
17
- // 1. Must have exactly one parameter (for simplicity in this v1)
18
- // 2. Must contain " = ?" pattern
19
- if (!params || params.length !== 1 || !query.includes(' = ?')) {
20
- return this.adapter.query(query, params);
21
- }
22
- return new Promise((resolve, reject) => {
23
- if (!this.pending.has(query)) {
24
- this.pending.set(query, []);
25
- }
26
- this.pending.get(query).push({
27
- query,
28
- paramValue: params[0],
29
- resolve: resolve,
30
- reject
31
- });
32
- this.scheduleFlush();
33
- });
34
- }
35
- scheduleFlush() {
36
- if (this.timeout)
37
- return;
38
- // Use microtask or short timeout to gather queries from the current event loop tick
39
- this.timeout = setTimeout(() => this.flush(), 0);
40
- }
41
- async flush() {
42
- this.timeout = null;
43
- const currentBatch = this.pending;
44
- this.pending = new Map(); // Clear for next batch
45
- for (const [originalQuery, items] of currentBatch.entries()) {
46
- if (items.length === 1) {
47
- // No fusion needed
48
- const item = items[0];
49
- try {
50
- const result = await this.adapter.query(item.query, [item.paramValue]);
51
- item.resolve(result);
52
- }
53
- catch (err) {
54
- item.reject(err);
55
- }
56
- continue;
57
- }
58
- // Fuse queries
59
- // Transform "SELECT * FROM table WHERE id = ?"
60
- // into "SELECT * FROM table WHERE id IN (?, ?, ...)"
61
- // Basic string manipulation (safe enough for this controlled feature)
62
- // We assume the query ends with " = ?" or contains it clearly.
63
- const fusedQuery = originalQuery.replace(' = ?', ` IN (${items.map(() => '?').join(', ')})`);
64
- const allParams = items.map(i => i.paramValue);
65
- try {
66
- const results = await this.adapter.query(fusedQuery, allParams);
67
- // Distribute results back to callers
68
- // We need to map results back to params.
69
- // This is the tricky part: standard SQL doesn't guarantee order matching input IN clause.
70
- // We must assume the result objects contain the key used in WHERE.
71
- // Extract the column name from the query
72
- // "WHERE id = ?" -> "id"
73
- const match = originalQuery.match(/WHERE\s+(\w+)\s*=\s*\?/i);
74
- if (!match) {
75
- // Fallback if we can't parse: execute individually (should not happen given check above)
76
- await Promise.all(items.map(async (item) => {
77
- try {
78
- const r = await this.adapter.query(item.query, [item.paramValue]);
79
- item.resolve(r);
80
- }
81
- catch (e) {
82
- item.reject(e);
83
- }
84
- }));
85
- continue;
86
- }
87
- const keyColumn = match[1];
88
- // Map results by key
89
- // Note: This assumes the result is an array of objects
90
- // If the adapter returns something else, this might fail.
91
- if (!Array.isArray(results)) {
92
- // Fallback for non-array results
93
- // Just give everyone the full result? No, that's wrong.
94
- // If it's not an array, we probably can't split it.
95
- // Reject? Or execute individually?
96
- // Let's execute individually as fallback.
97
- await Promise.all(items.map(async (item) => {
98
- try {
99
- const r = await this.adapter.query(item.query, [item.paramValue]);
100
- item.resolve(r);
101
- }
102
- catch (e) {
103
- item.reject(e);
104
- }
105
- }));
106
- continue;
107
- }
108
- const resultMap = new Map();
109
- results.forEach(row => {
110
- if (typeof row === 'object' && row !== null && keyColumn in row) {
111
- const typedRow = row;
112
- const key = typedRow[keyColumn];
113
- if (typeof key === 'string' || typeof key === 'number') {
114
- if (!resultMap.has(key)) {
115
- resultMap.set(key, []);
116
- }
117
- resultMap.get(key).push(row);
118
- }
119
- }
120
- });
121
- items.forEach(item => {
122
- const key = typeof item.paramValue === 'string' || typeof item.paramValue === 'number' ? item.paramValue : undefined;
123
- const res = key !== undefined ? resultMap.get(key) || [] : [];
124
- item.resolve(res);
125
- });
126
- }
127
- catch (err) {
128
- // Fail all
129
- items.forEach(item => item.reject(err));
130
- }
131
- }
132
- }
133
- }
134
- exports.QueryCoalescer = QueryCoalescer;