@aranzatech/diagrams-bpmn 0.1.3 → 0.2.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 (42) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +121 -0
  3. package/dist/{chunk-4AX573IV.js → chunk-5GRCJ5X6.js} +2 -2
  4. package/dist/{chunk-4AX573IV.js.map → chunk-5GRCJ5X6.js.map} +1 -1
  5. package/dist/chunk-G5S4ASP3.js +277 -0
  6. package/dist/chunk-G5S4ASP3.js.map +1 -0
  7. package/dist/{chunk-W3ROOC6E.js → chunk-MF2WE3OM.js} +145 -36
  8. package/dist/chunk-MF2WE3OM.js.map +1 -0
  9. package/dist/chunk-OZKTOILD.js +3 -0
  10. package/dist/chunk-OZKTOILD.js.map +1 -0
  11. package/dist/{chunk-NXMUX67A.js → chunk-S3GGEEA5.js} +31 -8
  12. package/dist/chunk-S3GGEEA5.js.map +1 -0
  13. package/dist/elements/index.d.cts +2 -2
  14. package/dist/elements/index.d.ts +2 -2
  15. package/dist/elements/index.js +2 -1
  16. package/dist/index.cjs +454 -66
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +7 -62
  19. package/dist/index.d.ts +7 -62
  20. package/dist/index.js +6 -40
  21. package/dist/index.js.map +1 -1
  22. package/dist/modeling/index.cjs +894 -0
  23. package/dist/modeling/index.cjs.map +1 -0
  24. package/dist/modeling/index.d.cts +88 -0
  25. package/dist/modeling/index.d.ts +88 -0
  26. package/dist/modeling/index.js +5 -0
  27. package/dist/modeling/index.js.map +1 -0
  28. package/dist/nodes/index.cjs +29 -6
  29. package/dist/nodes/index.cjs.map +1 -1
  30. package/dist/nodes/index.js +1 -1
  31. package/dist/{types-C78d_Kdh.d.cts → types-BKA0GZz5.d.cts} +6 -18
  32. package/dist/{types-C78d_Kdh.d.ts → types-BKA0GZz5.d.ts} +6 -18
  33. package/dist/types-CCkHqtC_.d.cts +20 -0
  34. package/dist/types-hj621ZRJ.d.ts +20 -0
  35. package/dist/xml/index.cjs +143 -34
  36. package/dist/xml/index.cjs.map +1 -1
  37. package/dist/xml/index.d.cts +4 -19
  38. package/dist/xml/index.d.ts +4 -19
  39. package/dist/xml/index.js +1 -1
  40. package/package.json +10 -3
  41. package/dist/chunk-NXMUX67A.js.map +0 -1
  42. package/dist/chunk-W3ROOC6E.js.map +0 -1
