monsqlize 1.3.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/CHANGELOG.md +56 -60
  2. package/LICENSE +201 -21
  3. package/README.md +537 -1828
  4. package/changelogs/README.md +160 -0
  5. package/changelogs/v2.0.0.md +222 -0
  6. package/dist/cjs/index.cjs +10600 -0
  7. package/dist/cjs/mongodb/common/transaction-aware.cjs +10 -0
  8. package/dist/cjs/transaction/CacheLockManager.cjs +100 -0
  9. package/dist/cjs/transaction/Transaction.cjs +158 -0
  10. package/dist/cjs/transaction/TransactionManager.cjs +298 -0
  11. package/dist/esm/index.mjs +10650 -0
  12. package/dist/types/base.d.ts +81 -0
  13. package/dist/types/collection.d.ts +1031 -0
  14. package/dist/types/expression.d.ts +115 -0
  15. package/dist/types/index.d.ts +23 -0
  16. package/dist/types/lock.d.ts +74 -0
  17. package/dist/types/model.d.ts +526 -0
  18. package/dist/types/mongodb.d.ts +49 -0
  19. package/dist/types/monsqlize.d.ts +491 -0
  20. package/dist/types/pool.d.ts +84 -0
  21. package/dist/types/runtime.d.ts +362 -0
  22. package/dist/types/saga.d.ts +143 -0
  23. package/dist/types/slow-query-log.d.ts +126 -0
  24. package/dist/types/sync.d.ts +103 -0
  25. package/dist/types/transaction.d.ts +132 -0
  26. package/package.json +67 -69
  27. package/index.d.ts +0 -206
  28. package/index.mjs +0 -52
  29. package/lib/cache-invalidation.js +0 -279
  30. package/lib/cache.js +0 -530
  31. package/lib/common/cursor.js +0 -59
  32. package/lib/common/docs-urls.js +0 -73
  33. package/lib/common/index-options.js +0 -223
  34. package/lib/common/log.js +0 -61
  35. package/lib/common/namespace.js +0 -22
  36. package/lib/common/normalize.js +0 -34
  37. package/lib/common/page-result.js +0 -43
  38. package/lib/common/runner.js +0 -57
  39. package/lib/common/server-features.js +0 -232
  40. package/lib/common/shape-builders.js +0 -27
  41. package/lib/common/validation.js +0 -113
  42. package/lib/connect.js +0 -99
  43. package/lib/constants.js +0 -55
  44. package/lib/count-queue.js +0 -188
  45. package/lib/distributed-cache-invalidator.js +0 -260
  46. package/lib/errors.js +0 -168
  47. package/lib/expression/cache/ExpressionCache.js +0 -114
  48. package/lib/expression/compiler/ExpressionCompiler.js +0 -1090
  49. package/lib/expression/compiler/ExpressionCompilerExtensions.js +0 -531
  50. package/lib/expression/detector.js +0 -84
  51. package/lib/expression/factory.js +0 -29
  52. package/lib/expression/index.js +0 -19
  53. package/lib/function-cache.js +0 -533
  54. package/lib/index.js +0 -1251
  55. package/lib/infrastructure/ConnectionPoolManager.js +0 -464
  56. package/lib/infrastructure/HealthChecker.js +0 -281
  57. package/lib/infrastructure/PoolConfig.js +0 -199
  58. package/lib/infrastructure/PoolSelector.js +0 -225
  59. package/lib/infrastructure/PoolStats.js +0 -244
  60. package/lib/infrastructure/ssh-tunnel-ssh2.js +0 -212
  61. package/lib/infrastructure/ssh-tunnel.js +0 -41
  62. package/lib/infrastructure/uri-parser.js +0 -36
  63. package/lib/lock/Lock.js +0 -67
  64. package/lib/lock/errors.js +0 -28
  65. package/lib/lock/index.js +0 -13
  66. package/lib/logger.js +0 -225
  67. package/lib/model/examples/test.js +0 -311
  68. package/lib/model/features/defaults.js +0 -161
  69. package/lib/model/features/populate.js +0 -568
  70. package/lib/model/features/relations.js +0 -120
  71. package/lib/model/features/soft-delete.js +0 -349
  72. package/lib/model/features/version.js +0 -157
  73. package/lib/model/features/virtuals.js +0 -219
  74. package/lib/model/index.js +0 -1265
  75. package/lib/mongodb/common/accessor-helpers.js +0 -59
  76. package/lib/mongodb/common/agg-pipeline.js +0 -36
  77. package/lib/mongodb/common/aggregation-validator.js +0 -127
  78. package/lib/mongodb/common/iid.js +0 -28
  79. package/lib/mongodb/common/lexicographic-expr.js +0 -53
  80. package/lib/mongodb/common/shape.js +0 -32
  81. package/lib/mongodb/common/sort.js +0 -39
  82. package/lib/mongodb/common/transaction-aware.js +0 -25
  83. package/lib/mongodb/connect.js +0 -234
  84. package/lib/mongodb/index.js +0 -639
  85. package/lib/mongodb/management/admin-ops.js +0 -200
  86. package/lib/mongodb/management/bookmark-ops.js +0 -167
  87. package/lib/mongodb/management/cache-ops.js +0 -50
  88. package/lib/mongodb/management/collection-ops.js +0 -387
  89. package/lib/mongodb/management/database-ops.js +0 -202
  90. package/lib/mongodb/management/index-ops.js +0 -475
  91. package/lib/mongodb/management/index.js +0 -17
  92. package/lib/mongodb/management/namespace.js +0 -31
  93. package/lib/mongodb/management/validation-ops.js +0 -268
  94. package/lib/mongodb/queries/aggregate.js +0 -172
  95. package/lib/mongodb/queries/chain.js +0 -631
  96. package/lib/mongodb/queries/count.js +0 -99
  97. package/lib/mongodb/queries/distinct.js +0 -78
  98. package/lib/mongodb/queries/find-and-count.js +0 -193
  99. package/lib/mongodb/queries/find-by-ids.js +0 -236
  100. package/lib/mongodb/queries/find-one-by-id.js +0 -171
  101. package/lib/mongodb/queries/find-one.js +0 -71
  102. package/lib/mongodb/queries/find-page.js +0 -618
  103. package/lib/mongodb/queries/find.js +0 -171
  104. package/lib/mongodb/queries/index.js +0 -51
  105. package/lib/mongodb/queries/watch.js +0 -538
  106. package/lib/mongodb/writes/common/batch-retry.js +0 -65
  107. package/lib/mongodb/writes/delete-batch.js +0 -323
  108. package/lib/mongodb/writes/delete-many.js +0 -181
  109. package/lib/mongodb/writes/delete-one.js +0 -173
  110. package/lib/mongodb/writes/find-one-and-delete.js +0 -203
  111. package/lib/mongodb/writes/find-one-and-replace.js +0 -239
  112. package/lib/mongodb/writes/find-one-and-update.js +0 -240
  113. package/lib/mongodb/writes/increment-one.js +0 -259
  114. package/lib/mongodb/writes/index.js +0 -46
  115. package/lib/mongodb/writes/insert-batch.js +0 -508
  116. package/lib/mongodb/writes/insert-many.js +0 -223
  117. package/lib/mongodb/writes/insert-one.js +0 -169
  118. package/lib/mongodb/writes/replace-one.js +0 -226
  119. package/lib/mongodb/writes/result-handler.js +0 -237
  120. package/lib/mongodb/writes/update-batch.js +0 -416
  121. package/lib/mongodb/writes/update-many.js +0 -275
  122. package/lib/mongodb/writes/update-one.js +0 -273
  123. package/lib/mongodb/writes/upsert-one.js +0 -203
  124. package/lib/multi-level-cache.js +0 -244
  125. package/lib/operators.js +0 -330
  126. package/lib/redis-cache-adapter.js +0 -267
  127. package/lib/saga/SagaContext.js +0 -67
  128. package/lib/saga/SagaDefinition.js +0 -32
  129. package/lib/saga/SagaExecutor.js +0 -201
  130. package/lib/saga/SagaOrchestrator.js +0 -186
  131. package/lib/saga/index.js +0 -11
  132. package/lib/slow-query-log/base-storage.js +0 -70
  133. package/lib/slow-query-log/batch-queue.js +0 -97
  134. package/lib/slow-query-log/config-manager.js +0 -196
  135. package/lib/slow-query-log/index.js +0 -238
  136. package/lib/slow-query-log/mongodb-storage.js +0 -324
  137. package/lib/slow-query-log/query-hash.js +0 -39
  138. package/lib/sync/ChangeStreamSyncManager.js +0 -405
  139. package/lib/sync/ResumeTokenStore.js +0 -192
  140. package/lib/sync/SyncConfig.js +0 -127
  141. package/lib/sync/SyncTarget.js +0 -240
  142. package/lib/sync/index.js +0 -20
  143. package/lib/transaction/CacheLockManager.js +0 -162
  144. package/lib/transaction/DistributedCacheLockManager.js +0 -475
  145. package/lib/transaction/Transaction.js +0 -315
  146. package/lib/transaction/TransactionManager.js +0 -267
  147. package/lib/transaction/index.js +0 -11
  148. package/lib/utils/objectid-converter.js +0 -632
  149. package/types/README.md +0 -122
  150. package/types/base.ts +0 -94
  151. package/types/batch.ts +0 -187
  152. package/types/cache.ts +0 -71
  153. package/types/chain.ts +0 -254
  154. package/types/collection.ts +0 -357
  155. package/types/expression.ts +0 -109
  156. package/types/function-cache.d.ts +0 -135
  157. package/types/lock.ts +0 -95
  158. package/types/model/definition.ts +0 -152
  159. package/types/model/index.ts +0 -10
  160. package/types/model/instance.ts +0 -121
  161. package/types/model/relations.ts +0 -121
  162. package/types/model/virtuals.ts +0 -32
  163. package/types/monsqlize.ts +0 -245
  164. package/types/options.ts +0 -192
  165. package/types/pagination.ts +0 -154
  166. package/types/pool.ts +0 -125
  167. package/types/query.ts +0 -71
  168. package/types/saga.ts +0 -125
  169. package/types/stream.ts +0 -64
  170. package/types/sync.ts +0 -79
  171. package/types/transaction.ts +0 -79
  172. package/types/write.ts +0 -77
