@bpmnkit/core 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +30 -1
  2. package/dist/bpmn/bpmn-builder.d.ts +209 -3
  3. package/dist/bpmn/bpmn-builder.js +456 -16
  4. package/dist/bpmn/bpmn-model.d.ts +110 -0
  5. package/dist/bpmn/bpmn-parser.js +1413 -528
  6. package/dist/bpmn/bpmn-serializer.js +101 -19
  7. package/dist/bpmn/compact.d.ts +17 -2
  8. package/dist/bpmn/compact.js +3 -3
  9. package/dist/bpmn/full-operations.d.ts +89 -0
  10. package/dist/bpmn/full-operations.js +478 -0
  11. package/dist/bpmn/index.d.ts +19 -0
  12. package/dist/bpmn/index.js +21 -0
  13. package/dist/bpmn/optimize/feel.js +2 -2
  14. package/dist/bpmn/optimize/patterns.js +23 -16
  15. package/dist/bpmn/optimize/tasks.js +30 -7
  16. package/dist/bpmn/optimize/utils.js +2 -4
  17. package/dist/bpmn/optimize/variable-flow.js +58 -67
  18. package/dist/bpmn/semantic-hash.d.ts +93 -0
  19. package/dist/bpmn/semantic-hash.js +155 -0
  20. package/dist/bpmn/sha256.d.ts +17 -0
  21. package/dist/bpmn/sha256.js +95 -0
  22. package/dist/bpmn/zeebe-extensions.d.ts +56 -0
  23. package/dist/bpmn/zeebe-extensions.js +79 -0
  24. package/dist/bpmn/zeebe-placement.d.ts +12 -0
  25. package/dist/bpmn/zeebe-placement.js +140 -0
  26. package/dist/errors.d.ts +40 -1
  27. package/dist/errors.js +41 -0
  28. package/dist/index.d.ts +10 -4
  29. package/dist/index.js +7 -3
  30. package/dist/layout/semantic/graph.d.ts +9 -1
  31. package/dist/layout/semantic/graph.js +42 -17
  32. package/dist/layout/semantic/route.js +102 -42
  33. package/dist/node/index.d.ts +10 -0
  34. package/dist/node/index.js +9 -0
  35. package/dist/node/write.d.ts +81 -0
  36. package/dist/node/write.js +167 -0
  37. package/dist/types/id-generator.js +11 -3
  38. package/dist/xml/index.d.ts +3 -1
  39. package/dist/xml/index.js +2 -1
  40. package/dist/xml/xml-parser.d.ts +32 -0
  41. package/dist/xml/xml-parser.js +394 -143
  42. package/package.json +8 -1
@@ -1,3 +1,4 @@
1
+ import { ZEEBE_PLACEMENT } from "./zeebe-placement.js";
1
2
  /** Convert Zeebe extensions to XmlElement array for the BPMN model. */
2
3
  export function zeebeExtensionsToXmlElements(extensions) {
3
4
  const elements = [];
@@ -134,4 +135,82 @@ export function zeebeExtensionsToXmlElements(extensions) {
134
135
  }
135
136
  return elements;
136
137
  }
