mongodash 2.0.0 → 2.1.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 (163) hide show
  1. package/README.md +40 -22
  2. package/dist/dashboard/index.html +40 -0
  3. package/dist/lib/playground/server.js +131 -0
  4. package/dist/lib/playground/server.js.map +1 -0
  5. package/dist/lib/src/ConcurrentRunner.js +148 -0
  6. package/dist/lib/src/ConcurrentRunner.js.map +1 -0
  7. package/dist/lib/{OnError.js → src/OnError.js} +3 -3
  8. package/dist/lib/src/OnError.js.map +1 -0
  9. package/dist/lib/{OnInfo.js → src/OnInfo.js} +6 -3
  10. package/dist/lib/src/OnInfo.js.map +1 -0
  11. package/dist/lib/{createContinuousLock.js → src/createContinuousLock.js} +5 -3
  12. package/dist/lib/src/createContinuousLock.js.map +1 -0
  13. package/dist/lib/{cronTasks.js → src/cronTasks.js} +129 -73
  14. package/dist/lib/src/cronTasks.js.map +1 -0
  15. package/dist/lib/{getCollection.js → src/getCollection.js} +2 -2
  16. package/dist/lib/src/getCollection.js.map +1 -0
  17. package/dist/lib/{getMongoClient.js → src/getMongoClient.js} +2 -2
  18. package/dist/lib/src/getMongoClient.js.map +1 -0
  19. package/dist/lib/src/globalsCollection.js +10 -0
  20. package/dist/lib/src/globalsCollection.js.map +1 -0
  21. package/dist/lib/src/index.js +101 -0
  22. package/dist/lib/src/index.js.map +1 -0
  23. package/dist/lib/{initPromise.js → src/initPromise.js} +2 -3
  24. package/dist/lib/src/initPromise.js.map +1 -0
  25. package/dist/lib/src/mongoCompatibility.js +10 -0
  26. package/dist/lib/src/mongoCompatibility.js.map +1 -0
  27. package/dist/lib/src/parseInterval.js +60 -0
  28. package/dist/lib/src/parseInterval.js.map +1 -0
  29. package/dist/lib/src/prefixFilterKeys.js +69 -0
  30. package/dist/lib/src/prefixFilterKeys.js.map +1 -0
  31. package/dist/lib/src/processInBatches.js +46 -0
  32. package/dist/lib/src/processInBatches.js.map +1 -0
  33. package/dist/lib/src/reactiveTasks/LeaderElector.js +155 -0
  34. package/dist/lib/src/reactiveTasks/LeaderElector.js.map +1 -0
  35. package/dist/lib/src/reactiveTasks/MetricsCollector.js +410 -0
  36. package/dist/lib/src/reactiveTasks/MetricsCollector.js.map +1 -0
  37. package/dist/lib/src/reactiveTasks/ReactiveTaskManager.js +288 -0
  38. package/dist/lib/src/reactiveTasks/ReactiveTaskManager.js.map +1 -0
  39. package/dist/lib/src/reactiveTasks/ReactiveTaskOps.js +185 -0
  40. package/dist/lib/src/reactiveTasks/ReactiveTaskOps.js.map +1 -0
  41. package/dist/lib/src/reactiveTasks/ReactiveTaskPlanner.js +443 -0
  42. package/dist/lib/src/reactiveTasks/ReactiveTaskPlanner.js.map +1 -0
  43. package/dist/lib/src/reactiveTasks/ReactiveTaskReconciler.js +218 -0
  44. package/dist/lib/src/reactiveTasks/ReactiveTaskReconciler.js.map +1 -0
  45. package/dist/lib/src/reactiveTasks/ReactiveTaskRegistry.js +184 -0
  46. package/dist/lib/src/reactiveTasks/ReactiveTaskRegistry.js.map +1 -0
  47. package/dist/lib/src/reactiveTasks/ReactiveTaskRepository.js +355 -0
  48. package/dist/lib/src/reactiveTasks/ReactiveTaskRepository.js.map +1 -0
  49. package/dist/lib/src/reactiveTasks/ReactiveTaskRetryStrategy.js +153 -0
  50. package/dist/lib/src/reactiveTasks/ReactiveTaskRetryStrategy.js.map +1 -0
  51. package/dist/lib/src/reactiveTasks/ReactiveTaskTypes.js +34 -0
  52. package/dist/lib/src/reactiveTasks/ReactiveTaskTypes.js.map +1 -0
  53. package/dist/lib/src/reactiveTasks/ReactiveTaskWorker.js +186 -0
  54. package/dist/lib/src/reactiveTasks/ReactiveTaskWorker.js.map +1 -0
  55. package/dist/lib/src/reactiveTasks/compileWatchProjection.js +65 -0
  56. package/dist/lib/src/reactiveTasks/compileWatchProjection.js.map +1 -0
  57. package/dist/lib/src/reactiveTasks/index.js +298 -0
  58. package/dist/lib/src/reactiveTasks/index.js.map +1 -0
  59. package/dist/lib/src/reactiveTasks/queryToExpression.js +160 -0
  60. package/dist/lib/src/reactiveTasks/queryToExpression.js.map +1 -0
  61. package/dist/lib/src/reactiveTasks/validateTaskFilter.js +88 -0
  62. package/dist/lib/src/reactiveTasks/validateTaskFilter.js.map +1 -0
  63. package/dist/lib/src/task-management/OperationalTaskController.js +162 -0
  64. package/dist/lib/src/task-management/OperationalTaskController.js.map +1 -0
  65. package/dist/lib/src/task-management/index.js +27 -0
  66. package/dist/lib/src/task-management/index.js.map +1 -0
  67. package/dist/lib/src/task-management/serveDashboard.js +149 -0
  68. package/dist/lib/src/task-management/serveDashboard.js.map +1 -0
  69. package/dist/lib/src/task-management/types.js +10 -0
  70. package/dist/lib/src/task-management/types.js.map +1 -0
  71. package/dist/lib/{withLock.js → src/withLock.js} +3 -4
  72. package/dist/lib/src/withLock.js.map +1 -0
  73. package/dist/lib/{withTransaction.js → src/withTransaction.js} +4 -4
  74. package/dist/lib/src/withTransaction.js.map +1 -0
  75. package/dist/lib/tools/check-db-connection.js +28 -0
  76. package/dist/lib/tools/check-db-connection.js.map +1 -0
  77. package/dist/lib/tools/clean-testing-databases.js +12 -0
  78. package/dist/lib/tools/clean-testing-databases.js.map +1 -0
  79. package/dist/lib/tools/prepare-republish.js +27 -0
  80. package/dist/lib/tools/prepare-republish.js.map +1 -0
  81. package/dist/lib/tools/test-matrix-local.js +212 -0
  82. package/dist/lib/tools/test-matrix-local.js.map +1 -0
  83. package/dist/lib/tools/testingDatabase.js +55 -0
  84. package/dist/lib/tools/testingDatabase.js.map +1 -0
  85. package/dist/types/playground/server.d.ts +1 -0
  86. package/dist/types/src/ConcurrentRunner.d.ts +30 -0
  87. package/dist/types/{OnInfo.d.ts → src/OnInfo.d.ts} +1 -1
  88. package/dist/types/{cronTasks.d.ts → src/cronTasks.d.ts} +44 -1
  89. package/dist/types/src/globalsCollection.d.ts +4 -0
  90. package/dist/types/src/index.d.ts +28 -0
  91. package/dist/types/src/mongoCompatibility.d.ts +29 -0
  92. package/dist/types/src/parseInterval.d.ts +12 -0
  93. package/dist/types/src/prefixFilterKeys.d.ts +11 -0
  94. package/dist/types/src/processInBatches.d.ts +10 -0
  95. package/dist/types/src/reactiveTasks/LeaderElector.d.ts +42 -0
  96. package/dist/types/src/reactiveTasks/MetricsCollector.d.ts +73 -0
  97. package/dist/types/src/reactiveTasks/ReactiveTaskManager.d.ts +18 -0
  98. package/dist/types/src/reactiveTasks/ReactiveTaskOps.d.ts +17 -0
  99. package/dist/types/src/reactiveTasks/ReactiveTaskPlanner.d.ts +62 -0
  100. package/dist/types/src/reactiveTasks/ReactiveTaskReconciler.d.ts +29 -0
  101. package/dist/types/src/reactiveTasks/ReactiveTaskRegistry.d.ts +34 -0
  102. package/dist/types/src/reactiveTasks/ReactiveTaskRepository.d.ts +59 -0
  103. package/dist/types/src/reactiveTasks/ReactiveTaskRetryStrategy.d.ts +21 -0
  104. package/dist/types/src/reactiveTasks/ReactiveTaskTypes.d.ts +389 -0
  105. package/dist/types/src/reactiveTasks/ReactiveTaskWorker.d.ts +36 -0
  106. package/dist/types/src/reactiveTasks/compileWatchProjection.d.ts +12 -0
  107. package/dist/types/src/reactiveTasks/index.d.ts +82 -0
  108. package/dist/types/src/reactiveTasks/queryToExpression.d.ts +13 -0
  109. package/dist/types/src/reactiveTasks/validateTaskFilter.d.ts +10 -0
  110. package/dist/types/src/task-management/OperationalTaskController.d.ts +59 -0
  111. package/dist/types/src/task-management/index.d.ts +3 -0
  112. package/dist/types/src/task-management/serveDashboard.d.ts +12 -0
  113. package/dist/types/src/task-management/types.d.ts +95 -0
  114. package/dist/types/tools/check-db-connection.d.ts +2 -0
  115. package/dist/types/tools/clean-testing-databases.d.ts +1 -0
  116. package/dist/types/tools/prepare-republish.d.ts +2 -0
  117. package/dist/types/tools/test-matrix-local.d.ts +1 -0
  118. package/dist/types/tools/testingDatabase.d.ts +2 -0
  119. package/docs/.vitepress/cache/deps/_metadata.json +31 -0
  120. package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js +12824 -0
  121. package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js.map +7 -0
  122. package/docs/.vitepress/cache/deps/package.json +3 -0
  123. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4505 -0
  124. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
  125. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +9731 -0
  126. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
  127. package/docs/.vitepress/cache/deps/vue.js +347 -0
  128. package/docs/.vitepress/cache/deps/vue.js.map +7 -0
  129. package/docs/.vitepress/config.mts +48 -0
  130. package/docs/.vitepress/theme/index.ts +4 -0
  131. package/docs/.vitepress/theme/style.css +16 -0
  132. package/docs/assets/dashboard.png +0 -0
  133. package/docs/cron-tasks.md +172 -0
  134. package/docs/dashboard.md +117 -0
  135. package/docs/getters.md +31 -0
  136. package/docs/getting-started.md +120 -0
  137. package/docs/index.md +29 -0
  138. package/docs/initialization.md +59 -0
  139. package/docs/process-in-batches.md +73 -0
  140. package/docs/reactive-tasks.md +914 -0
  141. package/docs/with-lock.md +45 -0
  142. package/docs/with-transaction.md +65 -0
  143. package/grafana/reactive_tasks.json +765 -0
  144. package/package.json +127 -116
  145. package/dist/lib/OnError.js.map +0 -1
  146. package/dist/lib/OnInfo.js.map +0 -1
  147. package/dist/lib/createContinuousLock.js.map +0 -1
  148. package/dist/lib/cronTasks.js.map +0 -1
  149. package/dist/lib/getCollection.js.map +0 -1
  150. package/dist/lib/getMongoClient.js.map +0 -1
  151. package/dist/lib/index.js +0 -64
  152. package/dist/lib/index.js.map +0 -1
  153. package/dist/lib/initPromise.js.map +0 -1
  154. package/dist/lib/withLock.js.map +0 -1
  155. package/dist/lib/withTransaction.js.map +0 -1
  156. package/dist/types/index.d.ts +0 -17
  157. /package/dist/types/{OnError.d.ts → src/OnError.d.ts} +0 -0
  158. /package/dist/types/{createContinuousLock.d.ts → src/createContinuousLock.d.ts} +0 -0
  159. /package/dist/types/{getCollection.d.ts → src/getCollection.d.ts} +0 -0
  160. /package/dist/types/{getMongoClient.d.ts → src/getMongoClient.d.ts} +0 -0
  161. /package/dist/types/{initPromise.d.ts → src/initPromise.d.ts} +0 -0
  162. /package/dist/types/{withLock.d.ts → src/withLock.d.ts} +0 -0
  163. /package/dist/types/{withTransaction.d.ts → src/withTransaction.d.ts} +0 -0