@@ -0,0 +1,894 @@
1
+ 'use strict';
2
+
3
+ var diagramsCore = require('@aranzatech/diagrams-core');
4
+ var serialization = require('@aranzatech/diagrams-core/serialization');
5
+
6
+ // src/modeling/index.ts
7
+
8
+ // src/elements/catalog.ts
9
+ var BPMN_ELEMENT_CATALOG = {
10
+ // ─── Events ──────────────────────────────────────────────────────────────────
11
+ StartEvent: {
12
+ label: "Start Event",
13
+ icon: "Circle",
14
+ category: "event",
15
+ defaultWidth: 36,
16
+ defaultHeight: 36,
17
+ handlePolicy: "source",
18
+ orientation: "free",
19
+ isContainer: false,
20
+ acceptsBoundaryEvents: false,
21
+ eventSemantics: "start",
22
+ canBeStart: true,
23
+ canBeEnd: false,
24
+ maxIncoming: 0,
25
+ maxOutgoing: 1
26
+ },
27
+ EndEvent: {
28
+ label: "End Event",
29
+ icon: "CircleDot",
30
+ category: "event",
31
+ defaultWidth: 36,
32
+ defaultHeight: 36,
33
+ handlePolicy: "target",
34
+ orientation: "free",
35
+ isContainer: false,
36
+ acceptsBoundaryEvents: false,
37
+ eventSemantics: "end",
38
+ canBeStart: false,
39
+ canBeEnd: true,
40
+ maxOutgoing: 0
41
+ },
42
+ IntermediateCatchEvent: {
43
+ label: "Intermediate Catch Event",
44
+ icon: "Clock",
45
+ category: "event",
46
+ defaultWidth: 36,
47
+ defaultHeight: 36,
48
+ handlePolicy: "all",
49
+ orientation: "free",
50
+ isContainer: false,
51
+ acceptsBoundaryEvents: false,
52
+ eventSemantics: "intermediateCatch",
53
+ canBeStart: false,
54
+ canBeEnd: false
55
+ },
56
+ IntermediateThrowEvent: {
57
+ label: "Intermediate Throw Event",
58
+ icon: "Zap",
59
+ category: "event",
60
+ defaultWidth: 36,
61
+ defaultHeight: 36,
62
+ handlePolicy: "all",
63
+ orientation: "free",
64
+ isContainer: false,
65
+ acceptsBoundaryEvents: false,
66
+ eventSemantics: "intermediateThrow",
67
+ canBeStart: false,
68
+ canBeEnd: false
69
+ },
70
+ BoundaryEvent: {
71
+ label: "Boundary Event",
72
+ icon: "AlertCircle",
73
+ category: "event",
74
+ defaultWidth: 36,
75
+ defaultHeight: 36,
76
+ handlePolicy: "source",
77
+ orientation: "free",
78
+ isContainer: false,
79
+ acceptsBoundaryEvents: false,
80
+ eventSemantics: "boundary",
81
+ canBeStart: false,
82
+ canBeEnd: false,
83
+ maxIncoming: 0
84
+ },
85
+ // ─── Tasks ───────────────────────────────────────────────────────────────────
86
+ Task: {
87
+ label: "Task",
88
+ icon: "Square",
89
+ category: "task",
90
+ defaultWidth: 120,
91
+ defaultHeight: 60,
92
+ handlePolicy: "all",
93
+ orientation: "free",
94
+ isContainer: false,
95
+ acceptsBoundaryEvents: true,
96
+ supportsMarkers: true,
97
+ canBeStart: false,
98
+ canBeEnd: false
99
+ },
100
+ UserTask: {
101
+ label: "User Task",
102
+ icon: "User",
103
+ category: "task",
104
+ defaultWidth: 120,
105
+ defaultHeight: 60,
106
+ handlePolicy: "all",
107
+ orientation: "free",
108
+ isContainer: false,
109
+ acceptsBoundaryEvents: true,
110
+ supportsMarkers: true,
111
+ canBeStart: false,
112
+ canBeEnd: false
113
+ },
114
+ ServiceTask: {
115
+ label: "Service Task",
116
+ icon: "Settings",
117
+ category: "task",
118
+ defaultWidth: 120,
119
+ defaultHeight: 60,
120
+ handlePolicy: "all",
121
+ orientation: "free",
122
+ isContainer: false,
123
+ acceptsBoundaryEvents: true,
124
+ supportsMarkers: true,
125
+ canBeStart: false,
126
+ canBeEnd: false
127
+ },
128
+ ScriptTask: {
129
+ label: "Script Task",
130
+ icon: "FileCode",
131
+ category: "task",
132
+ defaultWidth: 120,
133
+ defaultHeight: 60,
134
+ handlePolicy: "all",
135
+ orientation: "free",
136
+ isContainer: false,
137
+ acceptsBoundaryEvents: true,
138
+ supportsMarkers: true,
139
+ canBeStart: false,
140
+ canBeEnd: false
141
+ },
142
+ ManualTask: {
143
+ label: "Manual Task",
144
+ icon: "Hand",
145
+ category: "task",
146
+ defaultWidth: 120,
147
+ defaultHeight: 60,
148
+ handlePolicy: "all",
149
+ orientation: "free",
150
+ isContainer: false,
151
+ acceptsBoundaryEvents: true,
152
+ supportsMarkers: true,
153
+ canBeStart: false,
154
+ canBeEnd: false
155
+ },
156
+ BusinessRuleTask: {
157
+ label: "Business Rule Task",
158
+ icon: "Scale",
159
+ category: "task",
160
+ defaultWidth: 120,
161
+ defaultHeight: 60,
162
+ handlePolicy: "all",
163
+ orientation: "free",
164
+ isContainer: false,
165
+ acceptsBoundaryEvents: true,
166
+ supportsMarkers: true,
167
+ canBeStart: false,
168
+ canBeEnd: false
169
+ },
170
+ ReceiveTask: {
171
+ label: "Receive Task",
172
+ icon: "Mail",
173
+ category: "task",
174
+ defaultWidth: 120,
175
+ defaultHeight: 60,
176
+ handlePolicy: "all",
177
+ orientation: "free",
178
+ isContainer: false,
179
+ acceptsBoundaryEvents: true,
180
+ supportsMarkers: true,
181
+ canBeStart: false,
182
+ canBeEnd: false
183
+ },
184
+ SendTask: {
185
+ label: "Send Task",
186
+ icon: "Send",
187
+ category: "task",
188
+ defaultWidth: 120,
189
+ defaultHeight: 60,
190
+ handlePolicy: "all",
191
+ orientation: "free",
192
+ isContainer: false,
193
+ acceptsBoundaryEvents: true,
194
+ supportsMarkers: true,
195
+ canBeStart: false,
196
+ canBeEnd: false
197
+ },
198
+ CallActivity: {
199
+ label: "Call Activity",
200
+ icon: "ExternalLink",
201
+ category: "task",
202
+ defaultWidth: 120,
203
+ defaultHeight: 60,
204
+ handlePolicy: "all",
205
+ orientation: "free",
206
+ isContainer: false,
207
+ acceptsBoundaryEvents: true,
208
+ supportsMarkers: true,
209
+ canBeStart: false,
210
+ canBeEnd: false
211
+ },
212
+ // ─── Gateways ────────────────────────────────────────────────────────────────
213
+ ExclusiveGateway: {
214
+ label: "Exclusive Gateway",
215
+ icon: "GitBranch",
216
+ category: "gateway",
217
+ defaultWidth: 50,
218
+ defaultHeight: 50,
219
+ handlePolicy: "all",
220
+ orientation: "free",
221
+ isContainer: false,
222
+ acceptsBoundaryEvents: false,
223
+ canBeStart: false,
224
+ canBeEnd: false
225
+ },
226
+ InclusiveGateway: {
227
+ label: "Inclusive Gateway",
228
+ icon: "GitMerge",
229
+ category: "gateway",
230
+ defaultWidth: 50,
231
+ defaultHeight: 50,
232
+ handlePolicy: "all",
233
+ orientation: "free",
234
+ isContainer: false,
235
+ acceptsBoundaryEvents: false,
236
+ canBeStart: false,
237
+ canBeEnd: false
238
+ },
239
+ ParallelGateway: {
240
+ label: "Parallel Gateway",
241
+ icon: "GitFork",
242
+ category: "gateway",
243
+ defaultWidth: 50,
244
+ defaultHeight: 50,
245
+ handlePolicy: "all",
246
+ orientation: "free",
247
+ isContainer: false,
248
+ acceptsBoundaryEvents: false,
249
+ canBeStart: false,
250
+ canBeEnd: false
251
+ },
252
+ EventBasedGateway: {
253
+ label: "Event-Based Gateway",
254
+ icon: "Radio",
255
+ category: "gateway",
256
+ defaultWidth: 50,
257
+ defaultHeight: 50,
258
+ handlePolicy: "all",
259
+ orientation: "free",
260
+ isContainer: false,
261
+ acceptsBoundaryEvents: false,
262
+ canBeStart: false,
263
+ canBeEnd: false,
264
+ maxIncoming: 1
265
+ },
266
+ ComplexGateway: {
267
+ label: "Complex Gateway",
268
+ icon: "Asterisk",
269
+ category: "gateway",
270
+ defaultWidth: 50,
271
+ defaultHeight: 50,
272
+ handlePolicy: "all",
273
+ orientation: "free",
274
+ isContainer: false,
275
+ acceptsBoundaryEvents: false,
276
+ canBeStart: false,
277
+ canBeEnd: false
278
+ },
279
+ // ─── Containers ───────────────────────────────────────────────────────────────
280
+ SubProcess: {
281
+ label: "Sub-Process",
282
+ icon: "Layout",
283
+ category: "container",
284
+ defaultWidth: 350,
285
+ defaultHeight: 200,
286
+ handlePolicy: "all",
287
+ orientation: "horizontal",
288
+ isContainer: true,
289
+ acceptsBoundaryEvents: true,
290
+ supportsCollapse: true,
291
+ supportsMarkers: true,
292
+ canBeStart: false,
293
+ canBeEnd: false
294
+ },
295
+ Transaction: {
296
+ label: "Transaction",
297
+ icon: "CreditCard",
298
+ category: "container",
299
+ defaultWidth: 350,
300
+ defaultHeight: 200,
301
+ handlePolicy: "all",
302
+ orientation: "horizontal",
303
+ isContainer: true,
304
+ acceptsBoundaryEvents: true,
305
+ supportsCollapse: true,
306
+ supportsMarkers: true,
307
+ canBeStart: false,
308
+ canBeEnd: false
309
+ },
310
+ EventSubProcess: {
311
+ label: "Event Sub-Process",
312
+ icon: "Workflow",
313
+ category: "container",
314
+ defaultWidth: 350,
315
+ defaultHeight: 200,
316
+ handlePolicy: "all",
317
+ orientation: "horizontal",
318
+ isContainer: true,
319
+ acceptsBoundaryEvents: false,
320
+ supportsCollapse: true,
321
+ supportsMarkers: true,
322
+ canBeStart: false,
323
+ canBeEnd: false
324
+ },
325
+ AdHocSubProcess: {
326
+ label: "Ad-Hoc Sub-Process",
327
+ icon: "Shuffle",
328
+ category: "container",
329
+ defaultWidth: 350,
330
+ defaultHeight: 200,
331
+ handlePolicy: "all",
332
+ orientation: "horizontal",
333
+ isContainer: true,
334
+ acceptsBoundaryEvents: true,
335
+ supportsCollapse: true,
336
+ supportsMarkers: true,
337
+ canBeStart: false,
338
+ canBeEnd: false
339
+ },
340
+ Pool: {
341
+ label: "Pool",
342
+ icon: "Columns",
343
+ category: "container",
344
+ defaultWidth: 600,
345
+ defaultHeight: 200,
346
+ handlePolicy: "none",
347
+ orientation: "horizontal",
348
+ isContainer: true,
349
+ acceptsBoundaryEvents: false,
350
+ canBeStart: false,
351
+ canBeEnd: false,
352
+ maxIncoming: 0,
353
+ maxOutgoing: 0
354
+ },
355
+ Lane: {
356
+ label: "Lane",
357
+ icon: "AlignJustify",
358
+ category: "container",
359
+ defaultWidth: 600,
360
+ defaultHeight: 120,
361
+ handlePolicy: "none",
362
+ orientation: "horizontal",
363
+ isContainer: true,
364
+ acceptsBoundaryEvents: false,
365
+ canBeStart: false,
366
+ canBeEnd: false,
367
+ maxIncoming: 0,
368
+ maxOutgoing: 0
369
+ },
370
+ // ─── Artifacts ────────────────────────────────────────────────────────────────
371
+ Annotation: {
372
+ label: "Text Annotation",
373
+ icon: "StickyNote",
374
+ category: "artifact",
375
+ defaultWidth: 100,
376
+ defaultHeight: 60,
377
+ handlePolicy: "none",
378
+ orientation: "free",
379
+ isContainer: false,
380
+ acceptsBoundaryEvents: false,
381
+ canBeStart: false,
382
+ canBeEnd: false,
383
+ maxIncoming: 0,
384
+ maxOutgoing: 0
385
+ },
386
+ Group: {
387
+ label: "Group",
388
+ icon: "Group",
389
+ category: "artifact",
390
+ defaultWidth: 300,
391
+ defaultHeight: 200,
392
+ handlePolicy: "none",
393
+ orientation: "free",
394
+ isContainer: false,
395
+ acceptsBoundaryEvents: false,
396
+ canBeStart: false,
397
+ canBeEnd: false,
398
+ maxIncoming: 0,
399
+ maxOutgoing: 0
400
+ },
401
+ // ─── Data (BPMN 2.0 §10.3) ───────────────────────────────────────────────────
402
+ DataObject: {
403
+ label: "Data Object",
404
+ icon: "File",
405
+ category: "data",
406
+ defaultWidth: 36,
407
+ defaultHeight: 50,
408
+ handlePolicy: "all",
409
+ orientation: "free",
410
+ isContainer: false,
411
+ acceptsBoundaryEvents: false,
412
+ canBeStart: false,
413
+ canBeEnd: false,
414
+ maxIncoming: 0,
415
+ maxOutgoing: 0
416
+ },
417
+ DataObjectReference: {
418
+ label: "Data Object Reference",
419
+ icon: "FileSymlink",
420
+ category: "data",
421
+ defaultWidth: 36,
422
+ defaultHeight: 50,
423
+ handlePolicy: "all",
424
+ orientation: "free",
425
+ isContainer: false,
426
+ acceptsBoundaryEvents: false,
427
+ canBeStart: false,
428
+ canBeEnd: false,
429
+ maxIncoming: 0,
430
+ maxOutgoing: 0
431
+ },
432
+ DataInput: {
433
+ label: "Data Input",
434
+ icon: "FileInput",
435
+ category: "data",
436
+ defaultWidth: 36,
437
+ defaultHeight: 50,
438
+ handlePolicy: "all",
439
+ orientation: "free",
440
+ isContainer: false,
441
+ acceptsBoundaryEvents: false,
442
+ canBeStart: false,
443
+ canBeEnd: false,
444
+ maxIncoming: 0
445
+ },
446
+ DataOutput: {
447
+ label: "Data Output",
448
+ icon: "FileOutput",
449
+ category: "data",
450
+ defaultWidth: 36,
451
+ defaultHeight: 50,
452
+ handlePolicy: "all",
453
+ orientation: "free",
454
+ isContainer: false,
455
+ acceptsBoundaryEvents: false,
456
+ canBeStart: false,
457
+ canBeEnd: false,
458
+ maxOutgoing: 0
459
+ },
460
+ DataStore: {
461
+ label: "Data Store",
462
+ icon: "Database",
463
+ category: "data",
464
+ defaultWidth: 50,
465
+ defaultHeight: 50,
466
+ handlePolicy: "all",
467
+ orientation: "free",
468
+ isContainer: false,
469
+ acceptsBoundaryEvents: false,
470
+ canBeStart: false,
471
+ canBeEnd: false,
472
+ maxIncoming: 0,
473
+ maxOutgoing: 0
474
+ },
475
+ DataStoreReference: {
476
+ label: "Data Store Reference",
477
+ icon: "DatabaseZap",
478
+ category: "data",
479
+ defaultWidth: 50,
480
+ defaultHeight: 50,
481
+ handlePolicy: "all",
482
+ orientation: "free",
483
+ isContainer: false,
484
+ acceptsBoundaryEvents: false,
485
+ canBeStart: false,
486
+ canBeEnd: false,
487
+ maxIncoming: 0,
488
+ maxOutgoing: 0
489
+ },
490
+ // ─── Conversation (BPMN 2.0 §12) ─────────────────────────────────────────────
491
+ Conversation: {
492
+ label: "Conversation",
493
+ icon: "MessageCircle",
494
+ category: "conversation",
495
+ defaultWidth: 60,
496
+ defaultHeight: 52,
497
+ handlePolicy: "all",
498
+ orientation: "free",
499
+ isContainer: false,
500
+ acceptsBoundaryEvents: false,
501
+ canBeStart: false,
502
+ canBeEnd: false
503
+ },
504
+ SubConversation: {
505
+ label: "Sub-Conversation",
506
+ icon: "MessagesSquare",
507
+ category: "conversation",
508
+ defaultWidth: 60,
509
+ defaultHeight: 52,
510
+ handlePolicy: "all",
511
+ orientation: "free",
512
+ isContainer: true,
513
+ acceptsBoundaryEvents: false,
514
+ supportsCollapse: true,
515
+ canBeStart: false,
516
+ canBeEnd: false
517
+ },
518
+ CallConversation: {
519
+ label: "Call Conversation",
520
+ icon: "PhoneCall",
521
+ category: "conversation",
522
+ defaultWidth: 60,
523
+ defaultHeight: 52,
524
+ handlePolicy: "all",
525
+ orientation: "free",
526
+ isContainer: false,
527
+ acceptsBoundaryEvents: false,
528
+ canBeStart: false,
529
+ canBeEnd: false
530
+ },
531
+ // ─── Choreography (BPMN 2.0 §11) ─────────────────────────────────────────────
532
+ ChoreographyTask: {
533
+ label: "Choreography Task",
534
+ icon: "ArrowLeftRight",
535
+ category: "choreography",
536
+ defaultWidth: 120,
537
+ defaultHeight: 80,
538
+ handlePolicy: "all",
539
+ orientation: "horizontal",
540
+ isContainer: false,
541
+ acceptsBoundaryEvents: false,
542
+ canBeStart: false,
543
+ canBeEnd: false
544
+ },
545
+ SubChoreography: {
546
+ label: "Sub-Choreography",
547
+ icon: "BoxSelect",
548
+ category: "choreography",
549
+ defaultWidth: 120,
550
+ defaultHeight: 80,
551
+ handlePolicy: "all",
552
+ orientation: "horizontal",
553
+ isContainer: true,
554
+ acceptsBoundaryEvents: false,
555
+ supportsCollapse: true,
556
+ canBeStart: false,
557
+ canBeEnd: false
558
+ },
559
+ CallChoreography: {
560
+ label: "Call Choreography",
561
+ icon: "Phone",
562
+ category: "choreography",
563
+ defaultWidth: 120,
564
+ defaultHeight: 80,
565
+ handlePolicy: "all",
566
+ orientation: "horizontal",
567
+ isContainer: false,
568
+ acceptsBoundaryEvents: false,
569
+ canBeStart: false,
570
+ canBeEnd: false
571
+ }
572
+ };
573
+
574
+ // src/elements/guards.ts
575
+ var EVENT_TYPES = /* @__PURE__ */ new Set([
576
+ "StartEvent",
577
+ "EndEvent",
578
+ "IntermediateCatchEvent",
579
+ "IntermediateThrowEvent",
580
+ "BoundaryEvent"
581
+ ]);
582
+ var DATA_TYPES = /* @__PURE__ */ new Set([
583
+ "DataObject",
584
+ "DataObjectReference",
585
+ "DataInput",
586
+ "DataOutput",
587
+ "DataStore",
588
+ "DataStoreReference"
589
+ ]);
590
+ function isEventType(type) {
591
+ return EVENT_TYPES.has(type);
592
+ }
593
+ function isDataType(type) {
594
+ return DATA_TYPES.has(type);
595
+ }
596
+ function acceptsBoundaryEvents(type) {
597
+ return BPMN_ELEMENT_CATALOG[type].acceptsBoundaryEvents;
598
+ }
599
+ function getHandlePolicy(type) {
600
+ return BPMN_ELEMENT_CATALOG[type].handlePolicy;
601
+ }
602
+
603
+ // src/modeling/index.ts
604
+ function createBpmnNode(options) {
605
+ const meta = BPMN_ELEMENT_CATALOG[options.elementType];
606
+ return {
607
+ id: options.id,
608
+ type: options.elementType,
609
+ position: options.position,
610
+ data: {
611
+ elementType: options.elementType,
612
+ ...options.label ? { label: options.label } : {},
613
+ ...options.data ?? {}
614
+ },
615
+ width: options.width ?? meta.defaultWidth,
616
+ height: options.height ?? meta.defaultHeight,
617
+ ...options.parentId ? { parentId: options.parentId } : {}
618
+ };
619
+ }
620
+ function inferBpmnEdgeType(state, sourceId, targetId) {
621
+ const source = diagramsCore.getNode(state, sourceId);
622
+ const target = diagramsCore.getNode(state, targetId);
623
+ if (!source || !target) return "sequenceFlow";
624
+ if (isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
625
+ return "dataAssociation";
626
+ }
627
+ if (source.data.elementType === "Annotation" || target.data.elementType === "Annotation" || source.data.elementType === "Group" || target.data.elementType === "Group") {
628
+ return "association";
629
+ }
630
+ if (source.data.elementType === "Conversation" || source.data.elementType === "SubConversation" || source.data.elementType === "CallConversation" || target.data.elementType === "Conversation" || target.data.elementType === "SubConversation" || target.data.elementType === "CallConversation") {
631
+ return "conversationLink";
632
+ }
633
+ if (source.parentId && target.parentId && source.parentId !== target.parentId) {
634
+ return "messageFlow";
635
+ }
636
+ return "sequenceFlow";
637
+ }
638
+ function canUseSequenceFlow(type) {
639
+ const meta = BPMN_ELEMENT_CATALOG[type];
640
+ return meta.handlePolicy !== "none" && !isDataType(type) && type !== "Annotation" && type !== "Group" && meta.category !== "conversation";
641
+ }
642
+ function validateEdgeCardinality(state, edgeType, source, target) {
643
+ if (edgeType !== "sequenceFlow") return true;
644
+ const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
645
+ const targetMax = BPMN_ELEMENT_CATALOG[target.data.elementType].maxIncoming;
646
+ const outgoing = diagramsCore.getOutgoingEdges(state, source.id).filter(
647
+ (edge) => edge.data?.edgeType === "sequenceFlow"
648
+ );
649
+ const incoming = diagramsCore.getIncomingEdges(state, target.id).filter(
650
+ (edge) => edge.data?.edgeType === "sequenceFlow"
651
+ );
652
+ if (sourceMax !== void 0 && outgoing.length >= sourceMax) {
653
+ return `${source.data.elementType} cannot have more than ${sourceMax} outgoing sequence flow(s).`;
654
+ }
655
+ if (targetMax !== void 0 && incoming.length >= targetMax) {
656
+ return `${target.data.elementType} cannot have more than ${targetMax} incoming sequence flow(s).`;
657
+ }
658
+ return true;
659
+ }
660
+ var bpmnConnectionValidators = [
661
+ ({ state, source, target }) => {
662
+ if (source.id === target.id) return "BPMN self-connections are not allowed.";
663
+ const edgeType = inferBpmnEdgeType(state, source.id, target.id);
664
+ if (getHandlePolicy(source.data.elementType) === "none" || getHandlePolicy(target.data.elementType) === "none") {
665
+ return "Elements without BPMN connection handles cannot be directly connected.";
666
+ }
667
+ if (edgeType === "sequenceFlow") {
668
+ if (!canUseSequenceFlow(source.data.elementType) || !canUseSequenceFlow(target.data.elementType)) {
669
+ return "Sequence flows can only connect BPMN flow nodes.";
670
+ }
671
+ if (source.data.elementType === "EndEvent") return "End events cannot have outgoing sequence flows.";
672
+ if (target.data.elementType === "StartEvent") return "Start events cannot have incoming sequence flows.";
673
+ return validateEdgeCardinality(state, edgeType, source, target);
674
+ }
675
+ return true;
676
+ }
677
+ ];
678
+ var BPMN_MODELING_RULES = diagramsCore.createModelingRules({
679
+ connect: [
680
+ ({ state, source, target }) => {
681
+ if (!source || !target) return false;
682
+ for (const validator of bpmnConnectionValidators) {
683
+ const result = validator({
684
+ state,
685
+ source,
686
+ target,
687
+ existingEdges: state.edges
688
+ });
689
+ if (result !== true) return result;
690
+ }
691
+ return true;
692
+ }
693
+ ],
694
+ drop: [
695
+ ({ node, parent }) => {
696
+ if (!node || !parent) return true;
697
+ if (node.data.elementType === "BoundaryEvent") {
698
+ return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be attached to tasks or subprocesses.";
699
+ }
700
+ if (parent.data.elementType === "Pool" || parent.data.elementType === "Lane") {
701
+ return isEventType(node.data.elementType) || node.data.elementType.includes("Task") || node.data.elementType.includes("Gateway") || node.data.elementType.includes("SubProcess") ? true : "Only flow nodes can be dropped into pools or lanes.";
702
+ }
703
+ return true;
704
+ }
705
+ ],
706
+ reparent: [
707
+ ({ node, parent }) => {
708
+ if (!node || !parent) return true;
709
+ if (node.data.elementType === "BoundaryEvent") {
710
+ return acceptsBoundaryEvents(parent.data.elementType) ? true : "Boundary events can only be reparented to tasks or subprocesses.";
711
+ }
712
+ return true;
713
+ }
714
+ ],
715
+ delete: [() => true],
716
+ resize: [() => true]
717
+ });
718
+ function createBpmnNodeCommand(options) {
719
+ return {
720
+ id: `bpmn.createNode.${options.id}`,
721
+ label: `Create ${options.elementType}`,
722
+ execute: (state) => diagramsCore.addNode(state, createBpmnNode(options))
723
+ };
724
+ }
725
+ function connectBpmnCommand(options) {
726
+ return {
727
+ id: `bpmn.connect.${options.id ?? `${options.source}-${options.target}`}`,
728
+ label: "Connect BPMN elements",
729
+ execute: (state) => {
730
+ const edgeType = options.edgeType ?? inferBpmnEdgeType(state, options.source, options.target);
731
+ return diagramsCore.connectNodes(
732
+ state,
733
+ {
734
+ source: options.source,
735
+ target: options.target,
736
+ type: edgeType,
737
+ ...options.sourceHandle !== void 0 ? { sourceHandle: options.sourceHandle } : {},
738
+ ...options.targetHandle !== void 0 ? { targetHandle: options.targetHandle } : {},
739
+ ...options.id ? { id: options.id } : {},
740
+ data: {
741
+ edgeType,
742
+ ...options.label ? { label: options.label } : {},
743
+ ...options.data ?? {}
744
+ }
745
+ },
746
+ bpmnConnectionValidators
747
+ );
748
+ }
749
+ };
750
+ }
751
+ function attachBoundaryEventCommand(boundaryId, hostId) {
752
+ return {
753
+ id: `bpmn.attachBoundary.${boundaryId}.${hostId}`,
754
+ label: "Attach boundary event",
755
+ execute: (state) => {
756
+ const host = diagramsCore.getNode(state, hostId);
757
+ if (!host || !acceptsBoundaryEvents(host.data.elementType)) {
758
+ throw new Error(`Element "${hostId}" cannot host boundary events.`);
759
+ }
760
+ const boundary = diagramsCore.getNode(state, boundaryId);
761
+ if (!boundary || boundary.data.elementType !== "BoundaryEvent") {
762
+ throw new Error(`Element "${boundaryId}" is not a boundary event.`);
763
+ }
764
+ const reparented = diagramsCore.reparentNode(state, boundaryId, { parentId: hostId });
765
+ return diagramsCore.patchNode(reparented, boundaryId, {
766
+ data: { attachedToRef: hostId }
767
+ });
768
+ }
769
+ };
770
+ }
771
+ function replaceBpmnNodeCommand(options) {
772
+ return {
773
+ id: `bpmn.replaceNode.${options.id}.${options.elementType}`,
774
+ label: `Replace with ${options.elementType}`,
775
+ execute: (state) => {
776
+ const current = diagramsCore.getNode(state, options.id);
777
+ if (!current) throw new Error(`Element "${options.id}" does not exist.`);
778
+ const meta = BPMN_ELEMENT_CATALOG[options.elementType];
779
+ return diagramsCore.replaceNode(state, options.id, {
780
+ ...current,
781
+ type: options.elementType,
782
+ width: options.width ?? current.width ?? meta.defaultWidth,
783
+ height: options.height ?? current.height ?? meta.defaultHeight,
784
+ data: {
785
+ ...current.data,
786
+ elementType: options.elementType,
787
+ ...options.label ? { label: options.label } : {},
788
+ ...options.data ?? {}
789
+ }
790
+ });
791
+ }
792
+ };
793
+ }
794
+ function reparentBpmnNodeCommand(options) {
795
+ return {
796
+ id: `bpmn.reparent.${options.id}.${options.parentId ?? "root"}`,
797
+ label: "Reparent BPMN element",
798
+ execute: (state) => {
799
+ const node = diagramsCore.getNode(state, options.id);
800
+ const parent = options.parentId ? diagramsCore.getNode(state, options.parentId) : void 0;
801
+ if (!node) throw new Error(`Element "${options.id}" does not exist.`);
802
+ if (parent && node.data.elementType === "BoundaryEvent" && !acceptsBoundaryEvents(parent.data.elementType)) {
803
+ throw new Error("Boundary events can only be reparented to tasks or subprocesses.");
804
+ }
805
+ return diagramsCore.reparentNode(state, options.id, {
806
+ ...options.parentId !== void 0 ? { parentId: options.parentId } : {},
807
+ ...options.position ? { position: options.position } : {}
808
+ });
809
+ }
810
+ };
811
+ }
812
+ function resizeBpmnNodeCommand(options) {
813
+ return {
814
+ id: `bpmn.resize.${options.id}`,
815
+ label: "Resize BPMN element",
816
+ execute: (state) => diagramsCore.resizeNode(state, options.id, options)
817
+ };
818
+ }
819
+ function deleteBpmnElementsCommand(ids) {
820
+ return {
821
+ id: `bpmn.delete.${ids.join(".")}`,
822
+ label: "Delete BPMN elements",
823
+ execute: (state) => diagramsCore.removeElements(state, ids)
824
+ };
825
+ }
826
+ function copyBpmnElements(state, selection) {
827
+ return diagramsCore.copyElements(state, selection);
828
+ }
829
+ function pasteBpmnElementsCommand(clipboard, options = {}) {
830
+ return {
831
+ id: "bpmn.paste",
832
+ label: "Paste BPMN elements",
833
+ execute: (state) => diagramsCore.pasteElements(state, clipboard, options)
834
+ };
835
+ }
836
+ function selectBpmnElementsCommand(selection) {
837
+ return {
838
+ id: "bpmn.select",
839
+ label: "Select BPMN elements",
840
+ execute: (state) => diagramsCore.setSelection(state, diagramsCore.createSelectionState(selection.nodeIds, selection.edgeIds))
841
+ };
842
+ }
843
+ function createBpmnDiagramDocument(state, options = {}) {
844
+ return serialization.createDiagramDocument(diagramsCore.normalizeDiagramState(state), {
845
+ ...options,
846
+ diagramType: "bpmn"
847
+ });
848
+ }
849
+ function serializeBpmnDiagram(state, options = {}) {
850
+ return serialization.serializeDiagram(diagramsCore.normalizeDiagramState(state), {
851
+ ...options,
852
+ diagramType: "bpmn"
853
+ });
854
+ }
855
+ function parseBpmnDiagramDocument(json) {
856
+ const document = serialization.parseDiagramDocument(json);
857
+ if (document.diagramType && document.diagramType !== "bpmn") {
858
+ throw new Error(`Expected a BPMN diagram document, received "${document.diagramType}".`);
859
+ }
860
+ return document;
861
+ }
862
+ function deserializeBpmnDiagram(json) {
863
+ const document = parseBpmnDiagramDocument(json);
864
+ return serialization.deserializeDiagram(JSON.stringify(document));
865
+ }
866
+ function runBpmnCommand(stack, command) {
867
+ return diagramsCore.executeCommand(stack, command);
868
+ }
869
+ function runBpmnCommands(stack, commands, options = {}) {
870
+ return diagramsCore.executeCommands(stack, commands, options);
871
+ }
872
+
873
+ exports.BPMN_MODELING_RULES = BPMN_MODELING_RULES;
874
+ exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
875
+ exports.bpmnConnectionValidators = bpmnConnectionValidators;
876
+ exports.connectBpmnCommand = connectBpmnCommand;
877
+ exports.copyBpmnElements = copyBpmnElements;
878
+ exports.createBpmnDiagramDocument = createBpmnDiagramDocument;
879
+ exports.createBpmnNode = createBpmnNode;
880
+ exports.createBpmnNodeCommand = createBpmnNodeCommand;
881
+ exports.deleteBpmnElementsCommand = deleteBpmnElementsCommand;
882
+ exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
883
+ exports.inferBpmnEdgeType = inferBpmnEdgeType;
884
+ exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
885
+ exports.pasteBpmnElementsCommand = pasteBpmnElementsCommand;
886
+ exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
887
+ exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
888
+ exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
889
+ exports.runBpmnCommand = runBpmnCommand;
890
+ exports.runBpmnCommands = runBpmnCommands;
891
+ exports.selectBpmnElementsCommand = selectBpmnElementsCommand;
892
+ exports.serializeBpmnDiagram = serializeBpmnDiagram;
893
+ //# sourceMappingURL=index.cjs.map
894
+ //# sourceMappingURL=index.cjs.map