138
+ // ---------------------------------------------------------------------------
139
+ // Placement
140
+ // ---------------------------------------------------------------------------
141
+ /**
142
+ * Reports where a Zeebe extension may go, from the descriptor rather than from
143
+ * our own idea of the rules.
144
+ *
145
+ * `zeebe.json` records a `meta.allowedIn` list per extension type;
146
+ * `scripts/generate-zeebe-placement.ts` resolves those entries — many of which
147
+ * name abstract BPMN types or Zeebe aliases — into the concrete element names in
148
+ * `ZEEBE_PLACEMENT`. Writing `zeebe:calledDecision` onto a service task produces
149
+ * a file Camunda rejects at deploy time; catching it at the write is the point.
150
+ *
151
+ * **An extension the table does not mention is allowed.** The descriptor
152
+ * declares no owner for `zeebe:subscription` or `zeebe:properties`, so we do not
153
+ * know where they may go and must not invent a rule — this check rejects only
154
+ * what the descriptor positively forbids. Vendor extensions outside the `zeebe:`
155
+ * namespace are not this function's business and are likewise allowed.
156
+ *
157
+ * @param ownerElement - The owner's BPMN element name, e.g. `bpmn:serviceTask`.
158
+ * @param extension - The extension element name, e.g. `zeebe:taskDefinition`.
159
+ */
160
+ export function isZeebePlacementAllowed(ownerElement, extension) {
161
+ const owners = ZEEBE_PLACEMENT[extension];
162
+ return owners === undefined || owners.includes(ownerElement);
163
+ }
164
+ /** Thrown when a Zeebe extension is written somewhere the descriptor forbids. */
165
+ export class ZeebePlacementError extends Error {
166
+ ownerElement;
167
+ extension;
168
+ allowedOn;
169
+ constructor(ownerElement, extension, allowedOn) {
170
+ super(`<${extension}> is not allowed on <${ownerElement}>. The Zeebe schema allows it on: ${allowedOn.join(", ")}.`);
171
+ this.ownerElement = ownerElement;
172
+ this.extension = extension;
173
+ this.allowedOn = allowedOn;
174
+ this.name = "ZeebePlacementError";
175
+ }
176
+ }
177
+ /**
178
+ * Throws {@link ZeebePlacementError} if the placement is one the descriptor
179
+ * forbids. See {@link isZeebePlacementAllowed} for what "forbids" covers.
180
+ */
181
+ export function assertZeebePlacement(ownerElement, extension) {
182
+ if (isZeebePlacementAllowed(ownerElement, extension))
183
+ return;
184
+ throw new ZeebePlacementError(ownerElement, extension, ZEEBE_PLACEMENT[extension] ?? []);
185
+ }
186
+ /**
187
+ * The BPMN element name a flow element is written as.
188
+ *
189
+ * The model's `type` is the element's local name in every case but one:
190
+ * `eventSubProcess` is our name for a `bpmn:subProcess` carrying
191
+ * `triggeredByEvent`, and BPMN has no element of that name.
192
+ */
193
+ export function bpmnElementName(flowElement) {
194
+ const local = flowElement.type === "eventSubProcess" ? "subProcess" : flowElement.type;
195
+ return `bpmn:${local}`;
196
+ }
197
+ /**
198
+ * Finds a Zeebe extension element on a flow element, creating it if absent, and
199
+ * refuses a placement the descriptor forbids.
200
+ *
201
+ * Use this rather than pushing onto `extensionElements` directly: the push
202
+ * cannot fail, so an extension on the wrong element becomes a deploy-time error
203
+ * in someone else's terminal instead of a throw here.
204
+ *
205
+ * @throws ZeebePlacementError
206
+ */
207
+ export function ensureZeebeExtension(owner, extension) {
208
+ assertZeebePlacement(bpmnElementName(owner), extension);
209
+ const existing = owner.extensionElements.find((candidate) => candidate.name === extension);
210
+ if (existing)
211
+ return existing;
212
+ const created = { name: extension, attributes: {}, children: [] };
213
+ owner.extensionElements.push(created);
214
+ return created;
215
+ }
137
216
  //# sourceMappingURL=zeebe-extensions.js.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Where each Zeebe extension element may be placed, keyed by element name.
