@aranzatech/diagrams-bpmn 0.2.4 → 0.2.6

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 (43) hide show
  1. package/dist/{catalog-m8fHIiKH.d.cts → catalog-CZsXqhL9.d.cts} +1 -1
  2. package/dist/{catalog-DIBySQqA.d.ts → catalog-Clz8sN9x.d.ts} +1 -1
  3. package/dist/{chunk-33AR3PXF.js → chunk-L64NM77A.js} +290 -20
  4. package/dist/chunk-L64NM77A.js.map +1 -0
  5. package/dist/{chunk-QOGZITWB.js → chunk-M46UDUN3.js} +2 -2
  6. package/dist/{chunk-QOGZITWB.js.map → chunk-M46UDUN3.js.map} +1 -1
  7. package/dist/{chunk-7MKU37XQ.js → chunk-XTUYPA3E.js} +191 -15
  8. package/dist/chunk-XTUYPA3E.js.map +1 -0
  9. package/dist/elements/index.d.cts +3 -3
  10. package/dist/elements/index.d.ts +3 -3
  11. package/dist/index.cjs +477 -241
  12. package/dist/index.cjs.map +1 -1
  13. package/dist/index.d.cts +5 -5
  14. package/dist/index.d.ts +5 -5
  15. package/dist/index.js +3 -4
  16. package/dist/modeling/index.cjs +197 -10
  17. package/dist/modeling/index.cjs.map +1 -1
  18. package/dist/modeling/index.d.cts +103 -7
  19. package/dist/modeling/index.d.ts +103 -7
  20. package/dist/modeling/index.js +1 -1
  21. package/dist/simulation/index.cjs.map +1 -1
  22. package/dist/simulation/index.d.cts +36 -0
  23. package/dist/simulation/index.d.ts +36 -0
  24. package/dist/simulation/index.js +1 -1
  25. package/dist/{types-DznxZxpV.d.cts → types-BPqNeIU-.d.cts} +63 -1
  26. package/dist/{types-DznxZxpV.d.ts → types-BPqNeIU-.d.ts} +63 -1
  27. package/dist/{types-BxjCV2oX.d.ts → types-D0Flgue2.d.ts} +11 -2
  28. package/dist/{types-vVi5T7qj.d.cts → types-exnfq24-.d.cts} +11 -2
  29. package/dist/validation/index.cjs.map +1 -1
  30. package/dist/validation/index.d.cts +7 -2
  31. package/dist/validation/index.d.ts +7 -2
  32. package/dist/validation/index.js +224 -3
  33. package/dist/validation/index.js.map +1 -1
  34. package/dist/xml/index.cjs +287 -20
  35. package/dist/xml/index.cjs.map +1 -1
  36. package/dist/xml/index.d.cts +18 -2
  37. package/dist/xml/index.d.ts +18 -2
  38. package/dist/xml/index.js +1 -1
  39. package/package.json +2 -2
  40. package/dist/chunk-33AR3PXF.js.map +0 -1
  41. package/dist/chunk-7MKU37XQ.js.map +0 -1
  42. package/dist/chunk-ZFGQVLHB.js +0 -226
  43. package/dist/chunk-ZFGQVLHB.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -3,7 +3,6 @@
3
3
  var react = require('@xyflow/react');
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var routing = require('@aranzatech/diagrams-core/routing');
6
- var bpmnModdle = require('bpmn-moddle');
7
6
  var diagramsCore = require('@aranzatech/diagrams-core');
8
7
  var serialization = require('@aranzatech/diagrams-core/serialization');
9
8
 
@@ -2493,6 +2492,27 @@ var BPMN_EDGE_TYPES = {
2493
2492
  conversationLink: ConversationLinkEdge
2494
2493
  };
2495
2494
 
2495
+ // src/xml/aranza-descriptor.ts
2496
+ var ARANZA_DESCRIPTOR = {
2497
+ name: "Aranza",
2498
+ uri: "http://aranzatech.io/schema/bpmn-extension/1.0",
2499
+ prefix: "aranza",
2500
+ xml: { tagAlias: "lowerCase" },
2501
+ types: [
2502
+ {
2503
+ name: "TaskConfig",
2504
+ superClass: ["Element"],
2505
+ properties: [
2506
+ { name: "priority", isAttr: true, type: "String" },
2507
+ { name: "owner", isAttr: true, type: "String" },
2508
+ { name: "sla", isAttr: true, type: "String" }
2509
+ ]
2510
+ }
2511
+ ],
2512
+ enumerations: [],
2513
+ associations: []
2514
+ };
2515
+
2496
2516
  // src/xml/mapper.ts
