@aranzatech/diagrams-bpmn 0.2.15 → 0.3.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 (74) hide show
  1. package/README.md +34 -4
  2. package/dist/{catalog-xOMF2ifW.d.cts → catalog-DAGDhO-D.d.cts} +1 -1
  3. package/dist/{catalog-CK3_4cOb.d.ts → catalog-Q1QmKLDD.d.ts} +1 -1
  4. package/dist/{chunk-YUE5EM3W.js → chunk-334WN4JZ.js} +276 -107
  5. package/dist/chunk-334WN4JZ.js.map +1 -0
  6. package/dist/chunk-77L6O76M.js +3 -0
  7. package/dist/chunk-77L6O76M.js.map +1 -0
  8. package/dist/{chunk-QSMP34CT.js → chunk-CPFUQM6H.js} +80 -44
  9. package/dist/chunk-CPFUQM6H.js.map +1 -0
  10. package/dist/{chunk-XMVV7FRZ.js → chunk-FFWJA5BV.js} +3 -3
  11. package/dist/{chunk-XMVV7FRZ.js.map → chunk-FFWJA5BV.js.map} +1 -1
  12. package/dist/{chunk-FBTGIYZS.js → chunk-JEGYVEJO.js} +80 -3
  13. package/dist/{chunk-FBTGIYZS.js.map → chunk-JEGYVEJO.js.map} +1 -1
  14. package/dist/chunk-TB6V4S5N.js +104 -0
  15. package/dist/chunk-TB6V4S5N.js.map +1 -0
  16. package/dist/{chunk-HOWK3ZOO.js → chunk-YAYZW45I.js} +379 -16
  17. package/dist/chunk-YAYZW45I.js.map +1 -0
  18. package/dist/edges/index.cjs +78 -42
  19. package/dist/edges/index.cjs.map +1 -1
  20. package/dist/edges/index.js +1 -1
  21. package/dist/elements/index.cjs +78 -0
  22. package/dist/elements/index.cjs.map +1 -1
  23. package/dist/elements/index.d.cts +24 -5
  24. package/dist/elements/index.d.ts +24 -5
  25. package/dist/elements/index.js +1 -1
  26. package/dist/elk-QT7H4252.js +6 -0
  27. package/dist/elk-QT7H4252.js.map +1 -0
  28. package/dist/extensions/index.cjs +108 -0
  29. package/dist/extensions/index.cjs.map +1 -0
  30. package/dist/extensions/index.d.cts +145 -0
  31. package/dist/extensions/index.d.ts +145 -0
  32. package/dist/extensions/index.js +4 -0
  33. package/dist/extensions/index.js.map +1 -0
  34. package/dist/index.cjs +922 -160
  35. package/dist/index.cjs.map +1 -1
  36. package/dist/index.d.cts +7 -5
  37. package/dist/index.d.ts +7 -5
  38. package/dist/index.js +6 -4
  39. package/dist/index.js.map +1 -1
  40. package/dist/layout/index.cjs +11 -1
  41. package/dist/layout/index.cjs.map +1 -1
  42. package/dist/layout/index.d.cts +4 -3
  43. package/dist/layout/index.d.ts +4 -3
  44. package/dist/layout/index.js +3 -3
  45. package/dist/modeling/index.cjs +387 -13
  46. package/dist/modeling/index.cjs.map +1 -1
  47. package/dist/modeling/index.d.cts +62 -4
  48. package/dist/modeling/index.d.ts +62 -4
  49. package/dist/modeling/index.js +1 -1
  50. package/dist/types-BX_o95GC.d.cts +40 -0
  51. package/dist/{types-y-ZbX-ff.d.ts → types-BYN4Zuee.d.cts} +15 -1
  52. package/dist/{types-y-ZbX-ff.d.cts → types-BYN4Zuee.d.ts} +15 -1
  53. package/dist/{types-jIDz306Y.d.cts → types-CggktCqr.d.cts} +4 -1
  54. package/dist/types-D7zel9dq.d.ts +40 -0
  55. package/dist/{types-DG5yPKld.d.ts → types-DmDODKlh.d.ts} +4 -1
  56. package/dist/validation/index.cjs +81 -125
  57. package/dist/validation/index.cjs.map +1 -1
  58. package/dist/validation/index.d.cts +22 -5
  59. package/dist/validation/index.d.ts +22 -5
  60. package/dist/validation/index.js +82 -126
  61. package/dist/validation/index.js.map +1 -1
  62. package/dist/xml/index.cjs +319 -49
  63. package/dist/xml/index.cjs.map +1 -1
  64. package/dist/xml/index.d.cts +5 -3
  65. package/dist/xml/index.d.ts +5 -3
  66. package/dist/xml/index.js +2 -1
  67. package/package.json +6 -1
  68. package/dist/chunk-HOWK3ZOO.js.map +0 -1
  69. package/dist/chunk-QSMP34CT.js.map +0 -1
  70. package/dist/chunk-YUE5EM3W.js.map +0 -1
  71. package/dist/elk-FSFIEL6O.js +0 -6
  72. package/dist/elk-FSFIEL6O.js.map +0 -1
  73. package/dist/guards-C70uIY_O.d.cts +0 -16
  74. package/dist/guards-foB6XIfZ.d.ts +0 -16