3
+ *
4
+ * The value is the set of element names that may own it. Owners are BPMN
5
+ * elements for extensions that sit in an `extensionElements` bag, and Zeebe
6
+ * elements for the few that nest inside another extension.
7
+ *
8
+ * An extension absent from this table is one the descriptor says nothing about;
9
+ * see `isZeebePlacementAllowed` for what that means.
10
+ */
11
+ export declare const ZEEBE_PLACEMENT: Readonly<Record<string, readonly string[]>>;
12
+ //# sourceMappingURL=zeebe-placement.d.ts.map
@@ -0,0 +1,140 @@
1
+ // Generated by scripts/generate-zeebe-placement.ts — do not edit.
2
+ // Source: descriptors/zeebe.json (zeebe-bpmn-moddle, MIT) resolved against
3
+ // descriptors/bpmn.json (bpmn-moddle, MIT). Regenerate with:
4
+ // pnpm --filter @bpmnkit/core generate:placement
5
+ /**
6
+ * Where each Zeebe extension element may be placed, keyed by element name.
7
+ *
8
+ * The value is the set of element names that may own it. Owners are BPMN
9
+ * elements for extensions that sit in an `extensionElements` bag, and Zeebe
10
+ * elements for the few that nest inside another extension.
11
+ *
12
+ * An extension absent from this table is one the descriptor says nothing about;
13
+ * see `isZeebePlacementAllowed` for what that means.
14
+ */
15
+ export const ZEEBE_PLACEMENT = {
16
+ "zeebe:adHoc": ["bpmn:adHocSubProcess"],
17
+ "zeebe:agentDefinition": ["bpmn:adHocSubProcess", "bpmn:serviceTask"],
18
+ "zeebe:assignmentDefinition": ["bpmn:userTask"],
19
+ "zeebe:calledDecision": ["bpmn:businessRuleTask"],
20
+ "zeebe:calledElement": ["bpmn:callActivity"],
21
+ "zeebe:conditionalFilter": ["bpmn:conditionalEventDefinition"],
22
+ "zeebe:executionListener": ["zeebe:executionListeners"],
23
+ "zeebe:executionListeners": [
24
+ "bpmn:adHocSubProcess",
25
+ "bpmn:boundaryEvent",
26
+ "bpmn:businessRuleTask",
27
+ "bpmn:callActivity",
28
+ "bpmn:endEvent",
29
+ "bpmn:eventBasedGateway",
30
+ "bpmn:exclusiveGateway",
31
+ "bpmn:implicitThrowEvent",
32
+ "bpmn:inclusiveGateway",
33
+ "bpmn:intermediateCatchEvent",
34
+ "bpmn:intermediateThrowEvent",
35
+ "bpmn:manualTask",
36
+ "bpmn:parallelGateway",
37
+ "bpmn:process",
38
+ "bpmn:receiveTask",
39
+ "bpmn:scriptTask",
40
+ "bpmn:sendTask",
41
+ "bpmn:serviceTask",
42
+ "bpmn:startEvent",
43
+ "bpmn:subProcess",
44
+ "bpmn:task",
45
+ "bpmn:transaction",
46
+ "bpmn:userTask",
47
+ ],
48
+ "zeebe:formDefinition": ["bpmn:startEvent", "bpmn:userTask"],
49
+ "zeebe:input": [
50
+ "bpmn:adHocSubProcess",
51
+ "bpmn:businessRuleTask",
52
+ "bpmn:callActivity",
53
+ "bpmn:endEvent",
54
+ "bpmn:intermediateThrowEvent",
55
+ "bpmn:scriptTask",
56
+ "bpmn:sendTask",
57
+ "bpmn:serviceTask",
58
+ "bpmn:subProcess",
59
+ "bpmn:transaction",
60
+ "bpmn:userTask",
61
+ ],
62
+ "zeebe:ioMapping": [
63
+ "bpmn:adHocSubProcess",
64
+ "bpmn:boundaryEvent",
65
+ "bpmn:businessRuleTask",
66
+ "bpmn:callActivity",
67
+ "bpmn:endEvent",
68
+ "bpmn:implicitThrowEvent",
69
+ "bpmn:intermediateCatchEvent",
70
+ "bpmn:intermediateThrowEvent",
71
+ "bpmn:receiveTask",
72
+ "bpmn:scriptTask",
73
+ "bpmn:sendTask",
74
+ "bpmn:serviceTask",
75
+ "bpmn:startEvent",
76
+ "bpmn:subProcess",
77
+ "bpmn:transaction",
78
+ "bpmn:userTask",
79
+ ],
80
+ "zeebe:jobPriorityDefinition": [
81
+ "bpmn:adHocSubProcess",
82
+ "bpmn:businessRuleTask",
83
+ "bpmn:endEvent",
84
+ "bpmn:intermediateThrowEvent",
85
+ "bpmn:process",
86
+ "bpmn:scriptTask",
87
+ "bpmn:sendTask",
88
+ "bpmn:serviceTask",
89
+ ],
90
+ "zeebe:linkedResource": ["bpmn:serviceTask"],
91
+ "zeebe:linkedResources": ["bpmn:serviceTask"],
92
+ "zeebe:loopCharacteristics": ["bpmn:multiInstanceLoopCharacteristics"],
93
+ "zeebe:output": [
94
+ "bpmn:adHocSubProcess",
95
+ "bpmn:boundaryEvent",
96
+ "bpmn:businessRuleTask",
97
+ "bpmn:callActivity",
98
+ "bpmn:endEvent",
99
+ "bpmn:implicitThrowEvent",
100
+ "bpmn:intermediateCatchEvent",
101
+ "bpmn:intermediateThrowEvent",
102
+ "bpmn:receiveTask",
103
+ "bpmn:scriptTask",
104
+ "bpmn:sendTask",
105
+ "bpmn:serviceTask",
106
+ "bpmn:startEvent",
107
+ "bpmn:subProcess",
108
+ "bpmn:transaction",
109
+ "bpmn:userTask",
110
+ ],
111
+ "zeebe:priorityDefinition": ["bpmn:userTask"],
112
+ "zeebe:script": ["bpmn:scriptTask"],
113
+ "zeebe:taskDefinition": [
114
+ "bpmn:adHocSubProcess",
115
+ "bpmn:businessRuleTask",
116
+ "bpmn:endEvent",
117
+ "bpmn:intermediateThrowEvent",
118
+ "bpmn:scriptTask",
119
+ "bpmn:sendTask",
120
+ "bpmn:serviceTask",
121
+ ],
122
+ "zeebe:taskHeaders": [
123
+ "bpmn:adHocSubProcess",
124
+ "bpmn:businessRuleTask",
125
+ "bpmn:endEvent",
126
+ "bpmn:intermediateThrowEvent",
127
+ "bpmn:scriptTask",
128
+ "bpmn:sendTask",
129
+ "bpmn:serviceTask",
130
+ "bpmn:userTask",
131
+ "zeebe:executionListener",
132
+ ],
133
+ "zeebe:taskListener": ["zeebe:taskListeners"],
134
+ "zeebe:taskListeners": ["bpmn:userTask"],
135
+ "zeebe:taskSchedule": ["bpmn:userTask"],
136
+ "zeebe:userTask": ["bpmn:userTask"],
137
+ "zeebe:userTaskForm": ["bpmn:process"],
138
+ "zeebe:versionTag": ["bpmn:process"],
139
+ };
140
+ //# sourceMappingURL=zeebe-placement.js.map
package/dist/errors.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { SemanticDiff } from "./bpmn/semantic-hash.js";
1
2
  /**
2
3
  * Typed error codes for all errors thrown by `@bpmnkit/core`.
3
4
  *
@@ -18,7 +19,11 @@ export type ErrorCode =
18
19
  /** XML could not be parsed or a required attribute was missing. */