@@ -0,0 +1,288 @@
1
+ /**!
2
+ * mongodash v2.1.0
3
+ * git+https://github.com/VaclavObornik/mongodash.git
4
+ *
5
+ * Copyright (c) 2025 Václav Oborník
6
+ * Released under the MIT license
7
+ */
8
+ "use strict";
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ReactiveTaskManager = void 0;
11
+ const mongodb_1 = require("mongodb");
12
+ const processInBatches_1 = require("../processInBatches");
13
+ class ReactiveTaskManager {
14
+ constructor(registry) {
15
+ this.registry = registry;
16
+ }
17
+ async getTasks(query, pagination = {}) {
18
+ var _a, _b, _c, _d, _e, _f;
19
+ const groups = await this.resolveCollectionsAndQueries(query, 'getTasks');
20
+ const limit = (_a = pagination.limit) !== null && _a !== void 0 ? _a : 50;
21
+ const offset = (_b = pagination.skip) !== null && _b !== void 0 ? _b : 0;
22
+ const sortField = (_d = (_c = pagination.sort) === null || _c === void 0 ? void 0 : _c.field) !== null && _d !== void 0 ? _d : 'scheduledAt';
23
+ const sortDirection = (_f = (_e = pagination.sort) === null || _e === void 0 ? void 0 : _e.direction) !== null && _f !== void 0 ? _f : 1;
24
+ const sort = { [sortField]: sortDirection };
25
+ // Optimization: If only 1 group, use direct DB query (efficient)
26
+ if (groups.length === 1) {
27
+ const { collection, mongoQuery } = groups[0];
28
+ const [items, total] = await Promise.all([
29
+ collection.repository.findTasks(mongoQuery, { limit, skip: offset, sort }),
30
+ collection.repository.countTasks(mongoQuery),
31
+ ]);
32
+ return { items, total, limit, offset };
33
+ }
34
+ // Scatter-Gather for multiple collections
35
+ // 1. Fetch (limit + offset) from ALL collections (sorted)
36
+ // 2. Merge, Sort in Memory, Apply Limit/Offset
37
+ // NOTE: This is expensive for deep pagination (offset > 1000).
38
+ // For admin dashboard, this is acceptable.
39
+ const fetchLimit = limit + offset;
40
+ const results = await Promise.all(groups.map(async ({ collection, mongoQuery }) => {
41
+ const [items, total] = await Promise.all([
42
+ collection.repository.findTasks(mongoQuery, { limit: fetchLimit, sort }),
43
+ collection.repository.countTasks(mongoQuery),
44
+ ]);
45
+ return { items, total };
46
+ }));
47
+ const allItems = results.flatMap((r) => r.items);
48
+ const total = results.reduce((sum, r) => sum + r.total, 0);
49
+ // Sort in memory
50
+ allItems.sort((a, b) => {
51
+ const fieldA = a[sortField];
52
+ const fieldB = b[sortField];
53
+ // Normalize for comparison
54
+ const valA = fieldA instanceof Date ? fieldA.getTime() : fieldA;
55
+ const valB = fieldB instanceof Date ? fieldB.getTime() : fieldB;
56
+ if (valA === valB)
57
+ return 0;
58
+ if (valA === undefined || valA === null)
59
+ return 1;
60
+ if (valB === undefined || valB === null)
61
+ return -1;
62
+ // Use 'any' cast for comparison to handle potentially mixed but logically comparable types (e.g. string vs string, number vs number)
63
+ // without TypeScript complaining about disjoint union types.
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ if (valA < valB)
66
+ return sortDirection === 1 ? -1 : 1;
67
+ return sortDirection === 1 ? 1 : -1;
68
+ });
69
+ // Slice
70
+ const slicedItems = allItems.slice(offset, offset + limit);
71
+ return {
72
+ items: slicedItems,
73
+ total,
74
+ limit,
75
+ offset,
76
+ };
77
+ }
78
+ async countTasks(query) {
79
+ const groups = await this.resolveCollectionsAndQueries(query, 'countTasks');
80
+ const counts = await Promise.all(groups.map((g) => g.collection.repository.countTasks(g.mongoQuery)));
81
+ return counts.reduce((sum, c) => sum + c, 0);
82
+ }
83
+ async getAllTaskStats() {
84
+ const groups = await this.resolveCollectionsAndQueries({}, 'getAllTaskStats');
85
+ const results = await Promise.all(groups.map((g) => g.collection.repository.getStatistics(g.mongoQuery, {
86
+ includeStatusCounts: true,
87
+ includeErrorCount: true,
88
+ groupByTask: true,
89
+ })));
90
+ const taskStats = {};
91
+ for (const res of results) {
92
+ for (const s of res.statuses) {
93
+ const { task, status } = s._id;
94
+ if (!taskStats[task]) {
95
+ taskStats[task] = { statuses: [], errorCount: 0 };
96
+ }
97
+ taskStats[task].statuses.push({ _id: status, count: s.count });
98
+ }
99
+ // Extract per-task error counts from errorCounts array
100
+ if (res.errorCounts) {
101
+ for (const ec of res.errorCounts) {
102
+ const task = ec._id;
103
+ if (!taskStats[task]) {
104
+ taskStats[task] = { statuses: [], errorCount: 0 };
105
+ }
106
+ taskStats[task].errorCount = (taskStats[task].errorCount || 0) + ec.count;
107
+ }
108
+ }
109
+ }
110
+ return taskStats;
111
+ }
112
+ async getTaskStats(query) {
113
+ const groups = await this.resolveCollectionsAndQueries(query, 'getTaskStats');
114
+ const results = await Promise.all(groups.map((g) => g.collection.repository.getStatistics(g.mongoQuery, {
115
+ includeStatusCounts: true,
116
+ includeErrorCount: true,
117
+ groupByTask: false,
118
+ })));
119
+ const statusMap = new Map();
120
+ let errorCount = 0;
121
+ for (const res of results) {
122
+ errorCount += res.errorCount || 0;
123
+ for (const s of res.statuses) {
124
+ // When groupByTask is false, _id is string (status)
125
+ const status = s._id;
126
+ const current = statusMap.get(status) || 0;
127
+ statusMap.set(status, current + s.count);
128
+ }
129
+ }
130
+ const statuses = Array.from(statusMap.entries()).map(([id, count]) => ({ _id: id, count }));
131
+ return { statuses, errorCount };
132
+ }
133
+ async retryTasks(query) {
134
+ // Validation: Task name is required for retry if sourceDocFilter is complex
135
+ // to identify the source collection.
136
+ // If task name is NOT provided, we can only support simple status/id filters across ALL tasks?
137
+ // Actually, the registry stores tasks by name.
138
+ // If 'query.task' is missing, we might need to iterate ALL registered tasks?
139
+ // Let's support 'task' being optional:
140
+ // 1. If 'task' is provided: target that task's collection.
141
+ // 2. If 'task' is NOT provided: iterate all registered tasks and apply logic.
142
+ const taskNames = this.resolveTaskNames(query.task);
143
+ let totalModified = 0;
144
+ for (const taskName of taskNames) {
145
+ const entry = this.registry.getEntry(this.registry.getTask(taskName).sourceCollection.collectionName);
146
+ const taskQuery = Object.assign(Object.assign({}, query), { task: taskName }); // Ensure we filter by task name in the collection
147
+ // Handle Source Doc Filter
148
+ // If complex filter, use batching
149
+ if (this.isComplexSourceFilter(query.sourceDocFilter)) {
150
+ const sourceCollection = entry.sourceCollection;
151
+ await (0, processInBatches_1.processInBatches)(sourceCollection, [{ $match: query.sourceDocFilter }, { $project: { _id: 1 } }], (doc) => doc._id, async (batchIds) => {
152
+ const batchQuery = this.buildDirectQuery(Object.assign(Object.assign({}, taskQuery), { sourceDocFilter: undefined }));
153
+ batchQuery.sourceDocId = { $in: batchIds };
154
+ // Safety: ensure we are targeting the right task
155
+ batchQuery.task = taskName;
156
+ const res = await entry.repository.resetTasks(batchQuery);
157
+ totalModified += res.modifiedCount;
158
+ }, { batchSize: 1000 });
159
+ }
160
+ else {
161
+ // Direct Update
162
+ const mongoQuery = this.buildDirectQuery(taskQuery);
163
+ const res = await entry.repository.resetTasks(mongoQuery);
164
+ totalModified += res.modifiedCount;
165
+ }
166
+ }
167
+ return { modifiedCount: totalModified };
168
+ }
169
+ resolveTaskNames(taskInput) {
170
+ if (taskInput) {
171
+ const inputs = Array.isArray(taskInput) ? taskInput : [taskInput];
172
+ // Validate exist
173
+ for (const t of inputs) {
174
+ if (!this.registry.getTask(t)) {
175
+ throw new Error(`Task '${t}' not found in registry.`);
176
+ }
177
+ }
178
+ return inputs;
179
+ }
180
+ // If no task specified, target ALL tasks
181
+ return this.registry.getAllTasks().map((t) => t.task);
182
+ }
183
+ async resolveCollectionsAndQueries(query, operation) {
184
+ // Listing/Counting does NOT support complex sourceDocFilter currently
185
+ if (this.isComplexSourceFilter(query.sourceDocFilter)) {
186
+ throw new Error(`Operation '${operation}' does not support complex 'sourceDocFilter'. Use simple ID filter or 'retryTasks'.`);
187
+ }
188
+ const taskNames = this.resolveTaskNames(query.task);
189
+ if (taskNames.length === 0) {
190
+ return [];
191
+ }
192
+ // Group tasks by collection
193
+ const groups = new Map(); // collectionName -> taskNames[]
194
+ for (const tName of taskNames) {
195
+ const t = this.registry.getTask(tName);
196
+ const entry = this.registry.getEntry(t.sourceCollection.collectionName);
197
+ const colName = entry.tasksCollection.collectionName;
198
+ if (!groups.has(colName)) {
199
+ groups.set(colName, []);
200
+ }
201
+ groups.get(colName).push(tName);
202
+ }
203
+ const result = [];
204
+ for (const [, groupTaskNames] of groups) {
205
+ // We need to find the entry associated with this collection.
206
+ // Since we grouped by tasksCollection name, any task in the group points to the same entry (collection-wise).
207
+ const firstTaskInGroup = groupTaskNames[0];
208
+ const t = this.registry.getTask(firstTaskInGroup);
209
+ const entry = this.registry.getEntry(t.sourceCollection.collectionName);
210
+ // Build query for this group
211
+ // We must filter by the tasks in this group
212
+ const mongoQuery = this.buildDirectQuery(Object.assign(Object.assign({}, query), { task: groupTaskNames }));
213
+ result.push({ collection: entry, mongoQuery });
214
+ }
215
+ return result;
216
+ }
217
+ buildDirectQuery(query) {
218
+ const mongoQuery = {};
219
+ if (query.task) {
220
+ if (Array.isArray(query.task)) {
221
+ mongoQuery.task = { $in: query.task };
222
+ }
223
+ else {
224
+ mongoQuery.task = query.task;
225
+ }
226
+ }
227
+ if (query.status) {
228
+ if (Array.isArray(query.status)) {
229
+ mongoQuery.status = { $in: query.status };
230
+ }
231
+ else {
232
+ mongoQuery.status = query.status;
233
+ }
234
+ }
235
+ if (query.errorMessage) {
236
+ if (query.errorMessage instanceof RegExp) {
237
+ mongoQuery.lastError = query.errorMessage;
238
+ }
239
+ else {
240
+ mongoQuery.lastError = { $regex: query.errorMessage, $options: 'i' };
241
+ }
242
+ }
243
+ if (query.sourceDocFilter) {
244
+ // Should be simple filter here
245
+ if (query.sourceDocFilter._id) {
246
+ mongoQuery.sourceDocId = query.sourceDocFilter._id;
247
+ }
248
+ }
249
+ if (query._id) {
250
+ // Convert string _id to ObjectId if it's a valid 24-char hex string
251
+ const id = query._id;
252
+ if (typeof id === 'string' && /^[a-fA-F0-9]{24}$/.test(id)) {
253
+ mongoQuery._id = new mongodb_1.ObjectId(id);
254
+ }
255
+ else if (Array.isArray(id)) {
256
+ mongoQuery._id = {
257
+ $in: id.map((i) => (typeof i === 'string' && /^[a-fA-F0-9]{24}$/.test(i) ? new mongodb_1.ObjectId(i) : i)),
258
+ };
259
+ }
260
+ else {
261
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
262
+ mongoQuery._id = id;
263
+ }
264
+ }
265
+ if (query.hasError !== undefined) {
266
+ if (query.hasError) {
267
+ mongoQuery.lastError = { $exists: true, $ne: null };
268
+ }
269
+ else {
270
+ mongoQuery.lastError = { $exists: false };
271
+ }
272
+ }
273
+ return mongoQuery;
274
+ }
275
+ isComplexSourceFilter(filter) {
276
+ if (!filter)
277
+ return false;
278
+ // Simple if ONLY _id is present
279
+ const keys = Object.keys(filter);
280
+ if (keys.length === 0)
281
+ return false;
282
+ if (keys.length === 1 && keys[0] === '_id')
283
+ return false;
284
+ return true;
285
+ }
286
+ }
287
+ exports.ReactiveTaskManager = ReactiveTaskManager;
288
+ //# sourceMappingURL=ReactiveTaskManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReactiveTaskManager.js","sourceRoot":"","sources":["../../../../src/reactiveTasks/ReactiveTaskManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ /**!
2
+ * mongodash v2.1.0
3
+ * git+https://github.com/VaclavObornik/mongodash.git
4
+ *
5
+ * Copyright (c) 2025 Václav Oborník
6
+ * Released under the MIT license
7
+ */
8
+ "use strict";
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ReactiveTaskOps = void 0;
11
+ const _debug = require("debug");
12
+ const compileWatchProjection_1 = require("./compileWatchProjection");
13
+ const debug = _debug('mongodash:reactiveTasks:ops');
14
+ /**
15
+ * Helper class for generating and executing reactive task operations.
16
+ *
17
+ * Responsibilities:
18
+ * - Generates upsert operations for tasks based on source documents and task definitions.
19
+ * - Executes bulk write operations to the task collections.
20
+ * - Handles duplicate key errors gracefully (which can occur during reconciliation).
21
+ * - Manages debouncing logic by tracking the minimum debounce time for planned tasks.
22
+ */
23
+ class ReactiveTaskOps {
24
+ constructor(registry, onTaskPlanned) {
25
+ this.registry = registry;
26
+ this.onTaskPlanned = onTaskPlanned;
27
+ }
28
+ async executePlanningPipeline(collectionName, sourceDocIds, allowedTaskNames) {
29
+ debug(`executePlanningPipeline called for ${collectionName} with ${sourceDocIds.length} ids`);
30
+ const entry = this.registry.getEntry(collectionName);
31
+ if (!entry) {
32
+ debug(`No entry found for collection ${collectionName}`);
33
+ return;
34
+ }
35
+ const matchFilter = { _id: { $in: sourceDocIds } };
36
+ const pipeline = this.generatePlanningPipeline(entry, matchFilter, allowedTaskNames);
37
+ if (pipeline.length === 0) {
38
+ debug(`Pipeline empty for ${collectionName} (allowedTasks: ${allowedTaskNames ? Array.from(allowedTaskNames).join(',') : 'all'})`);
39
+ return;
40
+ }
41
+ debug(`Executing pipeline for ${collectionName} handling ${sourceDocIds.length} docs`);
42
+ try {
43
+ await entry.sourceCollection.aggregate(pipeline).toArray();
44
+ debug(`Pipeline executed successfully for ${collectionName}`);
45
+ // Notify that tasks have been planned
46
+ for (const task of entry.tasks.values()) {
47
+ if (allowedTaskNames && !allowedTaskNames.has(task.task))
48
+ continue;
49
+ this.onTaskPlanned(task.tasksCollection.collectionName, task.debounceMs);
50
+ }
51
+ }
52
+ catch (error) {
53
+ debug(`Error executing pipeline for ${collectionName}:`, error);
54
+ throw error;
55
+ }
56
+ }
57
+ generatePlanningPipeline(entry, matchFilter, allowedTaskNames) {
58
+ let tasks = Array.from(entry.tasks.values());
59
+ if (allowedTaskNames) {
60
+ tasks = tasks.filter((t) => allowedTaskNames.has(t.task));
61
+ }
62
+ if (tasks.length === 0) {
63
+ return [];
64
+ }
65
+ const pipeline = [
66
+ { $match: matchFilter || {} },
67
+ {
68
+ $project: {
69
+ _id: 0,
70
+ sourceDocId: '$_id',
71
+ tasks: {
72
+ $filter: {
73
+ input: tasks.map((task) => ({
74
+ task: task.task,
75
+ matches: task.filter || true,
76
+ watchedValues: (0, compileWatchProjection_1.compileWatchProjection)(task.watchProjection),
77
+ debounceMs: task.debounceMs,
78
+ resetRetriesOnDataChange: task.retryStrategy.policy.resetRetriesOnDataChange,
79
+ })),
80
+ as: 't',
81
+ cond: '$$t.matches',
82
+ },
83
+ },
84
+ },
85
+ },
86
+ { $unwind: '$tasks' },
87
+ {
88
+ $project: {
89
+ sourceDocId: 1,
90
+ task: '$tasks.task',
91
+ lastObservedValues: '$tasks.watchedValues',
92
+ status: { $literal: 'pending' },
93
+ attempts: { $literal: 0 },
94
+ createdAt: '$$NOW',
95
+ updatedAt: '$$NOW',
96
+ scheduledAt: { $add: ['$$NOW', '$tasks.debounceMs'] },
97
+ resetRetriesOnDataChange: { $ifNull: ['$tasks.resetRetriesOnDataChange', true] },
98
+ },
99
+ },
100
+ {
101
+ $merge: {
102
+ into: entry.tasksCollection.collectionName,
103
+ on: ['task', 'sourceDocId'],
104
+ whenNotMatched: 'insert',
105
+ whenMatched: [
106
+ {
107
+ $set: {
108
+ hasChanged: { $ne: ['$lastObservedValues', '$$new.lastObservedValues'] },
109
+ },
110
+ },
111
+ {
112
+ $set: {
113
+ sourceDocId: '$$new.sourceDocId',
114
+ task: '$$new.task',
115
+ lastObservedValues: '$$new.lastObservedValues',
116
+ updatedAt: {
117
+ $cond: { if: '$hasChanged', then: '$$new.updatedAt', else: '$updatedAt' },
118
+ },
119
+ firstErrorAt: {
120
+ $cond: {
121
+ if: '$hasChanged',
122
+ then: {
123
+ $cond: {
124
+ if: '$$new.resetRetriesOnDataChange',
125
+ then: null,
126
+ else: '$firstErrorAt',
127
+ },
128
+ },
129
+ else: '$firstErrorAt',
130
+ },
131
+ },
132
+ lastError: {
133
+ $cond: {
134
+ if: '$hasChanged',
135
+ then: {
136
+ $cond: {
137
+ if: '$$new.resetRetriesOnDataChange',
138
+ then: null,
139
+ else: '$lastError',
140
+ },
141
+ },
142
+ else: '$lastError',
143
+ },
144
+ },
145
+ status: {
146
+ $cond: {
147
+ if: '$hasChanged',
148
+ then: {
149
+ $cond: {
150
+ if: { $in: ['$status', ['processing', 'processing_dirty']] },
151
+ then: 'processing_dirty',
152
+ else: 'pending',
153
+ },
154
+ },
155
+ else: '$status',
156
+ },
157
+ },
158
+ scheduledAt: {
159
+ $cond: {
160
+ if: '$hasChanged',
161
+ then: {
162
+ $cond: {
163
+ if: { $in: ['$status', ['processing', 'processing_dirty']] },
164
+ then: '$scheduledAt',
165
+ else: '$$new.scheduledAt',
166
+ },
167
+ },
168
+ else: '$scheduledAt',
169
+ },
170
+ },
171
+ attempts: {
172
+ $cond: { if: '$hasChanged', then: 0, else: '$attempts' },
173
+ },
174
+ },
175
+ },
176
+ { $unset: 'hasChanged' },
177
+ ],
178
+ },
179
+ },
180
+ ];
181
+ return pipeline;
182
+ }
183
+ }
184
+ exports.ReactiveTaskOps = ReactiveTaskOps;
185
+ //# sourceMappingURL=ReactiveTaskOps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReactiveTaskOps.js","sourceRoot":"","sources":["../../../../src/reactiveTasks/ReactiveTaskOps.ts"],"names":[],"mappings":"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"}