@aranzatech/diagrams-bpmn 0.1.2 → 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 (47) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +121 -0
  3. package/dist/{chunk-MLUJKUTG.js → chunk-5GRCJ5X6.js} +3 -3
  4. package/dist/{chunk-MLUJKUTG.js.map → chunk-5GRCJ5X6.js.map} +1 -1
  5. package/dist/{chunk-6TUC5QX5.js → chunk-DNR5WBQH.js} +83 -2
  6. package/dist/chunk-DNR5WBQH.js.map +1 -0
  7. package/dist/chunk-G5S4ASP3.js +277 -0
  8. package/dist/chunk-G5S4ASP3.js.map +1 -0
  9. package/dist/{chunk-4OAEWYYU.js → chunk-MF2WE3OM.js} +146 -37
  10. package/dist/chunk-MF2WE3OM.js.map +1 -0
  11. package/dist/chunk-OZKTOILD.js +3 -0
  12. package/dist/chunk-OZKTOILD.js.map +1 -0
  13. package/dist/{chunk-NXMUX67A.js → chunk-S3GGEEA5.js} +31 -8
  14. package/dist/chunk-S3GGEEA5.js.map +1 -0
  15. package/dist/elements/index.cjs +81 -0
  16. package/dist/elements/index.cjs.map +1 -1
  17. package/dist/elements/index.d.cts +2 -2
  18. package/dist/elements/index.d.ts +2 -2
  19. package/dist/elements/index.js +3 -2
  20. package/dist/index.cjs +535 -66
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.d.cts +7 -62
  23. package/dist/index.d.ts +7 -62
  24. package/dist/index.js +6 -40
  25. package/dist/index.js.map +1 -1
  26. package/dist/modeling/index.cjs +894 -0
  27. package/dist/modeling/index.cjs.map +1 -0
  28. package/dist/modeling/index.d.cts +88 -0
  29. package/dist/modeling/index.d.ts +88 -0
  30. package/dist/modeling/index.js +5 -0
  31. package/dist/modeling/index.js.map +1 -0
  32. package/dist/nodes/index.cjs +29 -6
  33. package/dist/nodes/index.cjs.map +1 -1
  34. package/dist/nodes/index.js +1 -1
  35. package/dist/{types-CxzazgBX.d.cts → types-BKA0GZz5.d.cts} +9 -19
  36. package/dist/{types-CxzazgBX.d.ts → types-BKA0GZz5.d.ts} +9 -19
  37. package/dist/types-CCkHqtC_.d.cts +20 -0
  38. package/dist/types-hj621ZRJ.d.ts +20 -0
  39. package/dist/xml/index.cjs +224 -34
  40. package/dist/xml/index.cjs.map +1 -1
  41. package/dist/xml/index.d.cts +4 -19
  42. package/dist/xml/index.d.ts +4 -19
  43. package/dist/xml/index.js +2 -2
  44. package/package.json +12 -4
  45. package/dist/chunk-4OAEWYYU.js.map +0 -1
  46. package/dist/chunk-6TUC5QX5.js.map +0 -1
  47. package/dist/chunk-NXMUX67A.js.map +0 -1