19
20
  "parse-error"
20
21
  /** A builder received an invalid combination of options. */
21
- | "validation-error";
22
+ | "validation-error"
23
+ /** Serialising a model and reading it back did not reproduce the model. */
24
+ | "write-verification-error"
25
+ /** The output file could not be written. */
26
+ | "write-error";
22
27
  /**
23
28
  * Base class for all errors thrown by `@bpmnkit/core`.
24
29
  *
@@ -74,4 +79,38 @@ export declare class ParseError extends BpmnSdkError {
74
79
  export declare class ValidationError extends BpmnSdkError {
75
80
  constructor(message: string);
76
81
  }
82
+ /**
83
+ * Thrown when serialising a model and parsing the result back does not
84
+ * reproduce the model.
85
+ *
86
+ * This means the write would have put something on disk that no longer says
87
+ * what the model said, so nothing is written. {@link changes} names the
88
+ * elements that diverged.
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * import { writeBpmn } from "@bpmnkit/core/node"
93
+ * import { WriteVerificationError } from "@bpmnkit/core"
94
+ *
95
+ * try {
96
+ * await writeBpmn(definitions, { output: "flow.bpmn" })
97
+ * } catch (err) {
98
+ * if (err instanceof WriteVerificationError) {
99
+ * console.error("would have lost:", err.changes.removed)
100
+ * }
101
+ * }
102
+ * ```
103
+ */
104
+ export declare class WriteVerificationError extends BpmnSdkError {
105
+ /** What differed between the model and the model read back from the output. */
106
+ readonly changes: SemanticDiff;
107
+ constructor(message: string, changes: SemanticDiff);
108
+ }
109
+ /**
110
+ * Thrown when the output file cannot be written — it already exists and
111
+ * `force` was not given, or the filesystem refused the write.
112
+ */
113
+ export declare class WriteError extends BpmnSdkError {
114
+ constructor(message: string);
115
+ }
77
116
  //# sourceMappingURL=errors.d.ts.map
package/dist/errors.js CHANGED
@@ -63,4 +63,45 @@ export class ValidationError extends BpmnSdkError {
63
63
  this.name = "ValidationError";
64
64
  }
65
65
  }