@@ -1,464 +0,0 @@
1
- /**
2
- * ConnectionPoolManager - 多连接池管理器
3
- *
4
- * 负责管理多个 MongoDB 连接池的生命周期
5
- * 支持动态添加/移除连接池、健康检查、统计监控
6
- *
7
- * @module lib/infrastructure/ConnectionPoolManager
8
- * @since v1.0.8
9
- */
10
-
11
- const AsyncLock = require('async-lock');
12
- const { MongoClient } = require('mongodb');
13
- const PoolSelector = require('./PoolSelector');
14
- const HealthChecker = require('./HealthChecker');
15
- const PoolStats = require('./PoolStats');
16
- const { validatePoolConfig } = require('./PoolConfig');
17
-
18
- /**
19
- * 默认连接池配置
20
- */
21
- const DEFAULT_POOL_CONFIG = {
22
- maxPoolSize: 100,
23
- minPoolSize: 0,
24
- maxIdleTimeMS: 60000,
25
- waitQueueTimeoutMS: 30000,
26
- connectTimeoutMS: 10000,
27
- serverSelectionTimeoutMS: 30000
28
- };
29
-
30
- /**
31
- * 默认健康检查配置
32
- */
33
- const DEFAULT_HEALTH_CHECK = {
34
- enabled: true,
35
- interval: 5000,
36
- timeout: 3000,
37
- retries: 3
38
- };
39
-
40
- /**
41
- * 多连接池管理器
42
- */
43
- class ConnectionPoolManager {
44
- /**
45
- * 构造函数
46
- *
47
- * @param {Object} options - 配置选项
48
- * @param {Array<PoolConfig>} options.pools - 连接池配置数组
49
- * @param {string} options.poolStrategy - 选择策略
50
- * @param {Object} options.poolFallback - 故障转移配置
51
- * @param {Object} options.logger - 日志记录器
52
- */
53
- constructor(options = {}) {
54
- this._pools = new Map(); // 连接池 Map<name, {client, config}>
55
- this._configs = new Map(); // 配置 Map<name, PoolConfig>
56
- this._poolLock = new AsyncLock(); // 并发锁(修复问题2)
57
- this._logger = options.logger || console;
58
-
59
- // 初始化选择器
60
- this._selector = new PoolSelector({
61
- strategy: options.poolStrategy || 'auto',
62
- logger: this._logger
63
- });
64
-
65
- // 初始化健康检查器
66
- this._healthChecker = new HealthChecker({
67
- poolManager: this,
68
- logger: this._logger
69
- });
70
-
71
- // 初始化统计收集器
72
- this._stats = new PoolStats({
73
- logger: this._logger
74
- });
75
-
76
- // 故障转移配置(修复问题1)
77
- this._fallbackConfig = {
78
- enabled: options.poolFallback?.enabled || false,
79
- retryDelay: options.poolFallback?.retryDelay || 1000,
80
- maxRetries: options.poolFallback?.maxRetries || 3,
81
- fallbackStrategy: options.poolFallback?.fallbackStrategy || 'error'
82
- };
83
-
84
- // 连接池数量上限(修复问题5)
85
- this._maxPoolsCount = options.maxPoolsCount || 10;
86
-
87
- this._closed = false;
88
- }
89
-
90
- /**
91
- * 添加连接池
92
- *
93
- * @param {PoolConfig} config - 连接池配置
94
- * @returns {Promise<void>}
95
- * @throws {Error} 如果配置无效或连接失败
96
- */
97
- async addPool(config) {
98
- // 🔴 修复问题2:使用并发锁保护
99
- return await this._poolLock.acquire('pools', async () => {
100
- // 验证配置
101
- validatePoolConfig(config);
102
-
103
- // 检查是否已存在
104
- if (this._pools.has(config.name)) {
105
- throw new Error(`Pool '${config.name}' already exists`);
106
- }
107
-
108
- // 检查连接池数量上限(修复问题5)
109
- if (this._pools.size >= this._maxPoolsCount) {
110
- throw new Error(`Maximum pool count (${this._maxPoolsCount}) reached`);
111
- }
112
-
113
- // 合并配置
114
- const poolOptions = {
115
- ...DEFAULT_POOL_CONFIG,
116
- ...config.options,
117
- // 🔴 修复问题7:根据角色设置 readPreference
118
- readPreference: config.role === 'secondary' ? 'secondary' : 'primary'
119
- };
120
-
121
- try {
122
- // 连接 MongoDB
123
- const client = await MongoClient.connect(config.uri, poolOptions);
124
-
125
- // 保存连接池
126
- this._pools.set(config.name, { client, config });
127
- this._configs.set(config.name, config);
128
-
129
- // 启动健康检查
130
- const healthCheckConfig = {
131
- ...DEFAULT_HEALTH_CHECK,
132
- ...config.healthCheck
133
- };
134
- if (healthCheckConfig.enabled) {
135
- this._healthChecker.register(config.name, healthCheckConfig);
136
- }
137
-
138
- this._logger.info(`[PoolManager] 连接池已添加: ${config.name}`, {
139
- role: config.role,
140
- uri: this._maskUri(config.uri)
141
- });
142
- } catch (error) {
143
- this._logger.error(`[PoolManager] 连接池添加失败: ${config.name}`, {
144
- error: error.message
145
- });
146
- throw error;
147
- }
148
- });
149
- }
150
-
151
- /**
152
- * 移除连接池
153
- *
154
- * @param {string} name - 连接池名称
155
- * @returns {Promise<void>}
156
- * @throws {Error} 如果连接池不存在
157
- */
158
- async removePool(name) {
159
- // 🔴 修复问题2:使用并发锁保护
160
- return await this._poolLock.acquire('pools', async () => {
161
- const pool = this._pools.get(name);
162
- if (!pool) {
163
- throw new Error(`Pool '${name}' not found`);
164
- }
165
-
166
- try {
167
- // 停止健康检查
168
- this._healthChecker.unregister(name);
169
-
170
- // 关闭连接
171
- await pool.client.close();
172
-
173
- // 删除连接池
174
- this._pools.delete(name);
175
- this._configs.delete(name);
176
-
177
- this._logger.info(`[PoolManager] 连接池已移除: ${name}`);
178
- } catch (error) {
179
- this._logger.error(`[PoolManager] 连接池移除失败: ${name}`, {
180
- error: error.message
181
- });
182
- throw error;
183
- }
184
- });
185
- }
186
-
187
- /**
188
- * 获取连接池(内部方法)
189
- *
190
- * @private
191
- * @param {string} name - 连接池名称
192
- * @returns {MongoClient|null}
193
- */
194
- _getPool(name) {
195
- const pool = this._pools.get(name);
196
- return pool ? pool.client : null;
197
- }
198
-
199
- /**
200
- * 选择连接池
201
- *
202
- * @param {string} operation - 操作类型 ('read' | 'write')
203
- * @param {Object} options - 选项
204
- * @param {string} [options.pool] - 手动指定连接池名称
205
- * @param {Object} [options.poolPreference] - 连接池偏好
206
- * @returns {{name: string, client: MongoClient, db: Db, collection: Function}}
207
- * @throws {Error} 如果无可用连接池
208
- */
209
- selectPool(operation, options = {}) {
210
- // 手动指定连接池
211
- if (options.pool) {
212
- const poolData = this._pools.get(options.pool);
213
- if (!poolData) {
214
- throw new Error(`Pool '${options.pool}' not found`);
215
- }
216
- const config = this._configs.get(options.pool);
217
- return this._createPoolResult(options.pool, poolData.client, config);
218
- }
219
-
220
- // 获取健康的连接池列表
221
- let candidates = this._getHealthyPools();
222
-
223
- // 🔴 修复问题1:处理所有连接池故障的情况
224
- if (candidates.length === 0) {
225
- if (!this._fallbackConfig.enabled) {
226
- throw new Error('No available connection pool');
227
- }
228
-
229
- candidates = this._handleAllPoolsDown(operation);
230
-
231
- if (candidates.length === 0) {
232
- throw new Error('No available connection pool (all pools down)');
233
- }
234
- }
235
-
236
- // 使用选择器选择连接池
237
- const poolName = this._selector.select(candidates, {
238
- operation,
239
- healthStatus: this._healthChecker.getAllStatus(),
240
- stats: this._stats.getAllStats(),
241
- ...options
242
- });
243
-
244
- const poolData = this._pools.get(poolName);
245
- if (!poolData) {
246
- throw new Error(`Selected pool '${poolName}' not available`);
247
- }
248
-
249
- // 记录统计
250
- this._stats.recordSelection(poolName, operation);
251
-
252
- const config = this._configs.get(poolName);
253
- return this._createPoolResult(poolName, poolData.client, config);
254
- }
255
-
256
- /**
257
- * 创建连接池结果对象(包含 db 和 collection 访问器)
258
- *
259
- * @private
260
- * @param {string} name - 连接池名称
261
- * @param {MongoClient} client - MongoDB 客户端
262
- * @param {Object} config - 连接池配置
263
- * @returns {{name: string, client: MongoClient, db: Db, collection: Function}}
264
- */
265
- _createPoolResult(name, client, config) {
266
- // 从 URI 中提取数据库名称
267
- let dbName;
268
- try {
269
- const url = new URL(config.uri);
270
- dbName = url.pathname.slice(1) || 'test';
271
- } catch (err) {
272
- dbName = 'test';
273
- }
274
-
275
- const db = client.db(dbName);
276
-
277
- return {
278
- name,
279
- client,
280
- db,
281
- collection: (collectionName) => db.collection(collectionName)
282
- };
283
- }
284
-
285
- /**
286
- * 获取健康的连接池列表
287
- *
288
- * @private
289
- * @returns {Array<PoolConfig>}
290
- */
291
- _getHealthyPools() {
292
- const healthyPools = [];
293
-
294
- for (const [name, config] of this._configs.entries()) {
295
- const status = this._healthChecker.getStatus(name);
296
- if (status?.status === 'up' || !status) {
297
- healthyPools.push(config);
298
- }
299
- }
300
-
301
- return healthyPools;
302
- }
303
-
304
- /**
305
- * 处理所有连接池故障的情况(降级策略)
306
- *
307
- * @private
308
- * @param {string} operation - 操作类型
309
- * @returns {Array<PoolConfig>}
310
- */
311
- _handleAllPoolsDown(operation) {
312
- const strategy = this._fallbackConfig.fallbackStrategy;
313
-
314
- this._logger.warn(`[PoolManager] 所有连接池故障,使用降级策略: ${strategy}`);
315
-
316
- if (strategy === 'error') {
317
- return [];
318
- }
319
-
320
- if (strategy === 'readonly') {
321
- // 只允许读操作
322
- if (operation === 'write') {
323
- this._logger.error('[PoolManager] 写操作被拒绝(所有连接池故障)');
324
- return [];
325
- }
326
- // 尝试使用 down 状态的 secondary
327
- return this._getPoolsByRole('secondary');
328
- }
329
-
330
- if (strategy === 'secondary') {
331
- // 尝试使用 down 状态的 secondary
332
- return this._getPoolsByRole('secondary');
333
- }
334
-
335
- return [];
336
- }
337
-
338
- /**
339
- * 按角色获取连接池
340
- *
341
- * @private
342
- * @param {string} role - 角色
343
- * @returns {Array<PoolConfig>}
344
- */
345
- _getPoolsByRole(role) {
346
- const pools = [];
347
-
348
- for (const config of this._configs.values()) {
349
- if (config.role === role) {
350
- pools.push(config);
351
- }
352
- }
353
-
354
- return pools;
355
- }
356
-
357
- /**
358
- * 获取所有连接池名称
359
- *
360
- * @returns {string[]}
361
- */
362
- getPoolNames() {
363
- return Array.from(this._pools.keys());
364
- }
365
-
366
- /**
367
- * 获取连接池统计信息
368
- *
369
- * @returns {Object}
370
- */
371
- getPoolStats() {
372
- const stats = {};
373
-
374
- for (const name of this._pools.keys()) {
375
- const healthStatus = this._healthChecker.getStatus(name);
376
- const poolStats = this._stats.getStats(name);
377
-
378
- stats[name] = {
379
- connections: poolStats?.connections || 0,
380
- available: poolStats?.available || 0,
381
- waiting: poolStats?.waiting || 0,
382
- status: healthStatus?.status || 'unknown',
383
- avgResponseTime: poolStats?.avgResponseTime || 0,
384
- totalRequests: poolStats?.totalRequests || 0,
385
- errorRate: poolStats?.errorRate || 0
386
- };
387
- }
388
-
389
- return stats;
390
- }
391
-
392
- /**
393
- * 获取健康状态
394
- *
395
- * @returns {Map<string, HealthStatus>}
396
- */
397
- getPoolHealth() {
398
- return this._healthChecker.getAllStatus();
399
- }
400
-
401
- /**
402
- * 启动健康检查
403
- */
404
- startHealthCheck() {
405
- this._healthChecker.start();
406
- }
407
-
408
- /**
409
- * 停止健康检查
410
- */
411
- stopHealthCheck() {
412
- this._healthChecker.stop();
413
- }
414
-
415
- /**
416
- * 关闭所有连接池
417
- *
418
- * @returns {Promise<void>}
419
- */
420
- async close() {
421
- if (this._closed) {
422
- return;
423
- }
424
-
425
- this._closed = true;
426
-
427
- // 停止健康检查
428
- this.stopHealthCheck();
429
-
430
- // 关闭所有连接池
431
- const closePromises = [];
432
- for (const [name, pool] of this._pools.entries()) {
433
- closePromises.push(
434
- pool.client.close().catch(error => {
435
- this._logger.error(`[PoolManager] 关闭连接池失败: ${name}`, {
436
- error: error.message
437
- });
438
- })
439
- );
440
- }
441
-
442
- await Promise.all(closePromises);
443
-
444
- this._pools.clear();
445
- this._configs.clear();
446
-
447
- this._logger.info('[PoolManager] 所有连接池已关闭');
448
- }
449
-
450
- /**
451
- * 脱敏 URI(移除密码)
452
- *
453
- * @private
454
- * @param {string} uri - MongoDB URI
455
- * @returns {string}
456
- */
457
- _maskUri(uri) {
458
- return uri.replace(/:([^:@]+)@/, ':****@');
459
- }
460
- }
461
-
462
- module.exports = ConnectionPoolManager;
463
-
464
-