@@ -9,6 +9,7 @@ var BPMN_ELEMENT_CATALOG = {
9
9
  // ─── Events ──────────────────────────────────────────────────────────────────
10
10
  StartEvent: {
11
11
  label: "Start Event",
12
+ icon: "Circle",
12
13
  category: "event",
13
14
  defaultWidth: 36,
14
15
  defaultHeight: 36,
@@ -24,6 +25,7 @@ var BPMN_ELEMENT_CATALOG = {
24
25
  },
25
26
  EndEvent: {
26
27
  label: "End Event",
28
+ icon: "CircleDot",
27
29
  category: "event",
28
30
  defaultWidth: 36,
29
31
  defaultHeight: 36,
@@ -38,6 +40,7 @@ var BPMN_ELEMENT_CATALOG = {
38
40
  },
39
41
  IntermediateCatchEvent: {
40
42
  label: "Intermediate Catch Event",
43
+ icon: "Clock",
41
44
  category: "event",
42
45
  defaultWidth: 36,
43
46
  defaultHeight: 36,
@@ -51,6 +54,7 @@ var BPMN_ELEMENT_CATALOG = {
51
54
  },
52
55
  IntermediateThrowEvent: {
53
56
  label: "Intermediate Throw Event",
57
+ icon: "Zap",
54
58
  category: "event",
55
59
  defaultWidth: 36,
56
60
  defaultHeight: 36,
@@ -64,6 +68,7 @@ var BPMN_ELEMENT_CATALOG = {
64
68
  },
65
69
  BoundaryEvent: {
66
70
  label: "Boundary Event",
71
+ icon: "AlertCircle",
67
72
  category: "event",
68
73
  defaultWidth: 36,
69
74
  defaultHeight: 36,
@@ -79,6 +84,7 @@ var BPMN_ELEMENT_CATALOG = {
79
84
  // ─── Tasks ───────────────────────────────────────────────────────────────────
80
85
  Task: {
81
86
  label: "Task",
87
+ icon: "Square",
82
88
  category: "task",
83
89
  defaultWidth: 120,
84
90
  defaultHeight: 60,
@@ -92,6 +98,7 @@ var BPMN_ELEMENT_CATALOG = {
92
98
  },
93
99
  UserTask: {
94
100
  label: "User Task",
101
+ icon: "User",
95
102
  category: "task",
96
103
  defaultWidth: 120,
97
104
  defaultHeight: 60,
@@ -105,6 +112,7 @@ var BPMN_ELEMENT_CATALOG = {
105
112
  },
106
113
  ServiceTask: {
107
114
  label: "Service Task",
115
+ icon: "Settings",
108
116
  category: "task",
109
117
  defaultWidth: 120,
110
118
  defaultHeight: 60,
@@ -118,6 +126,7 @@ var BPMN_ELEMENT_CATALOG = {
118
126
  },
119
127
  ScriptTask: {
120
128
  label: "Script Task",
129
+ icon: "FileCode",
121
130
  category: "task",
122
131
  defaultWidth: 120,
123
132
  defaultHeight: 60,
@@ -131,6 +140,7 @@ var BPMN_ELEMENT_CATALOG = {
131
140
  },
132
141
  ManualTask: {
133
142
  label: "Manual Task",
143
+ icon: "Hand",
134
144
  category: "task",
135
145
  defaultWidth: 120,
136
146
  defaultHeight: 60,
@@ -144,6 +154,7 @@ var BPMN_ELEMENT_CATALOG = {
144
154
  },
145
155
  BusinessRuleTask: {
146
156
  label: "Business Rule Task",
157
+ icon: "Scale",
147
158
  category: "task",
148
159
  defaultWidth: 120,
149
160
  defaultHeight: 60,
@@ -157,6 +168,7 @@ var BPMN_ELEMENT_CATALOG = {
157
168
  },
158
169
  ReceiveTask: {
159
170
  label: "Receive Task",
171
+ icon: "Mail",
160
172
  category: "task",
161
173
  defaultWidth: 120,
162
174
  defaultHeight: 60,
@@ -170,6 +182,7 @@ var BPMN_ELEMENT_CATALOG = {
170
182
  },
171
183
  SendTask: {
172
184
  label: "Send Task",
185
+ icon: "Send",
173
186
  category: "task",
174
187
  defaultWidth: 120,
175
188
  defaultHeight: 60,
@@ -183,6 +196,7 @@ var BPMN_ELEMENT_CATALOG = {
183
196
  },
184
197
  CallActivity: {
185
198
  label: "Call Activity",
199
+ icon: "ExternalLink",
186
200
  category: "task",
187
201
  defaultWidth: 120,
188
202
  defaultHeight: 60,
@@ -197,6 +211,7 @@ var BPMN_ELEMENT_CATALOG = {
197
211
  // ─── Gateways ────────────────────────────────────────────────────────────────
198
212
  ExclusiveGateway: {
199
213
  label: "Exclusive Gateway",
214
+ icon: "GitBranch",
200
215
  category: "gateway",
201
216
  defaultWidth: 50,
202
217
  defaultHeight: 50,
@@ -209,6 +224,7 @@ var BPMN_ELEMENT_CATALOG = {
209
224
  },
210
225
  InclusiveGateway: {
211
226
  label: "Inclusive Gateway",
227
+ icon: "GitMerge",
212
228
  category: "gateway",
213
229
  defaultWidth: 50,
214
230
  defaultHeight: 50,
@@ -221,6 +237,7 @@ var BPMN_ELEMENT_CATALOG = {
221
237
  },
222
238
  ParallelGateway: {
223
239
  label: "Parallel Gateway",
240
+ icon: "GitFork",
224
241
  category: "gateway",
225
242
  defaultWidth: 50,
226
243
  defaultHeight: 50,
@@ -233,6 +250,7 @@ var BPMN_ELEMENT_CATALOG = {
233
250
  },
234
251
  EventBasedGateway: {
235
252
  label: "Event-Based Gateway",
253
+ icon: "Radio",
236
254
  category: "gateway",
237
255
  defaultWidth: 50,
238
256
  defaultHeight: 50,
@@ -246,6 +264,7 @@ var BPMN_ELEMENT_CATALOG = {
246
264
  },
247
265
  ComplexGateway: {
248
266
  label: "Complex Gateway",
267
+ icon: "Asterisk",
249
268
  category: "gateway",
250
269
  defaultWidth: 50,
251
270
  defaultHeight: 50,
@@ -259,6 +278,52 @@ var BPMN_ELEMENT_CATALOG = {
259
278
  // ─── Containers ───────────────────────────────────────────────────────────────
260
279
  SubProcess: {
261
280
  label: "Sub-Process",
281
+ icon: "Layout",
282
+ category: "container",
283
+ defaultWidth: 350,
284
+ defaultHeight: 200,
285
+ handlePolicy: "all",
286
+ orientation: "horizontal",
287
+ isContainer: true,
288
+ acceptsBoundaryEvents: true,
289
+ supportsCollapse: true,
290
+ supportsMarkers: true,
291
+ canBeStart: false,
292
+ canBeEnd: false
293
+ },
294
+ Transaction: {
295
+ label: "Transaction",
296
+ icon: "CreditCard",
297
+ category: "container",
298
+ defaultWidth: 350,
299
+ defaultHeight: 200,
300
+ handlePolicy: "all",
301
+ orientation: "horizontal",
302
+ isContainer: true,
303
+ acceptsBoundaryEvents: true,
304
+ supportsCollapse: true,
305
+ supportsMarkers: true,
306
+ canBeStart: false,
307
+ canBeEnd: false
308
+ },
309
+ EventSubProcess: {
310
+ label: "Event Sub-Process",
311
+ icon: "Workflow",
312
+ category: "container",
313
+ defaultWidth: 350,
314
+ defaultHeight: 200,
315
+ handlePolicy: "all",
316
+ orientation: "horizontal",
317
+ isContainer: true,
318
+ acceptsBoundaryEvents: false,
319
+ supportsCollapse: true,
320
+ supportsMarkers: true,
321
+ canBeStart: false,
322
+ canBeEnd: false
323
+ },
324
+ AdHocSubProcess: {
325
+ label: "Ad-Hoc Sub-Process",
326
+ icon: "Shuffle",
262
327
  category: "container",
263
328
  defaultWidth: 350,
264
329
  defaultHeight: 200,
@@ -273,6 +338,7 @@ var BPMN_ELEMENT_CATALOG = {
273
338
  },
274
339
  Pool: {
275
340
  label: "Pool",
341
+ icon: "Columns",
276
342
  category: "container",
277
343
  defaultWidth: 600,
278
344
  defaultHeight: 200,
@@ -287,6 +353,7 @@ var BPMN_ELEMENT_CATALOG = {
287
353
  },
288
354
  Lane: {
289
355
  label: "Lane",
356
+ icon: "AlignJustify",
290
357
  category: "container",
291
358
  defaultWidth: 600,
292
359
  defaultHeight: 120,
@@ -302,6 +369,7 @@ var BPMN_ELEMENT_CATALOG = {
302
369
  // ─── Artifacts ────────────────────────────────────────────────────────────────
303
370
  Annotation: {
304
371
  label: "Text Annotation",
372
+ icon: "StickyNote",
305
373
  category: "artifact",
306
374
  defaultWidth: 100,
307
375
  defaultHeight: 60,
@@ -316,6 +384,7 @@ var BPMN_ELEMENT_CATALOG = {
316
384
  },
317
385
  Group: {
318
386
  label: "Group",
387
+ icon: "Group",
319
388
  category: "artifact",
320
389
  defaultWidth: 300,
321
390
  defaultHeight: 200,
@@ -331,6 +400,7 @@ var BPMN_ELEMENT_CATALOG = {
331
400
  // ─── Data (BPMN 2.0 §10.3) ───────────────────────────────────────────────────
332
401
  DataObject: {
333
402
  label: "Data Object",
403
+ icon: "File",
334
404
  category: "data",
335
405
  defaultWidth: 36,
336
406
  defaultHeight: 50,
@@ -345,6 +415,7 @@ var BPMN_ELEMENT_CATALOG = {
345
415
  },
346
416
  DataObjectReference: {
347
417
  label: "Data Object Reference",
418
+ icon: "FileSymlink",
348
419
  category: "data",
349
420
  defaultWidth: 36,
350
421
  defaultHeight: 50,
@@ -359,6 +430,7 @@ var BPMN_ELEMENT_CATALOG = {
359
430
  },
360
431
  DataInput: {
361
432
  label: "Data Input",
433
+ icon: "FileInput",
362
434
  category: "data",
363
435
  defaultWidth: 36,
364
436
  defaultHeight: 50,
@@ -372,6 +444,7 @@ var BPMN_ELEMENT_CATALOG = {
372
444
  },
373
445
  DataOutput: {
374
446
  label: "Data Output",
447
+ icon: "FileOutput",
375
448
  category: "data",
376
449
  defaultWidth: 36,
377
450
  defaultHeight: 50,
@@ -385,6 +458,7 @@ var BPMN_ELEMENT_CATALOG = {
385
458
  },
386
459
  DataStore: {
387
460
  label: "Data Store",
461
+ icon: "Database",
388
462
  category: "data",
389
463
  defaultWidth: 50,
390
464
  defaultHeight: 50,
@@ -399,6 +473,7 @@ var BPMN_ELEMENT_CATALOG = {
399
473
  },
400
474
  DataStoreReference: {
401
475
  label: "Data Store Reference",
476
+ icon: "DatabaseZap",
402
477
  category: "data",
403
478
  defaultWidth: 50,
404
479
  defaultHeight: 50,
@@ -414,6 +489,7 @@ var BPMN_ELEMENT_CATALOG = {
414
489
  // ─── Conversation (BPMN 2.0 §12) ─────────────────────────────────────────────
415
490
  Conversation: {
416
491
  label: "Conversation",
492
+ icon: "MessageCircle",
417
493
  category: "conversation",
418
494
  defaultWidth: 60,
419
495
  defaultHeight: 52,
@@ -426,6 +502,7 @@ var BPMN_ELEMENT_CATALOG = {
426
502
  },
427
503
  SubConversation: {
428
504
  label: "Sub-Conversation",
505
+ icon: "MessagesSquare",
429
506
  category: "conversation",
430
507
  defaultWidth: 60,
431
508
  defaultHeight: 52,
@@ -439,6 +516,7 @@ var BPMN_ELEMENT_CATALOG = {
439
516
  },
440
517
  CallConversation: {
441
518
  label: "Call Conversation",
519
+ icon: "PhoneCall",
442
520
  category: "conversation",
443
521
  defaultWidth: 60,
444
522
  defaultHeight: 52,
@@ -452,6 +530,7 @@ var BPMN_ELEMENT_CATALOG = {
452
530
  // ─── Choreography (BPMN 2.0 §11) ─────────────────────────────────────────────
453
531
  ChoreographyTask: {
454
532
  label: "Choreography Task",
533
+ icon: "ArrowLeftRight",
455
534
  category: "choreography",
456
535
  defaultWidth: 120,
457
536
  defaultHeight: 80,
@@ -464,6 +543,7 @@ var BPMN_ELEMENT_CATALOG = {
464
543
  },
465
544
  SubChoreography: {
466
545
  label: "Sub-Choreography",
546
+ icon: "BoxSelect",
467
547
  category: "choreography",
468
548
  defaultWidth: 120,
469
549
  defaultHeight: 80,
@@ -477,6 +557,7 @@ var BPMN_ELEMENT_CATALOG = {
477
557
  },
478
558
  CallChoreography: {
479
559
  label: "Call Choreography",
560
+ icon: "Phone",
480
561
  category: "choreography",
481
562
  defaultWidth: 120,
482
563
  defaultHeight: 80,
@@ -511,8 +592,8 @@ var MODDLE_TO_ELEMENT_TYPE = {
511
592
  "bpmn:EventBasedGateway": "EventBasedGateway",
512
593
  "bpmn:ComplexGateway": "ComplexGateway",
513
594
  "bpmn:SubProcess": "SubProcess",
514
- "bpmn:AdHocSubProcess": "SubProcess",
515
- "bpmn:Transaction": "SubProcess",
595
+ "bpmn:AdHocSubProcess": "AdHocSubProcess",
596
+ "bpmn:Transaction": "Transaction",
516
597
  "bpmn:TextAnnotation": "Annotation",
517
598
  "bpmn:Group": "Group",
518
599
  "bpmn:DataObject": "DataObject",
@@ -550,6 +631,9 @@ var ELEMENT_TYPE_TO_MODDLE = {
550
631
  EventBasedGateway: "bpmn:EventBasedGateway",
551
632
  ComplexGateway: "bpmn:ComplexGateway",
552
633
  SubProcess: "bpmn:SubProcess",
634
+ Transaction: "bpmn:Transaction",
635
+ EventSubProcess: "bpmn:SubProcess",
636
+ AdHocSubProcess: "bpmn:AdHocSubProcess",
553
637
  Pool: "bpmn:Participant",
554
638
  Lane: "bpmn:Lane",
555
639
  Annotation: "bpmn:TextAnnotation",
@@ -614,6 +698,10 @@ function asElements(v) {
614
698
  function asString(v) {
615
699
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
616
700
  }
701
+ function extractDocumentation(el) {
702
+ const [doc] = asElements(el.documentation);
703
+ return asString(doc?.text);
704
+ }
617
705
  function extractDiagramInfo(definitions) {
618
706
  const shapes = /* @__PURE__ */ new Map();
619
707
  const waypoints = /* @__PURE__ */ new Map();
@@ -669,6 +757,7 @@ function extractTrigger(el) {
669
757
  function extractSubProcessVariant(el) {
670
758
  if (el.$type === "bpmn:Transaction") return "transaction";
671
759
  if (el.$type === "bpmn:AdHocSubProcess") return "adhoc";
760
+ if (el.$type === "bpmn:SubProcess" && el.triggeredByEvent === true) return "event";
672
761
  if (el.triggeredByEvent === true) return "event";
673
762
  return "embedded";
674
763
  }
@@ -682,7 +771,7 @@ function walkFlowElements(elements, parentId, ctx, nodes, edges) {
682
771
  continue;
683
772
  }
684
773
  if ($type === "bpmn:LaneSet") continue;
685
- const elementType = MODDLE_TO_ELEMENT_TYPE[$type];
774
+ const elementType = $type === "bpmn:SubProcess" && el.triggeredByEvent === true ? "EventSubProcess" : MODDLE_TO_ELEMENT_TYPE[$type];
686
775
  if (!elementType) {
687
776
  ctx.warnings.push(`Unknown element type "${$type}" (id=${id}) \u2014 skipped.`);
688
777
  continue;
@@ -703,22 +792,26 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
703
792
  const y = shape?.y ?? 100;
704
793
  if (!shape) ctx.autoX.value += (meta?.defaultWidth ?? 120) + 20;
705
794
  const label = asString(el.name);
795
+ const documentation = extractDocumentation(el);
706
796
  const trigger = extractTrigger(el);
707
797
  const isNonInterrupting = el.cancelActivity === false;
798
+ const attachedToRef = el.attachedToRef?.id;
708
799
  const data = {
709
800
  elementType,
710
801
  ...label ? { label } : {},
802
+ ...documentation ? { documentation } : {},
711
803
  ...trigger ? { trigger } : {},
712
- ...isNonInterrupting ? { isNonInterrupting: true } : {}
804
+ ...isNonInterrupting ? { isNonInterrupting: true } : {},
805
+ ...attachedToRef ? { attachedToRef } : {}
713
806
  };
714
- if (elementType === "SubProcess") {
807
+ if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
715
808
  const variant = extractSubProcessVariant(el);
716
809
  if (variant) data.subProcessVariant = variant;
717
810
  const isExpanded = shape?.isExpanded ?? true;
718
811
  data.isExpanded = isExpanded;
719
812
  }
720
813
  const laneId = ctx.laneMembership.get(id);
721
- const effectiveParentId = laneId ?? parentId;
814
+ const effectiveParentId = attachedToRef ?? laneId ?? parentId;
722
815
  const node = {
723
816
  id,
724
817
  type: elementType,
@@ -739,10 +832,12 @@ function buildEdge(el, edgeType, ctx, edges) {
739
832
  return;
740
833
  }
741
834
  const label = asString(el.name);
835
+ const documentation = extractDocumentation(el);
742
836
  const condExpr = el.conditionExpression;
743
837
  const data = {
744
838
  edgeType,
745
839
  ...label ? { label } : {},
840
+ ...documentation ? { documentation } : {},
746
841
  ...condExpr?.body ? { conditionExpression: condExpr.body } : {}
747
842
  };
748
843
  const waypoints = ctx.waypoints.get(id);
@@ -843,7 +938,46 @@ async function parseBpmnXml(xml) {
843
938
  );
844
939
  }
845
940
  }
846
- return { nodes, edges, warnings };
941
+ const defaultFlowById = /* @__PURE__ */ new Set();
942
+ const nodeIds = new Set(nodes.map((node) => node.id));
943
+ for (const rootEl of asElements(rootElement.rootElements)) {
944
+ collectDefaultFlows(rootEl, defaultFlowById);
945
+ }
946
+ const normalizedEdges = edges.map((edge) => {
947
+ if (!defaultFlowById.has(edge.id)) return edge;
948
+ const data = {
949
+ edgeType: edge.data?.edgeType ?? edge.type,
950
+ ...edge.data ?? {},
951
+ isDefault: true
952
+ };
953
+ return { ...edge, data };
954
+ });
955
+ return {
956
+ nodes: normalizeChildPositions(nodes, nodeIds),
957
+ edges: normalizedEdges,
958
+ warnings
959
+ };
960
+ }
961
+ function collectDefaultFlows(el, defaultFlowById) {
962
+ const defaultRef = el.default;
963
+ if (defaultRef?.id) defaultFlowById.add(defaultRef.id);
964
+ for (const child of asElements(el.rootElements)) collectDefaultFlows(child, defaultFlowById);
965
+ for (const child of asElements(el.flowElements)) collectDefaultFlows(child, defaultFlowById);
966
+ }
967
+ function normalizeChildPositions(nodes, nodeIds) {
968
+ const absoluteById = new Map(nodes.map((node) => [node.id, node.position]));
969
+ return nodes.map((node) => {
970
+ if (!node.parentId || !nodeIds.has(node.parentId)) return node;
971
+ const parentPosition = absoluteById.get(node.parentId);
972
+ if (!parentPosition) return node;
973
+ return {
974
+ ...node,
975
+ position: {
976
+ x: node.position.x - parentPosition.x,
977
+ y: node.position.y - parentPosition.y
978
+ }
979
+ };
980
+ });
847
981
  }
848
982
  function uid(prefix, id) {
849
983
  return `${prefix}_${id}`;
@@ -851,19 +985,6 @@ function uid(prefix, id) {
851
985
  function asNodes(nodes, types) {
852
986
  return nodes.filter((n) => types.includes(n.data.elementType));
853
987
  }
854
- function buildFlowableAttrs(data) {
855
- const attrs = {};
856
- if (data.flowableAssignee) attrs["flowable:assignee"] = data.flowableAssignee;
857
- if (data.flowableCandidateGroups) attrs["flowable:candidateGroups"] = data.flowableCandidateGroups;
858
- if (data.flowableCandidateUsers) attrs["flowable:candidateUsers"] = data.flowableCandidateUsers;
859
- if (data.flowableFormKey) attrs["flowable:formKey"] = data.flowableFormKey;
860
- if (data.flowableDueDate) attrs["flowable:dueDate"] = data.flowableDueDate;
861
- if (data.flowableType) attrs["flowable:type"] = data.flowableType;
862
- if (data.flowableExpression) attrs["flowable:expression"] = data.flowableExpression;
863
- if (data.flowableClass) attrs["flowable:class"] = data.flowableClass;
864
- if (data.flowableDelegateExpression) attrs["flowable:delegateExpression"] = data.flowableDelegateExpression;
865
- return attrs;
866
- }
867
988
  function buildSemanticModel(moddle, nodes, edges, opts) {
868
989
  const defId = opts.id ?? "Definitions_1";
869
990
  const defName = opts.name;
@@ -922,13 +1043,26 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
922
1043
  return definitions;
923
1044
  }
924
1045
  function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId) {
925
- const myNodes = poolId ? allNodes.filter(
1046
+ const subProcessIds = new Set(
1047
+ allNodes.filter(
1048
+ (n) => n.data.elementType === "SubProcess" || n.data.elementType === "Transaction" || n.data.elementType === "EventSubProcess" || n.data.elementType === "AdHocSubProcess"
1049
+ ).map((n) => n.id)
1050
+ );
1051
+ const isInsideSubProcess = (node) => {
1052
+ let parentId = node.parentId;
1053
+ while (parentId) {
1054
+ if (subProcessIds.has(parentId)) return true;
1055
+ parentId = allNodes.find((candidate) => candidate.id === parentId)?.parentId;
1056
+ }
1057
+ return false;
1058
+ };
1059
+ const myNodes = (poolId ? allNodes.filter(
926
1060
  (n) => n.parentId === poolId || laneNodes.some((l) => l.id === n.parentId && l.parentId === poolId)
927
- ) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane");
1061
+ ) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
928
1062
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
929
1063
  const flowElements = [];
930
1064
  for (const node of myNodes) {
931
- const el = buildFlowElement(moddle, node);
1065
+ const el = buildFlowElement(moddle, node, allNodes, allEdges);
932
1066
  if (el) flowElements.push(el);
933
1067
  }
934
1068
  const myNodeIds = new Set(myNodes.map((n) => n.id));
@@ -939,6 +1073,17 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
939
1073
  const edgeMeta = buildEdgeElement(moddle, edge);
940
1074
  if (edgeMeta) flowElements.push(edgeMeta);
941
1075
  }
1076
+ const elementById = new Map(
1077
+ flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
1078
+ );
1079
+ for (const edge of myEdges) {
1080
+ if (!edge.data?.isDefault) continue;
1081
+ const sourceElement = elementById.get(edge.source);
1082
+ const edgeElement = elementById.get(edge.id);
1083
+ if (sourceElement && edgeElement) {
1084
+ sourceElement.default = edgeElement;
1085
+ }
1086
+ }
942
1087
  const process = moddle.create("bpmn:Process", {
943
1088
  id: processId,
944
1089
  isExecutable: true,
@@ -959,7 +1104,7 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
959
1104
  }
960
1105
  return process;
961
1106
  }
962
- function buildFlowElement(moddle, node, _allNodes, _allEdges) {
1107
+ function buildFlowElement(moddle, node, allNodes, allEdges) {
963
1108
  const { elementType, label, trigger } = node.data;
964
1109
  if (elementType === "Pool" || elementType === "Lane") return null;
965
1110
  const moddleType = ELEMENT_TYPE_TO_MODDLE[elementType];
@@ -968,25 +1113,46 @@ function buildFlowElement(moddle, node, _allNodes, _allEdges) {
968
1113
  id: node.id,
969
1114
  name: label ?? ""
970
1115
  };
1116
+ if (node.data.documentation) {
1117
+ attrs.documentation = [
1118
+ moddle.create("bpmn:Documentation", { text: node.data.documentation })
1119
+ ];
1120
+ }
971
1121
  if (trigger && trigger !== "none") {
972
1122
  const defType = TRIGGER_TO_EVENT_DEF[trigger];
973
1123
  if (defType) {
974
1124
  attrs.eventDefinitions = [moddle.create(defType, { id: uid("EventDef", node.id) })];
975
1125
  }
976
1126
  }
977
- if (elementType === "SubProcess" && node.data.subProcessVariant === "transaction") {
978
- return moddle.create("bpmn:Transaction", attrs);
1127
+ if (elementType === "BoundaryEvent") {
1128
+ attrs.attachedToRef = { id: node.data.attachedToRef ?? node.parentId };
1129
+ attrs.cancelActivity = node.data.isNonInterrupting ? false : true;
979
1130
  }
980
- if (elementType === "SubProcess" && node.data.subProcessVariant === "adhoc") {
981
- return moddle.create("bpmn:AdHocSubProcess", attrs);
1131
+ const isSubProcess = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
1132
+ if (isSubProcess) {
1133
+ attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
1134
+ if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
1135
+ attrs.triggeredByEvent = true;
1136
+ }
982
1137
  }
983
1138
  const element = moddle.create(moddleType, attrs);
984
- const flowableAttrs = buildFlowableAttrs(node.data);
985
- if (Object.keys(flowableAttrs).length > 0) {
986
- element.$attrs = flowableAttrs;
987
- }
988
1139
  return element;
989
1140
  }
1141
+ function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
1142
+ const childNodes = allNodes.filter((node) => node.parentId === parent.id);
1143
+ const childNodeIds = new Set(childNodes.map((node) => node.id));
1144
+ const flowElements = [];
1145
+ for (const child of childNodes) {
1146
+ const element = buildFlowElement(moddle, child, allNodes, allEdges);
1147
+ if (element) flowElements.push(element);
1148
+ }
1149
+ for (const edge of allEdges) {
1150
+ if (!childNodeIds.has(edge.source) || !childNodeIds.has(edge.target)) continue;
1151
+ const element = buildEdgeElement(moddle, edge);
1152
+ if (element) flowElements.push(element);
1153
+ }
1154
+ return flowElements;
1155
+ }
990
1156
  function buildEdgeElement(moddle, edge) {
991
1157
  if (!edge.data) return null;
992
1158
  const moddleType = EDGE_TYPE_TO_MODDLE[edge.data.edgeType];
@@ -997,6 +1163,11 @@ function buildEdgeElement(moddle, edge) {
997
1163
  sourceRef: { id: edge.source },
998
1164
  targetRef: { id: edge.target }
999
1165
  };
1166
+ if (edge.data.documentation) {
1167
+ attrs.documentation = [
1168
+ moddle.create("bpmn:Documentation", { text: edge.data.documentation })
1169
+ ];
1170
+ }
1000
1171
  if (edge.data.conditionExpression) {
1001
1172
  attrs.conditionExpression = moddle.create("bpmn:FormalExpression", {
1002
1173
  body: edge.data.conditionExpression
@@ -1007,13 +1178,14 @@ function buildEdgeElement(moddle, edge) {
1007
1178
  function buildBpmnDI(moddle, definitions, nodes, edges) {
1008
1179
  const shapes = [];
1009
1180
  const edgeShapes = [];
1181
+ const absolutePositionById = buildAbsolutePositionMap(nodes);
1010
1182
  for (const node of nodes) {
1011
1183
  const meta = BPMN_ELEMENT_CATALOG[node.data.elementType];
1012
1184
  const w = node.width ?? meta?.defaultWidth ?? 120;
1013
1185
  const h = node.height ?? meta?.defaultHeight ?? 60;
1014
1186
  const bounds = moddle.create("dc:Bounds", {
1015
- x: node.position.x,
1016
- y: node.position.y,
1187
+ x: absolutePositionById.get(node.id)?.x ?? node.position.x,
1188
+ y: absolutePositionById.get(node.id)?.y ?? node.position.y,
1017
1189
  width: w,
1018
1190
  height: h
1019
1191
  });
@@ -1052,6 +1224,24 @@ function buildBpmnDI(moddle, definitions, nodes, edges) {
1052
1224
  });
1053
1225
  definitions.diagrams = [diagram];
1054
1226
  }
1227
+ function buildAbsolutePositionMap(nodes) {
1228
+ const nodeById = new Map(nodes.map((node) => [node.id, node]));
1229
+ const absoluteById = /* @__PURE__ */ new Map();
1230
+ function resolve(node) {
1231
+ const cached = absoluteById.get(node.id);
1232
+ if (cached) return cached;
1233
+ const parent = node.parentId ? nodeById.get(node.parentId) : void 0;
1234
+ const parentPosition = parent ? resolve(parent) : { x: 0, y: 0 };
1235
+ const absolute = {
1236
+ x: parentPosition.x + node.position.x,
1237
+ y: parentPosition.y + node.position.y
1238
+ };
1239
+ absoluteById.set(node.id, absolute);
1240
+ return absolute;
1241
+ }
1242
+ for (const node of nodes) resolve(node);
1243
+ return absoluteById;
1244
+ }
1055
1245
  async function serializeBpmnXml(nodes, edges, opts = {}) {
1056
1246
  const moddle = new bpmnModdle.BpmnModdle();
1057
1247
  const definitions = buildSemanticModel(moddle, nodes, edges, opts);