66
+ /**
67
+ * Thrown when serialising a model and parsing the result back does not
68
+ * reproduce the model.
69
+ *
70
+ * This means the write would have put something on disk that no longer says
71
+ * what the model said, so nothing is written. {@link changes} names the
72
+ * elements that diverged.
73
+ *
74
+ * @example
75
+ * ```typescript
76
+ * import { writeBpmn } from "@bpmnkit/core/node"
77
+ * import { WriteVerificationError } from "@bpmnkit/core"
78
+ *
79
+ * try {
80
+ * await writeBpmn(definitions, { output: "flow.bpmn" })
81
+ * } catch (err) {
82
+ * if (err instanceof WriteVerificationError) {
83
+ * console.error("would have lost:", err.changes.removed)
84
+ * }
85
+ * }
86
+ * ```
87
+ */
88
+ export class WriteVerificationError extends BpmnSdkError {
89
+ /** What differed between the model and the model read back from the output. */
90
+ changes;
91
+ constructor(message, changes) {
92
+ super(message, "write-verification-error");
93
+ this.name = "WriteVerificationError";
94
+ this.changes = changes;
95
+ }
96
+ }
97
+ /**
98
+ * Thrown when the output file cannot be written — it already exists and
99
+ * `force` was not given, or the filesystem refused the write.
100
+ */
101
+ export class WriteError extends BpmnSdkError {
102
+ constructor(message) {
103
+ super(message, "write-error");
104
+ this.name = "WriteError";
105
+ }
106
+ }
66
107
  //# sourceMappingURL=errors.js.map
package/dist/index.d.ts CHANGED
@@ -1,18 +1,22 @@
1
- export { BpmnSdkError, ParseError, ValidationError } from "./errors.js";
1
+ export { BpmnSdkError, ParseError, ValidationError, WriteError, WriteVerificationError, } from "./errors.js";
2
2
  export type { ErrorCode } from "./errors.js";
3
3
  export { isBpmnActivity, isBpmnAdHocSubProcess, isBpmnBoundaryEvent, isBpmnBusinessRuleTask, isBpmnCallActivity, isBpmnComplexGateway, isBpmnDataObject, isBpmnDataObjectReference, isBpmnDataStoreReference, isBpmnEndEvent, isBpmnEvent, isBpmnEventBasedGateway, isBpmnEventSubProcess, isBpmnExclusiveGateway, isBpmnGateway, isBpmnInclusiveGateway, isBpmnIntermediateCatchEvent, isBpmnIntermediateThrowEvent, isBpmnManualTask, isBpmnParallelGateway, isBpmnReceiveTask, isBpmnScriptTask, isBpmnSendTask, isBpmnServiceTask, isBpmnStartEvent, isBpmnSubProcess, isBpmnTask, isBpmnTransaction, isBpmnUserTask, } from "./bpmn/type-guards.js";
4
4
  export { findElement, findElementInProcess, findProcess, findSequenceFlow, getAllElements, getElementType, getZeebeExtensions, } from "./bpmn/utils.js";
5
5
  export { Bpmn, SAMPLE_BPMN_XML } from "./bpmn/index.js";
6
6
  export { applyAutoLayout } from "./bpmn/auto-layout.js";
7
+ export { diffSemantics, projectSemantics, semanticHash } from "./bpmn/semantic-hash.js";
8
+ export type { JsonValue, SemanticDiff, SemanticProjection } from "./bpmn/semantic-hash.js";
9
+ export { sha256Hex } from "./bpmn/sha256.js";
7
10
  export { checkDiCompleteness } from "./bpmn/di-check.js";
8
11
  export type { DiCompleteness } from "./bpmn/di-check.js";
9
12
  export { planeForElement, listPlaneElementIds } from "./bpmn/di-planes.js";