package/dist/index.cjs CHANGED
@@ -717,6 +717,186 @@ function supportsCollapse(type) {
717
717
  function supportsMarkers(type) {
718
718
  return BPMN_ELEMENT_CATALOG[type].supportsMarkers ?? false;
719
719
  }
720
+
721
+ // src/elements/event-subtypes.ts
722
+ var EVENT_TRIGGER_ORDER = [
723
+ "none",
724
+ "message",
725
+ "timer",
726
+ "signal",
727
+ "error",
728
+ "escalation",
729
+ "conditional",
730
+ "link",
731
+ "compensation",
732
+ "cancel",
733
+ "terminate",
734
+ "multiple",
735
+ "parallelMultiple"
736
+ ];
737
+ var BASE_ALLOWED_EVENT_TRIGGERS = {
738
+ StartEvent: /* @__PURE__ */ new Set(["none", "message", "timer", "conditional", "signal", "multiple", "parallelMultiple"]),
739
+ EndEvent: /* @__PURE__ */ new Set(["none", "message", "signal", "error", "escalation", "terminate", "compensation", "cancel", "multiple"]),
740
+ IntermediateCatchEvent: /* @__PURE__ */ new Set(["none", "message", "timer", "conditional", "signal", "link", "multiple", "parallelMultiple"]),
741
+ IntermediateThrowEvent: /* @__PURE__ */ new Set(["none", "message", "signal", "link", "escalation", "compensation", "multiple"]),
742
+ BoundaryEvent: /* @__PURE__ */ new Set(["message", "timer", "conditional", "signal", "error", "escalation", "cancel", "compensation"])
743
+ };
744
+ var EVENT_SUBPROCESS_ALLOWED_START_TRIGGERS = /* @__PURE__ */ new Set([
745
+ "message",
746
+ "timer",
747
+ "escalation",
748
+ "conditional",
749
+ "error",
750
+ "compensation",
751
+ "signal",
752
+ "multiple",
753
+ "parallelMultiple"
754
+ ]);
755
+ var NON_INTERRUPTING_EVENT_SUBPROCESS_START_TRIGGERS = /* @__PURE__ */ new Set([
756
+ "message",
757
+ "timer",
758
+ "escalation",
759
+ "conditional",
760
+ "signal",
761
+ "multiple",
762
+ "parallelMultiple"
763
+ ]);
764
+ var NON_INTERRUPTING_BOUNDARY_TRIGGERS = /* @__PURE__ */ new Set([
765
+ "message",
766
+ "timer",
767
+ "conditional",
768
+ "signal",
769
+ "escalation"
770
+ ]);
771
+ function isEventSubProcessParent(parentType, parentSubProcessVariant) {
772
+ return parentType === "EventSubProcess" || parentSubProcessVariant === "event";
773
+ }
774
+ function getAllowedEventTriggers(options) {
775
+ const allowed = new Set(BASE_ALLOWED_EVENT_TRIGGERS[options.baseType]);
776
+ if (options.baseType === "StartEvent" && isEventSubProcessParent(options.parentType, options.parentSubProcessVariant)) {
777
+ for (const trigger of Array.from(allowed)) {
778
+ if (!EVENT_SUBPROCESS_ALLOWED_START_TRIGGERS.has(trigger)) {
779
+ allowed.delete(trigger);
780
+ }
781
+ }
782
+ }
783
+ if (options.baseType === "StartEvent" && options.isNonInterrupting) {
784
+ for (const trigger of Array.from(allowed)) {
785
+ if (!NON_INTERRUPTING_EVENT_SUBPROCESS_START_TRIGGERS.has(trigger)) {
786
+ allowed.delete(trigger);
787
+ }
788
+ }
789
+ }
790
+ if (options.baseType === "BoundaryEvent" && options.isNonInterrupting) {
791
+ for (const trigger of Array.from(allowed)) {
792
+ if (!NON_INTERRUPTING_BOUNDARY_TRIGGERS.has(trigger)) {
793
+ allowed.delete(trigger);
794
+ }
795
+ }
796
+ }
797
+ return EVENT_TRIGGER_ORDER.filter((trigger) => allowed.has(trigger));
798
+ }
799
+
800
+ // src/xml/aranza-descriptor.ts
801
+ var ARANZA_DESCRIPTOR = {
802
+ name: "Aranza",
803
+ uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
804
+ prefix: "aranza",
805
+ xml: { tagAlias: "lowerCase" },
806
+ types: [
807
+ {
808
+ name: "TaskConfig",
809
+ superClass: ["Element"],
810
+ properties: [
811
+ { name: "priority", isAttr: true, type: "String" },
812
+ { name: "owner", isAttr: true, type: "String" },
813
+ { name: "sla", isAttr: true, type: "String" },
814
+ // Aranza connector execution config (resolved at runtime by the Flowable delegate)
815
+ { name: "implementation", isAttr: true, type: "String" },
816
+ { name: "connectorInstanceId", isAttr: true, type: "String" },
817
+ { name: "connectorId", isAttr: true, type: "String" },
818
+ { name: "connectorAction", isAttr: true, type: "String" },
819
+ { name: "connectorParamsJson", isAttr: true, type: "String" },
820
+ { name: "httpMethod", isAttr: true, type: "String" },
821
+ { name: "endpoint", isAttr: true, type: "String" },
822
+ { name: "operationRef", isAttr: true, type: "String" },
823
+ { name: "connector", isAttr: true, type: "String" },
824
+ { name: "action", isAttr: true, type: "String" },
825
+ // Flowable implementation hints stored for round-trip fidelity
826
+ { name: "flowableType", isAttr: true, type: "String" },
827
+ { name: "flowableDelegateExpression", isAttr: true, type: "String" },
828
+ // BusinessRuleTask: reference to a DMN decision table id
829
+ { name: "decisionRef", isAttr: true, type: "String" },
830
+ // UserTask: form key resolved to a FormDefinition name at runtime
831
+ { name: "formKey", isAttr: true, type: "String" },
832
+ // UserTask: Flowable task assignment — comma-separated ids
833
+ { name: "candidateUsers", isAttr: true, type: "String" },
834
+ { name: "candidateGroups", isAttr: true, type: "String" },
835
+ // UserTask: scheduling + skip expression
836
+ { name: "dueDate", isAttr: true, type: "String" },
837
+ { name: "skipExpression", isAttr: true, type: "String" },
838
+ { name: "businessCalendarName", isAttr: true, type: "String" }
839
+ ]
840
+ },
841
+ {
842
+ // BusinessRuleTask: simplified inline decision table (JSON-serialized)
843
+ name: "InlineDecision",
844
+ superClass: ["Element"],
845
+ properties: [
846
+ { name: "hitPolicy", isAttr: true, type: "String" },
847
+ { name: "tableJson", isAttr: true, type: "String" }
848
+ ]
849
+ },
850
+ {
851
+ // MessageFlow: payload schema + correlation key for executable BPMN
852
+ name: "MessageFlowConfig",
853
+ superClass: ["Element"],
854
+ properties: [
855
+ { name: "payloadSchema", isAttr: true, type: "String" },
856
+ { name: "correlationKey", isAttr: true, type: "String" }
857
+ ]
858
+ }
859
+ ],
860
+ enumerations: [],
861
+ associations: []
862
+ };
863
+
864
+ // src/extensions/types.ts
865
+ function hasText(value) {
866
+ return typeof value === "string" && value.trim().length > 0;
867
+ }
868
+ function getBpmnTaskExecutionExtensions(data) {
869
+ const result = {};
870
+ if (data.priority) result.priority = data.priority;
871
+ if (hasText(data.owner)) result.owner = data.owner;
872
+ if (hasText(data.sla)) result.sla = data.sla;
873
+ if (hasText(data.connector)) result.connector = data.connector;
874
+ if (hasText(data.action)) result.action = data.action;
875
+ if (hasText(data.flowableType)) result.flowableType = data.flowableType;
876
+ if (hasText(data.flowableDelegateExpression)) {
877
+ result.flowableDelegateExpression = data.flowableDelegateExpression;
878
+ }
879
+ if (data.serviceConfig && Object.keys(data.serviceConfig).length > 0) {
880
+ result.serviceConfig = data.serviceConfig;
881
+ }
882
+ if (hasText(data.decisionRef)) result.decisionRef = data.decisionRef;
883
+ if (data.inlineDecisionTable) result.inlineDecisionTable = data.inlineDecisionTable;
884
+ if (hasText(data.formKey)) result.formKey = data.formKey;
885
+ if (hasText(data.candidateUsers)) result.candidateUsers = data.candidateUsers;
886
+ if (hasText(data.candidateGroups)) result.candidateGroups = data.candidateGroups;
887
+ if (hasText(data.dueDate)) result.dueDate = data.dueDate;
888
+ if (hasText(data.skipExpression)) result.skipExpression = data.skipExpression;
889
+ if (hasText(data.businessCalendarName)) {
890
+ result.businessCalendarName = data.businessCalendarName;
891
+ }
892
+ return Object.keys(result).length > 0 ? result : void 0;
893
+ }
894
+ function getBpmnMessageFlowExecutionExtensions(data) {
895
+ const result = {};
896
+ if (hasText(data.payloadSchema)) result.payloadSchema = data.payloadSchema;
897
+ if (hasText(data.correlationKey)) result.correlationKey = data.correlationKey;
898
+ return Object.keys(result).length > 0 ? result : void 0;
899
+ }
720
900
  var ALL_POSITIONS = [
721
901
  react.Position.Top,
722
902
  react.Position.Right,
@@ -2079,32 +2259,32 @@ var BPMN_NODE_TYPES = {
2079
2259
  };
2080
2260
 
2081
2261
  // src/edges/path.ts
2082
- function getPolylineMidpoint(points) {
2262
+ function getPreferredLabelAnchor(points) {
2083
2263
  if (points.length === 0) return { x: 0, y: 0 };
2084
2264
  if (points.length === 1) return points[0];
2085
- let total = 0;
2086
- const lengths = [];
2265
+ let bestIndex = 1;
2266
+ let bestLength = -1;
2087
2267
  for (let i = 1; i < points.length; i += 1) {
2088
- const dx = points[i].x - points[i - 1].x;
2089
- const dy = points[i].y - points[i - 1].y;
2090
- const length = Math.hypot(dx, dy);
2091
- lengths.push(length);
2092
- total += length;
2093
- }
2094
- const halfway = total / 2;
2095
- let traversed = 0;
2096
- for (let i = 1; i < points.length; i += 1) {
2097
- const length = lengths[i - 1];
2098
- if (traversed + length >= halfway) {
2099
- const ratio = length === 0 ? 0 : (halfway - traversed) / length;
2100
- return {
2101
- x: points[i - 1].x + (points[i].x - points[i - 1].x) * ratio,
2102
- y: points[i - 1].y + (points[i].y - points[i - 1].y) * ratio
2103
- };
2268
+ const dx2 = points[i].x - points[i - 1].x;
2269
+ const dy2 = points[i].y - points[i - 1].y;
2270
+ const length = Math.hypot(dx2, dy2);
2271
+ if (length > bestLength) {
2272
+ bestLength = length;
2273
+ bestIndex = i;
2104
2274
  }
2105
- traversed += length;
2106
2275
  }
2107
- return points[points.length - 1];
2276
+ const from = points[bestIndex - 1];
2277
+ const to = points[bestIndex];
2278
+ const midpoint = {
2279
+ x: from.x + (to.x - from.x) / 2,
2280
+ y: from.y + (to.y - from.y) / 2
2281
+ };
2282
+ const dx = to.x - from.x;
2283
+ const dy = to.y - from.y;
2284
+ if (Math.abs(dx) >= Math.abs(dy)) {
2285
+ return { x: midpoint.x, y: midpoint.y - 12 };
2286
+ }
2287
+ return { x: midpoint.x + 12, y: midpoint.y };
2108
2288
  }
2109
2289
  function getSegmentAngle(points) {
2110
2290
  if (points.length < 2) return 0;
@@ -2144,10 +2324,13 @@ function SequenceFlowEdge({
2144
2324
  const points = d?.routingPoints;
2145
2325
  const polyline = points && points.length >= 2 ? [{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }] : [{ x: sourceX, y: sourceY }, { x: targetX, y: targetY }];
2146
2326
  const path = points && points.length >= 2 ? routing.pointsToSvgPath([{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }]) : routing.getOrthogonalPath(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
2147
- const midpoint = getPolylineMidpoint(polyline);
2327
+ const labelAnchor = getPreferredLabelAnchor(polyline);
2148
2328
  const defaultMarkerPath = d?.isDefault ? getDefaultFlowMarkerPath(polyline) : null;
2149
- const labelX = midpoint.x + (d?.labelOffsetX ?? 0);
2150
- const labelY = midpoint.y + (d?.labelOffsetY ?? 0);
2329
+ const labelX = labelAnchor.x + (d?.labelOffsetX ?? 0);
2330
+ const labelY = labelAnchor.y + (d?.labelOffsetY ?? 0);
2331
+ const strokeColor = selected ? "#1a56db" : "#404040";
2332
+ const strokeWidth = selected ? 2.25 : 1.5;
2333
+ const haloWidth = selected ? 7 : 5;
2151
2334
  const { updateEdgeData, getViewport } = react.useReactFlow();
2152
2335
  const dragStartRef = react$1.useRef(null);
2153
2336
  const handleLabelPointerDown = react$1.useCallback((e) => {
@@ -2174,6 +2357,17 @@ function SequenceFlowEdge({
2174
2357
  dragStartRef.current = null;
2175
2358
  }, []);
2176
2359
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2360
+ /* @__PURE__ */ jsxRuntime.jsx(
2361
+ react.BaseEdge,
2362
+ {
2363
+ id: `${id}__halo`,
2364
+ path,
2365
+ style: {
2366
+ stroke: "rgba(255,255,255,0.92)",
2367
+ strokeWidth: haloWidth
2368
+ }
2369
+ }
2370
+ ),
2177
2371
  /* @__PURE__ */ jsxRuntime.jsx(
2178
2372
  react.BaseEdge,
2179
2373
  {
@@ -2182,8 +2376,8 @@ function SequenceFlowEdge({
2182
2376
  ...d?.conditionExpression ? { markerStart: "url(#bpmn-diamond-open)" } : {},
2183
2377
  markerEnd: markerEnd ?? "url(#bpmn-arrow)",
2184
2378
  style: {
2185
- stroke: selected ? "#1a56db" : "#404040",
2186
- strokeWidth: selected ? 2 : 1.5,
2379
+ stroke: strokeColor,
2380
+ strokeWidth,
2187
2381
  ...style ?? {}
2188
2382
  }
2189
2383
  }
@@ -2193,8 +2387,8 @@ function SequenceFlowEdge({
2193
2387
  {
2194
2388
  d: defaultMarkerPath,
2195
2389
  fill: "none",
2196
- stroke: selected ? "#1a56db" : "#404040",
2197
- strokeWidth: selected ? 2 : 1.5,
2390
+ stroke: strokeColor,
2391
+ strokeWidth,
2198
2392
  strokeLinecap: "round",
2199
2393
  "data-testid": "bpmn-default-flow-marker"
2200
2394
  }
@@ -2209,13 +2403,17 @@ function SequenceFlowEdge({
2209
2403
  position: "absolute",
2210
2404
  transform: `translate(-50%,-50%) translate(${labelX}px,${labelY}px)`,
2211
2405
  fontSize: 11,
2212
- fontFamily: "Inter, system-ui, sans-serif",
2213
- background: "rgba(255,255,255,0.85)",
2214
- padding: "1px 4px",
2215
- borderRadius: 2,
2406
+ fontFamily: '"IBM Plex Sans", Inter, system-ui, sans-serif',
2407
+ background: "rgba(255,255,255,0.96)",
2408
+ color: "#1f2937",
2409
+ padding: "2px 6px",
2410
+ borderRadius: 999,
2411
+ border: "1px solid rgba(148, 163, 184, 0.45)",
2412
+ boxShadow: "0 1px 2px rgba(15, 23, 42, 0.10)",
2216
2413
  pointerEvents: "all",
2217
2414
  cursor: "grab",
2218
- userSelect: "none"
2415
+ userSelect: "none",
2416
+ whiteSpace: "nowrap"
2219
2417
  },
2220
2418
  className: "nodrag nopan",
2221
2419
  children: label ?? d?.label
@@ -2241,8 +2439,22 @@ function MessageFlowEdge({
2241
2439
  const points = d?.routingPoints;
2242
2440
  const polyline = points && points.length >= 2 ? [{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }] : [{ x: sourceX, y: sourceY }, { x: targetX, y: targetY }];
2243
2441
  const path = points && points.length >= 2 ? routing.pointsToSvgPath([{ x: sourceX, y: sourceY }, ...points.slice(1, -1), { x: targetX, y: targetY }]) : routing.getOrthogonalPath(sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition);
2244
- const midpoint = getPolylineMidpoint(polyline);
2442
+ const labelAnchor = getPreferredLabelAnchor(polyline);
2443
+ const strokeColor = selected ? "#1a56db" : "#404040";
2444
+ const strokeWidth = selected ? 2.25 : 1.5;
2445
+ const haloWidth = selected ? 7 : 5;
2245
2446
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2447
+ /* @__PURE__ */ jsxRuntime.jsx(
2448
+ react.BaseEdge,
2449
+ {
2450
+ id: `${id}__halo`,
2451
+ path,
2452
+ style: {
2453
+ stroke: "rgba(255,255,255,0.92)",
2454
+ strokeWidth: haloWidth
2455
+ }
2456
+ }
2457
+ ),
2246
2458
  /* @__PURE__ */ jsxRuntime.jsx(
2247
2459
  react.BaseEdge,
2248
2460
  {
@@ -2251,8 +2463,8 @@ function MessageFlowEdge({
2251
2463
  markerStart: "url(#bpmn-circle-open)",
2252
2464
  markerEnd: markerEnd ?? "url(#bpmn-arrow-open)",
2253
2465
  style: {
2254
- stroke: selected ? "#1a56db" : "#404040",
2255
- strokeWidth: selected ? 2 : 1.5,
2466
+ stroke: strokeColor,
2467
+ strokeWidth,
2256
2468
  strokeDasharray: "6 3",
2257
2469
  ...style ?? {}
2258
2470
  }
@@ -2263,13 +2475,17 @@ function MessageFlowEdge({
2263
2475
  {
2264
2476
  style: {
2265
2477
  position: "absolute",
2266
- transform: `translate(-50%,-50%) translate(${midpoint.x}px,${midpoint.y}px)`,
2478
+ transform: `translate(-50%,-50%) translate(${labelAnchor.x}px,${labelAnchor.y}px)`,
2267
2479
  fontSize: 11,
2268
- fontFamily: "Inter, system-ui, sans-serif",
2269
- background: "rgba(255,255,255,0.85)",
2270
- padding: "1px 4px",
2271
- borderRadius: 2,
2272
- pointerEvents: "all"
2480
+ fontFamily: '"IBM Plex Sans", Inter, system-ui, sans-serif',
2481
+ background: "rgba(255,255,255,0.96)",
2482
+ color: "#1f2937",
2483
+ padding: "2px 6px",
2484
+ borderRadius: 999,
2485
+ border: "1px solid rgba(148, 163, 184, 0.45)",
2486
+ boxShadow: "0 1px 2px rgba(15, 23, 42, 0.10)",
2487
+ pointerEvents: "all",
2488
+ whiteSpace: "nowrap"
2273
2489
  },
2274
2490
  className: "nodrag nopan",
2275
2491
  children: label ?? d?.label
@@ -2379,62 +2595,6 @@ var BPMN_EDGE_TYPES = {
2379
2595
  conversationLink: ConversationLinkEdge
2380
2596
  };
2381
2597
 
2382
- // src/xml/aranza-descriptor.ts
2383
- var ARANZA_DESCRIPTOR = {
2384
- name: "Aranza",
2385
- uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
2386
- prefix: "aranza",
2387
- xml: { tagAlias: "lowerCase" },
2388
- types: [
2389
- {
2390
- name: "TaskConfig",
2391
- superClass: ["Element"],
2392
- properties: [
2393
- { name: "priority", isAttr: true, type: "String" },
2394
- { name: "owner", isAttr: true, type: "String" },
2395
- { name: "sla", isAttr: true, type: "String" },
2396
- // Aranza connector execution config (resolved at runtime by the Flowable delegate)
2397
- { name: "connector", isAttr: true, type: "String" },
2398
- { name: "action", isAttr: true, type: "String" },
2399
- // Flowable implementation hints stored for round-trip fidelity
2400
- { name: "flowableType", isAttr: true, type: "String" },
2401
- { name: "flowableDelegateExpression", isAttr: true, type: "String" },
2402
- // BusinessRuleTask: reference to a DMN decision table id
2403
- { name: "decisionRef", isAttr: true, type: "String" },
2404
- // UserTask: form key resolved to a FormDefinition name at runtime
2405
- { name: "formKey", isAttr: true, type: "String" },
2406
- // UserTask: Flowable task assignment — comma-separated ids
2407
- { name: "candidateUsers", isAttr: true, type: "String" },
2408
- { name: "candidateGroups", isAttr: true, type: "String" },
2409
- // UserTask: scheduling + skip expression
2410
- { name: "dueDate", isAttr: true, type: "String" },
2411
- { name: "skipExpression", isAttr: true, type: "String" },
2412
- { name: "businessCalendarName", isAttr: true, type: "String" }
2413
- ]
2414
- },
2415
- {
2416
- // BusinessRuleTask: simplified inline decision table (JSON-serialized)
2417
- name: "InlineDecision",
2418
- superClass: ["Element"],
2419
- properties: [
2420
- { name: "hitPolicy", isAttr: true, type: "String" },
2421
- { name: "tableJson", isAttr: true, type: "String" }
2422
- ]
2423
- },
2424
- {
2425
- // MessageFlow: payload schema + correlation key for executable BPMN
2426
- name: "MessageFlowConfig",
2427
- superClass: ["Element"],
2428
- properties: [
2429
- { name: "payloadSchema", isAttr: true, type: "String" },
2430
- { name: "correlationKey", isAttr: true, type: "String" }
2431
- ]
2432
- }
2433
- ],
2434
- enumerations: [],
2435
- associations: []
2436
- };
2437
-
2438
2598
  // src/xml/mapper.ts
2439
2599
  var MODDLE_TO_ELEMENT_TYPE = {
2440
2600
  "bpmn:StartEvent": "StartEvent",
@@ -2563,6 +2723,11 @@ function asElements(v) {
2563
2723
  function asString(v) {
2564
2724
  return typeof v === "string" && v.trim() ? v.trim() : void 0;
2565
2725
  }
2726
+ function asStringRecord(value) {
2727
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
2728
+ const entries = Object.entries(value).filter((entry) => typeof entry[1] === "string");
2729
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
2730
+ }
2566
2731
  function extractDocumentation(el) {
2567
2732
  const [doc] = asElements(el.documentation);
2568
2733
  return asString(doc?.text);
@@ -2741,6 +2906,35 @@ function extractAranzaExtensions(el) {
2741
2906
  if (owner) result.owner = owner;
2742
2907
  const sla = asString(taskConfig.sla);
2743
2908
  if (sla) result.sla = sla;
2909
+ const serviceConfig = {};
2910
+ const implementation = asString(taskConfig.implementation);
2911
+ if (implementation === "none" || implementation === "connector" || implementation === "http" || implementation === "webService") {
2912
+ serviceConfig.implementation = implementation;
2913
+ }
2914
+ const connectorInstanceId = asString(taskConfig.connectorInstanceId);
2915
+ if (connectorInstanceId) serviceConfig.connectorInstanceId = connectorInstanceId;
2916
+ const connectorId = asString(taskConfig.connectorId);
2917
+ if (connectorId) serviceConfig.connectorId = connectorId;
2918
+ const connectorAction = asString(taskConfig.connectorAction);
2919
+ if (connectorAction) serviceConfig.connectorAction = connectorAction;
2920
+ const connectorParamsJson = asString(taskConfig.connectorParamsJson);
2921
+ if (connectorParamsJson) {
2922
+ try {
2923
+ const parsed = JSON.parse(connectorParamsJson);
2924
+ const connectorParams = asStringRecord(parsed);
2925
+ if (connectorParams) serviceConfig.connectorParams = connectorParams;
2926
+ } catch {
2927
+ }
2928
+ }
2929
+ const httpMethod = asString(taskConfig.httpMethod);
2930
+ if (httpMethod === "GET" || httpMethod === "POST" || httpMethod === "PUT" || httpMethod === "DELETE" || httpMethod === "PATCH") {
2931
+ serviceConfig.httpMethod = httpMethod;
2932
+ }
2933
+ const endpoint = asString(taskConfig.endpoint);
2934
+ if (endpoint) serviceConfig.endpoint = endpoint;
2935
+ const operationRef = asString(taskConfig.operationRef);
2936
+ if (operationRef) serviceConfig.operationRef = operationRef;
2937
+ if (Object.keys(serviceConfig).length > 0) result.serviceConfig = serviceConfig;
2744
2938
  const connector = asString(taskConfig.connector);
2745
2939
  if (connector) result.connector = connector;
2746
2940
  const action = asString(taskConfig.action);
@@ -2833,6 +3027,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2833
3027
  const completionCondition = elementType === "AdHocSubProcess" ? extractCompletionCondition(el) : void 0;
2834
3028
  const loopChars = extractLoopCharacteristics(el);
2835
3029
  const dataObjectRef = elementType === "DataObjectReference" ? asString(el.dataObjectRef?.id) : void 0;
3030
+ const dataStoreRef = elementType === "DataStoreReference" ? asString(el.dataStoreRef?.id) : void 0;
2836
3031
  const data = {
2837
3032
  elementType,
2838
3033
  ...label ? { label } : {},
@@ -2854,6 +3049,7 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2854
3049
  ...script ? { script } : {},
2855
3050
  ...completionCondition ? { completionCondition } : {},
2856
3051
  ...dataObjectRef ? { dataObjectRef } : {},
3052
+ ...dataStoreRef ? { dataStoreRef } : {},
2857
3053
  ...loopChars,
2858
3054
  ...aranzaExt
2859
3055
  };
@@ -3010,9 +3206,10 @@ async function parseBpmnXml(xml) {
3010
3206
  }
3011
3207
  }
3012
3208
  const defaultFlowById = /* @__PURE__ */ new Set();
3209
+ const defaultFlowBySourceId = /* @__PURE__ */ new Map();
3013
3210
  const nodeIds = new Set(nodes.map((node) => node.id));
3014
3211
  for (const rootEl of asElements(rootElement.rootElements)) {
3015
- collectDefaultFlows(rootEl, defaultFlowById);
3212
+ collectDefaultFlows(rootEl, defaultFlowById, defaultFlowBySourceId);
3016
3213
  }
3017
3214
  const normalizedEdges = edges.map((edge) => {
3018
3215
  if (!defaultFlowById.has(edge.id)) return edge;
@@ -3035,18 +3232,36 @@ async function parseBpmnXml(xml) {
3035
3232
  if (importedDefinitions) importedProcess.definitions = importedDefinitions;
3036
3233
  return importedProcess;
3037
3234
  })() : importedDefinitions ? { definitions: importedDefinitions } : void 0;
3235
+ const normalizedNodes = normalizeChildPositions(nodes, nodeIds).map((node) => {
3236
+ const defaultFlowId = defaultFlowBySourceId.get(node.id);
3237
+ if (!defaultFlowId) return node;
3238
+ return {
3239
+ ...node,
3240
+ data: {
3241
+ ...node.data,
3242
+ default: defaultFlowId
3243
+ }
3244
+ };
3245
+ });
3038
3246
  return {
3039
- nodes: normalizeChildPositions(nodes, nodeIds),
3247
+ nodes: normalizedNodes,
3040
3248
  edges: normalizedEdges,
3041
3249
  warnings,
3042
3250
  ...process ? { process } : {}
3043
3251
  };
3044
3252
  }
3045
- function collectDefaultFlows(el, defaultFlowById) {
3253
+ function collectDefaultFlows(el, defaultFlowById, defaultFlowBySourceId) {
3046
3254
  const defaultRef = el.default;
3047
- if (defaultRef?.id) defaultFlowById.add(defaultRef.id);
3048
- for (const child of asElements(el.rootElements)) collectDefaultFlows(child, defaultFlowById);
3049
- for (const child of asElements(el.flowElements)) collectDefaultFlows(child, defaultFlowById);
3255
+ if (defaultRef?.id) {
3256
+ defaultFlowById.add(defaultRef.id);
3257
+ if (el.id) defaultFlowBySourceId.set(el.id, defaultRef.id);
3258
+ }
3259
+ for (const child of asElements(el.rootElements)) {
3260
+ collectDefaultFlows(child, defaultFlowById, defaultFlowBySourceId);
3261
+ }
3262
+ for (const child of asElements(el.flowElements)) {
3263
+ collectDefaultFlows(child, defaultFlowById, defaultFlowBySourceId);
3264
+ }
3050
3265
  }
3051
3266
  function normalizeChildPositions(nodes, nodeIds) {
3052
3267
  const absoluteById = new Map(nodes.map((node) => [node.id, node.position]));
@@ -3107,6 +3322,12 @@ function parseVariableType2(type) {
3107
3322
  return "xsd:string";
3108
3323
  }
3109
3324
  }
3325
+ function escapeXml(text) {
3326
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
3327
+ }
3328
+ function escapeRegex(text) {
3329
+ return text.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3330
+ }
3110
3331
  function buildGlobalDefinitions(moddle, definitionsSet) {
3111
3332
  if (!definitionsSet) return [];
3112
3333
  const rootElements = [];
@@ -3132,6 +3353,33 @@ function buildGlobalDefinitions(moddle, definitionsSet) {
3132
3353
  }
3133
3354
  return rootElements;
3134
3355
  }
3356
+ function collectReferencedDataStoreIds(nodes) {
3357
+ const ids = /* @__PURE__ */ new Set();
3358
+ for (const node of nodes) {
3359
+ if (node.data.elementType !== "DataStoreReference") continue;
3360
+ const explicitRef = typeof node.data.dataStoreRef === "string" ? node.data.dataStoreRef : `DataStore_${node.id}`;
3361
+ ids.add(explicitRef);
3362
+ }
3363
+ return ids;
3364
+ }
3365
+ function buildGlobalDataStores(moddle, nodes) {
3366
+ const referencedIds = collectReferencedDataStoreIds(nodes);
3367
+ if (referencedIds.size === 0) return [];
3368
+ const byId = new Map(nodes.map((node) => [node.id, node]));
3369
+ const rootElements = [];
3370
+ for (const id of referencedIds) {
3371
+ const existing = byId.get(id);
3372
+ if (existing?.data.elementType === "DataStore") {
3373
+ rootElements.push(moddle.create("bpmn:DataStore", {
3374
+ id,
3375
+ name: existing.data.label ?? ""
3376
+ }));
3377
+ continue;
3378
+ }
3379
+ rootElements.push(moddle.create("bpmn:DataStore", { id }));
3380
+ }
3381
+ return rootElements;
3382
+ }
3135
3383
  function buildItemDefinitions(moddle, variables) {
3136
3384
  return (variables ?? []).map(
3137
3385
  (variable) => moddle.create("bpmn:ItemDefinition", {
@@ -3165,38 +3413,41 @@ function buildEventDefinitions(moddle, node, eventDefinition) {
3165
3413
  return [moddle.create(defType, attrs)];
3166
3414
  }
3167
3415
  function buildAranzaExtensionElements(moddle, node) {
3168
- const { priority, owner, sla } = node.data;
3169
- const connector = typeof node.data.connector === "string" ? node.data.connector : void 0;
3170
- const action = typeof node.data.action === "string" ? node.data.action : void 0;
3171
- const flowableType = typeof node.data.flowableType === "string" ? node.data.flowableType : void 0;
3172
- const flowableDelegateExpression = typeof node.data.flowableDelegateExpression === "string" ? node.data.flowableDelegateExpression : void 0;
3173
- const decisionRef = typeof node.data.decisionRef === "string" ? node.data.decisionRef : void 0;
3174
- const formKey = typeof node.data.formKey === "string" ? node.data.formKey : void 0;
3175
- const candidateUsers = typeof node.data.candidateUsers === "string" ? node.data.candidateUsers : void 0;
3176
- const candidateGroups = typeof node.data.candidateGroups === "string" ? node.data.candidateGroups : void 0;
3177
- const dueDate = typeof node.data.dueDate === "string" ? node.data.dueDate : void 0;
3178
- const skipExpression = typeof node.data.skipExpression === "string" ? node.data.skipExpression : void 0;
3179
- const businessCalendarName = typeof node.data.businessCalendarName === "string" ? node.data.businessCalendarName : void 0;
3180
- if (!priority && !owner && !sla && !connector && !action && !flowableType && !flowableDelegateExpression && !decisionRef && !formKey && !candidateUsers && !candidateGroups && !dueDate && !skipExpression && !businessCalendarName) {
3416
+ const ext = getBpmnTaskExecutionExtensions(node.data);
3417
+ if (!ext) {
3181
3418
  return null;
3182
3419
  }
3183
3420
  const configAttrs = {};
3184
- if (priority) configAttrs.priority = priority;
3185
- if (owner) configAttrs.owner = owner;
3186
- if (sla) configAttrs.sla = sla;
3187
- if (connector) configAttrs.connector = connector;
3188
- if (action) configAttrs.action = action;
3189
- if (flowableType) configAttrs.flowableType = flowableType;
3190
- if (flowableDelegateExpression) configAttrs.flowableDelegateExpression = flowableDelegateExpression;
3191
- if (decisionRef) configAttrs.decisionRef = decisionRef;
3192
- if (formKey) configAttrs.formKey = formKey;
3193
- if (candidateUsers) configAttrs.candidateUsers = candidateUsers;
3194
- if (candidateGroups) configAttrs.candidateGroups = candidateGroups;
3195
- if (dueDate) configAttrs.dueDate = dueDate;
3196
- if (skipExpression) configAttrs.skipExpression = skipExpression;
3197
- if (businessCalendarName) configAttrs.businessCalendarName = businessCalendarName;
3421
+ if (ext.priority) configAttrs.priority = ext.priority;
3422
+ if (ext.owner) configAttrs.owner = ext.owner;
3423
+ if (ext.sla) configAttrs.sla = ext.sla;
3424
+ if (ext.serviceConfig?.implementation) configAttrs.implementation = ext.serviceConfig.implementation;
3425
+ if (ext.serviceConfig?.connectorInstanceId) {
3426
+ configAttrs.connectorInstanceId = ext.serviceConfig.connectorInstanceId;
3427
+ }
3428
+ if (ext.serviceConfig?.connectorId) configAttrs.connectorId = ext.serviceConfig.connectorId;
3429
+ if (ext.serviceConfig?.connectorAction) {
3430
+ configAttrs.connectorAction = ext.serviceConfig.connectorAction;
3431
+ }
3432
+ if (ext.serviceConfig?.connectorParams && Object.keys(ext.serviceConfig.connectorParams).length > 0) {
3433
+ configAttrs.connectorParamsJson = JSON.stringify(ext.serviceConfig.connectorParams);
3434
+ }
3435
+ if (ext.serviceConfig?.httpMethod) configAttrs.httpMethod = ext.serviceConfig.httpMethod;
3436
+ if (ext.serviceConfig?.endpoint) configAttrs.endpoint = ext.serviceConfig.endpoint;
3437
+ if (ext.serviceConfig?.operationRef) configAttrs.operationRef = ext.serviceConfig.operationRef;
3438
+ if (ext.connector) configAttrs.connector = ext.connector;
3439
+ if (ext.action) configAttrs.action = ext.action;
3440
+ if (ext.flowableType) configAttrs.flowableType = ext.flowableType;
3441
+ if (ext.flowableDelegateExpression) configAttrs.flowableDelegateExpression = ext.flowableDelegateExpression;
3442
+ if (ext.decisionRef) configAttrs.decisionRef = ext.decisionRef;
3443
+ if (ext.formKey) configAttrs.formKey = ext.formKey;
3444
+ if (ext.candidateUsers) configAttrs.candidateUsers = ext.candidateUsers;
3445
+ if (ext.candidateGroups) configAttrs.candidateGroups = ext.candidateGroups;
3446
+ if (ext.dueDate) configAttrs.dueDate = ext.dueDate;
3447
+ if (ext.skipExpression) configAttrs.skipExpression = ext.skipExpression;
3448
+ if (ext.businessCalendarName) configAttrs.businessCalendarName = ext.businessCalendarName;
3198
3449
  const values = [moddle.create("aranza:TaskConfig", configAttrs)];
3199
- const inlineDecisionTable = node.data.inlineDecisionTable;
3450
+ const inlineDecisionTable = ext.inlineDecisionTable;
3200
3451
  if (inlineDecisionTable && typeof inlineDecisionTable === "object") {
3201
3452
  const tbl = inlineDecisionTable;
3202
3453
  const { hitPolicy, ...rest } = tbl;
@@ -3216,13 +3467,15 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3216
3467
  const poolNodes = asNodes(nodes, ["Pool"]);
3217
3468
  const laneNodes = asNodes(nodes, ["Lane"]);
3218
3469
  const isCollaboration = poolNodes.length > 0;
3470
+ const referencedDataStoreIds = collectReferencedDataStoreIds(nodes);
3219
3471
  const definitions = moddle.create("bpmn:Definitions", {
3220
3472
  id: defId,
3221
3473
  targetNamespace: "http://bpmn.io/schema/bpmn",
3222
3474
  ...defName ? { name: defName } : {}
3223
3475
  });
3224
3476
  const rootElements = [
3225
- ...buildGlobalDefinitions(moddle, opts.process?.definitions)
3477
+ ...buildGlobalDefinitions(moddle, opts.process?.definitions),
3478
+ ...buildGlobalDataStores(moddle, nodes)
3226
3479
  ];
3227
3480
  const itemDefinitions = buildItemDefinitions(moddle, opts.process?.definitions?.variables);
3228
3481
  if (itemDefinitions.length > 0) {
@@ -3233,7 +3486,7 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3233
3486
  const processes = [];
3234
3487
  for (const pool of poolNodes) {
3235
3488
  const processId = `Process_${pool.id}`;
3236
- const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId, opts);
3489
+ const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId, opts, referencedDataStoreIds);
3237
3490
  processes.push(process);
3238
3491
  const participant = moddle.create("bpmn:Participant", {
3239
3492
  id: pool.id,
@@ -3245,18 +3498,17 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3245
3498
  const messageFlowEdges = edges.filter((e) => e.data?.edgeType === "messageFlow");
3246
3499
  const conversationLinkEdges = edges.filter((e) => e.data?.edgeType === "conversationLink");
3247
3500
  const messageFlows = messageFlowEdges.map((e) => {
3248
- const ps = typeof e.data?.payloadSchema === "string" ? e.data.payloadSchema : void 0;
3249
- const ck = typeof e.data?.correlationKey === "string" ? e.data.correlationKey : void 0;
3501
+ const ext = e.data ? getBpmnMessageFlowExecutionExtensions(e.data) : void 0;
3250
3502
  const mfAttrs = {
3251
3503
  id: e.id,
3252
3504
  name: e.data?.label ?? "",
3253
3505
  sourceRef: { id: e.source },
3254
3506
  targetRef: { id: e.target }
3255
3507
  };
3256
- if (ps || ck) {
3508
+ if (ext?.payloadSchema || ext?.correlationKey) {
3257
3509
  const cfg = moddle.create("aranza:MessageFlowConfig", {
3258
- ...ps ? { payloadSchema: ps } : {},
3259
- ...ck ? { correlationKey: ck } : {}
3510
+ ...ext.payloadSchema ? { payloadSchema: ext.payloadSchema } : {},
3511
+ ...ext.correlationKey ? { correlationKey: ext.correlationKey } : {}
3260
3512
  });
3261
3513
  mfAttrs.extensionElements = moddle.create("bpmn:ExtensionElements", { values: [cfg] });
3262
3514
  }
@@ -3284,14 +3536,15 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
3284
3536
  void 0,
3285
3537
  laneNodes,
3286
3538
  opts.process?.processId ?? "Process_1",
3287
- opts
3539
+ opts,
3540
+ referencedDataStoreIds
3288
3541
  );
3289
3542
  rootElements.push(process);
3290
3543
  }
3291
3544
  definitions.rootElements = rootElements;
3292
3545
  return definitions;
3293
3546
  }
3294
- function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId, opts) {
3547
+ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId, opts, referencedDataStoreIds) {
3295
3548
  const subProcessIds = new Set(
3296
3549
  allNodes.filter(
3297
3550
  (n) => n.data.elementType === "SubProcess" || n.data.elementType === "Transaction" || n.data.elementType === "EventSubProcess" || n.data.elementType === "AdHocSubProcess"
@@ -3313,7 +3566,7 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3313
3566
  }
3314
3567
  return false;
3315
3568
  };
3316
- const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n));
3569
+ const myNodes = (poolId ? allNodes.filter((n) => belongsToPool(n)) : allNodes.filter((n) => n.data.elementType !== "Pool" && n.data.elementType !== "Lane")).filter((n) => !isInsideSubProcess(n)).filter((n) => !(n.data.elementType === "DataStore" && referencedDataStoreIds.has(n.id)));
3317
3570
  const myLanes = laneNodes.filter((l) => poolId ? l.parentId === poolId : true);
3318
3571
  const presentDataObjectIds = new Set(
3319
3572
  myNodes.filter((n) => n.data.elementType === "DataObject").map((n) => n.id)
@@ -3357,10 +3610,18 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId,
3357
3610
  const elementById = new Map(
3358
3611
  flowElements.filter((element) => typeof element.id === "string").map((element) => [element.id, element])
3359
3612
  );
3613
+ const defaultEdgeBySource = /* @__PURE__ */ new Map();
3614
+ for (const node of myNodes) {
3615
+ const defaultFlowId = typeof node.data.default === "string" ? node.data.default : void 0;
3616
+ if (defaultFlowId) defaultEdgeBySource.set(node.id, defaultFlowId);
3617
+ }
3360
3618
  for (const edge of myEdges) {
3361
- if (!edge.data?.isDefault) continue;
3362
- const sourceElement = elementById.get(edge.source);
3363
- const edgeElement = elementById.get(edge.id);
3619
+ if (!edge.data?.isDefault || defaultEdgeBySource.has(edge.source)) continue;
3620
+ defaultEdgeBySource.set(edge.source, edge.id);
3621
+ }
3622
+ for (const [sourceId, edgeId] of defaultEdgeBySource) {
3623
+ const sourceElement = elementById.get(sourceId);
3624
+ const edgeElement = elementById.get(edgeId);
3364
3625
  if (sourceElement && edgeElement) {
3365
3626
  sourceElement.default = edgeElement;
3366
3627
  }
@@ -3427,6 +3688,10 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3427
3688
  const refId = typeof node.data.dataObjectRef === "string" ? node.data.dataObjectRef : `DataObject_${node.id}`;
3428
3689
  attrs.dataObjectRef = { id: refId };
3429
3690
  }
3691
+ if (elementType === "DataStoreReference") {
3692
+ const refId = typeof node.data.dataStoreRef === "string" ? node.data.dataStoreRef : `DataStore_${node.id}`;
3693
+ attrs.dataStoreRef = { id: refId };
3694
+ }
3430
3695
  if (elementType === "ScriptTask") {
3431
3696
  const scriptFormat = typeof node.data.scriptFormat === "string" ? node.data.scriptFormat : void 0;
3432
3697
  const script = typeof node.data.script === "string" ? node.data.script : void 0;
@@ -3488,7 +3753,8 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3488
3753
  return element;
3489
3754
  }
3490
3755
  function buildNestedFlowElements(moddle, parent, allNodes, allEdges) {
3491
- const childNodes = allNodes.filter((node) => node.parentId === parent.id);
3756
+ const referencedDataStoreIds = collectReferencedDataStoreIds(allNodes);
3757
+ const childNodes = allNodes.filter((node) => node.parentId === parent.id).filter((node) => !(node.data.elementType === "DataStore" && referencedDataStoreIds.has(node.id)));
3492
3758
  const childNodeIds = new Set(childNodes.map((node) => node.id));
3493
3759
  const flowElements = [];
3494
3760
  const artifacts = [];
@@ -3642,6 +3908,124 @@ function buildAbsolutePositionMap(nodes) {
3642
3908
  for (const node of nodes) resolve(node);
3643
3909
  return absoluteById;
3644
3910
  }
3911
+ function getServiceTaskConfig(node, opts) {
3912
+ const override = opts.flowable?.serviceTaskConfigs?.[node.id];
3913
+ if (override) return override;
3914
+ const config = node.data.serviceConfig;
3915
+ return config && typeof config === "object" ? config : void 0;
3916
+ }
3917
+ function injectFlowableNamespace(xml) {
3918
+ if (xml.includes("xmlns:flowable=")) return xml;
3919
+ return xml.replace(
3920
+ "<bpmn:definitions",
3921
+ '<bpmn:definitions xmlns:flowable="http://flowable.org/bpmn"'
3922
+ );
3923
+ }
3924
+ function ensureOpeningTagAttribute(openTag, name, value) {
3925
+ if (new RegExp(`\\b${escapeRegex(name)}=`).test(openTag)) return openTag;
3926
+ return openTag.replace(/>$/, ` ${name}="${escapeXml(value)}">`);
3927
+ }
3928
+ function injectFlowableFieldsIntoElement(xml, elementTagName, nodeId, fieldsXml, flowableType) {
3929
+ const idPattern = escapeRegex(nodeId);
3930
+ const selfClosingPattern = new RegExp(
3931
+ `<bpmn:${elementTagName}\\b[^>]*?\\bid="${idPattern}"[^>]*/>`,
3932
+ "s"
3933
+ );
3934
+ const blockPattern = new RegExp(
3935
+ `<bpmn:${elementTagName}\\b[^>]*?\\bid="${idPattern}"[^>]*>[\\s\\S]*?<\\/bpmn:${elementTagName}>`,
3936
+ "s"
3937
+ );
3938
+ if (selfClosingPattern.test(xml)) {
3939
+ return xml.replace(selfClosingPattern, (match) => {
3940
+ const openTag = ensureOpeningTagAttribute(match.replace(/\/>$/, ">"), "flowable:type", flowableType);
3941
+ return `${openTag}
3942
+ <bpmn:extensionElements>
3943
+ ${fieldsXml}
3944
+ </bpmn:extensionElements>
3945
+ </bpmn:${elementTagName}>`;
3946
+ });
3947
+ }
3948
+ return xml.replace(blockPattern, (block) => {
3949
+ const openTagMatch = block.match(new RegExp(`^<bpmn:${elementTagName}\\b[^>]*>`, "s"));
3950
+ if (!openTagMatch) return block;
3951
+ const openTag = ensureOpeningTagAttribute(openTagMatch[0], "flowable:type", flowableType);
3952
+ let nextBlock = openTag + block.slice(openTagMatch[0].length);
3953
+ if (nextBlock.includes("<bpmn:extensionElements>")) {
3954
+ return nextBlock.replace(
3955
+ /<bpmn:extensionElements>([\s\S]*?)<\/bpmn:extensionElements>/,
3956
+ (_match, inner) => `<bpmn:extensionElements>${inner.trimEnd()}
3957
+ ${fieldsXml}
3958
+ </bpmn:extensionElements>`
3959
+ );
3960
+ }
3961
+ return nextBlock.replace(
3962
+ openTag,
3963
+ `${openTag}
3964
+ <bpmn:extensionElements>
3965
+ ${fieldsXml}
3966
+ </bpmn:extensionElements>`
3967
+ );
3968
+ });
3969
+ }
3970
+ function injectFlowableConnectorServiceTasks(xml, nodes, opts) {
3971
+ let result = xml;
3972
+ const backendUrlTemplate = opts.flowable?.backendUrlTemplate ?? "%%ARANZAFLOWS_BACKEND_URL%%";
3973
+ const responseVariableName = opts.flowable?.connectorResponseVariableName ?? "connectorResult";
3974
+ for (const node of nodes) {
3975
+ if (node.data.elementType !== "ServiceTask") continue;
3976
+ const cfg = getServiceTaskConfig(node, opts);
3977
+ if (cfg?.implementation !== "connector" || !cfg.connectorInstanceId || !cfg.connectorAction) {
3978
+ continue;
3979
+ }
3980
+ result = injectFlowableNamespace(result);
3981
+ const bodyObj = {
3982
+ action: cfg.connectorAction,
3983
+ params: cfg.connectorParams ?? {}
3984
+ };
3985
+ const url = `${backendUrlTemplate}/api/v1/integrations/${encodeURIComponent(cfg.connectorInstanceId)}/execute-internal`;
3986
+ const fieldsXml = [
3987
+ ' <flowable:field name="requestMethod"><flowable:string>POST</flowable:string></flowable:field>',
3988
+ ` <flowable:field name="requestUrl"><flowable:string>${escapeXml(url)}</flowable:string></flowable:field>`,
3989
+ ' <flowable:field name="requestHeaders"><flowable:string>Content-Type: application/json</flowable:string></flowable:field>',
3990
+ ` <flowable:field name="requestBody"><flowable:expression>${escapeXml(JSON.stringify(bodyObj))}</flowable:expression></flowable:field>`,
3991
+ ` <flowable:field name="responseVariableName"><flowable:string>${escapeXml(responseVariableName)}</flowable:string></flowable:field>`,
3992
+ ' <flowable:field name="saveResponseParameters"><flowable:string>false</flowable:string></flowable:field>'
3993
+ ].join("\n");
3994
+ result = injectFlowableFieldsIntoElement(result, "serviceTask", node.id, fieldsXml, "http");
3995
+ }
3996
+ return result;
3997
+ }
3998
+ function injectFlowableDecisionTasks(xml, nodes, opts) {
3999
+ let result = xml;
4000
+ const variables = opts.process?.definitions?.variables ?? [];
4001
+ const backendUrlTemplate = opts.flowable?.backendUrlTemplate ?? "%%ARANZAFLOWS_BACKEND_URL%%";
4002
+ const responseVariableName = opts.flowable?.decisionResponseVariableName ?? "decisionResult";
4003
+ for (const node of nodes) {
4004
+ if (node.data.elementType !== "BusinessRuleTask") continue;
4005
+ const decisionRef = typeof node.data.decisionRef === "string" ? node.data.decisionRef : void 0;
4006
+ if (!decisionRef) continue;
4007
+ result = injectFlowableNamespace(result);
4008
+ const url = `${backendUrlTemplate}/api/v1/decisions/${encodeURIComponent(decisionRef)}/evaluate-internal`;
4009
+ const bodyField = variables.length > 0 ? `<flowable:expression>${escapeXml(
4010
+ `{${variables.map((variable) => `"${variable.name}": \${${variable.name}}`).join(", ")}}`
4011
+ )}</flowable:expression>` : "<flowable:string>{}</flowable:string>";
4012
+ const fieldsXml = [
4013
+ ' <flowable:field name="requestMethod"><flowable:string>POST</flowable:string></flowable:field>',
4014
+ ` <flowable:field name="requestUrl"><flowable:string>${escapeXml(url)}</flowable:string></flowable:field>`,
4015
+ ' <flowable:field name="requestHeaders"><flowable:string>Content-Type: application/json</flowable:string></flowable:field>',
4016
+ ` <flowable:field name="requestBody">${bodyField}</flowable:field>`,
4017
+ ` <flowable:field name="responseVariableName"><flowable:string>${escapeXml(responseVariableName)}</flowable:string></flowable:field>`,
4018
+ ' <flowable:field name="saveResponseParameters"><flowable:string>false</flowable:string></flowable:field>'
4019
+ ].join("\n");
4020
+ result = injectFlowableFieldsIntoElement(result, "businessRuleTask", node.id, fieldsXml, "http");
4021
+ }
4022
+ return result;
4023
+ }
4024
+ function applyFlowableExportEnrichment(xml, nodes, opts) {
4025
+ if (!opts.flowable?.enabled) return xml;
4026
+ const withServiceTasks = injectFlowableConnectorServiceTasks(xml, nodes, opts);
4027
+ return injectFlowableDecisionTasks(withServiceTasks, nodes, opts);
4028
+ }
3645
4029
  async function serializeBpmnXml(nodes, edges, opts = {}) {
3646
4030
  const { BpmnModdle } = await import('bpmn-moddle');
3647
4031
  const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
@@ -3650,7 +4034,7 @@ async function serializeBpmnXml(nodes, edges, opts = {}) {
3650
4034
  const { xml } = await moddle.toXML(definitions, {
3651
4035
  format: opts.format ?? true
3652
4036
  });
3653
- return xml;
4037
+ return applyFlowableExportEnrichment(xml, nodes, opts);
3654
4038
  }
3655
4039
 
3656
4040
  // src/simulation/evaluator.ts
@@ -4302,6 +4686,13 @@ var BPMN_POOL_LANE_LAYOUT = {
4302
4686
  verticalPoolHeaderSize: 28,
4303
4687
  minLaneSize: 96
4304
4688
  };
4689
+ var BPMN_POOL_LANE_STACK_LAYOUT = {
4690
+ poolInnerPad: 8,
4691
+ laneGap: 8,
4692
+ minLaneWidth: 240,
4693
+ minLaneHeight: 80,
4694
+ defaultLaneHeight: 120
4695
+ };
4305
4696
  function getBpmnDragHandleSelector(elementType) {
4306
4697
  if (elementType === "Pool") return ".pool-drag-handle";
4307
4698
  if (elementType === "Lane") return ".lane-drag-handle";
@@ -4372,7 +4763,9 @@ function inferBpmnEdgeType(state, sourceId, targetId) {
4372
4763
  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") {
4373
4764
  return "conversationLink";
4374
4765
  }
4375
- if (source.parentId && target.parentId && source.parentId !== target.parentId) {
4766
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
4767
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
4768
+ if (sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId) {
4376
4769
  return "messageFlow";
4377
4770
  }
4378
4771
  return "sequenceFlow";
@@ -4430,6 +4823,35 @@ function getBpmnNodeBounds(state, node) {
4430
4823
  height: size.height
4431
4824
  };
4432
4825
  }
4826
+ var BPMN_BOUNDARY_ATTACH_MARGIN = 32;
4827
+ function clampBoundaryCoordinate(value, min, max) {
4828
+ return Math.min(max, Math.max(min, value));
4829
+ }
4830
+ function isPointInsideExpandedBounds(point, origin, size) {
4831
+ return point.x >= origin.x - BPMN_BOUNDARY_ATTACH_MARGIN && point.x <= origin.x + size.width + BPMN_BOUNDARY_ATTACH_MARGIN && point.y >= origin.y - BPMN_BOUNDARY_ATTACH_MARGIN && point.y <= origin.y + size.height + BPMN_BOUNDARY_ATTACH_MARGIN;
4832
+ }
4833
+ function snapBoundaryCenterToHostBorder(center, hostOrigin, hostSize) {
4834
+ const distances = [
4835
+ { side: "left", value: Math.abs(center.x - hostOrigin.x) },
4836
+ { side: "right", value: Math.abs(center.x - (hostOrigin.x + hostSize.width)) },
4837
+ { side: "top", value: Math.abs(center.y - hostOrigin.y) },
4838
+ { side: "bottom", value: Math.abs(center.y - (hostOrigin.y + hostSize.height)) }
4839
+ ].sort((a, b) => a.value - b.value);
4840
+ const side = distances[0]?.side;
4841
+ if (side === "left") {
4842
+ return { x: hostOrigin.x, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
4843
+ }
4844
+ if (side === "right") {
4845
+ return { x: hostOrigin.x + hostSize.width, y: clampBoundaryCoordinate(center.y, hostOrigin.y, hostOrigin.y + hostSize.height) };
4846
+ }
4847
+ if (side === "top") {
4848
+ return { x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width), y: hostOrigin.y };
4849
+ }
4850
+ return {
4851
+ x: clampBoundaryCoordinate(center.x, hostOrigin.x, hostOrigin.x + hostSize.width),
4852
+ y: hostOrigin.y + hostSize.height
4853
+ };
4854
+ }
4433
4855
  function findBpmnLaneAt(state, position) {
4434
4856
  return state.nodes.find((node) => {
4435
4857
  if (node.data.elementType !== "Lane") return false;
@@ -4445,6 +4867,14 @@ function getAncestorLaneId(state, node) {
4445
4867
  }
4446
4868
  return void 0;
4447
4869
  }
4870
+ function getAncestorContainerId(state, node, elementType) {
4871
+ let current = node;
4872
+ while (current) {
4873
+ if (current.data.elementType === elementType) return current.id;
4874
+ current = current.parentId ? diagramsCore.getNode(state, current.parentId) : void 0;
4875
+ }
4876
+ return void 0;
4877
+ }
4448
4878
  function getNodeDimension(node, axis) {
4449
4879
  return node[axis] ?? node.measured?.[axis] ?? getBpmnElementSize(node.data.elementType)[axis];
4450
4880
  }
@@ -4452,6 +4882,237 @@ function getBpmnLaneOrderPosition(lane, orientation) {
4452
4882
  const size = getBpmnNodeSize(lane);
4453
4883
  return orientation === "vertical" ? lane.position.x + size.width / 2 : lane.position.y + size.height / 2;
4454
4884
  }
4885
+ function getBpmnPoolOrientation(pool) {
4886
+ return pool.data.orientation === "vertical" ? "vertical" : "horizontal";
4887
+ }
4888
+ function getBpmnPoolLanesOrderedByStack(nodes, poolId, orientation) {
4889
+ return nodes.filter((node) => node.parentId === poolId && node.data.elementType === "Lane").sort((a, b) => {
4890
+ const aIndex = typeof a.data.laneIndex === "number" ? a.data.laneIndex : void 0;
4891
+ const bIndex = typeof b.data.laneIndex === "number" ? b.data.laneIndex : void 0;
4892
+ if (aIndex !== void 0 || bIndex !== void 0) return (aIndex ?? 0) - (bIndex ?? 0);
4893
+ return orientation === "vertical" ? (a.position?.x ?? 0) - (b.position?.x ?? 0) : (a.position?.y ?? 0) - (b.position?.y ?? 0);
4894
+ });
4895
+ }
4896
+ function layoutBpmnPoolLaneNodesPreservingHeights(nodes, poolId) {
4897
+ const pool = nodes.find((node) => node.id === poolId && node.data.elementType === "Pool");
4898
+ if (!pool) return nodes;
4899
+ const orientation = getBpmnPoolOrientation(pool);
4900
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4901
+ if (lanes.length === 0) return withBpmnNodeZIndexes(nodes);
4902
+ const poolW = pool.measured?.width ?? pool.width ?? 720;
4903
+ const poolH = pool.measured?.height ?? pool.height ?? 200;
4904
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
4905
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
4906
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
4907
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
4908
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
4909
+ if (orientation === "vertical") {
4910
+ const laneWidth2 = Math.max(
4911
+ minLaneW,
4912
+ Math.floor((poolW - pad * 2 - gap * Math.max(0, lanes.length - 1)) / Math.max(1, lanes.length))
4913
+ );
4914
+ const laneHeight = Math.max(minLaneH, poolH - pad * 2);
4915
+ let cumX = pad;
4916
+ const laneMap2 = new Map(
4917
+ lanes.map((lane, index) => {
4918
+ const nextLane = {
4919
+ ...lane,
4920
+ position: { x: cumX, y: pad },
4921
+ width: laneWidth2,
4922
+ height: laneHeight,
4923
+ parentId: pool.id,
4924
+ data: { ...lane.data, orientation: "vertical", laneIndex: index }
4925
+ };
4926
+ cumX += laneWidth2 + gap;
4927
+ return [lane.id, nextLane];
4928
+ })
4929
+ );
4930
+ const requiredPoolW = cumX - gap + pad;
4931
+ return withBpmnNodeZIndexes(
4932
+ nodes.map(
4933
+ (node) => laneMap2.get(node.id) ?? (node.id === pool.id ? { ...pool, width: Math.max(requiredPoolW, poolW) } : node)
4934
+ )
4935
+ );
4936
+ }
4937
+ const laneWidth = Math.max(minLaneW, poolW - pad * 2);
4938
+ let cumY = pad;
4939
+ const laneMap = new Map(
4940
+ lanes.map((lane, index) => {
4941
+ const laneHeight = Math.max(minLaneH, lane.measured?.height ?? lane.height ?? defaultLaneH);
4942
+ const nextLane = {
4943
+ ...lane,
4944
+ position: { x: pad, y: cumY },
4945
+ width: laneWidth,
4946
+ height: laneHeight,
4947
+ parentId: pool.id,
4948
+ data: { ...lane.data, orientation: "horizontal", laneIndex: index }
4949
+ };
4950
+ cumY += laneHeight + gap;
4951
+ return [lane.id, nextLane];
4952
+ })
4953
+ );
4954
+ const requiredPoolH = cumY - gap + pad;
4955
+ return withBpmnNodeZIndexes(
4956
+ nodes.map(
4957
+ (node) => laneMap.get(node.id) ?? (node.id === pool.id ? { ...pool, height: Math.max(requiredPoolH, poolH) } : node)
4958
+ )
4959
+ );
4960
+ }
4961
+ function reorderBpmnPoolLaneAfterDropPreservingHeights(nodes, laneId) {
4962
+ const lane = nodes.find((node) => node.id === laneId && node.data.elementType === "Lane");
4963
+ if (!lane?.parentId) return nodes;
4964
+ const pool = nodes.find((node) => node.id === lane.parentId && node.data.elementType === "Pool");
4965
+ if (!pool) return nodes;
4966
+ const orientation = getBpmnPoolOrientation(pool);
4967
+ const lanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4968
+ const moved = lanes.find((candidate) => candidate.id === lane.id);
4969
+ if (!moved) return layoutBpmnPoolLaneNodesPreservingHeights(nodes, pool.id);
4970
+ const withoutMoved = lanes.filter((candidate) => candidate.id !== lane.id);
4971
+ const movedCenter = orientation === "vertical" ? (lane.position?.x ?? 0) + (lane.width ?? 0) / 2 : (lane.position?.y ?? 0) + (lane.height ?? 0) / 2;
4972
+ const insertIndex = withoutMoved.findIndex((candidate) => {
4973
+ const candidateCenter = orientation === "vertical" ? (candidate.position?.x ?? 0) + (candidate.width ?? 0) / 2 : (candidate.position?.y ?? 0) + (candidate.height ?? 0) / 2;
4974
+ return movedCenter < candidateCenter;
4975
+ });
4976
+ const ordered = [...withoutMoved];
4977
+ ordered.splice(insertIndex === -1 ? ordered.length : insertIndex, 0, moved);
4978
+ const orderedMap = new Map(ordered.map((candidate, index) => [candidate.id, index]));
4979
+ return layoutBpmnPoolLaneNodesPreservingHeights(
4980
+ nodes.map(
4981
+ (node) => node.parentId === pool.id && node.data.elementType === "Lane" ? { ...node, data: { ...node.data, laneIndex: orderedMap.get(node.id) ?? 0 } } : node
4982
+ ),
4983
+ pool.id
4984
+ );
4985
+ }
4986
+ function getAppendedBpmnLaneFrame(nodes, poolOrId) {
4987
+ const pool = typeof poolOrId === "string" ? nodes.find((node) => node.id === poolOrId && node.data.elementType === "Pool") : poolOrId;
4988
+ if (!pool || pool.data.elementType !== "Pool") return null;
4989
+ const orientation = getBpmnPoolOrientation(pool);
4990
+ const existingLanes = getBpmnPoolLanesOrderedByStack(nodes, pool.id, orientation);
4991
+ const poolW = pool.measured?.width ?? pool.width ?? 600;
4992
+ const poolH = pool.measured?.height ?? pool.height ?? 400;
4993
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
4994
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
4995
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
4996
+ const minLaneH = BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
4997
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
4998
+ if (orientation === "horizontal") {
4999
+ const lastLane2 = existingLanes[existingLanes.length - 1];
5000
+ return {
5001
+ position: {
5002
+ x: pad,
5003
+ y: lastLane2 ? (lastLane2.position?.y ?? pad) + (lastLane2.height ?? defaultLaneH) + gap : pad
5004
+ },
5005
+ width: Math.max(minLaneW, poolW - pad * 2),
5006
+ height: existingLanes.length === 0 ? Math.max(minLaneH, poolH - pad * 2) : defaultLaneH,
5007
+ laneIndex: existingLanes.length,
5008
+ orientation
5009
+ };
5010
+ }
5011
+ const lastLane = existingLanes[existingLanes.length - 1];
5012
+ return {
5013
+ position: {
5014
+ x: lastLane ? (lastLane.position?.x ?? pad) + (lastLane.width ?? defaultLaneH) + gap : pad,
5015
+ y: pad
5016
+ },
5017
+ width: existingLanes.length === 0 ? Math.max(minLaneW, poolW - pad * 2) : defaultLaneH,
5018
+ height: Math.max(minLaneH, poolH - pad * 2),
5019
+ laneIndex: existingLanes.length,
5020
+ orientation
5021
+ };
5022
+ }
5023
+ function getBpmnPoolLaneNodeMaxSize(state, nodeId) {
5024
+ const n = diagramsCore.getNode(state, nodeId);
5025
+ if (n?.data.elementType === "Lane" && n.parentId) {
5026
+ const pool = diagramsCore.getNode(state, n.parentId);
5027
+ if (pool) {
5028
+ const siblings = state.nodes.filter(
5029
+ (x) => x.parentId === n.parentId && x.data.elementType === "Lane" && x.id !== n.id
5030
+ );
5031
+ const poolH = pool.measured?.height ?? pool.height ?? 500;
5032
+ const siblingsMinH = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight;
5033
+ const siblingGaps = siblings.length * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5034
+ const maxH = Math.max(
5035
+ BPMN_POOL_LANE_STACK_LAYOUT.minLaneHeight,
5036
+ poolH - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 - siblingsMinH - siblingGaps
5037
+ );
5038
+ return {
5039
+ width: (pool.width ?? 720) - BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2,
5040
+ height: maxH
5041
+ };
5042
+ }
5043
+ }
5044
+ return void 0;
5045
+ }
5046
+ function getBpmnPoolLaneNodeMinSize(state, nodeId) {
5047
+ const n = diagramsCore.getNode(state, nodeId);
5048
+ if (n?.data.elementType === "Pool") {
5049
+ const lanes = state.nodes.filter((x) => x.parentId === nodeId && x.data.elementType === "Lane");
5050
+ if (lanes.length > 0) {
5051
+ const minW = Math.max(...lanes.map((l) => (l.width ?? 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2));
5052
+ const minH = lanes.reduce((s, l) => s + (l.height ?? BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight), 0) + BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad * 2 + Math.max(0, lanes.length - 1) * BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5053
+ return { width: minW, height: minH };
5054
+ }
5055
+ }
5056
+ return void 0;
5057
+ }
5058
+ function applyBpmnPoolLaneDimensionChange(nodes, previousNodes, nodeId, width, height) {
5059
+ const node = nodes.find((candidate) => candidate.id === nodeId);
5060
+ const previousNode = previousNodes.find((candidate) => candidate.id === nodeId);
5061
+ if (!node) return nodes;
5062
+ const curW = previousNode?.measured?.width ?? previousNode?.width ?? 0;
5063
+ const curH = previousNode?.measured?.height ?? previousNode?.height ?? 0;
5064
+ if (Math.abs(width - curW) < 1 && Math.abs(height - curH) < 1) return nodes;
5065
+ const pad = BPMN_POOL_LANE_STACK_LAYOUT.poolInnerPad;
5066
+ const gap = BPMN_POOL_LANE_STACK_LAYOUT.laneGap;
5067
+ const minLaneW = BPMN_POOL_LANE_STACK_LAYOUT.minLaneWidth;
5068
+ const defaultLaneH = BPMN_POOL_LANE_STACK_LAYOUT.defaultLaneHeight;
5069
+ if (node.data.elementType === "Pool") {
5070
+ const targetLaneW = Math.max(minLaneW, width - pad * 2);
5071
+ return nodes.map(
5072
+ (candidate) => candidate.parentId === node.id && candidate.data.elementType === "Lane" ? {
5073
+ ...candidate,
5074
+ width: targetLaneW,
5075
+ measured: {
5076
+ width: targetLaneW,
5077
+ height: candidate.measured?.height ?? candidate.height ?? defaultLaneH
5078
+ },
5079
+ position: { x: pad, y: candidate.position?.y ?? pad }
5080
+ } : candidate
5081
+ );
5082
+ }
5083
+ if (node.data.elementType === "Lane" && node.parentId) {
5084
+ const pool = nodes.find((candidate) => candidate.id === node.parentId && candidate.data.elementType === "Pool");
5085
+ if (!pool) return nodes;
5086
+ const poolW = Math.max(width + pad * 2, pool.measured?.width ?? pool.width ?? 720);
5087
+ const sortedLanes = getBpmnPoolLanesOrderedByStack(nodes, node.parentId, "horizontal");
5088
+ let cumY = pad;
5089
+ const laneMap = /* @__PURE__ */ new Map();
5090
+ for (const lane of sortedLanes) {
5091
+ const laneH = lane.id === node.id ? height : lane.measured?.height ?? lane.height ?? defaultLaneH;
5092
+ laneMap.set(lane.id, {
5093
+ ...lane,
5094
+ width,
5095
+ height: laneH,
5096
+ measured: { width, height: laneH },
5097
+ position: { x: pad, y: cumY }
5098
+ });
5099
+ cumY += laneH + gap;
5100
+ }
5101
+ const newPoolH = cumY - gap + pad;
5102
+ return nodes.map((candidate) => {
5103
+ if (candidate.id === pool.id) {
5104
+ return {
5105
+ ...candidate,
5106
+ width: poolW,
5107
+ height: newPoolH,
5108
+ measured: { width: poolW, height: newPoolH }
5109
+ };
5110
+ }
5111
+ return laneMap.get(candidate.id) ?? candidate;
5112
+ });
5113
+ }
5114
+ return nodes;
5115
+ }
4455
5116
  function resizeHorizontalBpmnLanes(lanes, pool) {
4456
5117
  const pad = BPMN_POOL_LANE_LAYOUT.poolPad;
4457
5118
  const poolSize = getBpmnNodeSize(pool);
@@ -4619,6 +5280,66 @@ function resolveBpmnDropTarget(state, options) {
4619
5280
  function getBpmnNodeCenter(node, absolutePosition) {
4620
5281
  return diagramsCore.getNodeCenterPosition(absolutePosition, getBpmnNodeSize(node));
4621
5282
  }
5283
+ function getBoundaryEventAttachment(state, boundaryNode) {
5284
+ if (boundaryNode.data.elementType !== "BoundaryEvent") return null;
5285
+ const boundaryOrigin = getBpmnNodeAbsolutePosition(state, boundaryNode) ?? boundaryNode.position;
5286
+ const boundarySize = getBpmnNodeSize(boundaryNode);
5287
+ const boundaryCenter = {
5288
+ x: boundaryOrigin.x + boundarySize.width / 2,
5289
+ y: boundaryOrigin.y + boundarySize.height / 2
5290
+ };
5291
+ const candidates = state.nodes.filter((node) => node.id !== boundaryNode.id && acceptsBoundaryEvents(node.data.elementType)).map((node) => {
5292
+ const origin = getBpmnNodeAbsolutePosition(state, node) ?? node.position;
5293
+ const size = getBpmnNodeSize(node);
5294
+ const hostCenter = { x: origin.x + size.width / 2, y: origin.y + size.height / 2 };
5295
+ return {
5296
+ node,
5297
+ origin,
5298
+ size,
5299
+ distance: Math.hypot(boundaryCenter.x - hostCenter.x, boundaryCenter.y - hostCenter.y)
5300
+ };
5301
+ }).filter(({ origin, size }) => isPointInsideExpandedBounds(boundaryCenter, origin, size)).sort((a, b) => a.distance - b.distance);
5302
+ const host = candidates[0];
5303
+ if (!host) return null;
5304
+ const snappedCenter = snapBoundaryCenterToHostBorder(boundaryCenter, host.origin, host.size);
5305
+ return {
5306
+ hostId: host.node.id,
5307
+ position: {
5308
+ x: snappedCenter.x - host.origin.x - boundarySize.width / 2,
5309
+ y: snappedCenter.y - host.origin.y - boundarySize.height / 2
5310
+ }
5311
+ };
5312
+ }
5313
+ function getBpmnEdgeLaneContext(state, edgeOrId) {
5314
+ const edge = typeof edgeOrId === "string" ? state.edges.find((candidate) => candidate.id === edgeOrId) : edgeOrId;
5315
+ if (!edge) return void 0;
5316
+ const source = diagramsCore.getNode(state, edge.source);
5317
+ const target = diagramsCore.getNode(state, edge.target);
5318
+ if (!source || !target) return void 0;
5319
+ const sourceLaneId = getAncestorLaneId(state, source);
5320
+ const targetLaneId = getAncestorLaneId(state, target);
5321
+ const sourcePoolId = getAncestorContainerId(state, source, "Pool");
5322
+ const targetPoolId = getAncestorContainerId(state, target, "Pool");
5323
+ const sameLane = Boolean(sourceLaneId) && sourceLaneId === targetLaneId;
5324
+ const samePool = Boolean(sourcePoolId) && sourcePoolId === targetPoolId;
5325
+ const crossesLanesWithinPool = Boolean(
5326
+ sourceLaneId && targetLaneId && sourceLaneId !== targetLaneId && samePool
5327
+ );
5328
+ const crossesPools = Boolean(
5329
+ sourcePoolId && targetPoolId && sourcePoolId !== targetPoolId
5330
+ );
5331
+ return {
5332
+ edgeId: edge.id,
5333
+ ...sourceLaneId ? { sourceLaneId } : {},
5334
+ ...targetLaneId ? { targetLaneId } : {},
5335
+ ...sourcePoolId ? { sourcePoolId } : {},
5336
+ ...targetPoolId ? { targetPoolId } : {},
5337
+ sameLane,
5338
+ samePool,
5339
+ crossesLanesWithinPool,
5340
+ crossesPools
5341
+ };
5342
+ }
4622
5343
  function resolvePoolLaneDirection(pool) {
4623
5344
  return pool.data.orientation === "vertical" ? "horizontal" : "vertical";
4624
5345
  }
@@ -4708,6 +5429,14 @@ function validateBpmnConnectionForEdgeType(state, edgeType, source, target) {
4708
5429
  }
4709
5430
  return true;
4710
5431
  }
5432
+ function resolveBpmnConnection(state, sourceId, targetId, requestedType) {
5433
+ const source = diagramsCore.getNode(state, sourceId);
5434
+ const target = diagramsCore.getNode(state, targetId);
5435
+ if (!source || !target) return { ok: false, reason: "No se encontr\xF3 el origen o destino." };
5436
+ const validation = validateBpmnConnectionForEdgeType(state, requestedType, source, target);
5437
+ if (validation !== true) return { ok: false, reason: validation };
5438
+ return { ok: true, edgeType: requestedType };
5439
+ }
4711
5440
  function validateEdgeCardinality(state, edgeType, source, target) {
4712
5441
  if (edgeType !== "sequenceFlow") return true;
4713
5442
  const sourceMax = BPMN_ELEMENT_CATALOG[source.data.elementType].maxOutgoing;
@@ -4895,6 +5624,28 @@ function reparentBpmnNodeAtPosition(state, options) {
4895
5624
  });
4896
5625
  }
4897
5626
  var BE_HALF = 18;
5627
+ function getBoundarySpanRatio(value, size) {
5628
+ const min = BE_HALF;
5629
+ const max = size - BE_HALF;
5630
+ if (max <= min) return 0.5;
5631
+ return (clampBoundaryCoordinate(value, min, max) - min) / (max - min);
5632
+ }
5633
+ function fromBoundarySpanRatio(ratio, size) {
5634
+ const min = BE_HALF;
5635
+ const max = size - BE_HALF;
5636
+ if (max <= min) return size / 2;
5637
+ return min + (max - min) * ratio;
5638
+ }
5639
+ function detectBoundarySide(center, hostSize) {
5640
+ const distances = [
5641
+ { side: "left", value: Math.abs(center.x) },
5642
+ { side: "right", value: Math.abs(center.x - hostSize.width) },
5643
+ { side: "top", value: Math.abs(center.y) },
5644
+ { side: "bottom", value: Math.abs(center.y - hostSize.height) }
5645
+ ];
5646
+ distances.sort((a, b) => a.value - b.value);
5647
+ return distances[0]?.side ?? "bottom";
5648
+ }
4898
5649
  function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
4899
5650
  const boundaryEvents = state.nodes.filter(
4900
5651
  (n) => n.data.elementType === "BoundaryEvent" && n.parentId === hostId
@@ -4905,25 +5656,21 @@ function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
4905
5656
  const py = be.position?.y ?? 0;
4906
5657
  const cx = px + BE_HALF;
4907
5658
  const cy = py + BE_HALF;
4908
- const distLeft = Math.abs(cx);
4909
- const distRight = Math.abs(cx - oldW);
4910
- const distTop = Math.abs(cy);
4911
- const distBottom = Math.abs(cy - oldH);
4912
- const minDist = Math.min(distLeft, distRight, distTop, distBottom);
5659
+ const side = detectBoundarySide({ x: cx, y: cy }, { width: oldW, height: oldH });
4913
5660
  let newCx;
4914
5661
  let newCy;
4915
- if (minDist === distBottom) {
5662
+ if (side === "bottom") {
4916
5663
  newCy = newH;
4917
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
4918
- } else if (minDist === distRight) {
5664
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
5665
+ } else if (side === "right") {
4919
5666
  newCx = newW;
4920
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
4921
- } else if (minDist === distTop) {
5667
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
5668
+ } else if (side === "top") {
4922
5669
  newCy = 0;
4923
- newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
5670
+ newCx = fromBoundarySpanRatio(getBoundarySpanRatio(cx, oldW), newW);
4924
5671
  } else {
4925
5672
  newCx = 0;
4926
- newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
5673
+ newCy = fromBoundarySpanRatio(getBoundarySpanRatio(cy, oldH), newH);
4927
5674
  }
4928
5675
  next = diagramsCore.moveNode(next, be.id, { x: newCx - BE_HALF, y: newCy - BE_HALF });
4929
5676
  }
@@ -5187,6 +5934,7 @@ function withBpmnLayoutCache(layoutFn, cache) {
5187
5934
  return diagramsCore.withLayoutCache(layoutFn, cache ?? diagramsCore.createLayoutCache());
5188
5935
  }
5189
5936
 
5937
+ exports.ARANZA_DESCRIPTOR = ARANZA_DESCRIPTOR;
5190
5938
  exports.AnnotationNode = AnnotationNode;
5191
5939
  exports.AssociationEdge = AssociationEdge;
5192
5940
  exports.BPMN_EDGE_CONNECTION_RULES = BPMN_EDGE_CONNECTION_RULES;
@@ -5195,6 +5943,7 @@ exports.BPMN_ELEMENT_CATALOG = BPMN_ELEMENT_CATALOG;
5195
5943
  exports.BPMN_MODELING_RULES = BPMN_MODELING_RULES;
5196
5944
  exports.BPMN_NODE_TYPES = BPMN_NODE_TYPES;
5197
5945
  exports.BPMN_POOL_LANE_LAYOUT = BPMN_POOL_LANE_LAYOUT;
5946
+ exports.BPMN_POOL_LANE_STACK_LAYOUT = BPMN_POOL_LANE_STACK_LAYOUT;
5198
5947
  exports.BPMN_RESIZABLE_ELEMENT_TYPES = BPMN_RESIZABLE_ELEMENT_TYPES;
5199
5948
  exports.BPMN_ROUTABLE_EDGE_TYPES = BPMN_ROUTABLE_EDGE_TYPES;
5200
5949
  exports.BPMN_SELECTION_STYLE = BPMN_SELECTION_STYLE;
@@ -5226,6 +5975,7 @@ exports.SubConversationNode = SubConversationNode;
5226
5975
  exports.SubProcessNode = SubProcessNode;
5227
5976
  exports.TaskNode = TaskNode;
5228
5977
  exports.acceptsBoundaryEvents = acceptsBoundaryEvents;
5978
+ exports.applyBpmnPoolLaneDimensionChange = applyBpmnPoolLaneDimensionChange;
5229
5979
  exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
5230
5980
  exports.bpmnConnectionValidators = bpmnConnectionValidators;
5231
5981
  exports.canContainBpmnElement = canContainBpmnElement;
@@ -5243,16 +5993,25 @@ exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
5243
5993
  exports.deserializeBpmnDiagramSnapshot = deserializeBpmnDiagramSnapshot;
5244
5994
  exports.findBpmnContainerAt = findBpmnContainerAt;
5245
5995
  exports.fire = fire;
5996
+ exports.getAllowedEventTriggers = getAllowedEventTriggers;
5997
+ exports.getAppendedBpmnLaneFrame = getAppendedBpmnLaneFrame;
5998
+ exports.getBoundaryEventAttachment = getBoundaryEventAttachment;
5246
5999
  exports.getBpmnDragHandleSelector = getBpmnDragHandleSelector;
5247
6000
  exports.getBpmnEdgeLabelLayout = getBpmnEdgeLabelLayout;
6001
+ exports.getBpmnEdgeLaneContext = getBpmnEdgeLaneContext;
5248
6002
  exports.getBpmnElementSize = getBpmnElementSize;
5249
6003
  exports.getBpmnLaneIndexAtPosition = getBpmnLaneIndexAtPosition;
6004
+ exports.getBpmnMessageFlowExecutionExtensions = getBpmnMessageFlowExecutionExtensions;
5250
6005
  exports.getBpmnNodeAbsolutePosition = getBpmnNodeAbsolutePosition;
5251
6006
  exports.getBpmnNodeCenter = getBpmnNodeCenter;
5252
6007
  exports.getBpmnNodeSize = getBpmnNodeSize;
5253
6008
  exports.getBpmnNodeZIndex = getBpmnNodeZIndex;
6009
+ exports.getBpmnPoolLaneNodeMaxSize = getBpmnPoolLaneNodeMaxSize;
6010
+ exports.getBpmnPoolLaneNodeMinSize = getBpmnPoolLaneNodeMinSize;
5254
6011
  exports.getBpmnPoolLanes = getBpmnPoolLanes;
6012
+ exports.getBpmnPoolOrientation = getBpmnPoolOrientation;
5255
6013
  exports.getBpmnTabOrder = getBpmnTabOrder;
6014
+ exports.getBpmnTaskExecutionExtensions = getBpmnTaskExecutionExtensions;
5256
6015
  exports.getElementMeta = getElementMeta;
5257
6016
  exports.getFireable = getFireable;
5258
6017
  exports.getHandlePolicy = getHandlePolicy;
@@ -5272,6 +6031,7 @@ exports.isEventType = isEventType;
5272
6031
  exports.isGatewayType = isGatewayType;
5273
6032
  exports.isTaskType = isTaskType;
5274
6033
  exports.layoutBpmnPoolLaneNodes = layoutBpmnPoolLaneNodes;
6034
+ exports.layoutBpmnPoolLaneNodesPreservingHeights = layoutBpmnPoolLaneNodesPreservingHeights;
5275
6035
  exports.layoutBpmnPoolLanes = layoutBpmnPoolLanes;
5276
6036
  exports.moveBpmnLaneCommand = moveBpmnLaneCommand;
5277
6037
  exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
@@ -5281,11 +6041,13 @@ exports.persistBpmnHistory = persistBpmnHistory;
5281
6041
  exports.reorderBpmnLane = reorderBpmnLane;
5282
6042
  exports.reorderBpmnLaneAfterDrop = reorderBpmnLaneAfterDrop;
5283
6043
  exports.reorderBpmnLaneCommand = reorderBpmnLaneCommand;
6044
+ exports.reorderBpmnPoolLaneAfterDropPreservingHeights = reorderBpmnPoolLaneAfterDropPreservingHeights;
5284
6045
  exports.reparentBpmnNodeAtPosition = reparentBpmnNodeAtPosition;
5285
6046
  exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
5286
6047
  exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
5287
6048
  exports.resizeBpmnNodeByHandleCommand = resizeBpmnNodeByHandleCommand;
5288
6049
  exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
6050
+ exports.resolveBpmnConnection = resolveBpmnConnection;
5289
6051
  exports.resolveBpmnDropTarget = resolveBpmnDropTarget;
5290
6052
  exports.restoreBpmnHistory = restoreBpmnHistory;
5291
6053
  exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;