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
package/lib/operators.js DELETED
@@ -1,330 +0,0 @@
1
- module.exports = {
2
-
3
- // 比较运算符(查询阶段)
4
- comparisonOperators:{
5
- '$eq': { mysql: '=' }, // 等于 (MongoDB: $eq) —— null 在实现层转为 IS NULL
6
- '$ne': { mysql: '<>' }, // 不等于 (MongoDB: $ne) —— null 在实现层转为 IS NOT NULL
7
- '$gt': { mysql: '>' }, // 大于 (MongoDB: $gt)
8
- '$gte': { mysql: '>=' }, // 大于等于 (MongoDB: $gte)
9
- '$lt': { mysql: '<' }, // 小于 (MongoDB: $lt)
10
- '$lte': { mysql: '<=' }, // 小于等于 (MongoDB: $lte)
11
- '$in': { mysql: 'IN' }, // 在列表中 (MongoDB: $in)
12
- '$nin': { mysql: 'NOT IN' }, // 不在列表中 (MongoDB: $nin)
13
- },
14
-
15
- // 逻辑运算符(查询阶段)
16
- logicalOperators:{
17
- '$and': { mysql: 'AND' }, // 逻辑与 (MongoDB: $and)
18
- '$or': { mysql: 'OR' }, // 逻辑或 (MongoDB: $or)
19
- '$not': { mysql: 'NOT' }, // 逻辑非 (MongoDB: $not) —— 使用 NOT ( ... ) 包裹字段条件
20
- '$nor': { mysql: '' } // 逻辑或非 (MongoDB: $nor) —— 实现为 NOT ( ... OR ... ) 包裹(无独立 SQL 运算符)
21
- },
22
-
23
- // 元素运算符(查询阶段)
24
- elementOperators:{
25
- '$exists': { mysql: 'IS [NOT] NULL' }, // 是否存在 (MongoDB: $exists) —— MySQL 映射为 IS [NOT] NULL(列存在性以 NULL 判定)
26
- '$type': { mysql: '' } // 类型 (MongoDB: $type) —— 未实现
27
- },
28
-
29
- // 评估运算符(查询阶段)
30
- evaluationOperators:{
31
- '$expr': { mysql: '' }, // 使用聚合表达式 —— MySQL 端不支持
32
- '$jsonSchema': { mysql: '' }, // JSON Schema —— 未实现
33
- '$mod': { mysql: 'col % d = r' }, // 模运算 —— MySQL 使用取模:col % divisor = remainder(参数化)
34
- '$regex': { mysql: 'REGEXP' }, // 正则(MySQL: REGEXP)
35
- '$text': { mysql: 'MATCH...AGAINST' }, // 全文搜索 —— 使用 MATCH(...) AGAINST (? [MODE]),需指定 $columns
36
- '$where': { mysql: '' } // JavaScript 表达式 —— MySQL 端不支持
37
- },
38
-
39
- // 数组运算符(查询阶段)
40
- arrayOperators:{
41
- '$all': { mysql: '' }, // 未实现
42
- '$elemMatch': { mysql: '' }, // 未实现
43
- '$size': { mysql: '' }, // 未实现
44
- },
45
-
46
- // 位运算符(查询阶段)
47
- bitOperators:{
48
- '$bitsAllClear': { mysql: '' }, // 未实现
49
- '$bitsAllSet': { mysql: '' }, // 未实现
50
- '$bitsAnyClear': { mysql: '' }, // 未实现
51
- '$bitsAnySet': { mysql: '' }, // 未实现
52
- },
53
-
54
- // 地理空间运算符(查询阶段)
55
- geospatialOperators:{
56
- '$geoIntersects': { mysql: '' }, // 未实现
57
- '$geoWithin': { mysql: '' }, // 未实现
58
- '$near': { mysql: '' }, // 未实现
59
- '$nearSphere': { mysql: '' } // 未实现
60
- },
61
-
62
- // 投影运算符(读取阶段,当前由适配器自行处理语义)
63
- projectionOperators:{
64
- '$': { mysql: '' }, // 未实现
65
- '$elemMatch':{ mysql: '' }, // 未实现
66
- '$meta': { mysql: '' }, // 未实现
67
- '$slice': { mysql: '' } // 未实现
68
- },
69
-
70
- // 更新运算符(当前不在本项目范围,预留映射位)
71
- updateOperators:{
72
- // 字段更新运算符
73
- fieldUpdateOperators:{
74
- '$currentDate': { mysql: '' },
75
- '$inc': { mysql: '' },
76
- '$min': { mysql: '' },
77
- '$max': { mysql: '' },
78
- '$mul': { mysql: '' },
79
- '$rename': { mysql: '' },
80
- '$set': { mysql: '' },
81
- '$setOnInsert': { mysql: '' },
82
- '$unset': { mysql: '' },
83
- },
84
-
85
- // 数组更新运算符
86
- arrayUpdateOperators:{
87
- '$addToSet': { mysql: '' },
88
- '$pop': { mysql: '' },
89
- '$pull': { mysql: '' },
90
- '$push': { mysql: '' },
91
- '$pullAll': { mysql: '' },
92
- },
93
-
94
- // 数组更新修饰符
95
- arrayUpdateModifiers:{
96
- '$each': { mysql: '' },
97
- '$position':{ mysql: '' },
98
- '$slice': { mysql: '' },
99
- '$sort': { mysql: '' }
100
- },
101
-
102
- // 按位更新运算符
103
- bitUpdateOperators:{
104
- '$bit': { mysql: '' }
105
- }
106
- },
107
-
108
- // 聚合管道阶段(预留)
109
- aggregationPipelineStages:{
110
- '$addFields': { mysql: '' },
111
- '$bucket': { mysql: '' },
112
- '$bucketAuto': { mysql: '' },
113
- '$collStats': { mysql: '' },
114
- '$count': { mysql: '' },
115
- '$facet': { mysql: '' },
116
- '$geoNear': { mysql: '' },
117
- '$graphLookup': { mysql: '' },
118
- '$group': { mysql: '' },
119
- '$indexStats': { mysql: '' },
120
- '$limit': { mysql: '' },
121
- '$lookup': { mysql: '' },
122
- '$match': { mysql: '' },
123
- '$merge': { mysql: '' },
124
- '$out': { mysql: '' },
125
- '$project': { mysql: '' },
126
- '$redact': { mysql: '' },
127
- '$replaceRoot': { mysql: '' },
128
- '$replaceWith': { mysql: '' },
129
- '$sample': { mysql: '' },
130
- '$set': { mysql: '' },
131
- '$skip': { mysql: '' },
132
- '$sort': { mysql: '' },
133
- '$sortByCount': { mysql: '' },
134
- '$unionWith': { mysql: '' },
135
- '$unset': { mysql: '' },
136
- '$unwind': { mysql: '' }
137
- },
138
-
139
- // 聚合表达式运算符(预留)
140
- aggregationExpressionOperators:{
141
-
142
- // 算术运算符
143
- arithmeticOperators:{
144
- '$abs': { mysql: '' },
145
- '$add': { mysql: '' },
146
- '$ceil': { mysql: '' },
147
- '$divide': { mysql: '' },
148
- '$exp': { mysql: '' },
149
- '$floor': { mysql: '' },
150
- '$ln': { mysql: '' },
151
- '$log': { mysql: '' },
152
- '$log10': { mysql: '' },
153
- '$mod': { mysql: '' },
154
- '$multiply': { mysql: '' },
155
- '$pow': { mysql: '' },
156
- '$round': { mysql: '' },
157
- '$sqrt': { mysql: '' },
158
- '$subtract': { mysql: '' },
159
- '$trunc': { mysql: '' }
160
- },
161
-
162
- // 数组运算符
163
- arrayOperators:{
164
- '$arrayElemAt': { mysql: '' },
165
- '$arrayToObject': { mysql: '' },
166
- '$concatArrays': { mysql: '' },
167
- '$filter': { mysql: '' },
168
- '$first': { mysql: '' },
169
- '$in': { mysql: '' },
170
- '$indexOfArray': { mysql: '' },
171
- '$isArray': { mysql: '' },
172
- '$last': { mysql: '' },
173
- '$map': { mysql: '' },
174
- '$objectToArray': { mysql: '' },
175
- '$range': { mysql: '' },
176
- '$reduce': { mysql: '' },
177
- '$reverseArray': { mysql: '' },
178
- '$size': { mysql: '' },
179
- '$slice': { mysql: '' },
180
- '$zip': { mysql: '' }
181
- },
182
-
183
- // 布尔运算符
184
- booleanOperators:{
185
- '$and': { mysql: '' },
186
- '$not': { mysql: '' },
187
- '$or': { mysql: '' }
188
- },
189
-
190
- // 比较运算符
191
- comparisonOperators:{
192
- '$cmp': { mysql: '' },
193
- '$eq': { mysql: '' },
194
- '$gt': { mysql: '' },
195
- '$gte': { mysql: '' },
196
- '$lt': { mysql: '' },
197
- '$lte': { mysql: '' },
198
- '$ne': { mysql: '' }
199
- },
200
-
201
- // 条件运算符
202
- conditionalOperators:{
203
- '$cond': { mysql: '' },
204
- '$ifNull': { mysql: '' },
205
- '$switch': { mysql: '' }
206
- },
207
-
208
- // 数据类型运算符
209
- dataTypeOperators:{
210
- '$type': { mysql: '' },
211
- '$convert': { mysql: '' },
212
- '$toBool': { mysql: '' },
213
- '$toDate': { mysql: '' },
214
- '$toDecimal': { mysql: '' },
215
- '$toDouble': { mysql: '' },
216
- '$toInt': { mysql: '' },
217
- '$toLong': { mysql: '' },
218
- '$toObjectId': { mysql: '' },
219
- '$toString': { mysql: '' }
220
- },
221
-
222
- // 日期运算符
223
- dateOperators:{
224
- '$dateAdd': { mysql: '' },
225
- '$dateDiff': { mysql: '' },
226
- '$dateFromParts': { mysql: '' },
227
- '$dateFromString':{ mysql: '' },
228
- '$dateSubtract': { mysql: '' },
229
- '$dateToParts': { mysql: '' },
230
- '$dateToString': { mysql: '' },
231
- '$dayOfMonth': { mysql: '' },
232
- '$dayOfWeek': { mysql: '' },
233
- '$dayOfYear': { mysql: '' },
234
- '$hour': { mysql: '' },
235
- '$isoDayOfWeek': { mysql: '' },
236
- '$isoWeek': { mysql: '' },
237
- '$isoWeekYear': { mysql: '' },
238
- '$millisecond': { mysql: '' },
239
- '$minute': { mysql: '' },
240
- '$month': { mysql: '' },
241
- '$second': { mysql: '' },
242
- '$week': { mysql: '' },
243
- '$year': { mysql: '' }
244
- },
245
-
246
- // 字符串运算符
247
- stringOperators:{
248
- '$concat': { mysql: '' },
249
- '$indexOfBytes': { mysql: '' },
250
- '$indexOfCP': { mysql: '' },
251
- '$ltrim': { mysql: '' },
252
- '$regexFind': { mysql: '' },
253
- '$regexFindAll': { mysql: '' },
254
- '$regexMatch': { mysql: '' },
255
- '$replaceAll': { mysql: '' },
256
- '$replaceOne': { mysql: '' },
257
- '$rtrim': { mysql: '' },
258
- '$split': { mysql: '' },
259
- '$strcasecmp': { mysql: '' },
260
- '$strLenBytes': { mysql: '' },
261
- '$strLenCP': { mysql: '' },
262
- '$substr': { mysql: '' },
263
- '$substrBytes': { mysql: '' },
264
- '$substrCP': { mysql: '' },
265
- '$toLower': { mysql: '' },
266
- '$toUpper': { mysql: '' },
267
- '$trim': { mysql: '' }
268
- },
269
-
270
- // 文本运算符
271
- textOperators:{
272
- '$meta': { mysql: '' }
273
- },
274
-
275
- // 变量运算符
276
- variableOperators:{
277
- '$$NOW': { mysql: '' },
278
- '$$ROOT': { mysql: '' },
279
- '$$CURRENT': { mysql: '' },
280
- '$$DESCEND': { mysql: '' },
281
- '$$PRUNE': { mysql: '' },
282
- '$$KEEP': { mysql: '' }
283
- },
284
-
285
- // 累加器运算符(group 阶段)
286
- accumulatorOperatorsGroup:{
287
- '$accumulator': { mysql: '' },
288
- '$addToSet': { mysql: '' },
289
- '$avg': { mysql: '' },
290
- '$count': { mysql: '' },
291
- '$first': { mysql: '' },
292
- '$last': { mysql: '' },
293
- '$max': { mysql: '' },
294
- '$mergeObjects': { mysql: '' },
295
- '$min': { mysql: '' },
296
- '$push': { mysql: '' },
297
- '$stdDevPop': { mysql: '' },
298
- '$stdDevSamp': { mysql: '' },
299
- '$sum': { mysql: '' }
300
- },
301
-
302
- // 累加器运算符(project 阶段)
303
- accumulatorOperatorsProject:{
304
- '$avg': { mysql: '' },
305
- '$max': { mysql: '' },
306
- '$min': { mysql: '' },
307
- '$stdDevPop': { mysql: '' },
308
- '$stdDevSamp': { mysql: '' },
309
- '$sum': { mysql: '' }
310
- }
311
- },
312
-
313
- // 游标方法(仅保留占位,非 SQL 语义)
314
- cursorMethods:{
315
- '$addCursorFlag': { mysql: '' },
316
- '$batchSize': { mysql: '' },
317
- '$close': { mysql: '' },
318
- '$comment': { mysql: '' },
319
- '$itcount': { mysql: '' },
320
- '$isExhaust': { mysql: '' },
321
- '$isDead': { mysql: '' },
322
- '$isAlive': { mysql: '' },
323
- '$maxTimeMS': { mysql: '' },
324
- '$readConcern': { mysql: '' },
325
- '$readPref': { mysql: '' },
326
- '$setBatchSize': { mysql: '' },
327
- '$setReadConcern': { mysql: '' },
328
- '$setReadPref': { mysql: '' }
329
- }
330
- };
@@ -1,267 +0,0 @@
1
- /**
2
- * Redis 缓存适配器:将 Redis 封装为 CacheLike 接口
3
- * 支持直接传入 Redis URL 字符串或 ioredis 实例
4
- *
5
- * @example
6
- * const { createRedisCacheAdapter } = require('monsqlize/lib/redis-cache-adapter');
7
- *
8
- * // 方式 1:传入 URL 字符串(推荐)
9
- * const cache = createRedisCacheAdapter('redis://localhost:6379/0');
10
- *
11
- * // 方式 2:传入 ioredis 实例
12
- * const Redis = require('ioredis');
13
- * const redis = new Redis('redis://localhost:6379/0');
14
- * const cache = createRedisCacheAdapter(redis);
15
- */
16
-
17
- /**
18
- * 创建 Redis 缓存适配器
19
- * @param {string|Object} redisUrlOrInstance - Redis URL 字符串或 ioredis 实例
20
- * @returns {Object} 实现了 CacheLike 接口的缓存对象
21
- */
22
- function createRedisCacheAdapter(redisUrlOrInstance) {
23
- let redis;
24
- let shouldCloseOnDestroy = false;
25
-
26
- // 如果传入的是字符串,自动创建 Redis 实例
27
- if (typeof redisUrlOrInstance === 'string') {
28
- try {
29
- const IORedis = require('ioredis');
30
- redis = new IORedis(redisUrlOrInstance);
31
- shouldCloseOnDestroy = true;
32
- } catch (error) {
33
- throw new Error(
34
- 'ioredis 未安装。请运行: npm install ioredis\n' +
35
- '或传入已创建的 ioredis 实例'
36
- );
37
- }
38
- } else if (redisUrlOrInstance && typeof redisUrlOrInstance === 'object') {
39
- // 传入的是 ioredis 实例
40
- redis = redisUrlOrInstance;
41
- shouldCloseOnDestroy = false;
42
- } else {
43
- throw new Error('redisUrlOrInstance 必须是 Redis URL 字符串或 ioredis 实例');
44
- }
45
-
46
- // 实现 CacheLike 接口的 10 个方法
47
- return {
48
- /**
49
- * 获取单个缓存值
50
- * @param {string} key
51
- * @returns {Promise<any>}
52
- */
53
- async get(key) {
54
- try {
55
- const val = await redis.get(key);
56
- return val ? JSON.parse(val) : undefined;
57
- } catch (error) {
58
- // 解析失败返回 undefined
59
- return undefined;
60
- }
61
- },
62
-
63
- /**
64
- * 获取单个缓存值及剩余 TTL(毫秒),供 MultiLevelCache L2→L1 回填时携带正确 TTL
65
- * 使用 pipeline(GET + PTTL)单次 RTT,避免额外网络开销
66
- * @param {string} key
67
- * @returns {Promise<{value: any, remainingTTL: number}|undefined>}
68
- * key 不存在返回 undefined;value 为 null 时表示缓存了空结果
69
- * @since 1.1.9
70
- */
71
- async getWithTTL(key) {
72
- try {
73
- const [[, rawVal], [, pttl]] = await redis.pipeline().get(key).pttl(key).exec();
74
- // PTTL = -2 表示 key 不存在
75
- if (pttl === -2) return undefined;
76
- let value;
77
- try {
78
- value = JSON.parse(rawVal);
79
- } catch (_) {
80
- return undefined;
81
- }
82
- return {
83
- value,
84
- // PTTL = -1 表示永不过期,映射为 0(与 backfillLocalTTL=0 语义一致)
85
- remainingTTL: pttl > 0 ? pttl : 0,
86
- };
87
- } catch (_) {
88
- return undefined;
89
- }
90
- },
91
-
92
- /**
93
- * 设置单个缓存值
94
- * @param {string} key
95
- * @param {any} val
96
- * @param {number} ttl - TTL(毫秒)
97
- * @returns {Promise<void>}
98
- */
99
- async set(key, val, ttl = 0) {
100
- const str = JSON.stringify(val);
101
- if (ttl > 0) {
102
- await redis.psetex(key, ttl, str);
103
- } else {
104
- await redis.set(key, str);
105
- }
106
- },
107
-
108
- /**
109
- * 删除单个缓存项
110
- * @param {string} key
111
- * @returns {Promise<boolean>}
112
- */
113
- async del(key) {
114
- const result = await redis.del(key);
115
- return result > 0;
116
- },
117
-
118
- /**
119
- * 检查键是否存在
120
- * @param {string} key
121
- * @returns {Promise<boolean>}
122
- */
123
- async exists(key) {
124
- const result = await redis.exists(key);
125
- return result > 0;
126
- },
127
-
128
- /**
129
- * 批量获取
130
- * @param {string[]} keys
131
- * @returns {Promise<Object>}
132
- */
133
- async getMany(keys) {
134
- if (!keys || keys.length === 0) return {};
135
-
136
- const values = await redis.mget(keys);
137
- const result = {};
138
-
139
- keys.forEach((key, i) => {
140
- if (values[i]) {
141
- try {
142
- result[key] = JSON.parse(values[i]);
143
- } catch {
144
- // 解析失败跳过
145
- }
146
- }
147
- });
148
-
149
- return result;
150
- },
151
-
152
- /**
153
- * 批量设置
154
- * @param {Object} obj - 键值对对象
155
- * @param {number} ttl - TTL(毫秒)
156
- * @returns {Promise<boolean>}
157
- */
158
- async setMany(obj, ttl = 0) {
159
- if (!obj || Object.keys(obj).length === 0) return true;
160
-
161
- const pipeline = redis.pipeline();
162
-
163
- for (const [key, val] of Object.entries(obj)) {
164
- const str = JSON.stringify(val);
165
- if (ttl > 0) {
166
- pipeline.psetex(key, ttl, str);
167
- } else {
168
- pipeline.set(key, str);
169
- }
170
- }
171
-
172
- await pipeline.exec();
173
- return true;
174
- },
175
-
176
- /**
177
- * 批量删除
178
- * @param {string[]} keys
179
- * @returns {Promise<number>}
180
- */
181
- async delMany(keys) {
182
- if (!keys || keys.length === 0) return 0;
183
- return await redis.del(...keys);
184
- },
185
-
186
- /**
187
- * 按模式删除(支持通配符 *)
188
- * @param {string} pattern
189
- * @returns {Promise<number>}
190
- */
191
- async delPattern(pattern) {
192
- // 使用 SCAN 避免阻塞(生产环境推荐)
193
- let cursor = '0';
194
- let deletedCount = 0;
195
-
196
- do {
197
- const [nextCursor, keys] = await redis.scan(
198
- cursor,
199
- 'MATCH', pattern,
200
- 'COUNT', 100
201
- );
202
- cursor = nextCursor;
203
-
204
- if (keys.length > 0) {
205
- deletedCount += await redis.del(...keys);
206
- }
207
- } while (cursor !== '0');
208
-
209
- return deletedCount;
210
- },
211
-
212
- /**
213
- * 清空所有缓存(谨慎使用)
214
- * @returns {Promise<void>}
215
- */
216
- async clear() {
217
- await redis.flushdb();
218
- },
219
-
220
- /**
221
- * 获取所有键(可选模式匹配)
222
- * @param {string} pattern
223
- * @returns {Promise<string[]>}
224
- */
225
- async keys(pattern = '*') {
226
- // 使用 SCAN 避免阻塞
227
- const allKeys = [];
228
- let cursor = '0';
229
-
230
- do {
231
- const [nextCursor, keys] = await redis.scan(
232
- cursor,
233
- 'MATCH', pattern,
234
- 'COUNT', 100
235
- );
236
- cursor = nextCursor;
237
- allKeys.push(...keys);
238
- } while (cursor !== '0');
239
-
240
- return allKeys;
241
- },
242
-
243
- /**
244
- * 关闭 Redis 连接(仅当自动创建时才会关闭)
245
- * @returns {Promise<void>}
246
- */
247
- async close() {
248
- if (shouldCloseOnDestroy && redis) {
249
- try {
250
- await redis.quit();
251
- } catch {
252
- // 忽略关闭错误
253
- }
254
- }
255
- },
256
-
257
- /**
258
- * 获取底层 Redis 实例(用于高级操作)
259
- */
260
- getRedisInstance() {
261
- return redis;
262
- }
263
- };
264
- }
265
-
266
- module.exports = { createRedisCacheAdapter };
267
-
@@ -1,67 +0,0 @@
1
- /**
2
- * Saga 执行上下文
3
- * 负责保存执行数据和状态
4
- */
5
- class SagaContext {
6
- /**
7
- * 构造函数
8
- * @param {string} sagaId - Saga 唯一标识
9
- * @param {Object} data - 初始数据
10
- */
11
- constructor(sagaId, data) {
12
- this.sagaId = sagaId;
13
- this.data = data;
14
- this.customData = new Map();
15
- this.completedSteps = [];
16
- this.stepResults = new Map();
17
- }
18
-
19
- /**
20
- * 保存自定义数据
21
- * @param {string} key - 键
22
- * @param {*} value - 值
23
- */
24
- set(key, value) {
25
- this.customData.set(key, value);
26
- }
27
-
28
- /**
29
- * 获取自定义数据
30
- * @param {string} key - 键
31
- * @returns {*} 值
32
- */
33
- get(key) {
34
- return this.customData.get(key);
35
- }
36
-
37
- /**
38
- * 标记步骤完成
39
- * @param {string} stepName - 步骤名称
40
- * @param {*} result - 步骤结果
41
- */
42
- markStepCompleted(stepName, result) {
43
- this.completedSteps.push(stepName);
44
- this.stepResults.set(stepName, result);
45
- }
46
-
47
- /**
48
- * 获取步骤结果
49
- * @param {string} stepName - 步骤名称
50
- * @returns {*} 步骤结果
51
- */
52
- getStepResult(stepName) {
53
- return this.stepResults.get(stepName);
54
- }
55
-
56
- /**
57
- * 获取所有已完成步骤
58
- * @returns {string[]} 已完成步骤名称列表
59
- */
60
- getCompletedSteps() {
61
- return [...this.completedSteps];
62
- }
63
- }
64
-
65
- module.exports = SagaContext;
66
-
67
-
@@ -1,32 +0,0 @@
1
- /**
2
- * Saga 定义
3
- * 封装 Saga 配置和执行逻辑
4
- */
5
- const SagaExecutor = require('./SagaExecutor');
6
-
7
- class SagaDefinition {
8
- /**
9
- * 构造函数
10
- * @param {Object} config - Saga 配置
11
- * @param {Object} orchestrator - Saga 协调器
12
- */
13
- constructor(config, orchestrator) {
14
- this.name = config.name;
15
- this.steps = config.steps;
16
- this.orchestrator = orchestrator;
17
- }
18
-
19
- /**
20
- * 执行 Saga
21
- * @param {Object} data - 执行数据
22
- * @returns {Promise<Object>} 执行结果
23
- */
24
- async execute(data) {
25
- const executor = new SagaExecutor(this, data, this.orchestrator);
26
- return await executor.execute();
27
- }
28
- }
29
-
30
- module.exports = SagaDefinition;
31
-
32
-