10
- export { DiagramBuilder } from "./bpmn/bpmn-builder.js";
11
- export type { ProcessBuilder, BranchBuilder, SubProcessContentBuilder, ServiceTaskOptions, ScriptTaskOptions, UserTaskOptions, CallActivityOptions, BusinessRuleTaskOptions, ElementOptions, GatewayOptions, MultiInstanceOptions, SubProcessOptions, StartEventOptions, IntermediateCatchEventOptions, IntermediateThrowEventOptions, EndEventOptions, BoundaryEventOptions, AdHocSubProcessOptions, } from "./bpmn/bpmn-builder.js";
13
+ export { DiagramBuilder, ProcessBuilder } from "./bpmn/bpmn-builder.js";
14
+ export type { BranchBuilder, BuildOptions, MessageFlowOptions, ParticipantOptions, DiagramMessageOptions, SubProcessContentBuilder, ServiceTaskOptions, ScriptTaskOptions, UserTaskOptions, CallActivityOptions, BusinessRuleTaskOptions, ElementOptions, GatewayOptions, MultiInstanceOptions, SubProcessOptions, StartEventOptions, IntermediateCatchEventOptions, IntermediateThrowEventOptions, EndEventOptions, BoundaryEventOptions, AdHocSubProcessOptions, } from "./bpmn/bpmn-builder.js";
12
15
  export type { BpmnDefinitions, BpmnProcess, BpmnFlowNode, BpmnFlowElement, BpmnSequenceFlow, BpmnBoundaryEvent, BpmnElementType, BpmnStartEvent, BpmnEndEvent, BpmnIntermediateCatchEvent, BpmnIntermediateThrowEvent, BpmnTask, BpmnServiceTask, BpmnScriptTask, BpmnUserTask, BpmnSendTask, BpmnReceiveTask, BpmnBusinessRuleTask, BpmnManualTask, BpmnCallActivity, BpmnSubProcess, BpmnAdHocSubProcess, BpmnEventSubProcess, BpmnTransaction, BpmnExclusiveGateway, BpmnParallelGateway, BpmnInclusiveGateway, BpmnEventBasedGateway, BpmnComplexGateway, BpmnCollaboration, BpmnParticipant, BpmnMessageFlow, BpmnLane, BpmnLaneSet, BpmnError, BpmnEscalation, BpmnMessage, BpmnSignal, BpmnTextAnnotation, BpmnAssociation, BpmnGroup, BpmnDataObject, BpmnDataObjectReference, BpmnDataStoreReference, BpmnConditionExpression, BpmnEventDefinition, BpmnTimerEventDefinition, BpmnErrorEventDefinition, BpmnEscalationEventDefinition, BpmnMessageEventDefinition, BpmnSignalEventDefinition, BpmnConditionalEventDefinition, BpmnLinkEventDefinition, BpmnCancelEventDefinition, BpmnTerminateEventDefinition, BpmnCompensateEventDefinition, BpmnMultiInstanceLoopCharacteristics, BpmnDiagram, BpmnDiPlane, BpmnDiShape, BpmnDiEdge, BpmnDiLabel, BpmnBounds, BpmnWaypoint, } from "./bpmn/bpmn-model.js";
13
16
  export type { RestConnectorConfig, RestAuthentication, HttpMethod, } from "./bpmn/rest-connector.js";
14
17
  export type { ZeebeExtensions, ZeebeTaskDefinition, ZeebeIoMapping, ZeebeIoMappingEntry, ZeebeTaskHeaders, ZeebeTaskHeaderEntry, ZeebeProperties, ZeebePropertyEntry, ZeebeFormDefinition, ZeebeCalledDecision, ZeebeAssignmentDefinition, ZeebeTaskSchedule, ZeebePriorityDefinition, ZeebeSubscription, } from "./bpmn/zeebe-extensions.js";
15
- export { zeebeExtensionsToXmlElements } from "./bpmn/zeebe-extensions.js";
18
+ export { assertZeebePlacement, bpmnElementName, ensureZeebeExtension, isZeebePlacementAllowed, ZeebePlacementError, zeebeExtensionsToXmlElements, } from "./bpmn/zeebe-extensions.js";
19
+ export { ZEEBE_PLACEMENT } from "./bpmn/zeebe-placement.js";
16
20
  export { buildAiAgentSubProcess, AI_AGENT_JOB_WORKER_TASK_TYPE, AI_AGENT_DEFAULT_OUTPUT_ELEMENT, } from "./bpmn/agentic.js";
17
21
  export type { AiAgentOptions, AiAgentModelConfig, AiAgentToolSpec, AiAgentToolParam, AiAgentToolParamType, AiAgentBuild, } from "./bpmn/agentic.js";
18
22
  export { Dmn, layoutDmn, benchmarkDmnLayout, compactifyDmn, expandDmn } from "./dmn/index.js";
@@ -43,6 +47,8 @@ export { ELEMENT_SIZES, GRID_CELL_HEIGHT, GRID_CELL_WIDTH } from "./layout/index
43
47
  export { compactify, expand } from "./bpmn/compact.js";
