@bpmnkit/core 0.0.22 → 0.0.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bpmn/auto-layout.js +190 -21
- package/dist/bpmn/bpmn-builder.d.ts +104 -16
- package/dist/bpmn/bpmn-builder.js +561 -374
- package/dist/bpmn/bpmn-model.d.ts +6 -0
- package/dist/bpmn/bpmn-parser.js +10 -0
- package/dist/bpmn/bpmn-serializer.js +10 -1
- package/dist/bpmn/compact.js +1 -0
- package/dist/bpmn/index.d.ts +15 -1
- package/dist/bpmn/index.js +17 -1
- package/dist/bpmn/optimize/tasks.js +1 -0
- package/dist/bpmn/zeebe-extensions.d.ts +2 -0
- package/dist/bpmn/zeebe-extensions.js +3 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/layout/astar.d.ts +15 -0
- package/dist/layout/astar.js +191 -0
- package/dist/layout/block-builder.d.ts +37 -0
- package/dist/layout/block-builder.js +154 -0
- package/dist/layout/block-layout.d.ts +9 -0
- package/dist/layout/block-layout.js +163 -0
- package/dist/layout/coordinates.d.ts +23 -0
- package/dist/layout/coordinates.js +612 -88
- package/dist/layout/index.d.ts +5 -0
- package/dist/layout/index.js +4 -0
- package/dist/layout/layout-engine.d.ts +2 -1
- package/dist/layout/layout-engine.js +209 -29
- package/dist/layout/overlap.js +3 -0
- package/dist/layout/routing.d.ts +10 -3
- package/dist/layout/routing.js +254 -71
- package/dist/layout/types.d.ts +6 -0
- package/package.json +4 -3
package/dist/bpmn/auto-layout.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { layoutProcess } from "../layout/layout-engine.js";
|
|
2
|
+
import { resolveEdgeCrossings } from "../layout/routing.js";
|
|
2
3
|
const POOL_HEADER = 30;
|
|
3
4
|
const LANE_HEADER = 30;
|
|
4
5
|
const PADDING = 20;
|
|
5
6
|
const POOL_GAP = 30;
|
|
6
|
-
|
|
7
|
+
const ANN_H = 50;
|
|
8
|
+
const ANN_GAP = 60;
|
|
9
|
+
const ANN_PADDING = 20;
|
|
10
|
+
function contentBbox(nodes, extra) {
|
|
7
11
|
let minX = Number.POSITIVE_INFINITY;
|
|
8
12
|
let minY = Number.POSITIVE_INFINITY;
|
|
9
13
|
let maxX = Number.NEGATIVE_INFINITY;
|
|
@@ -20,8 +24,107 @@ function contentBbox(nodes) {
|
|
|
20
24
|
maxY = Math.max(maxY, n.labelBounds.y + n.labelBounds.height);
|
|
21
25
|
}
|
|
22
26
|
}
|
|
27
|
+
if (extra) {
|
|
28
|
+
for (const b of extra) {
|
|
29
|
+
minX = Math.min(minX, b.x);
|
|
30
|
+
minY = Math.min(minY, b.y);
|
|
31
|
+
maxX = Math.max(maxX, b.x + b.width);
|
|
32
|
+
maxY = Math.max(maxY, b.y + b.height);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
23
35
|
return { minX, minY, maxX, maxY };
|
|
24
36
|
}
|
|
37
|
+
/** Pre-compute annotation positions in layout space (before dx/dy shift). */
|
|
38
|
+
function computeAnnotationLocalBounds(process, layoutNodes) {
|
|
39
|
+
const nodeById = new Map(layoutNodes.map((n) => [n.id, n]));
|
|
40
|
+
const placements = new Map();
|
|
41
|
+
// Occupied regions for overlap checks (node bounds + label bounds)
|
|
42
|
+
const occupied = [];
|
|
43
|
+
for (const n of layoutNodes) {
|
|
44
|
+
occupied.push({ ...n.bounds });
|
|
45
|
+
if (n.labelBounds)
|
|
46
|
+
occupied.push({ ...n.labelBounds });
|
|
47
|
+
}
|
|
48
|
+
// Static obstacles for crossing detection (nodes + labels only, not annotations)
|
|
49
|
+
const obstacles = [...occupied];
|
|
50
|
+
for (const ta of process.textAnnotations) {
|
|
51
|
+
const assoc = process.associations.find((a) => a.sourceRef === ta.id || a.targetRef === ta.id);
|
|
52
|
+
const connId = assoc
|
|
53
|
+
? assoc.sourceRef === ta.id
|
|
54
|
+
? assoc.targetRef
|
|
55
|
+
: assoc.sourceRef
|
|
56
|
+
: undefined;
|
|
57
|
+
const connNode = connId ? nodeById.get(connId) : undefined;
|
|
58
|
+
const annW = Math.min(200, Math.max(100, (ta.text?.length ?? 10) * 5));
|
|
59
|
+
if (!connNode) {
|
|
60
|
+
const candidate = { x: 0, y: 0, width: annW, height: ANN_H };
|
|
61
|
+
occupied.push({ ...candidate });
|
|
62
|
+
placements.set(ta.id, candidate);
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const localX = connNode.bounds.x + connNode.bounds.width / 2 - annW / 2;
|
|
66
|
+
const anchorX = connNode.bounds.x + connNode.bounds.width / 2;
|
|
67
|
+
const pushStep = ANN_H + ANN_PADDING * 2 + 10;
|
|
68
|
+
// Try below: start below connected element, push down for overlaps
|
|
69
|
+
const belowY = connNode.bounds.y + connNode.bounds.height + ANN_GAP;
|
|
70
|
+
const below = { x: localX, y: belowY, width: annW, height: ANN_H };
|
|
71
|
+
for (let i = 0; i < 30 && hasOverlapPadded(below, occupied, ANN_PADDING); i++)
|
|
72
|
+
below.y += pushStep;
|
|
73
|
+
// Try above: gap scales with text length so longer annotations have more breathing room
|
|
74
|
+
const aboveGap = ANN_GAP + Math.round(annW * 0.2);
|
|
75
|
+
const aboveY = connNode.bounds.y - aboveGap - ANN_H;
|
|
76
|
+
const above = { x: localX, y: aboveY, width: annW, height: ANN_H };
|
|
77
|
+
for (let i = 0; i < 30 && hasOverlapPadded(above, occupied, ANN_PADDING); i++)
|
|
78
|
+
above.y -= pushStep;
|
|
79
|
+
// Count how many obstacles the association line would cross for each candidate
|
|
80
|
+
const belowCrossings = countLineCrossings(anchorX, connNode.bounds, below, obstacles);
|
|
81
|
+
const aboveCrossings = countLineCrossings(anchorX, connNode.bounds, above, obstacles);
|
|
82
|
+
const candidate = belowCrossings <= aboveCrossings ? below : above;
|
|
83
|
+
occupied.push({ ...candidate });
|
|
84
|
+
obstacles.push({ ...candidate });
|
|
85
|
+
placements.set(ta.id, candidate);
|
|
86
|
+
}
|
|
87
|
+
return placements;
|
|
88
|
+
}
|
|
89
|
+
/** Count how many obstacles the vertical association line from connNode to annotation crosses. */
|
|
90
|
+
function countLineCrossings(lineX, connBounds, annBounds, obstacles) {
|
|
91
|
+
const annCY = annBounds.y + annBounds.height / 2;
|
|
92
|
+
const connCY = connBounds.y + connBounds.height / 2;
|
|
93
|
+
const top = Math.min(annCY, connCY);
|
|
94
|
+
const bottom = Math.max(annCY, connCY);
|
|
95
|
+
const tolerance = 20;
|
|
96
|
+
let crossings = 0;
|
|
97
|
+
for (const b of obstacles) {
|
|
98
|
+
// Skip the connected element itself
|
|
99
|
+
if (b.x === connBounds.x && b.y === connBounds.y && b.width === connBounds.width)
|
|
100
|
+
continue;
|
|
101
|
+
// Obstacle must overlap with the line's X corridor
|
|
102
|
+
if (b.x + b.width < lineX - tolerance || b.x > lineX + tolerance)
|
|
103
|
+
continue;
|
|
104
|
+
// Obstacle must be between connNode and annotation vertically
|
|
105
|
+
if (b.y + b.height <= top || b.y >= bottom)
|
|
106
|
+
continue;
|
|
107
|
+
crossings++;
|
|
108
|
+
}
|
|
109
|
+
return crossings;
|
|
110
|
+
}
|
|
111
|
+
function hasOverlap(a, others) {
|
|
112
|
+
for (const b of others) {
|
|
113
|
+
if (a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y)
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
function hasOverlapPadded(a, others, padding) {
|
|
119
|
+
for (const b of others) {
|
|
120
|
+
if (a.x - padding < b.x + b.width &&
|
|
121
|
+
a.x + a.width + padding > b.x &&
|
|
122
|
+
a.y - padding < b.y + b.height &&
|
|
123
|
+
a.y + a.height + padding > b.y)
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
25
128
|
function nodeToShape(node, dx, dy) {
|
|
26
129
|
const shape = {
|
|
27
130
|
id: `${node.id}_di`,
|
|
@@ -112,6 +215,70 @@ function buildLaneShapes(lanes, nodes, dx, dy, poolY, poolHeaderWidth, laneConte
|
|
|
112
215
|
unknownAttributes: {},
|
|
113
216
|
}));
|
|
114
217
|
}
|
|
218
|
+
function addAnnotationShapes(process, layoutNodes, annLocalBounds, allShapes, allEdges, dx, dy) {
|
|
219
|
+
if (process.textAnnotations.length === 0 && process.associations.length === 0)
|
|
220
|
+
return;
|
|
221
|
+
const nodeById = new Map(layoutNodes.map((n) => [n.id, n]));
|
|
222
|
+
for (const ta of process.textAnnotations) {
|
|
223
|
+
const b = annLocalBounds.get(ta.id);
|
|
224
|
+
if (!b)
|
|
225
|
+
continue;
|
|
226
|
+
allShapes.push({
|
|
227
|
+
id: `${ta.id}_di`,
|
|
228
|
+
bpmnElement: ta.id,
|
|
229
|
+
bounds: {
|
|
230
|
+
x: Math.round(b.x + dx),
|
|
231
|
+
y: Math.round(b.y + dy),
|
|
232
|
+
width: b.width,
|
|
233
|
+
height: b.height,
|
|
234
|
+
},
|
|
235
|
+
unknownAttributes: {},
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
for (const assoc of process.associations) {
|
|
239
|
+
const annId = annLocalBounds.has(assoc.sourceRef)
|
|
240
|
+
? assoc.sourceRef
|
|
241
|
+
: annLocalBounds.has(assoc.targetRef)
|
|
242
|
+
? assoc.targetRef
|
|
243
|
+
: undefined;
|
|
244
|
+
const elId = annId === assoc.sourceRef ? assoc.targetRef : assoc.sourceRef;
|
|
245
|
+
const annB = annId ? annLocalBounds.get(annId) : undefined;
|
|
246
|
+
const elNode = nodeById.get(elId);
|
|
247
|
+
if (!annB || !elNode)
|
|
248
|
+
continue;
|
|
249
|
+
const elB = elNode.bounds;
|
|
250
|
+
const annCx = Math.round(annB.x + annB.width / 2 + dx);
|
|
251
|
+
const elCx = Math.round(elB.x + elB.width / 2 + dx);
|
|
252
|
+
let waypoints;
|
|
253
|
+
if (annB.y >= elB.y + elB.height) {
|
|
254
|
+
// annotation below: element bottom-center → annotation top-center
|
|
255
|
+
waypoints = [
|
|
256
|
+
{ x: elCx, y: Math.round(elB.y + elB.height + dy) },
|
|
257
|
+
{ x: annCx, y: Math.round(annB.y + dy) },
|
|
258
|
+
];
|
|
259
|
+
}
|
|
260
|
+
else if (annB.y + annB.height <= elB.y) {
|
|
261
|
+
// annotation above: element top-center → annotation bottom-center
|
|
262
|
+
waypoints = [
|
|
263
|
+
{ x: elCx, y: Math.round(elB.y + dy) },
|
|
264
|
+
{ x: annCx, y: Math.round(annB.y + annB.height + dy) },
|
|
265
|
+
];
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
// side-by-side: center-to-center
|
|
269
|
+
waypoints = [
|
|
270
|
+
{ x: Math.round(elB.x + elB.width / 2 + dx), y: Math.round(elB.y + elB.height / 2 + dy) },
|
|
271
|
+
{ x: annCx, y: Math.round(annB.y + annB.height / 2 + dy) },
|
|
272
|
+
];
|
|
273
|
+
}
|
|
274
|
+
allEdges.push({
|
|
275
|
+
id: `${assoc.id}_di`,
|
|
276
|
+
bpmnElement: assoc.id,
|
|
277
|
+
waypoints,
|
|
278
|
+
unknownAttributes: {},
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
}
|
|
115
282
|
/**
|
|
116
283
|
* Apply auto-layout to all processes in a BpmnDefinitions, replacing the
|
|
117
284
|
* diagram interchange (BPMNDi) with freshly computed positions.
|
|
@@ -138,28 +305,39 @@ export function applyAutoLayout(defs) {
|
|
|
138
305
|
const participantId = processToParticipant.get(process.id);
|
|
139
306
|
const lanes = process.laneSet?.lanes ?? [];
|
|
140
307
|
const hasLanes = lanes.length > 0;
|
|
308
|
+
// layoutProcess now handles boundary event repositioning internally.
|
|
141
309
|
const result = layoutProcess(process);
|
|
310
|
+
// Re-resolve edge crossings after boundary events moved shapes
|
|
311
|
+
const nodeMap = new Map(result.nodes.map((n) => [n.id, n]));
|
|
312
|
+
resolveEdgeCrossings(result.edges, nodeMap);
|
|
142
313
|
if (result.nodes.length === 0)
|
|
143
314
|
continue;
|
|
144
|
-
|
|
315
|
+
// Pre-compute annotation positions in layout space so they're included in the bbox
|
|
316
|
+
const annBounds = computeAnnotationLocalBounds(process, result.nodes);
|
|
317
|
+
const { minX, minY, maxX, maxY } = contentBbox(result.nodes, annBounds.values());
|
|
145
318
|
const contentW = maxX - minX;
|
|
146
319
|
const contentH = maxY - minY;
|
|
320
|
+
let dx;
|
|
321
|
+
let dy;
|
|
147
322
|
if (participantId) {
|
|
148
|
-
// Elements sit inside pool content area:
|
|
149
|
-
// x starts at: POOL_HEADER + optional LANE_HEADER + PADDING
|
|
150
|
-
// y starts at: poolY + PADDING
|
|
151
323
|
const elemX = POOL_HEADER + (hasLanes ? LANE_HEADER : 0) + PADDING;
|
|
152
324
|
const elemY = poolY + PADDING;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
325
|
+
dx = elemX - minX;
|
|
326
|
+
dy = elemY - minY;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
dx = PADDING - minX;
|
|
330
|
+
dy = PADDING - minY;
|
|
331
|
+
}
|
|
332
|
+
for (const node of result.nodes)
|
|
333
|
+
allShapes.push(nodeToShape(node, dx, dy));
|
|
334
|
+
for (const edge of result.edges)
|
|
335
|
+
allEdges.push(edgeToShape(edge, dx, dy));
|
|
336
|
+
addAnnotationShapes(process, result.nodes, annBounds, allShapes, allEdges, dx, dy);
|
|
337
|
+
if (participantId) {
|
|
159
338
|
const innerW = (hasLanes ? LANE_HEADER : 0) + contentW + 2 * PADDING;
|
|
160
339
|
const innerH = contentH + 2 * PADDING;
|
|
161
340
|
const poolW = POOL_HEADER + innerW;
|
|
162
|
-
// Pool (participant) shape
|
|
163
341
|
allShapes.push({
|
|
164
342
|
id: `${participantId}_di`,
|
|
165
343
|
bpmnElement: participantId,
|
|
@@ -173,15 +351,6 @@ export function applyAutoLayout(defs) {
|
|
|
173
351
|
}
|
|
174
352
|
poolY += innerH + POOL_GAP;
|
|
175
353
|
}
|
|
176
|
-
else {
|
|
177
|
-
// No collaboration — layout at (PADDING, PADDING)
|
|
178
|
-
const dx = PADDING - minX;
|
|
179
|
-
const dy = PADDING - minY;
|
|
180
|
-
for (const node of result.nodes)
|
|
181
|
-
allShapes.push(nodeToShape(node, dx, dy));
|
|
182
|
-
for (const edge of result.edges)
|
|
183
|
-
allEdges.push(edgeToShape(edge, dx, dy));
|
|
184
|
-
}
|
|
185
354
|
}
|
|
186
355
|
const planeBpmnElement = collab?.id ?? defs.processes[0]?.id ?? "plane";
|
|
187
356
|
const existingDiagram = defs.diagrams[0];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BpmnDefinitions, BpmnFlowElement, BpmnSequenceFlow } from "./bpmn-model.js";
|
|
1
|
+
import type { BpmnAssociation, BpmnDefinitions, BpmnFlowElement, BpmnSequenceFlow, BpmnTextAnnotation } from "./bpmn-model.js";
|
|
2
2
|
import type { RestConnectorConfig } from "./rest-connector.js";
|
|
3
3
|
/** Options shared by all element methods. */
|
|
4
4
|
export interface ElementOptions {
|
|
@@ -69,6 +69,8 @@ export interface UserTaskOptions {
|
|
|
69
69
|
name?: string;
|
|
70
70
|
/** Form key or form reference. */
|
|
71
71
|
formId?: string;
|
|
72
|
+
/** Emit <zeebe:userTask /> to mark as a Camunda 8 native user task. */
|
|
73
|
+
zeebeUserTask?: boolean;
|
|
72
74
|
}
|
|
73
75
|
/** Options for creating a call activity. */
|
|
74
76
|
export interface CallActivityOptions {
|
|
@@ -117,6 +119,19 @@ export interface IntermediateThrowEventOptions extends ElementOptions {
|
|
|
117
119
|
/** Escalation code — creates an escalation throw event (aspirational). */
|
|
118
120
|
escalationCode?: string;
|
|
119
121
|
}
|
|
122
|
+
/** Options for an end event. */
|
|
123
|
+
export interface EndEventOptions extends ElementOptions {
|
|
124
|
+
/** Error code — creates an error end event. */
|
|
125
|
+
errorCode?: string;
|
|
126
|
+
/** Error reference ID. */
|
|
127
|
+
errorRef?: string;
|
|
128
|
+
/** Message name — creates a message end event. */
|
|
129
|
+
messageName?: string;
|
|
130
|
+
/** Signal name — creates a signal end event. */
|
|
131
|
+
signalName?: string;
|
|
132
|
+
/** Escalation code — creates an escalation end event. */
|
|
133
|
+
escalationCode?: string;
|
|
134
|
+
}
|
|
120
135
|
/** Options for a boundary event. */
|
|
121
136
|
export interface BoundaryEventOptions extends ElementOptions {
|
|
122
137
|
/** ID of the activity this boundary event is attached to. */
|
|
@@ -212,6 +227,11 @@ export declare class BranchBuilder {
|
|
|
212
227
|
/** @internal – true once connectTo() has been called, meaning the branch end is already wired */
|
|
213
228
|
_connected: boolean;
|
|
214
229
|
/** @internal */
|
|
230
|
+
readonly _textAnnotations: BpmnTextAnnotation[];
|
|
231
|
+
/** @internal */
|
|
232
|
+
readonly _associations: BpmnAssociation[];
|
|
233
|
+
private readonly _annCounters;
|
|
234
|
+
/** @internal */
|
|
215
235
|
constructor(gatewayId: string, branchName: string);
|
|
216
236
|
/** Set a FEEL condition expression on this branch's outgoing sequence flow. */
|
|
217
237
|
condition(expression: string): this;
|
|
@@ -225,6 +245,10 @@ export declare class BranchBuilder {
|
|
|
225
245
|
connectTo(targetId: string): this;
|
|
226
246
|
/** @internal – ID of the last element added (or the gateway if branch is empty) */
|
|
227
247
|
get _lastNodeId(): string;
|
|
248
|
+
/** Attach a text annotation to the element at the current cursor position. */
|
|
249
|
+
textAnnotation(text: string): this;
|
|
250
|
+
/** Attach a text annotation to an element by explicit ID. */
|
|
251
|
+
annotate(elementId: string, text: string): this;
|
|
228
252
|
serviceTask(id: string, options: ServiceTaskOptions): this;
|
|
229
253
|
userTask(id: string, options?: UserTaskOptions): this;
|
|
230
254
|
scriptTask(id: string, options: ScriptTaskOptions): this;
|
|
@@ -233,7 +257,7 @@ export declare class BranchBuilder {
|
|
|
233
257
|
businessRuleTask(id: string, options?: BusinessRuleTaskOptions): this;
|
|
234
258
|
callActivity(id: string, options: CallActivityOptions): this;
|
|
235
259
|
startEvent(id?: string, options?: StartEventOptions): this;
|
|
236
|
-
endEvent(id?: string, options?:
|
|
260
|
+
endEvent(id?: string, options?: EndEventOptions): this;
|
|
237
261
|
intermediateThrowEvent(id?: string, options?: IntermediateThrowEventOptions): this;
|
|
238
262
|
intermediateCatchEvent(id?: string, options?: IntermediateCatchEventOptions): this;
|
|
239
263
|
exclusiveGateway(id: string, options?: GatewayOptions): this;
|
|
@@ -247,16 +271,37 @@ export declare class SubProcessContentBuilder {
|
|
|
247
271
|
readonly _elements: BpmnFlowElement[];
|
|
248
272
|
/** @internal */
|
|
249
273
|
readonly _flows: BpmnSequenceFlow[];
|
|
274
|
+
/** @internal */
|
|
275
|
+
readonly _textAnnotations: BpmnTextAnnotation[];
|
|
276
|
+
/** @internal */
|
|
277
|
+
readonly _associations: BpmnAssociation[];
|
|
278
|
+
private readonly _annCounters;
|
|
250
279
|
private lastNodeId;
|
|
280
|
+
private currentGatewayId;
|
|
281
|
+
private openBranchEnds;
|
|
251
282
|
private addElement;
|
|
252
283
|
startEvent(id?: string, options?: StartEventOptions): this;
|
|
253
|
-
endEvent(id?: string, options?:
|
|
284
|
+
endEvent(id?: string, options?: EndEventOptions): this;
|
|
285
|
+
intermediateThrowEvent(id?: string, options?: IntermediateThrowEventOptions): this;
|
|
286
|
+
intermediateCatchEvent(id?: string, options?: IntermediateCatchEventOptions): this;
|
|
254
287
|
serviceTask(id: string, options: ServiceTaskOptions): this;
|
|
255
|
-
userTask(id: string, options?: UserTaskOptions): this;
|
|
256
288
|
scriptTask(id: string, options: ScriptTaskOptions): this;
|
|
289
|
+
userTask(id: string, options?: UserTaskOptions): this;
|
|
290
|
+
businessRuleTask(id: string, options?: BusinessRuleTaskOptions): this;
|
|
257
291
|
callActivity(id: string, options: CallActivityOptions): this;
|
|
258
|
-
|
|
259
|
-
|
|
292
|
+
sendTask(id: string, options?: ElementOptions): this;
|
|
293
|
+
receiveTask(id: string, options?: ElementOptions): this;
|
|
294
|
+
exclusiveGateway(id: string, options?: GatewayOptions): this;
|
|
295
|
+
parallelGateway(id: string, options?: ElementOptions): this;
|
|
296
|
+
inclusiveGateway(id: string, options?: GatewayOptions): this;
|
|
297
|
+
eventBasedGateway(id: string, options?: ElementOptions): this;
|
|
298
|
+
/** Attach a text annotation to the element at the current cursor position. */
|
|
299
|
+
textAnnotation(text: string): this;
|
|
300
|
+
/** Attach a text annotation to an element by explicit ID. */
|
|
301
|
+
annotate(elementId: string, text: string): this;
|
|
302
|
+
branch(name: string, callback: (b: BranchBuilder) => void): this;
|
|
303
|
+
connectTo(targetId: string): this;
|
|
304
|
+
element(elementId: string): this;
|
|
260
305
|
}
|
|
261
306
|
/** Fluent builder for constructing BPMN processes. */
|
|
262
307
|
export declare class ProcessBuilder {
|
|
@@ -268,13 +313,26 @@ export declare class ProcessBuilder {
|
|
|
268
313
|
private readonly sequenceFlows;
|
|
269
314
|
private readonly rootErrors;
|
|
270
315
|
private readonly rootMessages;
|
|
316
|
+
private readonly _textAnnotations;
|
|
317
|
+
private readonly _associations;
|
|
318
|
+
private readonly _annCounters;
|
|
271
319
|
private lastNodeId;
|
|
272
320
|
private currentGatewayId;
|
|
273
321
|
private openBranchEnds;
|
|
274
322
|
private _autoLayout;
|
|
323
|
+
private _executionPlatformVersion;
|
|
324
|
+
private _serviceTaskDefaults;
|
|
275
325
|
constructor(processId: string);
|
|
276
326
|
/** Enable auto-layout: `build()` will run the layout engine and populate diagram interchange data. */
|
|
277
327
|
withAutoLayout(): this;
|
|
328
|
+
/** Set the Camunda execution platform version stamped into the BPMN definitions. Defaults to `"8.9.0"`. */
|
|
329
|
+
executionPlatformVersion(version: string): this;
|
|
330
|
+
/** Set process-wide defaults applied to subsequently added elements. */
|
|
331
|
+
defaults(options: {
|
|
332
|
+
serviceTask?: {
|
|
333
|
+
retries?: string;
|
|
334
|
+
};
|
|
335
|
+
}): this;
|
|
278
336
|
/** Set the display name for this process. */
|
|
279
337
|
name(name: string): this;
|
|
280
338
|
/** Set whether this process is executable. */
|
|
@@ -291,8 +349,14 @@ export declare class ProcessBuilder {
|
|
|
291
349
|
* is completely disconnected.
|
|
292
350
|
*/
|
|
293
351
|
addStartEvent(id?: string, options?: StartEventOptions): this;
|
|
352
|
+
/**
|
|
353
|
+
* Alias for `addStartEvent()` — begins a new disconnected parallel path.
|
|
354
|
+
*
|
|
355
|
+
* Use this for readability when modeling processes with multiple independent paths.
|
|
356
|
+
*/
|
|
357
|
+
disconnectedStartEvent(id?: string, options?: StartEventOptions): this;
|
|
294
358
|
/** Add an end event. */
|
|
295
|
-
endEvent(id?: string, options?:
|
|
359
|
+
endEvent(id?: string, options?: EndEventOptions): this;
|
|
296
360
|
/** Add an intermediate throw event (none, message, signal, escalation). */
|
|
297
361
|
intermediateThrowEvent(id?: string, options?: IntermediateThrowEventOptions): this;
|
|
298
362
|
/** Add an intermediate catch event (timer, message, signal). */
|
|
@@ -304,6 +368,15 @@ export declare class ProcessBuilder {
|
|
|
304
368
|
* They start a new outgoing chain from the boundary event itself.
|
|
305
369
|
*/
|
|
306
370
|
boundaryEvent(id: string, options: BoundaryEventOptions): this;
|
|
371
|
+
/**
|
|
372
|
+
* Attach a boundary event to the preceding task and build its outgoing path,
|
|
373
|
+
* then restore the builder cursor to the preceding task so the main flow continues.
|
|
374
|
+
*
|
|
375
|
+
* @param id - ID for the boundary event element.
|
|
376
|
+
* @param options - Boundary event options (without `attachedTo` — inferred from cursor).
|
|
377
|
+
* @param handler - Callback that chains elements from the boundary event.
|
|
378
|
+
*/
|
|
379
|
+
withBoundary(id: string, options: Omit<BoundaryEventOptions, "attachedTo">, handler: (b: ProcessBuilder) => void): this;
|
|
307
380
|
/** Add a service task with Zeebe task definition and optional IO mappings. */
|
|
308
381
|
serviceTask(id: string, options: ServiceTaskOptions): this;
|
|
309
382
|
/** Add a REST connector task — syntactic sugar over `serviceTask()`. */
|
|
@@ -361,21 +434,36 @@ export declare class ProcessBuilder {
|
|
|
361
434
|
subProcess(id: string, content: (b: SubProcessContentBuilder) => void, options?: SubProcessOptions): this;
|
|
362
435
|
/** Add an event sub-process (aspirational). */
|
|
363
436
|
eventSubProcess(id: string, content: (b: SubProcessContentBuilder) => void, options?: ElementOptions): this;
|
|
437
|
+
/** Attach a text annotation to the element at the current cursor position. */
|
|
438
|
+
textAnnotation(text: string): this;
|
|
439
|
+
/** Attach a text annotation to any flow element by explicit ID. */
|
|
440
|
+
annotate(elementId: string, text: string): this;
|
|
364
441
|
/**
|
|
365
442
|
* Build the complete BPMN definitions model.
|
|
366
443
|
*
|
|
367
444
|
* Resolves all forward-referenced `incoming` / `outgoing` arrays and wraps
|
|
368
445
|
* the process in a {@link BpmnDefinitions} ready for XML serialization.
|
|
369
446
|
*/
|
|
370
|
-
build(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
* on a non-gateway target. BPMN best practice: every split has a join.
|
|
375
|
-
*/
|
|
376
|
-
private insertJoinGateways;
|
|
377
|
-
/** Trace backward from a node to find which split gateway it belongs to. */
|
|
378
|
-
private traceBackToSplit;
|
|
447
|
+
build(options?: {
|
|
448
|
+
strict?: boolean;
|
|
449
|
+
}): BpmnDefinitions;
|
|
450
|
+
private validate;
|
|
379
451
|
private addFlowElement;
|
|
380
452
|
}
|
|
453
|
+
/**
|
|
454
|
+
* Builder for a complete BPMN definitions document containing one or more processes.
|
|
455
|
+
* Use `Bpmn.createDiagram(id?)` to obtain an instance.
|
|
456
|
+
*/
|
|
457
|
+
export declare class DiagramBuilder {
|
|
458
|
+
private readonly _id;
|
|
459
|
+
private readonly _processes;
|
|
460
|
+
private readonly _errors;
|
|
461
|
+
private readonly _messages;
|
|
462
|
+
private _executionPlatformVersion;
|
|
463
|
+
constructor(id: string);
|
|
464
|
+
/** Set the Camunda execution platform version stamped into the BPMN definitions. Defaults to `"8.9.0"`. */
|
|
465
|
+
executionPlatformVersion(version: string): this;
|
|
466
|
+
process(id: string, callback: (b: ProcessBuilder) => void): this;
|
|
467
|
+
build(): BpmnDefinitions;
|
|
468
|
+
}
|
|
381
469
|
//# sourceMappingURL=bpmn-builder.d.ts.map
|