2497
2517
  var MODDLE_TO_ELEMENT_TYPE = {
2498
2518
  "bpmn:StartEvent": "StartEvent",
@@ -2674,9 +2694,84 @@ function extractLaneMembership(process) {
2674
2694
  function extractTrigger(el) {
2675
2695
  const defs = asElements(el.eventDefinitions);
2676
2696
  if (defs.length === 0) return void 0;
2677
- if (defs.length > 1) return el.$type.includes("Parallel") ? "parallelMultiple" : "multiple";
2697
+ if (defs.length > 1) {
2698
+ return defs.some((def) => def.$type === "bpmn:ParallelMultipleEventDefinition") ? "parallelMultiple" : "multiple";
2699
+ }
2678
2700
  return EVENT_DEF_TO_TRIGGER[defs[0].$type];
2679
2701
  }
2702
+ function parseVariableType(value) {
2703
+ const text = asString(value) ?? "";
2704
+ if (text.includes("int")) return "integer";
2705
+ if (text.includes("boolean")) return "boolean";
2706
+ if (text.includes("date")) return "date";
2707
+ if (text.includes("array")) return "array";
2708
+ if (text.includes("anyType")) return "object";
2709
+ return "string";
2710
+ }
2711
+ function extractEventDefinition(el) {
2712
+ const defs = asElements(el.eventDefinitions);
2713
+ if (defs.length === 0) return void 0;
2714
+ if (defs.length > 1) {
2715
+ return {
2716
+ type: defs.some((def2) => def2.$type === "bpmn:ParallelMultipleEventDefinition") ? "parallelMultiple" : "multiple"
2717
+ };
2718
+ }
2719
+ const [def] = defs;
2720
+ const type = EVENT_DEF_TO_TRIGGER[def.$type];
2721
+ if (!type) return void 0;
2722
+ const eventDefinition = {
2723
+ type,
2724
+ ...asString(def.messageRef?.id) ? { messageRef: def.messageRef.id } : {},
2725
+ ...asString(def.signalRef?.id) ? { signalRef: def.signalRef.id } : {},
2726
+ ...asString(def.errorRef?.id) ? { errorRef: def.errorRef.id } : {},
2727
+ ...asString(def.escalationRef?.id) ? { escalationRef: def.escalationRef.id } : {},
2728
+ ...asString(def.condition?.body) ? { conditionExpression: def.condition.body } : {}
2729
+ };
2730
+ const timeDate = asString(def.timeDate?.body);
2731
+ const timeDuration = asString(def.timeDuration?.body);
2732
+ const timeCycle = asString(def.timeCycle?.body);
2733
+ if (timeDate) eventDefinition.timer = { kind: "date", value: timeDate };
2734
+ else if (timeCycle) eventDefinition.timer = { kind: "cycle", value: timeCycle };
2735
+ else if (timeDuration) eventDefinition.timer = { kind: "duration", value: timeDuration };
2736
+ if (type === "link") {
2737
+ const linkName = asString(el.name) ?? asString(def.name);
2738
+ if (linkName) eventDefinition.linkName = linkName;
2739
+ }
2740
+ return eventDefinition;
2741
+ }
2742
+ function extractDefinitions(rootElement) {
2743
+ const definitions = {};
2744
+ const rootElements = asElements(rootElement.rootElements);
2745
+ const messages = rootElements.filter((element) => element.$type === "bpmn:Message" && asString(element.id)).map((message) => ({
2746
+ id: message.id,
2747
+ name: asString(message.name) ?? message.id
2748
+ }));
2749
+ if (messages.length > 0) definitions.messages = messages;
2750
+ const signals = rootElements.filter((element) => element.$type === "bpmn:Signal" && asString(element.id)).map((signal) => ({
2751
+ id: signal.id,
2752
+ name: asString(signal.name) ?? signal.id
2753
+ }));
2754
+ if (signals.length > 0) definitions.signals = signals;
2755
+ const errors = rootElements.filter((element) => element.$type === "bpmn:Error" && asString(element.id)).map((error) => ({
2756
+ id: error.id,
2757
+ name: asString(error.name) ?? error.id,
2758
+ ...asString(error.errorCode) ? { errorCode: error.errorCode } : {}
2759
+ }));
2760
+ if (errors.length > 0) definitions.errors = errors;
2761
+ const escalations = rootElements.filter((element) => element.$type === "bpmn:Escalation" && asString(element.id)).map((escalation) => ({
2762
+ id: escalation.id,
2763
+ name: asString(escalation.name) ?? escalation.id,
2764
+ ...asString(escalation.escalationCode) ? { escalationCode: escalation.escalationCode } : {}
2765
+ }));
2766
+ if (escalations.length > 0) definitions.escalations = escalations;
2767
+ const itemDefinitions = asElements(rootElement.itemDefinitions).filter((item) => asString(item.id)).map((item) => ({
2768
+ id: String(item.id).replace(/_item$/, ""),
2769
+ name: String(item.id).replace(/_item$/, ""),
2770
+ type: parseVariableType(item.structureRef)
2771
+ }));
2772
+ if (itemDefinitions.length > 0) definitions.variables = itemDefinitions;
2773
+ return Object.keys(definitions).length > 0 ? definitions : void 0;
2774
+ }
2680
2775
  function extractSubProcessVariant(el) {
2681
2776
  if (el.$type === "bpmn:Transaction") return "transaction";
2682
2777
  if (el.$type === "bpmn:AdHocSubProcess") return "adhoc";
@@ -2684,6 +2779,22 @@ function extractSubProcessVariant(el) {
2684
2779
  if (el.triggeredByEvent === true) return "event";
2685
2780
  return "embedded";
2686
2781
  }
2782
+ function extractAranzaExtensions(el) {
2783
+ const ext = el.extensionElements;
2784
+ if (!ext) return {};
2785
+ const taskConfig = asElements(ext.values).find((v) => v.$type === "aranza:TaskConfig");
2786
+ if (!taskConfig) return {};
2787
+ const result = {};
2788
+ const priority = asString(taskConfig.priority);
2789
+ if (priority === "critical" || priority === "high" || priority === "medium" || priority === "low") {
2790
+ result.priority = priority;
2791
+ }
2792
+ const owner = asString(taskConfig.owner);
2793
+ if (owner) result.owner = owner;
2794
+ const sla = asString(taskConfig.sla);
2795
+ if (sla) result.sla = sla;
2796
+ return result;
2797
+ }
2687
2798
  function walkFlowElements(elements, parentId, ctx, nodes, edges) {
2688
2799
  for (const el of elements) {
2689
2800
  const { $type, id } = el;
@@ -2717,15 +2828,29 @@ function buildNode(el, elementType, parentId, ctx, nodes) {
2717
2828
  const label = asString(el.name);
2718
2829
  const documentation = extractDocumentation(el);
2719
2830
  const trigger = extractTrigger(el);
2831
+ const eventDefinition = extractEventDefinition(el);
2720
2832
  const isNonInterrupting = el.cancelActivity === false;
2721
2833
  const attachedToRef = el.attachedToRef?.id;
2834
+ const calledElement = elementType === "CallActivity" ? asString(el.calledElement) : void 0;
2835
+ const aranzaExt = extractAranzaExtensions(el);
2722
2836
  const data = {
2723
2837
  elementType,
2724
2838
  ...label ? { label } : {},
2725
2839
  ...documentation ? { documentation } : {},
2726
2840
  ...trigger ? { trigger } : {},
2841
+ ...eventDefinition ? { eventDefinition } : {},
2727
2842
  ...isNonInterrupting ? { isNonInterrupting: true } : {},
2728
- ...attachedToRef ? { attachedToRef } : {}
2843
+ ...elementType === "BoundaryEvent" ? { cancelActivity: el.cancelActivity !== false } : {},
2844
+ ...attachedToRef ? { attachedToRef } : {},
2845
+ ...eventDefinition?.timer ? { timer: eventDefinition.timer, timerExpression: eventDefinition.timer } : {},
2846
+ ...eventDefinition?.messageRef ? { messageRef: eventDefinition.messageRef } : {},
2847
+ ...eventDefinition?.signalRef ? { signalRef: eventDefinition.signalRef } : {},
2848
+ ...eventDefinition?.errorRef ? { errorRef: eventDefinition.errorRef } : {},
2849
+ ...eventDefinition?.escalationRef ? { escalationRef: eventDefinition.escalationRef } : {},
2850
+ ...eventDefinition?.conditionExpression ? { conditionExpression: eventDefinition.conditionExpression } : {},
2851
+ ...eventDefinition?.linkName ? { linkName: eventDefinition.linkName } : {},
2852
+ ...calledElement ? { calledElement } : {},
2853
+ ...aranzaExt
2729
2854
  };
2730
2855
  if (elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess") {
2731
2856
  const variant = extractSubProcessVariant(el);
@@ -2825,7 +2950,8 @@ function addLaneNodes(laneSet, poolId, ctx, nodes) {
2825
2950
  }
2826
2951
  }
2827
2952
  async function parseBpmnXml(xml) {
2828
- const moddle = new bpmnModdle.BpmnModdle();
2953
+ const { BpmnModdle } = await import('bpmn-moddle');
2954
+ const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
2829
2955
  const warnings = [];
2830
2956
  let rootElement;
2831
2957
  try {
@@ -2875,10 +3001,23 @@ async function parseBpmnXml(xml) {
2875
3001
  };
2876
3002
  return { ...edge, data };
2877
3003
  });
3004
+ const firstProcess = asElements(rootElement.rootElements).find((rootEl) => rootEl.$type === "bpmn:Process");
3005
+ const importedDefinitions = extractDefinitions(rootElement);
3006
+ const process = firstProcess ? (() => {
3007
+ const importedProcess = {};
3008
+ const processId = asString(firstProcess.id);
3009
+ const documentation = extractDocumentation(firstProcess);
3010
+ if (processId) importedProcess.processId = processId;
3011
+ if (typeof firstProcess.isExecutable === "boolean") importedProcess.executable = firstProcess.isExecutable;
3012
+ if (documentation) importedProcess.documentation = documentation;
3013
+ if (importedDefinitions) importedProcess.definitions = importedDefinitions;
3014
+ return importedProcess;
3015
+ })() : importedDefinitions ? { definitions: importedDefinitions } : void 0;
2878
3016
  return {
2879
3017
  nodes: normalizeChildPositions(nodes, nodeIds),
2880
3018
  edges: normalizedEdges,
2881
- warnings
3019
+ warnings,
3020
+ ...process ? { process } : {}
2882
3021
  };
2883
3022
  }
2884
3023
  function collectDefaultFlows(el, defaultFlowById) {
@@ -2902,12 +3041,117 @@ function normalizeChildPositions(nodes, nodeIds) {
2902
3041
  };
2903
3042
  });
2904
3043
  }
3044
+
3045
+ // src/xml/exporter.ts
2905
3046
  function uid(prefix, id) {
2906
3047
  return `${prefix}_${id}`;
2907
3048
  }
2908
3049
  function asNodes(nodes, types) {
2909
3050
  return nodes.filter((n) => types.includes(n.data.elementType));
2910
3051
  }
3052
+ function normalizeEventDefinition(data) {
3053
+ const trigger = data.eventDefinition?.type ?? data.trigger;
3054
+ if (!trigger || trigger === "none") return void 0;
3055
+ const normalized = { type: trigger };
3056
+ const timer = data.eventDefinition?.timer ?? data.timer ?? data.timerExpression;
3057
+ const messageRef = data.eventDefinition?.messageRef ?? (typeof data.messageRef === "string" ? data.messageRef : void 0);
3058
+ const signalRef = data.eventDefinition?.signalRef ?? (typeof data.signalRef === "string" ? data.signalRef : void 0);
3059
+ const errorRef = data.eventDefinition?.errorRef ?? (typeof data.errorRef === "string" ? data.errorRef : void 0);
3060
+ const escalationRef = data.eventDefinition?.escalationRef ?? (typeof data.escalationRef === "string" ? data.escalationRef : void 0);
3061
+ const conditionExpression = data.eventDefinition?.conditionExpression ?? (typeof data.conditionExpression === "string" ? data.conditionExpression : void 0);
3062
+ const linkName = data.eventDefinition?.linkName ?? (typeof data.linkName === "string" ? data.linkName : void 0);
3063
+ if (timer) normalized.timer = timer;
3064
+ if (messageRef) normalized.messageRef = messageRef;
3065
+ if (signalRef) normalized.signalRef = signalRef;
3066
+ if (errorRef) normalized.errorRef = errorRef;
3067
+ if (escalationRef) normalized.escalationRef = escalationRef;
3068
+ if (conditionExpression) normalized.conditionExpression = conditionExpression;
3069
+ if (linkName) normalized.linkName = linkName;
3070
+ return normalized;
3071
+ }
3072
+ function parseVariableType2(type) {
3073
+ switch (type) {
3074
+ case "integer":
3075
+ return "xsd:int";
3076
+ case "boolean":
3077
+ return "xsd:boolean";
3078
+ case "date":
3079
+ return "xsd:dateTime";
3080
+ case "object":
3081
+ return "xsd:anyType";
3082
+ case "array":
3083
+ return "xsd:anyType";
3084
+ default:
3085
+ return "xsd:string";
3086
+ }
3087
+ }
3088
+ function buildGlobalDefinitions(moddle, definitionsSet) {
3089
+ if (!definitionsSet) return [];
3090
+ const rootElements = [];
3091
+ for (const message of definitionsSet.messages ?? []) {
3092
+ rootElements.push(moddle.create("bpmn:Message", { id: message.id, name: message.name }));
3093
+ }
3094
+ for (const signal of definitionsSet.signals ?? []) {
3095
+ rootElements.push(moddle.create("bpmn:Signal", { id: signal.id, name: signal.name }));
3096
+ }
3097
+ for (const error of definitionsSet.errors ?? []) {
3098
+ rootElements.push(moddle.create("bpmn:Error", {
3099
+ id: error.id,
3100
+ name: error.name,
3101
+ ...error.errorCode ? { errorCode: error.errorCode } : {}
3102
+ }));
3103
+ }
3104
+ for (const escalation of definitionsSet.escalations ?? []) {
3105
+ rootElements.push(moddle.create("bpmn:Escalation", {
3106
+ id: escalation.id,
3107
+ name: escalation.name,
3108
+ ...escalation.escalationCode ? { escalationCode: escalation.escalationCode } : {}
3109
+ }));
3110
+ }
3111
+ return rootElements;
3112
+ }
3113
+ function buildItemDefinitions(moddle, variables) {
3114
+ return (variables ?? []).map(
3115
+ (variable) => moddle.create("bpmn:ItemDefinition", {
3116
+ id: `${variable.id}_item`,
3117
+ itemKind: "Information",
3118
+ structureRef: parseVariableType2(variable.type)
3119
+ })
3120
+ );
3121
+ }
3122
+ function buildEventDefinitions(moddle, node, eventDefinition) {
3123
+ if (eventDefinition.type === "multiple" || eventDefinition.type === "parallelMultiple") {
3124
+ return [];
3125
+ }
3126
+ const defType = TRIGGER_TO_EVENT_DEF[eventDefinition.type];
3127
+ if (!defType) return [];
3128
+ const attrs = { id: uid("EventDef", node.id) };
3129
+ if (eventDefinition.messageRef) attrs.messageRef = { id: eventDefinition.messageRef };
3130
+ if (eventDefinition.signalRef) attrs.signalRef = { id: eventDefinition.signalRef };
3131
+ if (eventDefinition.errorRef) attrs.errorRef = { id: eventDefinition.errorRef };
3132
+ if (eventDefinition.escalationRef) attrs.escalationRef = { id: eventDefinition.escalationRef };
3133
+ if (eventDefinition.conditionExpression) {
3134
+ attrs.condition = moddle.create("bpmn:FormalExpression", {
3135
+ body: eventDefinition.conditionExpression
3136
+ });
3137
+ }
3138
+ if (eventDefinition.timer?.value) {
3139
+ attrs[eventDefinition.timer.kind === "date" ? "timeDate" : eventDefinition.timer.kind === "cycle" ? "timeCycle" : "timeDuration"] = moddle.create("bpmn:FormalExpression", {
3140
+ body: eventDefinition.timer.value
3141
+ });
3142
+ }
3143
+ return [moddle.create(defType, attrs)];
3144
+ }
3145
+ function buildAranzaExtensionElements(moddle, node) {
3146
+ const { priority, owner, sla } = node.data;
3147
+ if (!priority && !owner && !sla) return null;
3148
+ const configAttrs = {};
3149
+ if (priority) configAttrs.priority = priority;
3150
+ if (owner) configAttrs.owner = owner;
3151
+ if (sla) configAttrs.sla = sla;
3152
+ const taskConfig = moddle.create("aranza:TaskConfig", configAttrs);
3153
+ return moddle.create("bpmn:ExtensionElements", { values: [taskConfig] });
3154
+ }
2911
3155
  function buildSemanticModel(moddle, nodes, edges, opts) {
2912
3156
  const defId = opts.id ?? "Definitions_1";
2913
3157
  const defName = opts.name;
@@ -2919,13 +3163,19 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
2919
3163
  targetNamespace: "http://bpmn.io/schema/bpmn",
2920
3164
  ...defName ? { name: defName } : {}
2921
3165
  });
2922
- const rootElements = [];
3166
+ const rootElements = [
3167
+ ...buildGlobalDefinitions(moddle, opts.process?.definitions)
3168
+ ];
3169
+ const itemDefinitions = buildItemDefinitions(moddle, opts.process?.definitions?.variables);
3170
+ if (itemDefinitions.length > 0) {
3171
+ definitions.itemDefinitions = itemDefinitions;
3172
+ }
2923
3173
  if (isCollaboration) {
2924
3174
  const participants = [];
2925
3175
  const processes = [];
2926
3176
  for (const pool of poolNodes) {
2927
3177
  const processId = `Process_${pool.id}`;
2928
- const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId);
3178
+ const process = buildProcess(moddle, nodes, edges, pool.id, laneNodes, processId, opts);
2929
3179
  processes.push(process);
2930
3180
  const participant = moddle.create("bpmn:Participant", {
2931
3181
  id: pool.id,
@@ -2959,13 +3209,21 @@ function buildSemanticModel(moddle, nodes, edges, opts) {
2959
3209
  });
2960
3210
  rootElements.push(collaboration, ...processes);
2961
3211
  } else {
2962
- const process = buildProcess(moddle, nodes, edges, void 0, laneNodes, "Process_1");
3212
+ const process = buildProcess(
3213
+ moddle,
3214
+ nodes,
3215
+ edges,
3216
+ void 0,
3217
+ laneNodes,
3218
+ opts.process?.processId ?? "Process_1",
3219
+ opts
3220
+ );
2963
3221
  rootElements.push(process);
2964
3222
  }
2965
3223
  definitions.rootElements = rootElements;
2966
3224
  return definitions;
2967
3225
  }
2968
- function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId) {
3226
+ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId, opts) {
2969
3227
  const subProcessIds = new Set(
2970
3228
  allNodes.filter(
2971
3229
  (n) => n.data.elementType === "SubProcess" || n.data.elementType === "Transaction" || n.data.elementType === "EventSubProcess" || n.data.elementType === "AdHocSubProcess"
@@ -3015,9 +3273,14 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
3015
3273
  }
3016
3274
  const process = moddle.create("bpmn:Process", {
3017
3275
  id: processId,
3018
- isExecutable: true,
3276
+ isExecutable: opts.process?.executable ?? true,
3019
3277
  flowElements
3020
3278
  });
3279
+ if (opts.process?.documentation) {
3280
+ process.documentation = [
3281
+ moddle.create("bpmn:Documentation", { text: opts.process.documentation })
3282
+ ];
3283
+ }
3021
3284
  if (myLanes.length > 0) {
3022
3285
  const laneElements = myLanes.map(
3023
3286
  (l) => moddle.create("bpmn:Lane", {
@@ -3034,7 +3297,8 @@ function buildProcess(moddle, allNodes, allEdges, poolId, laneNodes, processId)
3034
3297
  return process;
3035
3298
  }
3036
3299
  function buildFlowElement(moddle, node, allNodes, allEdges) {
3037
- const { elementType, label, trigger } = node.data;
3300
+ const { elementType, label } = node.data;
3301
+ const eventDefinition = normalizeEventDefinition(node.data);
3038
3302
  if (elementType === "Pool" || elementType === "Lane") return null;
3039
3303
  const moddleType = ELEMENT_TYPE_TO_MODDLE[elementType];
3040
3304
  if (!moddleType) return null;
@@ -3047,18 +3311,23 @@ function buildFlowElement(moddle, node, allNodes, allEdges) {
3047
3311
  moddle.create("bpmn:Documentation", { text: node.data.documentation })
3048
3312
  ];
3049
3313
  }
3050
- if (trigger && trigger !== "none") {
3051
- const defType = TRIGGER_TO_EVENT_DEF[trigger];
3052
- if (defType) {
3053
- attrs.eventDefinitions = [moddle.create(defType, { id: uid("EventDef", node.id) })];
3054
- }
3314
+ if (eventDefinition) {
3315
+ const eventDefinitions = buildEventDefinitions(moddle, node, eventDefinition);
3316
+ if (eventDefinitions.length > 0) attrs.eventDefinitions = eventDefinitions;
3317
+ if (eventDefinition.linkName) attrs.name = eventDefinition.linkName;
3055
3318
  }
3056
3319
  if (elementType === "BoundaryEvent") {
3057
3320
  attrs.attachedToRef = { id: node.data.attachedToRef ?? node.parentId };
3058
- attrs.cancelActivity = node.data.isNonInterrupting ? false : true;
3321
+ const interrupting = node.data.cancelActivity ?? !node.data.isNonInterrupting;
3322
+ attrs.cancelActivity = interrupting;
3059
3323
  }
3060
- const isSubProcess3 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
3061
- if (isSubProcess3) {
3324
+ if (elementType === "CallActivity" && node.data.calledElement) {
3325
+ attrs.calledElement = node.data.calledElement;
3326
+ }
3327
+ const aranzaConfig = buildAranzaExtensionElements(moddle, node);
3328
+ if (aranzaConfig) attrs.extensionElements = aranzaConfig;
3329
+ const isSubProcess2 = elementType === "SubProcess" || elementType === "Transaction" || elementType === "EventSubProcess" || elementType === "AdHocSubProcess";
3330
+ if (isSubProcess2) {
3062
3331
  attrs.flowElements = buildNestedFlowElements(moddle, node, allNodes, allEdges);
3063
3332
  if (elementType === "EventSubProcess" || node.data.subProcessVariant === "event") {
3064
3333
  attrs.triggeredByEvent = true;
@@ -3194,7 +3463,8 @@ function buildAbsolutePositionMap(nodes) {
3194
3463
  return absoluteById;
3195
3464
  }
3196
3465
  async function serializeBpmnXml(nodes, edges, opts = {}) {
3197
- const moddle = new bpmnModdle.BpmnModdle();
3466
+ const { BpmnModdle } = await import('bpmn-moddle');
3467
+ const moddle = new BpmnModdle({ aranza: ARANZA_DESCRIPTOR });
3198
3468
  const definitions = buildSemanticModel(moddle, nodes, edges, opts);
3199
3469
  buildBpmnDI(moddle, definitions, nodes, edges);
3200
3470
  const { xml } = await moddle.toXML(definitions, {
@@ -4225,6 +4495,41 @@ function reparentBpmnNodeAtPosition(state, options) {
4225
4495
  position: nextPosition
4226
4496
  });
4227
4497
  }
4498
+ var BE_HALF = 18;
4499
+ function clampBoundaryEventsAfterResize(state, hostId, oldW, oldH, newW, newH) {
4500
+ const boundaryEvents = state.nodes.filter(
4501
+ (n) => n.data.elementType === "BoundaryEvent" && n.parentId === hostId
4502
+ );
4503
+ let next = state;
4504
+ for (const be of boundaryEvents) {
4505
+ const px = be.position?.x ?? 0;
4506
+ const py = be.position?.y ?? 0;
4507
+ const cx = px + BE_HALF;
4508
+ const cy = py + BE_HALF;
4509
+ const distLeft = Math.abs(cx);
4510
+ const distRight = Math.abs(cx - oldW);
4511
+ const distTop = Math.abs(cy);
4512
+ const distBottom = Math.abs(cy - oldH);
4513
+ const minDist = Math.min(distLeft, distRight, distTop, distBottom);
4514
+ let newCx;
4515
+ let newCy;
4516
+ if (minDist === distBottom) {
4517
+ newCy = newH;
4518
+ newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
4519
+ } else if (minDist === distRight) {
4520
+ newCx = newW;
4521
+ newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
4522
+ } else if (minDist === distTop) {
4523
+ newCy = 0;
4524
+ newCx = Math.min(Math.max(cx, BE_HALF), newW - BE_HALF);
4525
+ } else {
4526
+ newCx = 0;
4527
+ newCy = Math.min(Math.max(cy, BE_HALF), newH - BE_HALF);
4528
+ }
4529
+ next = diagramsCore.moveNode(next, be.id, { x: newCx - BE_HALF, y: newCy - BE_HALF });
4530
+ }
4531
+ return next;
4532
+ }
4228
4533
  function resizeBpmnNodeCommand(options) {
4229
4534
  return {
4230
4535
  id: `bpmn.resize.${options.id}`,
@@ -4236,10 +4541,18 @@ function resizeBpmnNodeCommand(options) {
4236
4541
  if (!size.resizable) {
4237
4542
  throw new Error(`${node.data.elementType} is not resizable in BPMN.`);
4238
4543
  }
4239
- return diagramsCore.resizeNode(state, options.id, {
4240
- width: options.width === void 0 ? void 0 : Math.max(size.minWidth, options.width),
4241
- height: options.height === void 0 ? void 0 : Math.max(size.minHeight, options.height)
4544
+ const oldW = node.width ?? size.width;
4545
+ const oldH = node.height ?? size.height;
4546
+ const clampedW = options.width === void 0 ? void 0 : Math.max(size.minWidth, options.width);
4547
+ const clampedH = options.height === void 0 ? void 0 : Math.max(size.minHeight, options.height);
4548
+ const resized = diagramsCore.resizeNode(state, options.id, {
4549
+ width: clampedW,
4550
+ height: clampedH
4242
4551
  });
4552
+ const updatedNode = diagramsCore.getNode(resized, options.id);
4553
+ const newW = updatedNode?.width ?? clampedW ?? oldW;
4554
+ const newH = updatedNode?.height ?? clampedH ?? oldH;
4555
+ return clampBoundaryEventsAfterResize(resized, options.id, oldW, oldH, newW, newH);
4243
4556
  }
4244
4557
  };
4245
4558
  }
@@ -4319,10 +4632,15 @@ function createBpmnDiagramDocument(state, options = {}) {
4319
4632
  });
4320
4633
  }
4321
4634
  function serializeBpmnDiagram(state, options = {}) {
4322
- return serialization.serializeDiagram(diagramsCore.normalizeDiagramState(state), {
4323
- ...options,
4324
- diagramType: "bpmn"
4325
- });
4635
+ const { viewport, ...docOptions } = options;
4636
+ const normalized = diagramsCore.normalizeDiagramState(state);
4637
+ if (viewport) {
4638
+ return serialization.serializeDiagramSnapshot(
4639
+ { nodes: normalized.nodes, edges: normalized.edges, viewport },
4640
+ { ...docOptions, diagramType: "bpmn" }
4641
+ );
4642
+ }
4643
+ return serialization.serializeDiagram(normalized, { ...docOptions, diagramType: "bpmn" });
4326
4644
  }
4327
4645
  function parseBpmnDiagramDocument(json) {
4328
4646
  const document = serialization.parseDiagramDocument(json);
@@ -4335,232 +4653,140 @@ function deserializeBpmnDiagram(json) {
4335
4653
  const document = parseBpmnDiagramDocument(json);
4336
4654
  return serialization.deserializeDiagram(JSON.stringify(document));
4337
4655
  }
4338
- function runBpmnCommand(stack, command) {
4339
- return diagramsCore.executeCommand(stack, command);
4340
- }
4341
- function runBpmnCommands(stack, commands, options = {}) {
4342
- return diagramsCore.executeCommands(stack, commands, options);
4343
- }
4344
-
4345
- // src/validation/index.ts
4346
- function isFlowNode(type) {
4347
- return isEventType(type) || isGatewayType(type) || type.includes("Task") || type === "CallActivity" || type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess" || type === "ChoreographyTask" || type === "SubChoreography" || type === "CallChoreography";
4348
- }
4349
- function isProcessNode(type) {
4350
- return isFlowNode(type) && type !== "BoundaryEvent";
4351
- }
4352
- function isSubProcess2(type) {
4353
- return type === "SubProcess" || type === "Transaction" || type === "EventSubProcess" || type === "AdHocSubProcess";
4354
- }
4355
- function isCatchTarget(type) {
4356
- return type === "IntermediateCatchEvent" || type === "ReceiveTask";
4357
- }
4358
- function poolAncestor(node, nodeById2) {
4359
- let current = node;
4360
- const visited = /* @__PURE__ */ new Set();
4361
- while (current?.parentId && !visited.has(current.id)) {
4362
- visited.add(current.id);
4363
- const parent = nodeById2.get(current.parentId);
4364
- if (parent?.data.elementType === "Pool") return parent.id;
4365
- current = parent;
4366
- }
4367
- return void 0;
4656
+ function deserializeBpmnDiagramSnapshot(json) {
4657
+ const document = parseBpmnDiagramDocument(json);
4658
+ return serialization.deserializeDiagramSnapshot(JSON.stringify(document));
4368
4659
  }
4369
- function countSequenceEdges(edges, nodeId, direction) {
4370
- return edges.filter((edge) => {
4371
- if (edge.data?.edgeType !== "sequenceFlow") return false;
4372
- return direction === "in" ? edge.target === nodeId : edge.source === nodeId;
4373
- }).length;
4660
+ function createBpmnEventBus() {
4661
+ return diagramsCore.createDiagramEventBus();
4374
4662
  }
4375
- function sequenceEdges(edges) {
4376
- return edges.filter((edge) => (edge.data?.edgeType ?? edge.type) === "sequenceFlow");
4663
+ function runBpmnCommand(stack, command, bus) {
4664
+ const next = diagramsCore.executeCommand(stack, command);
4665
+ bus?.emit("command:executed", {
4666
+ commandId: command.id,
4667
+ ...command.label !== void 0 ? { label: command.label } : {},
4668
+ state: next.current
4669
+ });
4670
+ return next;
4377
4671
  }
4378
- function sequenceOut(edges, nodeId) {
4379
- return sequenceEdges(edges).filter((edge) => edge.source === nodeId);
4672
+ function runBpmnCommands(stack, commands, options = {}) {
4673
+ const { bus, ...execOptions } = options;
4674
+ const next = diagramsCore.executeCommands(stack, commands, execOptions);
4675
+ bus?.emit("command:executed", {
4676
+ commandId: execOptions.id ?? "bpmn.batch",
4677
+ ...execOptions.label !== void 0 ? { label: execOptions.label } : {},
4678
+ state: next.current
4679
+ });
4680
+ return next;
4380
4681
  }
4381
- function sequenceIn(edges, nodeId) {
4382
- return sequenceEdges(edges).filter((edge) => edge.target === nodeId);
4682
+ function persistBpmnHistory(stack, diagramId) {
4683
+ diagramsCore.persistCommandHistory(stack, `bpmn.history.${diagramId}`);
4684
+ }
4685
+ function restoreBpmnHistory(diagramId) {
4686
+ return diagramsCore.restoreCommandHistory(`bpmn.history.${diagramId}`);
4687
+ }
4688
+ function computeBpmnSmartGuides(movingNodes, state, poolId) {
4689
+ const movingIds = new Set(movingNodes.map((n) => n.id));
4690
+ const staticNodes = state.nodes.filter((n) => {
4691
+ if (movingIds.has(n.id)) return false;
4692
+ const et = n.data.elementType;
4693
+ if (et === "BoundaryEvent" || et === "Lane" || et === "Pool") return false;
4694
+ if (poolId) {
4695
+ const inPool = n.parentId === poolId || n.parentId !== void 0 && diagramsCore.getNode(state, n.parentId)?.parentId === poolId;
4696
+ if (!inPool) return false;
4697
+ }
4698
+ return true;
4699
+ });
4700
+ return diagramsCore.computeSmartGuides(movingNodes, staticNodes);
4383
4701
  }
4384
- function issue(code, severity, message, elementId, relatedElementIds) {
4702
+ function groupAsBpmnSubProcessCommand(options) {
4385
4703
  return {
4386
- id: `${code}:${elementId ?? relatedElementIds?.join(",") ?? "diagram"}`,
4387
- code,
4388
- severity,
4389
- message,
4390
- ...elementId ? { elementId } : {},
4391
- ...relatedElementIds ? { relatedElementIds } : {}
4392
- };
4393
- }
4394
- function validateBpmnDiagram(nodes, edges, options = {}) {
4395
- const opts = {
4396
- requireStartEvent: true,
4397
- requireEndEvent: true,
4398
- strictNames: false,
4399
- ...options
4400
- };
4401
- const issues = [];
4402
- const nodeById2 = new Map(nodes.map((node) => [node.id, node]));
4403
- const seqEdges = sequenceEdges(edges);
4404
- const processNodes = nodes.filter((node) => isProcessNode(node.data.elementType));
4405
- if (opts.requireStartEvent && !processNodes.some((node) => node.data.elementType === "StartEvent")) {
4406
- issues.push(issue("bpmn/start-event-required", "error", "The diagram must contain at least one start event."));
4407
- }
4408
- if (opts.requireEndEvent && !processNodes.some((node) => node.data.elementType === "EndEvent")) {
4409
- issues.push(issue("bpmn/end-event-required", "error", "The diagram must contain at least one end event."));
4410
- }
4411
- for (const edge of edges) {
4412
- const edgeType = edge.data?.edgeType ?? edge.type;
4413
- const source = nodeById2.get(edge.source);
4414
- const target = nodeById2.get(edge.target);
4415
- if (!source || !target) {
4416
- issues.push(issue(
4417
- "bpmn/no-orphan-edges",
4418
- "error",
4419
- `Edge "${edge.id}" references a missing ${!source ? "source" : "target"} node.`,
4420
- edge.id,
4421
- [edge.source, edge.target]
4422
- ));
4423
- continue;
4424
- }
4425
- if (edge.source === edge.target) {
4426
- issues.push(issue("bpmn/no-self-loop", "error", "BPMN edges cannot connect an element to itself.", edge.id, [edge.source]));
4427
- }
4428
- if (edgeType === "sequenceFlow") {
4429
- if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType) || isDataType(source.data.elementType) || isDataType(target.data.elementType)) {
4430
- issues.push(issue("bpmn/sequence-flow-valid-endpoints", "error", "Sequence flows must connect BPMN flow nodes.", edge.id, [source.id, target.id]));
4431
- }
4432
- const sourcePool = poolAncestor(source, nodeById2);
4433
- const targetPool = poolAncestor(target, nodeById2);
4434
- if (sourcePool && targetPool && sourcePool !== targetPool) {
4435
- issues.push(issue("bpmn/sequence-flow-no-cross-pool", "error", "Sequence flows cannot cross pools. Use message flow between participants.", edge.id, [source.id, target.id]));
4436
- }
4437
- }
4438
- if (edgeType === "messageFlow") {
4439
- const sourcePool = poolAncestor(source, nodeById2);
4440
- const targetPool = poolAncestor(target, nodeById2);
4441
- if (!sourcePool || !targetPool || sourcePool === targetPool) {
4442
- issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect flow nodes in different pools.", edge.id, [source.id, target.id]));
4443
- }
4444
- if (!isFlowNode(source.data.elementType) || !isFlowNode(target.data.elementType)) {
4445
- issues.push(issue("bpmn/message-flow-valid-endpoints", "error", "Message flows must connect BPMN flow nodes, not containers.", edge.id, [source.id, target.id]));
4446
- }
4447
- }
4448
- if (edgeType === "dataAssociation") {
4449
- const hasDataEndpoint = isDataType(source.data.elementType) || isDataType(target.data.elementType);
4450
- const hasFlowEndpoint = isFlowNode(source.data.elementType) || isFlowNode(target.data.elementType);
4451
- if (!hasDataEndpoint || !hasFlowEndpoint) {
4452
- issues.push(issue("bpmn/data-association-valid-endpoints", "error", "Data associations must connect data elements with flow nodes.", edge.id, [source.id, target.id]));
4704
+ id: `bpmn.groupAsSubProcess.${options.groupId ?? options.nodeIds.join(".")}`,
4705
+ label: "Group as SubProcess",
4706
+ execute: (state) => {
4707
+ for (const nodeId of options.nodeIds) {
4708
+ const node = diagramsCore.getNode(state, nodeId);
4709
+ if (!node) continue;
4710
+ const result = canContainBpmnElement("SubProcess", node.data.elementType);
4711
+ if (result !== true) throw new Error(result);
4453
4712
  }
4713
+ const groupId = options.groupId ?? diagramsCore.createUniqueId("subprocess", state.nodes.map((n) => n.id));
4714
+ const groupNode = createBpmnNode({
4715
+ id: groupId,
4716
+ elementType: "SubProcess",
4717
+ position: { x: 0, y: 0 },
4718
+ ...options.label !== void 0 ? { label: options.label } : {},
4719
+ ...options.data !== void 0 ? { data: options.data } : {}
4720
+ });
4721
+ return diagramsCore.groupNodes(state, {
4722
+ groupNode,
4723
+ nodeIds: options.nodeIds,
4724
+ padding: options.padding ?? 20
4725
+ });
4454
4726
  }
4727
+ };
4728
+ }
4729
+ function getBpmnTabOrder(state, poolId) {
4730
+ if (!poolId) return diagramsCore.getNodeTabOrder(state);
4731
+ const pool = diagramsCore.getNode(state, poolId);
4732
+ if (!pool) return [];
4733
+ const scopeIds = state.nodes.filter((n) => {
4734
+ if (n.id === poolId) return false;
4735
+ if (n.parentId === poolId) return true;
4736
+ const parent = diagramsCore.getNode(state, n.parentId ?? "");
4737
+ return parent?.parentId === poolId;
4738
+ }).map((n) => n.id);
4739
+ return diagramsCore.getNodeTabOrder(state, scopeIds);
4740
+ }
4741
+ function getBpmnEdgeLabelLayout(edgeId, state, options) {
4742
+ const edge = state.edges.find((e) => e.id === edgeId);
4743
+ if (!edge) return null;
4744
+ const routingPoints = edge.data?.routingPoints ?? [];
4745
+ if (routingPoints.length >= 2) {
4746
+ return diagramsCore.getEdgeLabelLayout(routingPoints, options);
4455
4747
  }
4456
- const duplicateSequenceKeys = /* @__PURE__ */ new Set();
4457
- const reportedDuplicateKeys = /* @__PURE__ */ new Set();
4458
- for (const edge of seqEdges) {
4459
- const key = `${edge.source}->${edge.target}`;
4460
- if (duplicateSequenceKeys.has(key) && !reportedDuplicateKeys.has(key)) {
4461
- reportedDuplicateKeys.add(key);
4462
- issues.push(issue("bpmn/no-duplicate-sequence-flow", "error", "Only one sequence flow is allowed between the same source and target.", edge.id, [edge.source, edge.target]));
4463
- }
4464
- duplicateSequenceKeys.add(key);
4465
- }
4466
- for (const node of nodes) {
4467
- const type = node.data.elementType;
4468
- const incoming = countSequenceEdges(edges, node.id, "in");
4469
- const outgoing = countSequenceEdges(edges, node.id, "out");
4470
- const meta = BPMN_ELEMENT_CATALOG[type];
4471
- if (type === "StartEvent" && incoming > 0) {
4472
- issues.push(issue("bpmn/start-event-no-incoming", "error", "Start events cannot have incoming sequence flows.", node.id));
4473
- }
4474
- if (type === "EndEvent") {
4475
- if (outgoing > 0) issues.push(issue("bpmn/no-outgoing-from-end-event", "error", "End events cannot have outgoing sequence flows.", node.id));
4476
- if (incoming === 0) issues.push(issue("bpmn/end-event-has-incoming", "error", "End events should have at least one incoming sequence flow.", node.id));
4477
- }
4478
- if ((type === "IntermediateCatchEvent" || type === "IntermediateThrowEvent") && (incoming === 0 || outgoing === 0)) {
4479
- issues.push(issue("bpmn/intermediate-event-both-flows", "error", "Intermediate events should have both incoming and outgoing sequence flows.", node.id));
4480
- }
4481
- if (type === "BoundaryEvent") {
4482
- const hostId = node.data.attachedToRef ?? node.parentId;
4483
- const host = hostId ? nodeById2.get(hostId) : void 0;
4484
- if (!host || !BPMN_ELEMENT_CATALOG[host.data.elementType]?.acceptsBoundaryEvents) {
4485
- issues.push(issue("bpmn/boundary-event-attached", "error", "Boundary events must be attached to an activity or subprocess.", node.id, hostId ? [hostId] : void 0));
4486
- }
4487
- if (sequenceIn(edges, node.id).length > 0) {
4488
- issues.push(issue("bpmn/boundary-no-incoming", "error", "Boundary events cannot have incoming sequence flows.", node.id));
4489
- }
4490
- if (sequenceOut(edges, node.id).length === 0) {
4491
- issues.push(issue("bpmn/boundary-has-outgoing", "warning", "Boundary events should define an outgoing exception path.", node.id));
4492
- }
4493
- }
4494
- if (isGatewayType(type)) {
4495
- if (incoming === 0) issues.push(issue("bpmn/gateway-has-incoming", "error", "Gateways should have at least one incoming sequence flow.", node.id));
4496
- if (outgoing === 0) issues.push(issue("bpmn/gateway-has-outgoing", "error", "Gateways should have at least one outgoing sequence flow.", node.id));
4497
- }
4498
- if (type === "ExclusiveGateway" || type === "InclusiveGateway" || type === "ComplexGateway") {
4499
- const outgoingEdges = sequenceOut(edges, node.id);
4500
- const defaults = outgoingEdges.filter((edge) => edge.data?.isDefault);
4501
- if (defaults.length > 1) {
4502
- issues.push(issue("bpmn/gateway-single-default", "error", "Gateways can have at most one default sequence flow.", node.id, defaults.map((edge) => edge.id)));
4503
- }
4504
- if (outgoingEdges.length >= 2) {
4505
- for (const edge of outgoingEdges) {
4506
- if (!edge.data?.isDefault && !edge.data?.conditionExpression) {
4507
- issues.push(issue("bpmn/gateway-condition", "error", "Conditional gateway branches should have a condition or be marked as default.", edge.id, [node.id, edge.target]));
4508
- }
4509
- }
4510
- }
4511
- }
4512
- if (type === "EventBasedGateway") {
4513
- const outgoingEdges = edges.filter((edge) => edge.data?.edgeType === "sequenceFlow" && edge.source === node.id);
4514
- if (outgoingEdges.length < 2) {
4515
- issues.push(issue("bpmn/event-based-gateway-min-outgoing", "error", "Event-based gateways should have at least two outgoing sequence flows.", node.id));
4516
- }
4517
- for (const edge of outgoingEdges) {
4518
- const target = nodeById2.get(edge.target);
4519
- if (target && !isCatchTarget(target.data.elementType)) {
4520
- issues.push(issue("bpmn/event-based-gateway-valid-targets", "error", "Event-based gateways must target catch events or receive tasks.", edge.id, [node.id, target.id]));
4521
- }
4522
- }
4523
- }
4524
- if (meta.maxIncoming !== void 0 && incoming > meta.maxIncoming) {
4525
- issues.push(issue("bpmn/max-incoming", "error", `${type} cannot have more than ${meta.maxIncoming} incoming sequence flow(s).`, node.id));
4526
- }
4527
- if (meta.maxOutgoing !== void 0 && outgoing > meta.maxOutgoing) {
4528
- issues.push(issue("bpmn/max-outgoing", "error", `${type} cannot have more than ${meta.maxOutgoing} outgoing sequence flow(s).`, node.id));
4529
- }
4530
- if (opts.strictNames && (type.includes("Task") || isGatewayType(type)) && !node.data.label) {
4531
- issues.push(issue("bpmn/name-required", "warning", `${type} should have a label.`, node.id));
4532
- }
4533
- if (isSubProcess2(type)) {
4534
- const childNodes = nodes.filter((child) => child.parentId === node.id);
4535
- if (childNodes.length > 0) {
4536
- if (!childNodes.some((child) => child.data.elementType === "StartEvent")) {
4537
- issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain a start event.", node.id));
4538
- }
4539
- if (!childNodes.some((child) => child.data.elementType === "EndEvent")) {
4540
- issues.push(issue("bpmn/subprocess-has-start-end", "error", "Expanded subprocesses should contain an end event.", node.id));
4541
- }
4542
- }
4543
- if (type === "EventSubProcess") {
4544
- const starts = childNodes.filter((child) => child.data.elementType === "StartEvent");
4545
- for (const start of starts) {
4546
- if (!start.data.trigger || start.data.trigger === "none") {
4547
- issues.push(issue("bpmn/event-subprocess-triggered-start", "error", "Event subprocess start events must define an event trigger.", start.id, [node.id]));
4548
- }
4549
- }
4550
- }
4551
- }
4552
- if (type === "Lane") {
4553
- const parent = node.parentId ? nodeById2.get(node.parentId) : void 0;
4554
- if (parent?.data.elementType !== "Pool") {
4555
- issues.push(issue("bpmn/lane-parent-pool", "error", "Lanes must be contained by a pool.", node.id));
4748
+ const sourceNode = diagramsCore.getNode(state, edge.source);
4749
+ const targetNode = diagramsCore.getNode(state, edge.target);
4750
+ if (!sourceNode || !targetNode) return null;
4751
+ const sourceAbsPos = getBpmnNodeAbsolutePosition(state, edge.source) ?? sourceNode.position;
4752
+ const targetAbsPos = getBpmnNodeAbsolutePosition(state, edge.target) ?? targetNode.position;
4753
+ const sourceCenter = diagramsCore.getNodeCenterPosition(sourceAbsPos, getBpmnNodeSize(sourceNode));
4754
+ const targetCenter = diagramsCore.getNodeCenterPosition(targetAbsPos, getBpmnNodeSize(targetNode));
4755
+ return diagramsCore.getEdgeLabelLayout([sourceCenter, targetCenter], options);
4756
+ }
4757
+ function resizeBpmnNodeByHandleCommand(options) {
4758
+ return {
4759
+ id: `bpmn.resizeByHandle.${options.id}`,
4760
+ label: "Resize BPMN element",
4761
+ execute: (state) => {
4762
+ const node = diagramsCore.getNode(state, options.id);
4763
+ if (!node) throw new Error(`Element "${options.id}" does not exist.`);
4764
+ const size = getBpmnElementSize(node.data.elementType);
4765
+ if (!size.resizable) {
4766
+ throw new Error(`${node.data.elementType} is not resizable in BPMN.`);
4556
4767
  }
4768
+ const oldW = node.width ?? size.width;
4769
+ const oldH = node.height ?? size.height;
4770
+ const resized = diagramsCore.resizeNodeByHandle(state, {
4771
+ id: options.id,
4772
+ handle: options.handle,
4773
+ dx: options.dx,
4774
+ dy: options.dy,
4775
+ constraints: { minWidth: size.minWidth, minHeight: size.minHeight }
4776
+ });
4777
+ const updatedNode = diagramsCore.getNode(resized, options.id);
4778
+ const newW = updatedNode?.width ?? oldW;
4779
+ const newH = updatedNode?.height ?? oldH;
4780
+ return clampBoundaryEventsAfterResize(resized, options.id, oldW, oldH, newW, newH);
4557
4781
  }
4558
- }
4559
- return {
4560
- valid: issues.every((item) => item.severity !== "error"),
4561
- issues
4562
4782
  };
4563
4783
  }
4784
+ function createBpmnLayoutCache(options) {
4785
+ return diagramsCore.createLayoutCache(options);
4786
+ }
4787
+ function withBpmnLayoutCache(layoutFn, cache) {
4788
+ return diagramsCore.withLayoutCache(layoutFn, cache ?? diagramsCore.createLayoutCache());
4789
+ }
4564
4790
 
4565
4791
  exports.AnnotationNode = AnnotationNode;
4566
4792
  exports.AssociationEdge = AssociationEdge;
@@ -4604,17 +4830,22 @@ exports.acceptsBoundaryEvents = acceptsBoundaryEvents;
4604
4830
  exports.attachBoundaryEventCommand = attachBoundaryEventCommand;
4605
4831
  exports.bpmnConnectionValidators = bpmnConnectionValidators;
4606
4832
  exports.canContainBpmnElement = canContainBpmnElement;
4833
+ exports.computeBpmnSmartGuides = computeBpmnSmartGuides;
4607
4834
  exports.connectBpmnCommand = connectBpmnCommand;
4608
4835
  exports.copyBpmnElements = copyBpmnElements;
4609
4836
  exports.createBpmnDiagramDocument = createBpmnDiagramDocument;
4837
+ exports.createBpmnEventBus = createBpmnEventBus;
4838
+ exports.createBpmnLayoutCache = createBpmnLayoutCache;
4610
4839
  exports.createBpmnNode = createBpmnNode;
4611
4840
  exports.createBpmnNodeCommand = createBpmnNodeCommand;
4612
4841
  exports.createSimulation = createSimulation;
4613
4842
  exports.deleteBpmnElementsCommand = deleteBpmnElementsCommand;
4614
4843
  exports.deserializeBpmnDiagram = deserializeBpmnDiagram;
4844
+ exports.deserializeBpmnDiagramSnapshot = deserializeBpmnDiagramSnapshot;
4615
4845
  exports.findBpmnContainerAt = findBpmnContainerAt;
4616
4846
  exports.fire = fire;
4617
4847
  exports.getBpmnDragHandleSelector = getBpmnDragHandleSelector;
4848
+ exports.getBpmnEdgeLabelLayout = getBpmnEdgeLabelLayout;
4618
4849
  exports.getBpmnElementSize = getBpmnElementSize;
4619
4850
  exports.getBpmnLaneIndexAtPosition = getBpmnLaneIndexAtPosition;
4620
4851
  exports.getBpmnNodeAbsolutePosition = getBpmnNodeAbsolutePosition;
@@ -4622,10 +4853,12 @@ exports.getBpmnNodeCenter = getBpmnNodeCenter;
4622
4853
  exports.getBpmnNodeSize = getBpmnNodeSize;
4623
4854
  exports.getBpmnNodeZIndex = getBpmnNodeZIndex;
4624
4855
  exports.getBpmnPoolLanes = getBpmnPoolLanes;
4856
+ exports.getBpmnTabOrder = getBpmnTabOrder;
4625
4857
  exports.getElementMeta = getElementMeta;
4626
4858
  exports.getFireable = getFireable;
4627
4859
  exports.getHandlePolicy = getHandlePolicy;
4628
4860
  exports.getOrientation = getOrientation;
4861
+ exports.groupAsBpmnSubProcessCommand = groupAsBpmnSubProcessCommand;
4629
4862
  exports.inferBpmnEdgeType = inferBpmnEdgeType;
4630
4863
  exports.isBpmnEdgeRoutingEditable = isBpmnEdgeRoutingEditable;
4631
4864
  exports.isBpmnElementResizable = isBpmnElementResizable;
@@ -4644,13 +4877,16 @@ exports.moveBpmnLaneCommand = moveBpmnLaneCommand;
4644
4877
  exports.parseBpmnDiagramDocument = parseBpmnDiagramDocument;
4645
4878
  exports.parseBpmnXml = parseBpmnXml;
4646
4879
  exports.pasteBpmnElementsCommand = pasteBpmnElementsCommand;
4880
+ exports.persistBpmnHistory = persistBpmnHistory;
4647
4881
  exports.reorderBpmnLane = reorderBpmnLane;
4648
4882
  exports.reorderBpmnLaneAfterDrop = reorderBpmnLaneAfterDrop;
4649
4883
  exports.reorderBpmnLaneCommand = reorderBpmnLaneCommand;
4650
4884
  exports.reparentBpmnNodeAtPosition = reparentBpmnNodeAtPosition;
4651
4885
  exports.reparentBpmnNodeCommand = reparentBpmnNodeCommand;
4652
4886
  exports.replaceBpmnNodeCommand = replaceBpmnNodeCommand;
4887
+ exports.resizeBpmnNodeByHandleCommand = resizeBpmnNodeByHandleCommand;
4653
4888
  exports.resizeBpmnNodeCommand = resizeBpmnNodeCommand;
4889
+ exports.restoreBpmnHistory = restoreBpmnHistory;
4654
4890
  exports.routeBpmnEdgeCommand = routeBpmnEdgeCommand;
4655
4891
  exports.runBpmnCommand = runBpmnCommand;
4656
4892
  exports.runBpmnCommands = runBpmnCommands;
@@ -4663,7 +4899,7 @@ exports.supportsMarkers = supportsMarkers;
4663
4899
  exports.tick = tick;
4664
4900
  exports.toBpmnRelativePosition = toBpmnRelativePosition;
4665
4901
  exports.validateBpmnConnectionForEdgeType = validateBpmnConnectionForEdgeType;
4666
- exports.validateBpmnDiagram = validateBpmnDiagram;
4902
+ exports.withBpmnLayoutCache = withBpmnLayoutCache;
4667
4903
  exports.withBpmnNodeZIndexes = withBpmnNodeZIndexes;
4668
4904
  //# sourceMappingURL=index.cjs.map
4669
4905
  //# sourceMappingURL=index.cjs.map