qhttpx 1.8.12 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/package.json +12 -3
  2. package/prebuilds/darwin-arm64/qhttpx.node +0 -0
  3. package/prebuilds/linux-x64/qhttpx.node +0 -0
  4. package/prebuilds/win32-x64/qhttpx.node +0 -0
  5. package/src/native/index.ts +104 -24
  6. package/src/native/picohttpparser.h +5 -0
  7. package/src/native/server.cc +2 -0
  8. package/dist/examples/api-server.d.ts +0 -1
  9. package/dist/examples/api-server.js +0 -77
  10. package/dist/examples/basic.d.ts +0 -1
  11. package/dist/examples/basic.js +0 -10
  12. package/dist/examples/compression.d.ts +0 -1
  13. package/dist/examples/compression.js +0 -17
  14. package/dist/examples/cors.d.ts +0 -1
  15. package/dist/examples/cors.js +0 -19
  16. package/dist/examples/errors.d.ts +0 -1
  17. package/dist/examples/errors.js +0 -25
  18. package/dist/examples/file-upload.d.ts +0 -1
  19. package/dist/examples/file-upload.js +0 -24
  20. package/dist/examples/fusion.d.ts +0 -1
  21. package/dist/examples/fusion.js +0 -21
  22. package/dist/examples/rate-limiting.d.ts +0 -1
  23. package/dist/examples/rate-limiting.js +0 -17
  24. package/dist/examples/validation.d.ts +0 -1
  25. package/dist/examples/validation.js +0 -23
  26. package/dist/examples/websockets.d.ts +0 -1
  27. package/dist/examples/websockets.js +0 -20
  28. package/dist/package.json +0 -101
  29. package/dist/src/benchmarks/quantam-users.d.ts +0 -1
  30. package/dist/src/benchmarks/quantam-users.js +0 -56
  31. package/dist/src/benchmarks/simple-json.d.ts +0 -1
  32. package/dist/src/benchmarks/simple-json.js +0 -60
  33. package/dist/src/benchmarks/ultra-mode.d.ts +0 -1
  34. package/dist/src/benchmarks/ultra-mode.js +0 -94
  35. package/dist/src/cli/index.d.ts +0 -2
  36. package/dist/src/cli/index.js +0 -222
  37. package/dist/src/client/index.d.ts +0 -17
  38. package/dist/src/client/index.js +0 -72
  39. package/dist/src/core/batch.d.ts +0 -24
  40. package/dist/src/core/batch.js +0 -97
  41. package/dist/src/core/body-parser.d.ts +0 -15
  42. package/dist/src/core/body-parser.js +0 -121
  43. package/dist/src/core/buffer-pool.d.ts +0 -41
  44. package/dist/src/core/buffer-pool.js +0 -70
  45. package/dist/src/core/config.d.ts +0 -7
  46. package/dist/src/core/config.js +0 -50
  47. package/dist/src/core/errors.d.ts +0 -34
  48. package/dist/src/core/errors.js +0 -70
  49. package/dist/src/core/fusion.d.ts +0 -14
  50. package/dist/src/core/fusion.js +0 -183
  51. package/dist/src/core/logger.d.ts +0 -22
  52. package/dist/src/core/logger.js +0 -49
  53. package/dist/src/core/metrics.d.ts +0 -45
  54. package/dist/src/core/metrics.js +0 -111
  55. package/dist/src/core/native-adapter.d.ts +0 -11
  56. package/dist/src/core/native-adapter.js +0 -211
  57. package/dist/src/core/resources.d.ts +0 -9
  58. package/dist/src/core/resources.js +0 -25
  59. package/dist/src/core/scheduler.d.ts +0 -34
  60. package/dist/src/core/scheduler.js +0 -85
  61. package/dist/src/core/scope.d.ts +0 -26
  62. package/dist/src/core/scope.js +0 -68
  63. package/dist/src/core/serializer.d.ts +0 -10
  64. package/dist/src/core/serializer.js +0 -44
  65. package/dist/src/core/server.d.ts +0 -138
  66. package/dist/src/core/server.js +0 -1082
  67. package/dist/src/core/stream.d.ts +0 -15
  68. package/dist/src/core/stream.js +0 -71
  69. package/dist/src/core/tasks.d.ts +0 -29
  70. package/dist/src/core/tasks.js +0 -87
  71. package/dist/src/core/types.d.ts +0 -173
  72. package/dist/src/core/types.js +0 -19
  73. package/dist/src/core/websocket.d.ts +0 -25
  74. package/dist/src/core/websocket.js +0 -86
  75. package/dist/src/core/worker-queue.d.ts +0 -41
  76. package/dist/src/core/worker-queue.js +0 -73
  77. package/dist/src/database/adapters/memory.d.ts +0 -21
  78. package/dist/src/database/adapters/memory.js +0 -90
  79. package/dist/src/database/adapters/mongo.d.ts +0 -11
  80. package/dist/src/database/adapters/mongo.js +0 -141
  81. package/dist/src/database/adapters/postgres.d.ts +0 -10
  82. package/dist/src/database/adapters/postgres.js +0 -111
  83. package/dist/src/database/adapters/sqlite.d.ts +0 -10
  84. package/dist/src/database/adapters/sqlite.js +0 -42
  85. package/dist/src/database/coalescer.d.ts +0 -14
  86. package/dist/src/database/coalescer.js +0 -134
  87. package/dist/src/database/manager.d.ts +0 -35
  88. package/dist/src/database/manager.js +0 -87
  89. package/dist/src/database/types.d.ts +0 -20
  90. package/dist/src/database/types.js +0 -2
  91. package/dist/src/index.d.ts +0 -50
  92. package/dist/src/index.js +0 -91
  93. package/dist/src/middleware/compression.d.ts +0 -2
  94. package/dist/src/middleware/compression.js +0 -133
  95. package/dist/src/middleware/cors.d.ts +0 -2
  96. package/dist/src/middleware/cors.js +0 -66
  97. package/dist/src/middleware/presets.d.ts +0 -16
  98. package/dist/src/middleware/presets.js +0 -52
  99. package/dist/src/middleware/rate-limit.d.ts +0 -14
  100. package/dist/src/middleware/rate-limit.js +0 -83
  101. package/dist/src/middleware/security.d.ts +0 -21
  102. package/dist/src/middleware/security.js +0 -69
  103. package/dist/src/middleware/static.d.ts +0 -11
  104. package/dist/src/middleware/static.js +0 -191
  105. package/dist/src/native/index.d.ts +0 -29
  106. package/dist/src/native/index.js +0 -64
  107. package/dist/src/openapi/generator.d.ts +0 -19
  108. package/dist/src/openapi/generator.js +0 -149
  109. package/dist/src/router/radix-router.d.ts +0 -18
  110. package/dist/src/router/radix-router.js +0 -89
  111. package/dist/src/router/radix-tree.d.ts +0 -18
  112. package/dist/src/router/radix-tree.js +0 -131
  113. package/dist/src/router/router.d.ts +0 -34
  114. package/dist/src/router/router.js +0 -186
  115. package/dist/src/testing/index.d.ts +0 -25
  116. package/dist/src/testing/index.js +0 -84
  117. package/dist/src/utils/cookies.d.ts +0 -3
  118. package/dist/src/utils/cookies.js +0 -59
  119. package/dist/src/utils/logger.d.ts +0 -12
  120. package/dist/src/utils/logger.js +0 -45
  121. package/dist/src/utils/signals.d.ts +0 -6
  122. package/dist/src/utils/signals.js +0 -31
  123. package/dist/src/utils/sse.d.ts +0 -6
  124. package/dist/src/utils/sse.js +0 -32
  125. package/dist/src/validation/index.d.ts +0 -3
  126. package/dist/src/validation/index.js +0 -19
  127. package/dist/src/validation/simple.d.ts +0 -5
  128. package/dist/src/validation/simple.js +0 -102
  129. package/dist/src/validation/types.d.ts +0 -32
  130. package/dist/src/validation/types.js +0 -12
  131. package/dist/src/validation/zod.d.ts +0 -4
  132. package/dist/src/validation/zod.js +0 -18
  133. package/dist/src/views/index.d.ts +0 -1
  134. package/dist/src/views/index.js +0 -17
  135. package/dist/src/views/types.d.ts +0 -3
  136. package/dist/src/views/types.js +0 -2
  137. package/dist/tests/adapters.test.d.ts +0 -1
  138. package/dist/tests/adapters.test.js +0 -106
  139. package/dist/tests/batch.test.d.ts +0 -1
  140. package/dist/tests/batch.test.js +0 -117
  141. package/dist/tests/body-parser.test.d.ts +0 -1
  142. package/dist/tests/body-parser.test.js +0 -52
  143. package/dist/tests/compression-sse.test.d.ts +0 -1
  144. package/dist/tests/compression-sse.test.js +0 -87
  145. package/dist/tests/cookies.test.d.ts +0 -1
  146. package/dist/tests/cookies.test.js +0 -63
  147. package/dist/tests/cors.test.d.ts +0 -1
  148. package/dist/tests/cors.test.js +0 -55
  149. package/dist/tests/database.test.d.ts +0 -1
  150. package/dist/tests/database.test.js +0 -80
  151. package/dist/tests/dx.test.d.ts +0 -1
  152. package/dist/tests/dx.test.js +0 -114
  153. package/dist/tests/ecosystem.test.d.ts +0 -1
  154. package/dist/tests/ecosystem.test.js +0 -133
  155. package/dist/tests/features.test.d.ts +0 -1
  156. package/dist/tests/features.test.js +0 -47
  157. package/dist/tests/fusion.test.d.ts +0 -1
  158. package/dist/tests/fusion.test.js +0 -92
  159. package/dist/tests/http-basic.test.d.ts +0 -1
  160. package/dist/tests/http-basic.test.js +0 -124
  161. package/dist/tests/logger.test.d.ts +0 -1
  162. package/dist/tests/logger.test.js +0 -33
  163. package/dist/tests/middleware.test.d.ts +0 -1
  164. package/dist/tests/middleware.test.js +0 -109
  165. package/dist/tests/native-adapter.test.d.ts +0 -1
  166. package/dist/tests/native-adapter.test.js +0 -71
  167. package/dist/tests/observability.test.d.ts +0 -1
  168. package/dist/tests/observability.test.js +0 -59
  169. package/dist/tests/openapi.test.d.ts +0 -1
  170. package/dist/tests/openapi.test.js +0 -64
  171. package/dist/tests/plugin.test.d.ts +0 -1
  172. package/dist/tests/plugin.test.js +0 -65
  173. package/dist/tests/plugins.test.d.ts +0 -1
  174. package/dist/tests/plugins.test.js +0 -71
  175. package/dist/tests/rate-limit.test.d.ts +0 -1
  176. package/dist/tests/rate-limit.test.js +0 -77
  177. package/dist/tests/resources.test.d.ts +0 -1
  178. package/dist/tests/resources.test.js +0 -47
  179. package/dist/tests/scheduler.test.d.ts +0 -1
  180. package/dist/tests/scheduler.test.js +0 -46
  181. package/dist/tests/schema-routes.test.d.ts +0 -1
  182. package/dist/tests/schema-routes.test.js +0 -77
  183. package/dist/tests/security.test.d.ts +0 -1
  184. package/dist/tests/security.test.js +0 -83
  185. package/dist/tests/server-db.test.d.ts +0 -1
  186. package/dist/tests/server-db.test.js +0 -72
  187. package/dist/tests/smoke.test.d.ts +0 -1
  188. package/dist/tests/smoke.test.js +0 -10
  189. package/dist/tests/sqlite-fusion.test.d.ts +0 -1
  190. package/dist/tests/sqlite-fusion.test.js +0 -92
  191. package/dist/tests/static.test.d.ts +0 -1
  192. package/dist/tests/static.test.js +0 -102
  193. package/dist/tests/stream.test.d.ts +0 -1
  194. package/dist/tests/stream.test.js +0 -44
  195. package/dist/tests/task-metrics.test.d.ts +0 -1
  196. package/dist/tests/task-metrics.test.js +0 -53
  197. package/dist/tests/tasks.test.d.ts +0 -1
  198. package/dist/tests/tasks.test.js +0 -62
  199. package/dist/tests/testing.test.d.ts +0 -1
  200. package/dist/tests/testing.test.js +0 -47
  201. package/dist/tests/validation.test.d.ts +0 -1
  202. package/dist/tests/validation.test.js +0 -107
  203. package/dist/tests/websocket.test.d.ts +0 -1
  204. package/dist/tests/websocket.test.js +0 -146
  205. package/dist/vitest.config.d.ts +0 -2
  206. package/dist/vitest.config.js +0 -9