44
48
  export { applyOperations } from "./bpmn/operations.js";
45
49
  export type { BpmnOperation } from "./bpmn/operations.js";
50
+ export { applyBpmnOperations, reconcileCompact, OperationError } from "./bpmn/full-operations.js";
51
+ export type { ApplyBpmnOperationsOptions, ApplyBpmnOperationsResult, OperationProblem, } from "./bpmn/full-operations.js";
46
52
  export { buildValidationDmn, findValidationStructure, getValidationInputNames, insertValidationStructure, removeValidationStructure, validationDecisionId, } from "./bpmn/input-validation.js";
47
53
  export type { InputVariableDef, ValidationStructure, ValidationVariableType, } from "./bpmn/input-validation.js";
48
54
  export { exportSvg } from "./bpmn/svg.js";
package/dist/index.js CHANGED
@@ -1,12 +1,15 @@
1
- export { BpmnSdkError, ParseError, ValidationError } from "./errors.js";
1
+ export { BpmnSdkError, ParseError, ValidationError, WriteError, WriteVerificationError, } from "./errors.js";
2
2
  export { isBpmnActivity, isBpmnAdHocSubProcess, isBpmnBoundaryEvent, isBpmnBusinessRuleTask, isBpmnCallActivity, isBpmnComplexGateway, isBpmnDataObject, isBpmnDataObjectReference, isBpmnDataStoreReference, isBpmnEndEvent, isBpmnEvent, isBpmnEventBasedGateway, isBpmnEventSubProcess, isBpmnExclusiveGateway, isBpmnGateway, isBpmnInclusiveGateway, isBpmnIntermediateCatchEvent, isBpmnIntermediateThrowEvent, isBpmnManualTask, isBpmnParallelGateway, isBpmnReceiveTask, isBpmnScriptTask, isBpmnSendTask, isBpmnServiceTask, isBpmnStartEvent, isBpmnSubProcess, isBpmnTask, isBpmnTransaction, isBpmnUserTask, } from "./bpmn/type-guards.js";
3
3
  export { findElement, findElementInProcess, findProcess, findSequenceFlow, getAllElements, getElementType, getZeebeExtensions, } from "./bpmn/utils.js";
4
4
  export { Bpmn, SAMPLE_BPMN_XML } from "./bpmn/index.js";
5
5
  export { applyAutoLayout } from "./bpmn/auto-layout.js";
6
+ export { diffSemantics, projectSemantics, semanticHash } from "./bpmn/semantic-hash.js";
7
+ export { sha256Hex } from "./bpmn/sha256.js";
6
8
  export { checkDiCompleteness } from "./bpmn/di-check.js";
7
9
  export { planeForElement, listPlaneElementIds } from "./bpmn/di-planes.js";
8
- export { DiagramBuilder } from "./bpmn/bpmn-builder.js";
9
- export { zeebeExtensionsToXmlElements } from "./bpmn/zeebe-extensions.js";
10
+ export { DiagramBuilder, ProcessBuilder } from "./bpmn/bpmn-builder.js";
11
+ export { assertZeebePlacement, bpmnElementName, ensureZeebeExtension, isZeebePlacementAllowed, ZeebePlacementError, zeebeExtensionsToXmlElements, } from "./bpmn/zeebe-extensions.js";
12
+ export { ZEEBE_PLACEMENT } from "./bpmn/zeebe-placement.js";
10
13
  export { buildAiAgentSubProcess, AI_AGENT_JOB_WORKER_TASK_TYPE, AI_AGENT_DEFAULT_OUTPUT_ELEMENT, } from "./bpmn/agentic.js";
11
14
  export { Dmn, layoutDmn, benchmarkDmnLayout, compactifyDmn, expandDmn } from "./dmn/index.js";
12
15
  export { Form, compactifyForm, expandForm } from "./form/index.js";
