@auto-engineer/pipeline 0.20.0 → 0.21.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/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-test.log +4 -4
  3. package/.turbo/turbo-type-check.log +1 -1
  4. package/CHANGELOG.md +12 -0
  5. package/dist/tsconfig.tsbuildinfo +1 -1
  6. package/package.json +3 -3
  7. package/coverage/base.css +0 -224
  8. package/coverage/block-navigation.js +0 -87
  9. package/coverage/builder/define.ts.html +0 -2224
  10. package/coverage/builder/index.html +0 -116
  11. package/coverage/config/index.html +0 -116
  12. package/coverage/config/pipeline-config.ts.html +0 -181
  13. package/coverage/core/descriptors.ts.html +0 -397
  14. package/coverage/core/index.html +0 -131
  15. package/coverage/core/types.ts.html +0 -133
  16. package/coverage/coverage-final.json +0 -33
  17. package/coverage/favicon.png +0 -0
  18. package/coverage/graph/filter-graph.ts.html +0 -418
  19. package/coverage/graph/index.html +0 -131
  20. package/coverage/graph/types.ts.html +0 -172
  21. package/coverage/index.html +0 -266
  22. package/coverage/logging/event-logger.ts.html +0 -235
  23. package/coverage/logging/index.html +0 -116
  24. package/coverage/plugins/handler-adapter.ts.html +0 -148
  25. package/coverage/plugins/index.html +0 -131
  26. package/coverage/plugins/plugin-loader.ts.html +0 -691
  27. package/coverage/prettify.css +0 -1
  28. package/coverage/prettify.js +0 -2
  29. package/coverage/projections/await-tracker-projection.ts.html +0 -289
  30. package/coverage/projections/index.html +0 -221
  31. package/coverage/projections/item-status-projection.ts.html +0 -181
  32. package/coverage/projections/latest-run-projection.ts.html +0 -145
  33. package/coverage/projections/message-log-projection.ts.html +0 -424
  34. package/coverage/projections/node-status-projection.ts.html +0 -184
  35. package/coverage/projections/phased-execution-projection.ts.html +0 -523
  36. package/coverage/projections/settled-instance-projection.ts.html +0 -565
  37. package/coverage/projections/stats-projection.ts.html +0 -163
  38. package/coverage/runtime/await-tracker.ts.html +0 -271
  39. package/coverage/runtime/context.ts.html +0 -124
  40. package/coverage/runtime/event-command-map.ts.html +0 -220
  41. package/coverage/runtime/index.html +0 -191
  42. package/coverage/runtime/phased-executor.ts.html +0 -775
  43. package/coverage/runtime/pipeline-runtime.ts.html +0 -448
  44. package/coverage/runtime/settled-tracker.ts.html +0 -790
  45. package/coverage/server/index.html +0 -131
  46. package/coverage/server/pipeline-server.ts.html +0 -3253
  47. package/coverage/server/sse-manager.ts.html +0 -310
  48. package/coverage/sort-arrow-sprite.png +0 -0
  49. package/coverage/sorter.js +0 -210
  50. package/coverage/store/index.html +0 -146
  51. package/coverage/store/pipeline-event-store.ts.html +0 -553
  52. package/coverage/store/pipeline-read-model.ts.html +0 -754
  53. package/coverage/store/sqlite-pipeline-event-store.ts.html +0 -193
  54. package/coverage/testing/event-capture.ts.html +0 -280
  55. package/coverage/testing/index.html +0 -161
  56. package/coverage/testing/mock-handlers.ts.html +0 -259
  57. package/coverage/testing/snapshot-compare.ts.html +0 -403
  58. package/coverage/testing/snapshot-sanitize.ts.html +0 -136
  59. package/dist/src/builder/define.specs.d.ts +0 -2
  60. package/dist/src/builder/define.specs.d.ts.map +0 -1
  61. package/dist/src/builder/define.specs.js +0 -435
  62. package/dist/src/builder/define.specs.js.map +0 -1
  63. package/dist/src/core/descriptors.specs.d.ts +0 -2
  64. package/dist/src/core/descriptors.specs.d.ts.map +0 -1
  65. package/dist/src/core/descriptors.specs.js +0 -24
  66. package/dist/src/core/descriptors.specs.js.map +0 -1
  67. package/dist/src/core/types.specs.d.ts +0 -2
  68. package/dist/src/core/types.specs.d.ts.map +0 -1
  69. package/dist/src/core/types.specs.js +0 -40
  70. package/dist/src/core/types.specs.js.map +0 -1
  71. package/dist/src/graph/filter-graph.specs.d.ts +0 -2
  72. package/dist/src/graph/filter-graph.specs.d.ts.map +0 -1
  73. package/dist/src/graph/filter-graph.specs.js +0 -204
  74. package/dist/src/graph/filter-graph.specs.js.map +0 -1
  75. package/dist/src/graph/types.specs.d.ts +0 -2
  76. package/dist/src/graph/types.specs.d.ts.map +0 -1
  77. package/dist/src/graph/types.specs.js +0 -148
  78. package/dist/src/graph/types.specs.js.map +0 -1
  79. package/dist/src/logging/event-logger.specs.d.ts +0 -2
  80. package/dist/src/logging/event-logger.specs.d.ts.map +0 -1
  81. package/dist/src/logging/event-logger.specs.js +0 -81
  82. package/dist/src/logging/event-logger.specs.js.map +0 -1
  83. package/dist/src/plugins/handler-adapter.specs.d.ts +0 -2
  84. package/dist/src/plugins/handler-adapter.specs.d.ts.map +0 -1
  85. package/dist/src/plugins/handler-adapter.specs.js +0 -129
  86. package/dist/src/plugins/handler-adapter.specs.js.map +0 -1
  87. package/dist/src/plugins/plugin-loader.specs.d.ts +0 -2
  88. package/dist/src/plugins/plugin-loader.specs.d.ts.map +0 -1
  89. package/dist/src/plugins/plugin-loader.specs.js +0 -246
  90. package/dist/src/plugins/plugin-loader.specs.js.map +0 -1
  91. package/dist/src/projections/item-status-projection.specs.d.ts +0 -2
  92. package/dist/src/projections/item-status-projection.specs.d.ts.map +0 -1
  93. package/dist/src/projections/item-status-projection.specs.js +0 -119
  94. package/dist/src/projections/item-status-projection.specs.js.map +0 -1
  95. package/dist/src/projections/latest-run-projection.specs.d.ts +0 -2
  96. package/dist/src/projections/latest-run-projection.specs.d.ts.map +0 -1
  97. package/dist/src/projections/latest-run-projection.specs.js +0 -33
  98. package/dist/src/projections/latest-run-projection.specs.js.map +0 -1
  99. package/dist/src/projections/message-log-projection.specs.d.ts +0 -2
  100. package/dist/src/projections/message-log-projection.specs.d.ts.map +0 -1
  101. package/dist/src/projections/message-log-projection.specs.js +0 -101
  102. package/dist/src/projections/message-log-projection.specs.js.map +0 -1
  103. package/dist/src/projections/node-status-projection.specs.d.ts +0 -2
  104. package/dist/src/projections/node-status-projection.specs.d.ts.map +0 -1
  105. package/dist/src/projections/node-status-projection.specs.js +0 -116
  106. package/dist/src/projections/node-status-projection.specs.js.map +0 -1
  107. package/dist/src/projections/phased-execution-projection.specs.d.ts +0 -2
  108. package/dist/src/projections/phased-execution-projection.specs.d.ts.map +0 -1
  109. package/dist/src/projections/phased-execution-projection.specs.js +0 -171
  110. package/dist/src/projections/phased-execution-projection.specs.js.map +0 -1
  111. package/dist/src/projections/settled-instance-projection.specs.d.ts +0 -2
  112. package/dist/src/projections/settled-instance-projection.specs.d.ts.map +0 -1
  113. package/dist/src/projections/settled-instance-projection.specs.js +0 -217
  114. package/dist/src/projections/settled-instance-projection.specs.js.map +0 -1
  115. package/dist/src/projections/stats-projection.specs.d.ts +0 -2
  116. package/dist/src/projections/stats-projection.specs.d.ts.map +0 -1
  117. package/dist/src/projections/stats-projection.specs.js +0 -91
  118. package/dist/src/projections/stats-projection.specs.js.map +0 -1
  119. package/dist/src/runtime/await-tracker.specs.d.ts +0 -2
  120. package/dist/src/runtime/await-tracker.specs.d.ts.map +0 -1
  121. package/dist/src/runtime/await-tracker.specs.js +0 -64
  122. package/dist/src/runtime/await-tracker.specs.js.map +0 -1
  123. package/dist/src/runtime/context.specs.d.ts +0 -2
  124. package/dist/src/runtime/context.specs.d.ts.map +0 -1
  125. package/dist/src/runtime/context.specs.js +0 -26
  126. package/dist/src/runtime/context.specs.js.map +0 -1
  127. package/dist/src/runtime/event-command-map.specs.d.ts +0 -2
  128. package/dist/src/runtime/event-command-map.specs.d.ts.map +0 -1
  129. package/dist/src/runtime/event-command-map.specs.js +0 -108
  130. package/dist/src/runtime/event-command-map.specs.js.map +0 -1
  131. package/dist/src/runtime/phased-executor.specs.d.ts +0 -2
  132. package/dist/src/runtime/phased-executor.specs.d.ts.map +0 -1
  133. package/dist/src/runtime/phased-executor.specs.js +0 -418
  134. package/dist/src/runtime/phased-executor.specs.js.map +0 -1
  135. package/dist/src/runtime/pipeline-runtime.specs.d.ts +0 -2
  136. package/dist/src/runtime/pipeline-runtime.specs.d.ts.map +0 -1
  137. package/dist/src/runtime/pipeline-runtime.specs.js +0 -227
  138. package/dist/src/runtime/pipeline-runtime.specs.js.map +0 -1
  139. package/dist/src/runtime/settled-tracker.specs.d.ts +0 -2
  140. package/dist/src/runtime/settled-tracker.specs.d.ts.map +0 -1
  141. package/dist/src/runtime/settled-tracker.specs.js +0 -811
  142. package/dist/src/runtime/settled-tracker.specs.js.map +0 -1
  143. package/dist/src/server/full-orchestration.e2e.specs.d.ts +0 -2
  144. package/dist/src/server/full-orchestration.e2e.specs.d.ts.map +0 -1
  145. package/dist/src/server/full-orchestration.e2e.specs.js +0 -561
  146. package/dist/src/server/full-orchestration.e2e.specs.js.map +0 -1
  147. package/dist/src/server/pipeline-server.e2e.specs.d.ts +0 -2
  148. package/dist/src/server/pipeline-server.e2e.specs.d.ts.map +0 -1
  149. package/dist/src/server/pipeline-server.e2e.specs.js +0 -373
  150. package/dist/src/server/pipeline-server.e2e.specs.js.map +0 -1
  151. package/dist/src/server/pipeline-server.specs.d.ts +0 -2
  152. package/dist/src/server/pipeline-server.specs.d.ts.map +0 -1
  153. package/dist/src/server/pipeline-server.specs.js +0 -1407
  154. package/dist/src/server/pipeline-server.specs.js.map +0 -1
  155. package/dist/src/server/sse-manager.specs.d.ts +0 -2
  156. package/dist/src/server/sse-manager.specs.d.ts.map +0 -1
  157. package/dist/src/server/sse-manager.specs.js +0 -178
  158. package/dist/src/server/sse-manager.specs.js.map +0 -1
  159. package/dist/src/store/pipeline-event-store.specs.d.ts +0 -2
  160. package/dist/src/store/pipeline-event-store.specs.d.ts.map +0 -1
  161. package/dist/src/store/pipeline-event-store.specs.js +0 -287
  162. package/dist/src/store/pipeline-event-store.specs.js.map +0 -1
  163. package/dist/src/store/pipeline-read-model.specs.d.ts +0 -2
  164. package/dist/src/store/pipeline-read-model.specs.d.ts.map +0 -1
  165. package/dist/src/store/pipeline-read-model.specs.js +0 -830
  166. package/dist/src/store/pipeline-read-model.specs.js.map +0 -1
  167. package/dist/src/testing/event-capture.specs.d.ts +0 -2
  168. package/dist/src/testing/event-capture.specs.d.ts.map +0 -1
  169. package/dist/src/testing/event-capture.specs.js +0 -114
  170. package/dist/src/testing/event-capture.specs.js.map +0 -1
  171. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.d.ts +0 -2
  172. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.d.ts.map +0 -1
  173. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.js +0 -263
  174. package/dist/src/testing/fixtures/kanban-full.pipeline.specs.js.map +0 -1
  175. package/dist/src/testing/fixtures/kanban.pipeline.specs.d.ts +0 -2
  176. package/dist/src/testing/fixtures/kanban.pipeline.specs.d.ts.map +0 -1
  177. package/dist/src/testing/fixtures/kanban.pipeline.specs.js +0 -29
  178. package/dist/src/testing/fixtures/kanban.pipeline.specs.js.map +0 -1
  179. package/dist/src/testing/kanban-todo.e2e.specs.d.ts +0 -2
  180. package/dist/src/testing/kanban-todo.e2e.specs.d.ts.map +0 -1
  181. package/dist/src/testing/kanban-todo.e2e.specs.js +0 -160
  182. package/dist/src/testing/kanban-todo.e2e.specs.js.map +0 -1
  183. package/dist/src/testing/mock-handlers.specs.d.ts +0 -2
  184. package/dist/src/testing/mock-handlers.specs.d.ts.map +0 -1
  185. package/dist/src/testing/mock-handlers.specs.js +0 -193
  186. package/dist/src/testing/mock-handlers.specs.js.map +0 -1
  187. package/dist/src/testing/real-execution.e2e.specs.d.ts +0 -2
  188. package/dist/src/testing/real-execution.e2e.specs.d.ts.map +0 -1
  189. package/dist/src/testing/real-execution.e2e.specs.js +0 -140
  190. package/dist/src/testing/real-execution.e2e.specs.js.map +0 -1
  191. package/dist/src/testing/real-plugin.e2e.specs.d.ts +0 -2
  192. package/dist/src/testing/real-plugin.e2e.specs.d.ts.map +0 -1
  193. package/dist/src/testing/real-plugin.e2e.specs.js +0 -65
  194. package/dist/src/testing/real-plugin.e2e.specs.js.map +0 -1
  195. package/dist/src/testing/server-startup.e2e.specs.d.ts +0 -2
  196. package/dist/src/testing/server-startup.e2e.specs.d.ts.map +0 -1
  197. package/dist/src/testing/server-startup.e2e.specs.js +0 -104
  198. package/dist/src/testing/server-startup.e2e.specs.js.map +0 -1
  199. package/dist/src/testing/snapshot-compare.specs.d.ts +0 -2
  200. package/dist/src/testing/snapshot-compare.specs.d.ts.map +0 -1
  201. package/dist/src/testing/snapshot-compare.specs.js +0 -112
  202. package/dist/src/testing/snapshot-compare.specs.js.map +0 -1
  203. package/dist/src/testing/snapshot-sanitize.specs.d.ts +0 -2
  204. package/dist/src/testing/snapshot-sanitize.specs.d.ts.map +0 -1
  205. package/dist/src/testing/snapshot-sanitize.specs.js +0 -104
  206. package/dist/src/testing/snapshot-sanitize.specs.js.map +0 -1
