eventmodeler 0.5.0 → 0.6.1

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 (150) hide show
  1. package/dist/index.js +6776 -2132
  2. package/package.json +11 -5
  3. package/dist/api/index.d.ts +0 -285
  4. package/dist/api/index.js +0 -323
  5. package/dist/cloud/slices/index.d.ts +0 -276
  6. package/dist/cloud/slices/index.js +0 -406
  7. package/dist/eventmodeler.js +0 -5646
  8. package/dist/formatters.d.ts +0 -17
  9. package/dist/formatters.js +0 -482
  10. package/dist/index.d.ts +0 -2
  11. package/dist/lib/auth.d.ts +0 -24
  12. package/dist/lib/auth.js +0 -331
  13. package/dist/lib/backend.d.ts +0 -43
  14. package/dist/lib/backend.js +0 -73
  15. package/dist/lib/chapter-utils.d.ts +0 -13
  16. package/dist/lib/chapter-utils.js +0 -71
  17. package/dist/lib/cloud-client.d.ts +0 -69
  18. package/dist/lib/cloud-client.js +0 -364
  19. package/dist/lib/config.d.ts +0 -30
  20. package/dist/lib/config.js +0 -95
  21. package/dist/lib/diff/merge-rules.d.ts +0 -45
  22. package/dist/lib/diff/merge-rules.js +0 -210
  23. package/dist/lib/diff/model-differ.d.ts +0 -8
  24. package/dist/lib/diff/model-differ.js +0 -568
  25. package/dist/lib/diff/three-way-merge.d.ts +0 -7
  26. package/dist/lib/diff/three-way-merge.js +0 -390
  27. package/dist/lib/diff/types.d.ts +0 -75
  28. package/dist/lib/diff/types.js +0 -1
  29. package/dist/lib/element-lookup.d.ts +0 -58
  30. package/dist/lib/element-lookup.js +0 -126
  31. package/dist/lib/file-loader.d.ts +0 -8
  32. package/dist/lib/file-loader.js +0 -108
  33. package/dist/lib/flow-utils.d.ts +0 -53
  34. package/dist/lib/flow-utils.js +0 -348
  35. package/dist/lib/format.d.ts +0 -10
  36. package/dist/lib/format.js +0 -23
  37. package/dist/lib/project-config.d.ts +0 -27
  38. package/dist/lib/project-config.js +0 -83
  39. package/dist/lib/slice-utils.d.ts +0 -59
  40. package/dist/lib/slice-utils.js +0 -140
  41. package/dist/local/slices/index.d.ts +0 -11
  42. package/dist/local/slices/index.js +0 -13
  43. package/dist/projection.d.ts +0 -3
  44. package/dist/projection.js +0 -828
  45. package/dist/slices/add-field/index.d.ts +0 -8
  46. package/dist/slices/add-field/index.js +0 -211
  47. package/dist/slices/add-scenario/index.d.ts +0 -27
  48. package/dist/slices/add-scenario/index.js +0 -307
  49. package/dist/slices/codegen-chapter-events/index.d.ts +0 -2
  50. package/dist/slices/codegen-chapter-events/index.js +0 -145
  51. package/dist/slices/codegen-slice/index.d.ts +0 -2
  52. package/dist/slices/codegen-slice/index.js +0 -448
  53. package/dist/slices/create-automation-slice/index.d.ts +0 -2
  54. package/dist/slices/create-automation-slice/index.js +0 -304
  55. package/dist/slices/create-flow/index.d.ts +0 -2
  56. package/dist/slices/create-flow/index.js +0 -183
  57. package/dist/slices/create-state-change-slice/index.d.ts +0 -2
  58. package/dist/slices/create-state-change-slice/index.js +0 -263
  59. package/dist/slices/create-state-view-slice/index.d.ts +0 -2
  60. package/dist/slices/create-state-view-slice/index.js +0 -128
  61. package/dist/slices/diff/index.d.ts +0 -11
  62. package/dist/slices/diff/index.js +0 -293
  63. package/dist/slices/export-eventmodel-to-json/index.d.ts +0 -2
  64. package/dist/slices/export-eventmodel-to-json/index.js +0 -355
  65. package/dist/slices/git/index.d.ts +0 -2
  66. package/dist/slices/git/index.js +0 -125
  67. package/dist/slices/guide/guides/codegen.d.ts +0 -5
  68. package/dist/slices/guide/guides/codegen.js +0 -339
  69. package/dist/slices/guide/guides/connect-slices.d.ts +0 -5
  70. package/dist/slices/guide/guides/connect-slices.js +0 -202
  71. package/dist/slices/guide/guides/create-slices.d.ts +0 -5
  72. package/dist/slices/guide/guides/create-slices.js +0 -303
  73. package/dist/slices/guide/guides/explore.d.ts +0 -5
  74. package/dist/slices/guide/guides/explore.js +0 -251
  75. package/dist/slices/guide/guides/information-flow.d.ts +0 -5
  76. package/dist/slices/guide/guides/information-flow.js +0 -318
  77. package/dist/slices/guide/guides/scenarios.d.ts +0 -5
  78. package/dist/slices/guide/guides/scenarios.js +0 -269
  79. package/dist/slices/guide/index.d.ts +0 -1
  80. package/dist/slices/guide/index.js +0 -40
  81. package/dist/slices/import/index.d.ts +0 -8
  82. package/dist/slices/import/index.js +0 -63
  83. package/dist/slices/init/index.d.ts +0 -5
  84. package/dist/slices/init/index.js +0 -80
  85. package/dist/slices/list-chapters/index.d.ts +0 -3
  86. package/dist/slices/list-chapters/index.js +0 -21
  87. package/dist/slices/list-commands/index.d.ts +0 -3
  88. package/dist/slices/list-commands/index.js +0 -20
  89. package/dist/slices/list-events/index.d.ts +0 -3
  90. package/dist/slices/list-events/index.js +0 -98
  91. package/dist/slices/list-processors/index.d.ts +0 -3
  92. package/dist/slices/list-processors/index.js +0 -20
  93. package/dist/slices/list-readmodels/index.d.ts +0 -3
  94. package/dist/slices/list-readmodels/index.js +0 -21
  95. package/dist/slices/list-scenarios/index.d.ts +0 -3
  96. package/dist/slices/list-scenarios/index.js +0 -35
  97. package/dist/slices/list-screens/index.d.ts +0 -3
  98. package/dist/slices/list-screens/index.js +0 -47
  99. package/dist/slices/list-slices/index.d.ts +0 -3
  100. package/dist/slices/list-slices/index.js +0 -35
  101. package/dist/slices/login/index.d.ts +0 -1
  102. package/dist/slices/login/index.js +0 -20
  103. package/dist/slices/logout/index.d.ts +0 -1
  104. package/dist/slices/logout/index.js +0 -14
  105. package/dist/slices/map-fields/index.d.ts +0 -2
  106. package/dist/slices/map-fields/index.js +0 -269
  107. package/dist/slices/mark-slice-status/index.d.ts +0 -2
  108. package/dist/slices/mark-slice-status/index.js +0 -31
  109. package/dist/slices/merge/index.d.ts +0 -19
  110. package/dist/slices/merge/index.js +0 -147
  111. package/dist/slices/open-app/index.d.ts +0 -1
  112. package/dist/slices/open-app/index.js +0 -36
  113. package/dist/slices/remove-field/index.d.ts +0 -8
  114. package/dist/slices/remove-field/index.js +0 -167
  115. package/dist/slices/remove-scenario/index.d.ts +0 -2
  116. package/dist/slices/remove-scenario/index.js +0 -77
  117. package/dist/slices/search/index.d.ts +0 -3
  118. package/dist/slices/search/index.js +0 -302
  119. package/dist/slices/show-actor/index.d.ts +0 -4
  120. package/dist/slices/show-actor/index.js +0 -115
  121. package/dist/slices/show-aggregate/index.d.ts +0 -3
  122. package/dist/slices/show-aggregate/index.js +0 -108
  123. package/dist/slices/show-aggregate-completeness/index.d.ts +0 -4
  124. package/dist/slices/show-aggregate-completeness/index.js +0 -181
  125. package/dist/slices/show-chapter/index.d.ts +0 -3
  126. package/dist/slices/show-chapter/index.js +0 -195
  127. package/dist/slices/show-command/index.d.ts +0 -3
  128. package/dist/slices/show-command/index.js +0 -133
  129. package/dist/slices/show-completeness/index.d.ts +0 -4
  130. package/dist/slices/show-completeness/index.js +0 -731
  131. package/dist/slices/show-event/index.d.ts +0 -3
  132. package/dist/slices/show-event/index.js +0 -118
  133. package/dist/slices/show-model-summary/index.d.ts +0 -3
  134. package/dist/slices/show-model-summary/index.js +0 -31
  135. package/dist/slices/show-processor/index.d.ts +0 -3
  136. package/dist/slices/show-processor/index.js +0 -111
  137. package/dist/slices/show-readmodel/index.d.ts +0 -3
  138. package/dist/slices/show-readmodel/index.js +0 -158
  139. package/dist/slices/show-scenario/index.d.ts +0 -3
  140. package/dist/slices/show-scenario/index.js +0 -196
  141. package/dist/slices/show-screen/index.d.ts +0 -3
  142. package/dist/slices/show-screen/index.js +0 -139
  143. package/dist/slices/show-slice/index.d.ts +0 -3
  144. package/dist/slices/show-slice/index.js +0 -696
  145. package/dist/slices/update-field/index.d.ts +0 -15
  146. package/dist/slices/update-field/index.js +0 -208
  147. package/dist/slices/whoami/index.d.ts +0 -2
  148. package/dist/slices/whoami/index.js +0 -44
  149. package/dist/types.d.ts +0 -195
  150. package/dist/types.js +0 -1