@@ -22,6 +25,7 @@ export { benchmarkLayout, compareLayouts, formatBenchmarkResult, generateAutoLay
22
25
  export { ELEMENT_SIZES, GRID_CELL_HEIGHT, GRID_CELL_WIDTH } from "./layout/index.js";
23
26
  export { compactify, expand } from "./bpmn/compact.js";
24
27
  export { applyOperations } from "./bpmn/operations.js";
28
+ export { applyBpmnOperations, reconcileCompact, OperationError } from "./bpmn/full-operations.js";
25
29
  export { buildValidationDmn, findValidationStructure, getValidationInputNames, insertValidationStructure, removeValidationStructure, validationDecisionId, } from "./bpmn/input-validation.js";
26
30
  export { exportSvg } from "./bpmn/svg.js";
27
31
  export { compilePlan, extractPlan, mergePlan, slugify, uniqueId, } from "./plan/index.js";
@@ -22,8 +22,16 @@ export interface SemanticGraph {
22
22
  starts: string[];
23
23
  /** Longest-path rank per node id. */
24
24
  ranks: Map<string, number>;
25
+ /** Lazily built: ids from which an end (or terminal) node is reachable. See {@link reachesEnd}. */
26
+ endReach?: Set<string>;
25
27
  }
26
28
  export declare function buildSemanticGraph(flowElements: BpmnFlowElement[], sequenceFlows: BpmnSequenceFlow[]): SemanticGraph;
27
- /** True when an end event is reachable from `id` without traversing a back edge. */
29
+ /**
30
+ * True when an end event is reachable from `id` without traversing a back edge.
31
+ * A node other than `id` itself that has no outgoing flow also ends the path.
32
+ *
33
+ * The reverse reachability set is computed once per graph, so repeated calls
34
+ * from the spine tracer stay O(1) instead of re-walking the graph each time.
35
+ */
28
36
  export declare function reachesEnd(graph: SemanticGraph, id: string): boolean;
29
37
  //# sourceMappingURL=graph.d.ts.map
@@ -192,26 +192,51 @@ function assignRanks(graph) {
192
192
  ranks.set(id, (ranks.get(id) ?? 0) - min);
193
193
  }
194
194
  }
195
- /** True when an end event is reachable from `id` without traversing a back edge. */
195
+ /**
196
+ * True when an end event is reachable from `id` without traversing a back edge.
197
+ * A node other than `id` itself that has no outgoing flow also ends the path.
198
+ *
199
+ * The reverse reachability set is computed once per graph, so repeated calls
200
+ * from the spine tracer stay O(1) instead of re-walking the graph each time.
201
+ */
196
202
  export function reachesEnd(graph, id) {
197
- const seen = new Set();
198
- const stack = [id];
199
- while (stack.length > 0) {
200
- const current = stack.pop();
201
- if (current === undefined || seen.has(current))
202
- continue;
203
- seen.add(current);
204
- const node = graph.byId.get(current);
205
- if (node && END_TYPES.has(node.type))
203
+ const node = graph.byId.get(id);
204
+ if (node && END_TYPES.has(node.type))
205
+ return true;
206
+ const endReach = graph.endReach ?? buildEndReach(graph);
207
+ for (const flow of graph.outgoing.get(id) ?? []) {
208
+ if (!graph.backEdges.has(flow.id) && endReach.has(flow.targetRef))
206
209
  return true;
207
- const out = graph.outgoing.get(current) ?? [];
208
- if (out.length === 0 && seen.size > 1)
209
- return true; // a terminal node ends the path
210
- for (const flow of out) {
211
- if (!graph.backEdges.has(flow.id))
212
- stack.push(flow.targetRef);
213
- }
214
210
  }
215
211
  return false;
216
212
  }
213
+ /**
214
+ * Every node from which a path along non-back edges reaches an end event or a
215
+ * node with no outgoing flow (both inclusive), found by one reverse walk.
216
+ */
217
+ function buildEndReach(graph) {
218
+ const reach = new Set();
219
+ const stack = [];
220
+ for (const node of graph.byId.values()) {
221
+ const out = graph.outgoing.get(node.id);
222
+ if (END_TYPES.has(node.type) || out === undefined || out.length === 0) {
223
+ reach.add(node.id);
224
+ stack.push(node.id);
225
+ }
226
+ }
227
+ while (stack.length > 0) {
228
+ const id = stack.pop();
229
+ for (const flow of graph.incoming.get(id) ?? []) {
230
+ if (graph.backEdges.has(flow.id))
231
+ continue;
232
+ const from = effectiveSource(flow, graph.byId);
233
+ if (!reach.has(from)) {
234
+ reach.add(from);
235
+ stack.push(from);
236
+ }
237
+ }
238
+ }
239
+ graph.endReach = reach;
240
+ return reach;
241
+ }
217
242
  //# sourceMappingURL=graph.js.map