eventmodeler 0.3.1 → 0.3.2
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.
package/dist/index.js
CHANGED
|
@@ -282,14 +282,16 @@ async function main() {
|
|
|
282
282
|
break;
|
|
283
283
|
case 'mark': {
|
|
284
284
|
// mark <slice-name> <status> - status is last arg, slice name is everything before
|
|
285
|
+
// Note: subcommand contains first part of slice name, remainingArgs has the rest
|
|
285
286
|
const validStatuses = ['created', 'in-progress', 'blocked', 'done'];
|
|
286
|
-
const
|
|
287
|
-
|
|
287
|
+
const allArgs = subcommand ? [subcommand, ...remainingArgs] : remainingArgs;
|
|
288
|
+
const lastArg = allArgs[allArgs.length - 1];
|
|
289
|
+
if (allArgs.length < 2 || !validStatuses.includes(lastArg)) {
|
|
288
290
|
console.error('Usage: eventmodeler mark <slice-name> <status>');
|
|
289
291
|
console.error('Valid statuses: created, in-progress, blocked, done');
|
|
290
292
|
process.exit(1);
|
|
291
293
|
}
|
|
292
|
-
const sliceName =
|
|
294
|
+
const sliceName = allArgs.slice(0, -1).join(' ');
|
|
293
295
|
const status = lastArg;
|
|
294
296
|
markSliceStatus(model, filePath, sliceName, status);
|
|
295
297
|
break;
|
package/dist/lib/flow-utils.js
CHANGED
|
@@ -61,12 +61,16 @@ function isElementInSlice(slice, position, width, height) {
|
|
|
61
61
|
centerY >= slice.position.y &&
|
|
62
62
|
centerY <= slice.position.y + slice.size.height);
|
|
63
63
|
}
|
|
64
|
-
// Get all component IDs in a slice
|
|
64
|
+
// Get all component IDs in a slice (including canonical group members for linked copies)
|
|
65
65
|
export function getSliceComponentIds(model, slice) {
|
|
66
66
|
const ids = new Set();
|
|
67
|
+
const canonicalIds = new Set();
|
|
68
|
+
// First pass: collect IDs and canonical IDs of elements in the slice
|
|
67
69
|
for (const screen of model.screens.values()) {
|
|
68
70
|
if (isElementInSlice(slice, screen.position, screen.width, screen.height)) {
|
|
69
71
|
ids.add(screen.id);
|
|
72
|
+
if (screen.canonicalId)
|
|
73
|
+
canonicalIds.add(screen.canonicalId);
|
|
70
74
|
}
|
|
71
75
|
}
|
|
72
76
|
for (const command of model.commands.values()) {
|
|
@@ -77,11 +81,15 @@ export function getSliceComponentIds(model, slice) {
|
|
|
77
81
|
for (const event of model.events.values()) {
|
|
78
82
|
if (isElementInSlice(slice, event.position, event.width, event.height)) {
|
|
79
83
|
ids.add(event.id);
|
|
84
|
+
if (event.canonicalId)
|
|
85
|
+
canonicalIds.add(event.canonicalId);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
for (const readModel of model.readModels.values()) {
|
|
83
89
|
if (isElementInSlice(slice, readModel.position, readModel.width, readModel.height)) {
|
|
84
90
|
ids.add(readModel.id);
|
|
91
|
+
if (readModel.canonicalId)
|
|
92
|
+
canonicalIds.add(readModel.canonicalId);
|
|
85
93
|
}
|
|
86
94
|
}
|
|
87
95
|
for (const processor of model.processors.values()) {
|
|
@@ -89,6 +97,25 @@ export function getSliceComponentIds(model, slice) {
|
|
|
89
97
|
ids.add(processor.id);
|
|
90
98
|
}
|
|
91
99
|
}
|
|
100
|
+
// Second pass: add all elements that share a canonical ID with elements in the slice
|
|
101
|
+
// This ensures flows targeting any element in a canonical group are detected
|
|
102
|
+
if (canonicalIds.size > 0) {
|
|
103
|
+
for (const screen of model.screens.values()) {
|
|
104
|
+
if (screen.canonicalId && canonicalIds.has(screen.canonicalId)) {
|
|
105
|
+
ids.add(screen.id);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
for (const event of model.events.values()) {
|
|
109
|
+
if (event.canonicalId && canonicalIds.has(event.canonicalId)) {
|
|
110
|
+
ids.add(event.id);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
for (const readModel of model.readModels.values()) {
|
|
114
|
+
if (readModel.canonicalId && canonicalIds.has(readModel.canonicalId)) {
|
|
115
|
+
ids.add(readModel.id);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
92
119
|
return ids;
|
|
93
120
|
}
|
|
94
121
|
// Find which slice contains a component
|
|
@@ -292,12 +292,42 @@ export function codegenSlice(model, sliceName) {
|
|
|
292
292
|
const slice = findElementOrExit(model.slices, sliceName, 'slice');
|
|
293
293
|
// 2. Get components inside slice
|
|
294
294
|
const components = getSliceComponents(model, slice);
|
|
295
|
-
// 3. Build component ID set
|
|
295
|
+
// 3. Build component ID set (including canonical group members for linked copies)
|
|
296
296
|
const componentIds = new Set();
|
|
297
297
|
components.commands.forEach(c => componentIds.add(c.id));
|
|
298
|
-
components.events.forEach(e =>
|
|
299
|
-
|
|
300
|
-
|
|
298
|
+
components.events.forEach(e => {
|
|
299
|
+
componentIds.add(e.id);
|
|
300
|
+
// If this is a linked copy, also add all elements in the same canonical group
|
|
301
|
+
if (e.canonicalId) {
|
|
302
|
+
for (const evt of model.events.values()) {
|
|
303
|
+
if (evt.canonicalId === e.canonicalId) {
|
|
304
|
+
componentIds.add(evt.id);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
components.readModels.forEach(rm => {
|
|
310
|
+
componentIds.add(rm.id);
|
|
311
|
+
// If this is a linked copy, also add all elements in the same canonical group
|
|
312
|
+
if (rm.canonicalId) {
|
|
313
|
+
for (const r of model.readModels.values()) {
|
|
314
|
+
if (r.canonicalId === rm.canonicalId) {
|
|
315
|
+
componentIds.add(r.id);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
components.screens.forEach(s => {
|
|
321
|
+
componentIds.add(s.id);
|
|
322
|
+
// If this is a linked copy, also add all elements in the same canonical group
|
|
323
|
+
if (s.canonicalId) {
|
|
324
|
+
for (const scr of model.screens.values()) {
|
|
325
|
+
if (scr.canonicalId === s.canonicalId) {
|
|
326
|
+
componentIds.add(scr.id);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
});
|
|
301
331
|
components.processors.forEach(p => componentIds.add(p.id));
|
|
302
332
|
// 4. Determine slice type
|
|
303
333
|
const sliceType = determineSliceType(components.processors.length > 0, components.commands.length > 0, components.events.length > 0, components.readModels.length > 0, components.screens.length > 0);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { escapeXml, escapeXmlText, outputJson } from '../../lib/format.js';
|
|
2
2
|
import { findElementOrExit } from '../../lib/element-lookup.js';
|
|
3
3
|
import { findChapterForSlice, getChapterHierarchy } from '../../lib/chapter-utils.js';
|
|
4
|
-
import { getInboundFlows, getOutboundFlows, getFlowsForElement, } from '../../lib/flow-utils.js';
|
|
4
|
+
import { getInboundFlows, getOutboundFlows, getFlowsForElement, getSliceComponentIds, } from '../../lib/flow-utils.js';
|
|
5
5
|
function formatFieldValues(values) {
|
|
6
6
|
if (!values || Object.keys(values).length === 0)
|
|
7
7
|
return '';
|
|
@@ -189,12 +189,8 @@ function formatSliceXml(model, slice) {
|
|
|
189
189
|
const components = getSliceComponents(model, slice);
|
|
190
190
|
const scenarios = [...model.scenarios.values()].filter(s => s.sliceId === slice.id);
|
|
191
191
|
const chapter = findChapterForSlice(model, slice);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
components.events.forEach(e => componentIds.add(e.id));
|
|
195
|
-
components.readModels.forEach(rm => componentIds.add(rm.id));
|
|
196
|
-
components.screens.forEach(s => componentIds.add(s.id));
|
|
197
|
-
components.processors.forEach(p => componentIds.add(p.id));
|
|
192
|
+
// Use shared function that handles canonical groups for linked copies
|
|
193
|
+
const componentIds = getSliceComponentIds(model, slice);
|
|
198
194
|
const flows = [...model.flows.values()].filter(f => componentIds.has(f.sourceId) || componentIds.has(f.targetId));
|
|
199
195
|
const internalFlows = flows.filter(f => componentIds.has(f.sourceId) && componentIds.has(f.targetId));
|
|
200
196
|
// Get inbound and outbound flows for the slice
|
|
@@ -430,12 +426,8 @@ function formatSliceJson(model, slice) {
|
|
|
430
426
|
const components = getSliceComponents(model, slice);
|
|
431
427
|
const scenarios = [...model.scenarios.values()].filter(s => s.sliceId === slice.id);
|
|
432
428
|
const chapter = findChapterForSlice(model, slice);
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
components.events.forEach(e => componentIds.add(e.id));
|
|
436
|
-
components.readModels.forEach(rm => componentIds.add(rm.id));
|
|
437
|
-
components.screens.forEach(s => componentIds.add(s.id));
|
|
438
|
-
components.processors.forEach(p => componentIds.add(p.id));
|
|
429
|
+
// Use shared function that handles canonical groups for linked copies
|
|
430
|
+
const componentIds = getSliceComponentIds(model, slice);
|
|
439
431
|
const flows = [...model.flows.values()].filter(f => componentIds.has(f.sourceId) || componentIds.has(f.targetId));
|
|
440
432
|
const internalFlows = flows.filter(f => componentIds.has(f.sourceId) && componentIds.has(f.targetId));
|
|
441
433
|
// Get inbound and outbound flows for the slice
|