@@ -1,304 +0,0 @@
1
- import { appendEvent } from '../../lib/file-loader.js';
2
- import { AUTOMATION_SLICE, SLICE_GAP, calculateSlicePosition, validateSliceNameUnique, inferFieldMappings, parseFieldsFromXml, getSlicesToShift, fieldInputToField, } from '../../lib/slice-utils.js';
3
- function getAttr(attrs, name) {
4
- const match = attrs.match(new RegExp(`${name}="([^"]*)"`));
5
- return match ? match[1] : undefined;
6
- }
7
- function parseXmlInput(xml) {
8
- // Parse <automation-slice name="..." after="..." before="...">
9
- const sliceMatch = xml.match(/<automation-slice([^>]*)>/);
10
- if (!sliceMatch) {
11
- throw new Error('Invalid XML: missing <automation-slice> tag');
12
- }
13
- const sliceName = getAttr(sliceMatch[1], 'name');
14
- if (!sliceName) {
15
- throw new Error('Invalid XML: automation-slice must have a name attribute');
16
- }
17
- const after = getAttr(sliceMatch[1], 'after');
18
- const before = getAttr(sliceMatch[1], 'before');
19
- // Parse read-model
20
- const readModelMatch = xml.match(/<read-model([^>]*)>([\s\S]*?)<\/read-model>/);
21
- if (!readModelMatch) {
22
- throw new Error('Invalid XML: missing <read-model> element');
23
- }
24
- const readModelName = getAttr(readModelMatch[1], 'name');
25
- if (!readModelName) {
26
- throw new Error('Invalid XML: read-model must have a name attribute');
27
- }
28
- const readModelFields = parseFieldsFromXml(readModelMatch[2]);
29
- // Parse processor (no fields)
30
- const processorMatch = xml.match(/<processor([^>]*?)(?:\/>|>([\s\S]*?)<\/processor>)/);
31
- if (!processorMatch) {
32
- throw new Error('Invalid XML: missing <processor> element');
33
- }
34
- const processorName = getAttr(processorMatch[1], 'name');
35
- if (!processorName) {
36
- throw new Error('Invalid XML: processor must have a name attribute');
37
- }
38
- // Parse command
39
- const commandMatch = xml.match(/<command([^>]*)>([\s\S]*?)<\/command>/);
40
- if (!commandMatch) {
41
- throw new Error('Invalid XML: missing <command> element');
42
- }
43
- const commandName = getAttr(commandMatch[1], 'name');
44
- if (!commandName) {
45
- throw new Error('Invalid XML: command must have a name attribute');
46
- }
47
- const commandFields = parseFieldsFromXml(commandMatch[2]);
48
- // Parse event
49
- const eventMatch = xml.match(/<event([^>]*)>([\s\S]*?)<\/event>/);
50
- if (!eventMatch) {
51
- throw new Error('Invalid XML: missing <event> element');
52
- }
53
- const eventName = getAttr(eventMatch[1], 'name');
54
- if (!eventName) {
55
- throw new Error('Invalid XML: event must have a name attribute');
56
- }
57
- const eventFields = parseFieldsFromXml(eventMatch[2]);
58
- return {
59
- sliceName,
60
- after,
61
- before,
62
- readModel: { name: readModelName, fields: readModelFields },
63
- processor: { name: processorName },
64
- command: { name: commandName, fields: commandFields },
65
- event: { name: eventName, fields: eventFields },
66
- };
67
- }
68
- export function createAutomationSlice(model, filePath, xmlInput) {
69
- // Parse input
70
- let input;
71
- try {
72
- input = parseXmlInput(xmlInput);
73
- }
74
- catch (err) {
75
- console.error(`Error: ${err.message}`);
76
- process.exit(1);
77
- }
78
- // Validate slice name is unique
79
- try {
80
- validateSliceNameUnique(model, input.sliceName);
81
- }
82
- catch (err) {
83
- console.error(`Error: ${err.message}`);
84
- process.exit(1);
85
- }
86
- // Calculate position
87
- let slicePosition;
88
- try {
89
- slicePosition = calculateSlicePosition(model, AUTOMATION_SLICE.width, {
90
- after: input.after,
91
- before: input.before,
92
- });
93
- }
94
- catch (err) {
95
- console.error(`Error: ${err.message}`);
96
- process.exit(1);
97
- }
98
- // Handle "before" positioning - shift existing slices
99
- if (input.before) {
100
- const shiftAmount = AUTOMATION_SLICE.width + SLICE_GAP;
101
- const toShift = getSlicesToShift(model, slicePosition.x, shiftAmount);
102
- for (const { sliceId, newX, currentY } of toShift) {
103
- appendEvent(filePath, {
104
- type: 'SliceMoved',
105
- data: {
106
- sliceId,
107
- position: { x: newX, y: currentY },
108
- timestamp: Date.now(),
109
- },
110
- });
111
- }
112
- }
113
- // Generate IDs
114
- const sliceId = crypto.randomUUID();
115
- const readModelId = crypto.randomUUID();
116
- const processorId = crypto.randomUUID();
117
- const commandId = crypto.randomUUID();
118
- const eventId = crypto.randomUUID();
119
- const readModelToProcessorFlowId = crypto.randomUUID();
120
- const processorToCommandFlowId = crypto.randomUUID();
121
- const commandToEventFlowId = crypto.randomUUID();
122
- // Convert field inputs to fields with IDs
123
- const readModelFields = input.readModel.fields.map(fieldInputToField);
124
- const commandFields = input.command.fields.map(fieldInputToField);
125
- const eventFields = input.event.fields.map(fieldInputToField);
126
- // Infer field mappings
127
- const readModelToCommandMappings = inferFieldMappings(readModelFields, commandFields);
128
- const commandToEventMappings = inferFieldMappings(commandFields, eventFields);
129
- // Calculate absolute positions for components within the slice
130
- const readModelPosition = {
131
- x: slicePosition.x + AUTOMATION_SLICE.readModel.offsetX,
132
- y: slicePosition.y + AUTOMATION_SLICE.readModel.offsetY,
133
- };
134
- const processorPosition = {
135
- x: slicePosition.x + AUTOMATION_SLICE.processor.offsetX,
136
- y: slicePosition.y + AUTOMATION_SLICE.processor.offsetY,
137
- };
138
- const commandPosition = {
139
- x: slicePosition.x + AUTOMATION_SLICE.command.offsetX,
140
- y: slicePosition.y + AUTOMATION_SLICE.command.offsetY,
141
- };
142
- const eventPosition = {
143
- x: slicePosition.x + AUTOMATION_SLICE.event.offsetX,
144
- y: slicePosition.y + AUTOMATION_SLICE.event.offsetY,
145
- };
146
- // Emit atomic events in sequence
147
- // 1. Create the slice
148
- appendEvent(filePath, {
149
- type: 'SlicePlaced',
150
- data: {
151
- sliceId,
152
- name: input.sliceName,
153
- position: slicePosition,
154
- size: { width: AUTOMATION_SLICE.width, height: AUTOMATION_SLICE.height },
155
- timestamp: Date.now(),
156
- },
157
- });
158
- // 2. Create the read model
159
- appendEvent(filePath, {
160
- type: 'ReadModelStickyPlaced',
161
- data: {
162
- readModelStickyId: readModelId,
163
- name: input.readModel.name,
164
- position: readModelPosition,
165
- width: AUTOMATION_SLICE.readModel.width,
166
- height: AUTOMATION_SLICE.readModel.height,
167
- timestamp: Date.now(),
168
- },
169
- });
170
- // 3. Add read model fields
171
- for (const field of readModelFields) {
172
- appendEvent(filePath, {
173
- type: 'ReadModelFieldAdded',
174
- data: {
175
- readModelStickyId: readModelId,
176
- field,
177
- timestamp: Date.now(),
178
- },
179
- });
180
- }
181
- // 4. Create the processor
182
- appendEvent(filePath, {
183
- type: 'ProcessorPlaced',
184
- data: {
185
- processorId,
186
- name: input.processor.name,
187
- position: processorPosition,
188
- width: AUTOMATION_SLICE.processor.width,
189
- height: AUTOMATION_SLICE.processor.height,
190
- timestamp: Date.now(),
191
- },
192
- });
193
- // 5. Create the command
194
- appendEvent(filePath, {
195
- type: 'CommandStickyPlaced',
196
- data: {
197
- commandStickyId: commandId,
198
- name: input.command.name,
199
- position: commandPosition,
200
- width: AUTOMATION_SLICE.command.width,
201
- height: AUTOMATION_SLICE.command.height,
202
- timestamp: Date.now(),
203
- },
204
- });
205
- // 6. Add command fields
206
- for (const field of commandFields) {
207
- appendEvent(filePath, {
208
- type: 'CommandFieldAdded',
209
- data: {
210
- commandStickyId: commandId,
211
- field,
212
- timestamp: Date.now(),
213
- },
214
- });
215
- }
216
- // 7. Create the event
217
- appendEvent(filePath, {
218
- type: 'EventStickyPlaced',
219
- data: {
220
- eventStickyId: eventId,
221
- name: input.event.name,
222
- position: eventPosition,
223
- width: AUTOMATION_SLICE.event.width,
224
- height: AUTOMATION_SLICE.event.height,
225
- timestamp: Date.now(),
226
- },
227
- });
228
- // 8. Add event fields
229
- for (const field of eventFields) {
230
- appendEvent(filePath, {
231
- type: 'EventFieldAdded',
232
- data: {
233
- eventStickyId: eventId,
234
- field,
235
- timestamp: Date.now(),
236
- },
237
- });
238
- }
239
- // 9. Create read model -> processor flow
240
- appendEvent(filePath, {
241
- type: 'ReadModelToProcessorFlowSpecified',
242
- data: {
243
- flowId: readModelToProcessorFlowId,
244
- readModelStickyId: readModelId,
245
- processorId,
246
- sourceHandle: 'top-source',
247
- targetHandle: 'bottom-target',
248
- timestamp: Date.now(),
249
- },
250
- });
251
- // 10. Add read model -> command field mappings
252
- if (readModelToCommandMappings.length > 0) {
253
- appendEvent(filePath, {
254
- type: 'FieldMappingSpecified',
255
- data: {
256
- flowId: readModelToProcessorFlowId,
257
- mappings: readModelToCommandMappings,
258
- timestamp: Date.now(),
259
- },
260
- });
261
- }
262
- // 11. Create processor -> command flow
263
- appendEvent(filePath, {
264
- type: 'ProcessorToCommandFlowSpecified',
265
- data: {
266
- flowId: processorToCommandFlowId,
267
- processorId,
268
- commandStickyId: commandId,
269
- sourceHandle: 'bottom-source',
270
- targetHandle: 'top-target',
271
- timestamp: Date.now(),
272
- },
273
- });
274
- // 12. Create command -> event flow
275
- appendEvent(filePath, {
276
- type: 'CommandToEventFlowSpecified',
277
- data: {
278
- flowId: commandToEventFlowId,
279
- commandStickyId: commandId,
280
- eventStickyId: eventId,
281
- sourceHandle: 'bottom-source',
282
- targetHandle: 'top-target',
283
- timestamp: Date.now(),
284
- },
285
- });
286
- // 13. Add command -> event field mappings
287
- if (commandToEventMappings.length > 0) {
288
- appendEvent(filePath, {
289
- type: 'FieldMappingSpecified',
290
- data: {
291
- flowId: commandToEventFlowId,
292
- mappings: commandToEventMappings,
293
- timestamp: Date.now(),
294
- },
295
- });
296
- }
297
- console.log(`Created automation slice "${input.sliceName}"`);
298
- console.log(` ReadModel: ${input.readModel.name} (${readModelFields.length} fields)`);
299
- console.log(` Processor: ${input.processor.name}`);
300
- console.log(` Command: ${input.command.name} (${commandFields.length} fields)`);
301
- console.log(` Event: ${input.event.name} (${eventFields.length} fields)`);
302
- console.log(` ReadModel -> Command mappings: ${readModelToCommandMappings.length}`);
303
- console.log(` Command -> Event mappings: ${commandToEventMappings.length}`);
304
- }
@@ -1,2 +0,0 @@
1
- import type { EventModel } from '../../types.js';
2
- export declare function createFlow(model: EventModel, filePath: string, fromName: string, toName: string): void;
@@ -1,183 +0,0 @@
1
- import { appendEvent } from '../../lib/file-loader.js';
2
- import { findElement, excludeLinkedCopies } from '../../lib/element-lookup.js';
3
- function findSource(model, name) {
4
- // Try events first (exclude linked copies - they share identity with canonical original)
5
- const eventResult = findElement(excludeLinkedCopies(model.events), name);
6
- if (eventResult.success) {
7
- return { type: 'event', element: eventResult.element };
8
- }
9
- // Try read models (exclude linked copies)
10
- const readModelResult = findElement(excludeLinkedCopies(model.readModels), name);
11
- if (readModelResult.success) {
12
- return { type: 'readModel', element: readModelResult.element };
13
- }
14
- return null;
15
- }
16
- function findTarget(model, name) {
17
- // Try read models first (exclude linked copies)
18
- const readModelResult = findElement(excludeLinkedCopies(model.readModels), name);
19
- if (readModelResult.success) {
20
- return { type: 'readModel', element: readModelResult.element };
21
- }
22
- // Try screens (exclude linked copies)
23
- const screenResult = findElement(excludeLinkedCopies(model.screens), name);
24
- if (screenResult.success) {
25
- return { type: 'screen', element: screenResult.element };
26
- }
27
- // Try processors
28
- const processorResult = findElement(model.processors, name);
29
- if (processorResult.success) {
30
- return { type: 'processor', element: processorResult.element };
31
- }
32
- return null;
33
- }
34
- function listAvailableSources(model) {
35
- const sources = [];
36
- for (const event of model.events.values()) {
37
- sources.push(` - Event: "${event.name}"`);
38
- }
39
- for (const rm of model.readModels.values()) {
40
- sources.push(` - ReadModel: "${rm.name}"`);
41
- }
42
- return sources;
43
- }
44
- function listAvailableTargets(model) {
45
- const targets = [];
46
- for (const rm of model.readModels.values()) {
47
- targets.push(` - ReadModel: "${rm.name}"`);
48
- }
49
- for (const screen of model.screens.values()) {
50
- targets.push(` - Screen: "${screen.name}"`);
51
- }
52
- for (const proc of model.processors.values()) {
53
- targets.push(` - Processor: "${proc.name}"`);
54
- }
55
- return targets;
56
- }
57
- function flowExists(model, sourceId, targetId) {
58
- for (const flow of model.flows.values()) {
59
- if (flow.sourceId === sourceId && flow.targetId === targetId) {
60
- return true;
61
- }
62
- }
63
- return false;
64
- }
65
- export function createFlow(model, filePath, fromName, toName) {
66
- // Find source element
67
- const source = findSource(model, fromName);
68
- if (!source) {
69
- console.error(`Error: Source not found: "${fromName}"`);
70
- console.error('Valid sources are events or read models.');
71
- const available = listAvailableSources(model);
72
- if (available.length > 0) {
73
- console.error('Available sources:');
74
- available.forEach(s => console.error(s));
75
- }
76
- process.exit(1);
77
- }
78
- // Find target element
79
- const target = findTarget(model, toName);
80
- if (!target) {
81
- console.error(`Error: Target not found: "${toName}"`);
82
- console.error('Valid targets are read models, screens, or processors.');
83
- const available = listAvailableTargets(model);
84
- if (available.length > 0) {
85
- console.error('Available targets:');
86
- available.forEach(t => console.error(t));
87
- }
88
- process.exit(1);
89
- }
90
- // Validate the flow combination
91
- const flowId = crypto.randomUUID();
92
- let event;
93
- if (source.type === 'event' && target.type === 'readModel') {
94
- // Event → ReadModel (event top → read model bottom)
95
- if (flowExists(model, source.element.id, target.element.id)) {
96
- console.error(`Error: Flow already exists from "${source.element.name}" to "${target.element.name}"`);
97
- process.exit(1);
98
- }
99
- event = {
100
- type: 'EventToReadModelFlowSpecified',
101
- data: {
102
- flowId,
103
- eventStickyId: source.element.id,
104
- readModelStickyId: target.element.id,
105
- sourceHandle: 'top-source',
106
- targetHandle: 'bottom-target',
107
- timestamp: Date.now(),
108
- },
109
- };
110
- appendEvent(filePath, event);
111
- console.log(`Created flow: Event "${source.element.name}" → ReadModel "${target.element.name}"`);
112
- }
113
- else if (source.type === 'readModel' && target.type === 'screen') {
114
- // ReadModel → Screen (read model top → screen bottom)
115
- if (flowExists(model, source.element.id, target.element.id)) {
116
- console.error(`Error: Flow already exists from "${source.element.name}" to "${target.element.name}"`);
117
- process.exit(1);
118
- }
119
- event = {
120
- type: 'ReadModelToScreenFlowSpecified',
121
- data: {
122
- flowId,
123
- readModelStickyId: source.element.id,
124
- screenId: target.element.id,
125
- sourceHandle: 'top-source',
126
- targetHandle: 'bottom-target',
127
- timestamp: Date.now(),
128
- },
129
- };
130
- appendEvent(filePath, event);
131
- console.log(`Created flow: ReadModel "${source.element.name}" → Screen "${target.element.name}"`);
132
- }
133
- else if (source.type === 'readModel' && target.type === 'processor') {
134
- // ReadModel → Processor (read model top → processor bottom)
135
- if (flowExists(model, source.element.id, target.element.id)) {
136
- console.error(`Error: Flow already exists from "${source.element.name}" to "${target.element.name}"`);
137
- process.exit(1);
138
- }
139
- event = {
140
- type: 'ReadModelToProcessorFlowSpecified',
141
- data: {
142
- flowId,
143
- readModelStickyId: source.element.id,
144
- processorId: target.element.id,
145
- sourceHandle: 'top-source',
146
- targetHandle: 'bottom-target',
147
- timestamp: Date.now(),
148
- },
149
- };
150
- appendEvent(filePath, event);
151
- console.log(`Created flow: ReadModel "${source.element.name}" → Processor "${target.element.name}"`);
152
- }
153
- else if (source.type === 'event' && target.type === 'screen') {
154
- console.error('Error: Cannot create flow directly from Event to Screen.');
155
- console.error('Events flow to ReadModels, which then flow to Screens.');
156
- console.error('Create a ReadModel first, then:');
157
- console.error(` 1. eventmodeler create flow --from "${source.element.name}" --to "<ReadModelName>"`);
158
- console.error(` 2. eventmodeler create flow --from "<ReadModelName>" --to "${target.element.name}"`);
159
- process.exit(1);
160
- }
161
- else if (source.type === 'event' && target.type === 'processor') {
162
- console.error('Error: Cannot create flow directly from Event to Processor.');
163
- console.error('Events flow to ReadModels, which then flow to Processors.');
164
- console.error('Create a ReadModel first, then:');
165
- console.error(` 1. eventmodeler create flow --from "${source.element.name}" --to "<ReadModelName>"`);
166
- console.error(` 2. eventmodeler create flow --from "<ReadModelName>" --to "${target.element.name}"`);
167
- process.exit(1);
168
- }
169
- else if (source.type === 'readModel' && target.type === 'readModel') {
170
- console.error('Error: Cannot create flow from ReadModel to ReadModel.');
171
- console.error('ReadModels receive data from Events and provide data to Screens or Processors.');
172
- process.exit(1);
173
- }
174
- else {
175
- console.error(`Error: Invalid flow combination: ${source.type} → ${target.type}`);
176
- console.error('Valid combinations:');
177
- console.error(' - Event → ReadModel');
178
- console.error(' - ReadModel → Screen');
179
- console.error(' - ReadModel → Processor');
180
- process.exit(1);
181
- }
182
- console.log(`Use 'eventmodeler map fields --flow "${fromName}→${toName}"' to set field mappings.`);
183
- }
@@ -1,2 +0,0 @@
1
- import type { EventModel } from '../../types.js';
2
- export declare function createStateChangeSlice(model: EventModel, filePath: string, xmlInput: string): void;