@@ -1,830 +0,0 @@
1
- import { getInMemoryDatabase } from '@event-driven-io/emmett';
2
- import { beforeEach, describe, expect, it } from 'vitest';
3
- import { PipelineReadModel } from './pipeline-read-model.js';
4
- describe('PipelineReadModel', () => {
5
- let database;
6
- let readModel;
7
- beforeEach(() => {
8
- database = getInMemoryDatabase();
9
- readModel = new PipelineReadModel(database);
10
- });
11
- describe('computeCommandStats', () => {
12
- it('should return idle stats when no items exist', async () => {
13
- const result = await readModel.computeCommandStats('c1', 'Cmd');
14
- expect(result).toEqual({
15
- pendingCount: 0,
16
- endedCount: 0,
17
- aggregateStatus: 'idle',
18
- });
19
- });
20
- it('should count running items as pending', async () => {
21
- const collection = database.collection('ItemStatus');
22
- await collection.insertOne({
23
- _id: 'c1-Cmd-a',
24
- correlationId: 'c1',
25
- commandType: 'Cmd',
26
- itemKey: 'a',
27
- currentRequestId: 'r1',
28
- status: 'running',
29
- attemptCount: 1,
30
- });
31
- const result = await readModel.computeCommandStats('c1', 'Cmd');
32
- expect(result).toEqual({
33
- pendingCount: 1,
34
- endedCount: 0,
35
- aggregateStatus: 'running',
36
- });
37
- });
38
- it('should count success items as ended', async () => {
39
- const collection = database.collection('ItemStatus');
40
- await collection.insertOne({
41
- _id: 'c1-Cmd-a',
42
- correlationId: 'c1',
43
- commandType: 'Cmd',
44
- itemKey: 'a',
45
- currentRequestId: 'r1',
46
- status: 'success',
47
- attemptCount: 1,
48
- });
49
- const result = await readModel.computeCommandStats('c1', 'Cmd');
50
- expect(result).toEqual({
51
- pendingCount: 0,
52
- endedCount: 1,
53
- aggregateStatus: 'success',
54
- });
55
- });
56
- it('should count error items as ended with error status', async () => {
57
- const collection = database.collection('ItemStatus');
58
- await collection.insertOne({
59
- _id: 'c1-Cmd-a',
60
- correlationId: 'c1',
61
- commandType: 'Cmd',
62
- itemKey: 'a',
63
- currentRequestId: 'r1',
64
- status: 'error',
65
- attemptCount: 1,
66
- });
67
- const result = await readModel.computeCommandStats('c1', 'Cmd');
68
- expect(result).toEqual({
69
- pendingCount: 0,
70
- endedCount: 1,
71
- aggregateStatus: 'error',
72
- });
73
- });
74
- it('should aggregate multiple items correctly', async () => {
75
- const collection = database.collection('ItemStatus');
76
- await collection.insertOne({
77
- _id: 'c1-Cmd-a',
78
- correlationId: 'c1',
79
- commandType: 'Cmd',
80
- itemKey: 'a',
81
- currentRequestId: 'r1',
82
- status: 'running',
83
- attemptCount: 1,
84
- });
85
- await collection.insertOne({
86
- _id: 'c1-Cmd-b',
87
- correlationId: 'c1',
88
- commandType: 'Cmd',
89
- itemKey: 'b',
90
- currentRequestId: 'r2',
91
- status: 'running',
92
- attemptCount: 1,
93
- });
94
- await collection.insertOne({
95
- _id: 'c1-Cmd-c',
96
- correlationId: 'c1',
97
- commandType: 'Cmd',
98
- itemKey: 'c',
99
- currentRequestId: 'r3',
100
- status: 'success',
101
- attemptCount: 1,
102
- });
103
- const result = await readModel.computeCommandStats('c1', 'Cmd');
104
- expect(result).toEqual({
105
- pendingCount: 2,
106
- endedCount: 1,
107
- aggregateStatus: 'running',
108
- });
109
- });
110
- it('should return error status when any item has error and none running', async () => {
111
- const collection = database.collection('ItemStatus');
112
- await collection.insertOne({
113
- _id: 'c1-Cmd-a',
114
- correlationId: 'c1',
115
- commandType: 'Cmd',
116
- itemKey: 'a',
117
- currentRequestId: 'r1',
118
- status: 'success',
119
- attemptCount: 1,
120
- });
121
- await collection.insertOne({
122
- _id: 'c1-Cmd-b',
123
- correlationId: 'c1',
124
- commandType: 'Cmd',
125
- itemKey: 'b',
126
- currentRequestId: 'r2',
127
- status: 'error',
128
- attemptCount: 1,
129
- });
130
- const result = await readModel.computeCommandStats('c1', 'Cmd');
131
- expect(result).toEqual({
132
- pendingCount: 0,
133
- endedCount: 2,
134
- aggregateStatus: 'error',
135
- });
136
- });
137
- it('should filter by correlationId', async () => {
138
- const collection = database.collection('ItemStatus');
139
- await collection.insertOne({
140
- _id: 'c1-Cmd-a',
141
- correlationId: 'c1',
142
- commandType: 'Cmd',
143
- itemKey: 'a',
144
- currentRequestId: 'r1',
145
- status: 'running',
146
- attemptCount: 1,
147
- });
148
- await collection.insertOne({
149
- _id: 'c2-Cmd-a',
150
- correlationId: 'c2',
151
- commandType: 'Cmd',
152
- itemKey: 'a',
153
- currentRequestId: 'r2',
154
- status: 'success',
155
- attemptCount: 1,
156
- });
157
- const result = await readModel.computeCommandStats('c1', 'Cmd');
158
- expect(result).toEqual({
159
- pendingCount: 1,
160
- endedCount: 0,
161
- aggregateStatus: 'running',
162
- });
163
- });
164
- it('should filter by commandType', async () => {
165
- const collection = database.collection('ItemStatus');
166
- await collection.insertOne({
167
- _id: 'c1-CmdA-a',
168
- correlationId: 'c1',
169
- commandType: 'CmdA',
170
- itemKey: 'a',
171
- currentRequestId: 'r1',
172
- status: 'running',
173
- attemptCount: 1,
174
- });
175
- await collection.insertOne({
176
- _id: 'c1-CmdB-a',
177
- correlationId: 'c1',
178
- commandType: 'CmdB',
179
- itemKey: 'a',
180
- currentRequestId: 'r2',
181
- status: 'success',
182
- attemptCount: 1,
183
- });
184
- const result = await readModel.computeCommandStats('c1', 'CmdA');
185
- expect(result).toEqual({
186
- pendingCount: 1,
187
- endedCount: 0,
188
- aggregateStatus: 'running',
189
- });
190
- });
191
- });
192
- describe('hasCorrelation', () => {
193
- it('should return false when no node status exists', async () => {
194
- const result = await readModel.hasCorrelation('c1');
195
- expect(result).toBe(false);
196
- });
197
- it('should return true when node status exists for correlation', async () => {
198
- const collection = database.collection('NodeStatus');
199
- await collection.insertOne({
200
- _id: 'c1-Cmd',
201
- correlationId: 'c1',
202
- commandName: 'Cmd',
203
- status: 'running',
204
- pendingCount: 1,
205
- endedCount: 0,
206
- });
207
- const result = await readModel.hasCorrelation('c1');
208
- expect(result).toBe(true);
209
- });
210
- it('should return false for different correlationId', async () => {
211
- const collection = database.collection('NodeStatus');
212
- await collection.insertOne({
213
- _id: 'c1-Cmd',
214
- correlationId: 'c1',
215
- commandName: 'Cmd',
216
- status: 'running',
217
- pendingCount: 1,
218
- endedCount: 0,
219
- });
220
- const result = await readModel.hasCorrelation('c2');
221
- expect(result).toBe(false);
222
- });
223
- });
224
- describe('getMessages', () => {
225
- it('should return empty array when no messages exist', async () => {
226
- const result = await readModel.getMessages();
227
- expect(result).toEqual([]);
228
- });
229
- it('should return all messages from MessageLog collection', async () => {
230
- const collection = database.collection('MessageLog');
231
- const timestamp = new Date('2025-01-01T00:00:00Z');
232
- await collection.insertOne({
233
- _id: 'r1',
234
- correlationId: 'c1',
235
- requestId: 'r1',
236
- messageType: 'command',
237
- messageName: 'CreateUser',
238
- messageData: { name: 'Alice' },
239
- timestamp,
240
- });
241
- const result = await readModel.getMessages();
242
- expect(result).toHaveLength(1);
243
- expect(result[0]).toMatchObject({
244
- correlationId: 'c1',
245
- requestId: 'r1',
246
- messageType: 'command',
247
- messageName: 'CreateUser',
248
- });
249
- });
250
- it('should return messages filtered by correlationId', async () => {
251
- const collection = database.collection('MessageLog');
252
- const timestamp = new Date('2025-01-01T00:00:00Z');
253
- await collection.insertOne({
254
- _id: 'r1',
255
- correlationId: 'c1',
256
- requestId: 'r1',
257
- messageType: 'command',
258
- messageName: 'CreateUser',
259
- messageData: {},
260
- timestamp,
261
- });
262
- await collection.insertOne({
263
- _id: 'r2',
264
- correlationId: 'c2',
265
- requestId: 'r2',
266
- messageType: 'command',
267
- messageName: 'DeleteUser',
268
- messageData: {},
269
- timestamp,
270
- });
271
- const result = await readModel.getMessages('c1');
272
- expect(result).toHaveLength(1);
273
- expect(result[0].correlationId).toBe('c1');
274
- });
275
- });
276
- describe('getItemStatus', () => {
277
- it('should return null when no item status exists', async () => {
278
- const result = await readModel.getItemStatus('c1', 'CreateUser', 'item1');
279
- expect(result).toBeNull();
280
- });
281
- it('should return item status from ItemStatus collection', async () => {
282
- const collection = database.collection('ItemStatus');
283
- await collection.insertOne({
284
- _id: 'c1-CreateUser-item1',
285
- correlationId: 'c1',
286
- commandType: 'CreateUser',
287
- itemKey: 'item1',
288
- currentRequestId: 'r1',
289
- status: 'running',
290
- attemptCount: 1,
291
- });
292
- const result = await readModel.getItemStatus('c1', 'CreateUser', 'item1');
293
- expect(result).toMatchObject({
294
- correlationId: 'c1',
295
- commandType: 'CreateUser',
296
- itemKey: 'item1',
297
- currentRequestId: 'r1',
298
- status: 'running',
299
- attemptCount: 1,
300
- });
301
- });
302
- it('should return null for different correlationId', async () => {
303
- const collection = database.collection('ItemStatus');
304
- await collection.insertOne({
305
- _id: 'c1-CreateUser-item1',
306
- correlationId: 'c1',
307
- commandType: 'CreateUser',
308
- itemKey: 'item1',
309
- currentRequestId: 'r1',
310
- status: 'running',
311
- attemptCount: 1,
312
- });
313
- const result = await readModel.getItemStatus('c2', 'CreateUser', 'item1');
314
- expect(result).toBeNull();
315
- });
316
- it('should return null for different commandType', async () => {
317
- const collection = database.collection('ItemStatus');
318
- await collection.insertOne({
319
- _id: 'c1-CreateUser-item1',
320
- correlationId: 'c1',
321
- commandType: 'CreateUser',
322
- itemKey: 'item1',
323
- currentRequestId: 'r1',
324
- status: 'running',
325
- attemptCount: 1,
326
- });
327
- const result = await readModel.getItemStatus('c1', 'DeleteUser', 'item1');
328
- expect(result).toBeNull();
329
- });
330
- it('should return null for different itemKey', async () => {
331
- const collection = database.collection('ItemStatus');
332
- await collection.insertOne({
333
- _id: 'c1-CreateUser-item1',
334
- correlationId: 'c1',
335
- commandType: 'CreateUser',
336
- itemKey: 'item1',
337
- currentRequestId: 'r1',
338
- status: 'running',
339
- attemptCount: 1,
340
- });
341
- const result = await readModel.getItemStatus('c1', 'CreateUser', 'item2');
342
- expect(result).toBeNull();
343
- });
344
- });
345
- describe('getNodeStatus', () => {
346
- it('should return null when no node status exists', async () => {
347
- const result = await readModel.getNodeStatus('c1', 'CreateUser');
348
- expect(result).toBeNull();
349
- });
350
- it('should return node status from NodeStatus collection', async () => {
351
- const collection = database.collection('NodeStatus');
352
- await collection.insertOne({
353
- _id: 'c1-CreateUser',
354
- correlationId: 'c1',
355
- commandName: 'CreateUser',
356
- status: 'running',
357
- pendingCount: 1,
358
- endedCount: 0,
359
- });
360
- const result = await readModel.getNodeStatus('c1', 'CreateUser');
361
- expect(result).toEqual({
362
- correlationId: 'c1',
363
- commandName: 'CreateUser',
364
- status: 'running',
365
- pendingCount: 1,
366
- endedCount: 0,
367
- });
368
- });
369
- it('should return null for different correlationId', async () => {
370
- const collection = database.collection('NodeStatus');
371
- await collection.insertOne({
372
- _id: 'c1-CreateUser',
373
- correlationId: 'c1',
374
- commandName: 'CreateUser',
375
- status: 'running',
376
- pendingCount: 1,
377
- endedCount: 0,
378
- });
379
- const result = await readModel.getNodeStatus('c2', 'CreateUser');
380
- expect(result).toBeNull();
381
- });
382
- it('should return null for different commandName', async () => {
383
- const collection = database.collection('NodeStatus');
384
- await collection.insertOne({
385
- _id: 'c1-CreateUser',
386
- correlationId: 'c1',
387
- commandName: 'CreateUser',
388
- status: 'running',
389
- pendingCount: 1,
390
- endedCount: 0,
391
- });
392
- const result = await readModel.getNodeStatus('c1', 'DeleteUser');
393
- expect(result).toBeNull();
394
- });
395
- });
396
- describe('getStats', () => {
397
- it('should return zero stats when no messages exist', async () => {
398
- const result = await readModel.getStats();
399
- expect(result).toEqual({
400
- totalMessages: 0,
401
- totalCommands: 0,
402
- totalEvents: 0,
403
- });
404
- });
405
- it('should return stats from Stats collection', async () => {
406
- const collection = database.collection('Stats');
407
- await collection.insertOne({
408
- _id: 'global',
409
- totalMessages: 10,
410
- totalCommands: 6,
411
- totalEvents: 4,
412
- });
413
- const result = await readModel.getStats();
414
- expect(result).toEqual({
415
- totalMessages: 10,
416
- totalCommands: 6,
417
- totalEvents: 4,
418
- });
419
- });
420
- });
421
- describe('getSettledInstance', () => {
422
- it('should return null when no settled instance exists', async () => {
423
- const result = await readModel.getSettledInstance('template-CmdA', 'c1');
424
- expect(result).toBeNull();
425
- });
426
- it('should return settled instance from collection', async () => {
427
- const collection = database.collection('SettledInstance');
428
- await collection.insertOne({
429
- _id: 'template-CmdA-c1',
430
- instanceId: 'template-CmdA-c1',
431
- templateId: 'template-CmdA',
432
- correlationId: 'c1',
433
- commandTrackers: [{ commandType: 'CmdA', hasStarted: true, hasCompleted: false, events: [] }],
434
- status: 'active',
435
- firedCount: 0,
436
- });
437
- const result = await readModel.getSettledInstance('template-CmdA', 'c1');
438
- expect(result).toMatchObject({
439
- instanceId: 'template-CmdA-c1',
440
- templateId: 'template-CmdA',
441
- correlationId: 'c1',
442
- status: 'active',
443
- });
444
- });
445
- it('should return null for different templateId', async () => {
446
- const collection = database.collection('SettledInstance');
447
- await collection.insertOne({
448
- _id: 'template-CmdA-c1',
449
- instanceId: 'template-CmdA-c1',
450
- templateId: 'template-CmdA',
451
- correlationId: 'c1',
452
- commandTrackers: [],
453
- status: 'active',
454
- firedCount: 0,
455
- });
456
- const result = await readModel.getSettledInstance('template-CmdB', 'c1');
457
- expect(result).toBeNull();
458
- });
459
- it('should return null for different correlationId', async () => {
460
- const collection = database.collection('SettledInstance');
461
- await collection.insertOne({
462
- _id: 'template-CmdA-c1',
463
- instanceId: 'template-CmdA-c1',
464
- templateId: 'template-CmdA',
465
- correlationId: 'c1',
466
- commandTrackers: [],
467
- status: 'active',
468
- firedCount: 0,
469
- });
470
- const result = await readModel.getSettledInstance('template-CmdA', 'c2');
471
- expect(result).toBeNull();
472
- });
473
- });
474
- describe('getActiveSettledInstances', () => {
475
- it('should return empty array when no instances exist', async () => {
476
- const result = await readModel.getActiveSettledInstances('c1');
477
- expect(result).toEqual([]);
478
- });
479
- it('should return only active instances for correlationId', async () => {
480
- const collection = database.collection('SettledInstance');
481
- await collection.insertOne({
482
- _id: 'template-CmdA-c1',
483
- instanceId: 'template-CmdA-c1',
484
- templateId: 'template-CmdA',
485
- correlationId: 'c1',
486
- commandTrackers: [],
487
- status: 'active',
488
- firedCount: 0,
489
- });
490
- await collection.insertOne({
491
- _id: 'template-CmdB-c1',
492
- instanceId: 'template-CmdB-c1',
493
- templateId: 'template-CmdB',
494
- correlationId: 'c1',
495
- commandTrackers: [],
496
- status: 'fired',
497
- firedCount: 1,
498
- });
499
- const result = await readModel.getActiveSettledInstances('c1');
500
- expect(result).toHaveLength(1);
501
- expect(result[0].templateId).toBe('template-CmdA');
502
- });
503
- it('should filter by correlationId', async () => {
504
- const collection = database.collection('SettledInstance');
505
- await collection.insertOne({
506
- _id: 'template-CmdA-c1',
507
- instanceId: 'template-CmdA-c1',
508
- templateId: 'template-CmdA',
509
- correlationId: 'c1',
510
- commandTrackers: [],
511
- status: 'active',
512
- firedCount: 0,
513
- });
514
- await collection.insertOne({
515
- _id: 'template-CmdA-c2',
516
- instanceId: 'template-CmdA-c2',
517
- templateId: 'template-CmdA',
518
- correlationId: 'c2',
519
- commandTrackers: [],
520
- status: 'active',
521
- firedCount: 0,
522
- });
523
- const result = await readModel.getActiveSettledInstances('c1');
524
- expect(result).toHaveLength(1);
525
- expect(result[0].correlationId).toBe('c1');
526
- });
527
- it('should exclude cleaned instances', async () => {
528
- const collection = database.collection('SettledInstance');
529
- await collection.insertOne({
530
- _id: 'template-CmdA-c1',
531
- instanceId: 'template-CmdA-c1',
532
- templateId: 'template-CmdA',
533
- correlationId: 'c1',
534
- commandTrackers: [],
535
- status: 'cleaned',
536
- firedCount: 0,
537
- });
538
- const result = await readModel.getActiveSettledInstances('c1');
539
- expect(result).toEqual([]);
540
- });
541
- });
542
- describe('getPhasedExecution', () => {
543
- it('should return null when no execution exists', async () => {
544
- const result = await readModel.getPhasedExecution('exec-1');
545
- expect(result).toBeNull();
546
- });
547
- it('should return execution from collection', async () => {
548
- const collection = database.collection('PhasedExecution');
549
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
550
- await collection.insertOne({
551
- _id: 'exec-1',
552
- executionId: 'exec-1',
553
- correlationId: 'c1',
554
- handlerId: 'handler-1',
555
- triggerEvent,
556
- items: [{ key: 'a', phase: 'prepare', dispatched: false, completed: false }],
557
- phases: ['prepare'],
558
- currentPhaseIndex: 0,
559
- status: 'active',
560
- failedItems: [],
561
- });
562
- const result = await readModel.getPhasedExecution('exec-1');
563
- expect(result).toMatchObject({
564
- executionId: 'exec-1',
565
- correlationId: 'c1',
566
- handlerId: 'handler-1',
567
- status: 'active',
568
- });
569
- });
570
- it('should return null for different executionId', async () => {
571
- const collection = database.collection('PhasedExecution');
572
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
573
- await collection.insertOne({
574
- _id: 'exec-1',
575
- executionId: 'exec-1',
576
- correlationId: 'c1',
577
- handlerId: 'handler-1',
578
- triggerEvent,
579
- items: [],
580
- phases: ['prepare'],
581
- currentPhaseIndex: 0,
582
- status: 'active',
583
- failedItems: [],
584
- });
585
- const result = await readModel.getPhasedExecution('exec-2');
586
- expect(result).toBeNull();
587
- });
588
- });
589
- describe('getActivePhasedExecutions', () => {
590
- it('should return empty array when no executions exist', async () => {
591
- const result = await readModel.getActivePhasedExecutions('c1');
592
- expect(result).toEqual([]);
593
- });
594
- it('should return only active executions for correlationId', async () => {
595
- const collection = database.collection('PhasedExecution');
596
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
597
- await collection.insertOne({
598
- _id: 'exec-1',
599
- executionId: 'exec-1',
600
- correlationId: 'c1',
601
- handlerId: 'handler-1',
602
- triggerEvent,
603
- items: [],
604
- phases: ['prepare'],
605
- currentPhaseIndex: 0,
606
- status: 'active',
607
- failedItems: [],
608
- });
609
- await collection.insertOne({
610
- _id: 'exec-2',
611
- executionId: 'exec-2',
612
- correlationId: 'c1',
613
- handlerId: 'handler-2',
614
- triggerEvent,
615
- items: [],
616
- phases: ['prepare'],
617
- currentPhaseIndex: 0,
618
- status: 'completed',
619
- failedItems: [],
620
- });
621
- const result = await readModel.getActivePhasedExecutions('c1');
622
- expect(result).toHaveLength(1);
623
- expect(result[0].executionId).toBe('exec-1');
624
- });
625
- it('should filter by correlationId', async () => {
626
- const collection = database.collection('PhasedExecution');
627
- const triggerEvent1 = { type: 'TestEvent', correlationId: 'c1', data: {} };
628
- const triggerEvent2 = { type: 'TestEvent', correlationId: 'c2', data: {} };
629
- await collection.insertOne({
630
- _id: 'exec-1',
631
- executionId: 'exec-1',
632
- correlationId: 'c1',
633
- handlerId: 'handler-1',
634
- triggerEvent: triggerEvent1,
635
- items: [],
636
- phases: ['prepare'],
637
- currentPhaseIndex: 0,
638
- status: 'active',
639
- failedItems: [],
640
- });
641
- await collection.insertOne({
642
- _id: 'exec-2',
643
- executionId: 'exec-2',
644
- correlationId: 'c2',
645
- handlerId: 'handler-1',
646
- triggerEvent: triggerEvent2,
647
- items: [],
648
- phases: ['prepare'],
649
- currentPhaseIndex: 0,
650
- status: 'active',
651
- failedItems: [],
652
- });
653
- const result = await readModel.getActivePhasedExecutions('c1');
654
- expect(result).toHaveLength(1);
655
- expect(result[0].correlationId).toBe('c1');
656
- });
657
- it('should exclude failed executions', async () => {
658
- const collection = database.collection('PhasedExecution');
659
- const triggerEvent = { type: 'TestEvent', correlationId: 'c1', data: {} };
660
- await collection.insertOne({
661
- _id: 'exec-1',
662
- executionId: 'exec-1',
663
- correlationId: 'c1',
664
- handlerId: 'handler-1',
665
- triggerEvent,
666
- items: [],
667
- phases: ['prepare'],
668
- currentPhaseIndex: 0,
669
- status: 'failed',
670
- failedItems: [{ key: 'a', error: { message: 'Failed' } }],
671
- });
672
- const result = await readModel.getActivePhasedExecutions('c1');
673
- expect(result).toEqual([]);
674
- });
675
- });
676
- describe('computeSettledStats', () => {
677
- it('should return pendingCount=1 and status=running when instance is active', async () => {
678
- const collection = database.collection('SettledInstance');
679
- await collection.insertOne({
680
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
681
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
682
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
683
- correlationId: 'c1',
684
- commandTrackers: [
685
- { commandType: 'CheckTests', hasStarted: true, hasCompleted: false, events: [] },
686
- { commandType: 'CheckTypes', hasStarted: true, hasCompleted: false, events: [] },
687
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
688
- ],
689
- status: 'active',
690
- firedCount: 0,
691
- });
692
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
693
- expect(result).toEqual({
694
- status: 'running',
695
- pendingCount: 1,
696
- endedCount: 0,
697
- });
698
- });
699
- it('should return status=error when any collected event contains Failed', async () => {
700
- const collection = database.collection('SettledInstance');
701
- await collection.insertOne({
702
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
703
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
704
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
705
- correlationId: 'c1',
706
- commandTrackers: [
707
- {
708
- commandType: 'CheckTests',
709
- hasStarted: true,
710
- hasCompleted: true,
711
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
712
- },
713
- {
714
- commandType: 'CheckTypes',
715
- hasStarted: true,
716
- hasCompleted: true,
717
- events: [{ type: 'TypeCheckFailed', correlationId: 'c1', data: { errors: 'TS2322' } }],
718
- },
719
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
720
- ],
721
- status: 'active',
722
- firedCount: 0,
723
- });
724
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
725
- expect(result).toEqual({
726
- status: 'error',
727
- pendingCount: 1,
728
- endedCount: 0,
729
- });
730
- });
731
- it('should return endedCount=1 and status=success after handler fires without failures', async () => {
732
- const collection = database.collection('SettledInstance');
733
- await collection.insertOne({
734
- _id: 'template-CheckTests,CheckTypes,CheckLint-c1',
735
- instanceId: 'template-CheckTests,CheckTypes,CheckLint-c1',
736
- templateId: 'template-CheckTests,CheckTypes,CheckLint',
737
- correlationId: 'c1',
738
- commandTrackers: [
739
- { commandType: 'CheckTests', hasStarted: true, hasCompleted: false, events: [] },
740
- { commandType: 'CheckTypes', hasStarted: true, hasCompleted: false, events: [] },
741
- { commandType: 'CheckLint', hasStarted: true, hasCompleted: false, events: [] },
742
- ],
743
- status: 'active',
744
- firedCount: 1,
745
- });
746
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests,CheckTypes,CheckLint');
747
- expect(result).toEqual({
748
- status: 'success',
749
- pendingCount: 1,
750
- endedCount: 1,
751
- });
752
- });
753
- it('should return pendingCount=0 and endedCount when instance status is fired', async () => {
754
- const collection = database.collection('SettledInstance');
755
- await collection.insertOne({
756
- _id: 'template-CheckTests-c1',
757
- instanceId: 'template-CheckTests-c1',
758
- templateId: 'template-CheckTests',
759
- correlationId: 'c1',
760
- commandTrackers: [
761
- {
762
- commandType: 'CheckTests',
763
- hasStarted: true,
764
- hasCompleted: true,
765
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
766
- },
767
- ],
768
- status: 'fired',
769
- firedCount: 2,
770
- });
771
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
772
- expect(result).toEqual({
773
- status: 'success',
774
- pendingCount: 0,
775
- endedCount: 2,
776
- });
777
- });
778
- it('should return status=error when fired instance has failed events', async () => {
779
- const collection = database.collection('SettledInstance');
780
- await collection.insertOne({
781
- _id: 'template-CheckTests-c1',
782
- instanceId: 'template-CheckTests-c1',
783
- templateId: 'template-CheckTests',
784
- correlationId: 'c1',
785
- commandTrackers: [
786
- {
787
- commandType: 'CheckTests',
788
- hasStarted: true,
789
- hasCompleted: true,
790
- events: [{ type: 'TestsFailed', correlationId: 'c1', data: {} }],
791
- },
792
- ],
793
- status: 'fired',
794
- firedCount: 1,
795
- });
796
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
797
- expect(result).toEqual({
798
- status: 'error',
799
- pendingCount: 0,
800
- endedCount: 1,
801
- });
802
- });
803
- it('should return pendingCount=0 and endedCount when instance status is cleaned', async () => {
804
- const collection = database.collection('SettledInstance');
805
- await collection.insertOne({
806
- _id: 'template-CheckTests-c1',
807
- instanceId: 'template-CheckTests-c1',
808
- templateId: 'template-CheckTests',
809
- correlationId: 'c1',
810
- commandTrackers: [
811
- {
812
- commandType: 'CheckTests',
813
- hasStarted: true,
814
- hasCompleted: true,
815
- events: [{ type: 'TestsPassed', correlationId: 'c1', data: {} }],
816
- },
817
- ],
818
- status: 'cleaned',
819
- firedCount: 3,
820
- });
821
- const result = await readModel.computeSettledStats('c1', 'template-CheckTests');
822
- expect(result).toEqual({
823
- status: 'success',
824
- pendingCount: 0,
825
- endedCount: 3,
826
- });
827
- });
828
- });
829
- });
830
- //# sourceMappingURL=pipeline-read-model.specs.js.map