@@ -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;
@@ -1,35 +0,0 @@
1
- import { DatabaseAdapter, DatabaseConfig, DatabaseEngineOptions } from './types';
2
- export type AdapterConstructor = new (config: DatabaseConfig) => DatabaseAdapter;
3
- export declare class DatabaseManager {
4
- private config;
5
- private static adapterRegistry;
6
- private connections;
7
- constructor(config: DatabaseEngineOptions);
8
- /**
9
- * Manually register an already initialized adapter instance
10
- * @param name The connection name
11
- * @param adapter The initialized adapter instance
12
- */
13
- registerConnection(name: string, adapter: DatabaseAdapter): void;
14
- /**
15
- * Register a new database adapter type
16
- * @param type The type identifier (e.g., 'postgres', 'mysql', 'mongo')
17
- * @param adapter The adapter class
18
- */
19
- static registerAdapter(type: string, adapter: AdapterConstructor): void;
20
- /**
21
- * Connect to a specific database or the default one
22
- * @param name Connection name from config
23
- */
24
- connect(name?: string): Promise<DatabaseAdapter>;
25
- /**
26
- * Disconnect a specific connection or all connections
27
- * @param name Connection name (optional). If not provided, disconnects all.
28
- */
29
- disconnect(name?: string): Promise<void>;
30
- /**
31
- * Get an active connection
32
- * @param name Connection name
33
- */
34
- get(name?: string): DatabaseAdapter;
35
- }