@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.
- package/README.md +30 -1
- package/dist/bpmn/bpmn-builder.d.ts +209 -3
- package/dist/bpmn/bpmn-builder.js +456 -16
- package/dist/bpmn/bpmn-model.d.ts +110 -0
- package/dist/bpmn/bpmn-parser.js +1413 -528
- package/dist/bpmn/bpmn-serializer.js +101 -19
- package/dist/bpmn/compact.d.ts +17 -2
- package/dist/bpmn/compact.js +3 -3
- package/dist/bpmn/full-operations.d.ts +89 -0
- package/dist/bpmn/full-operations.js +478 -0
- package/dist/bpmn/index.d.ts +19 -0
- package/dist/bpmn/index.js +21 -0
- package/dist/bpmn/optimize/feel.js +2 -2
- package/dist/bpmn/optimize/patterns.js +23 -16
- package/dist/bpmn/optimize/tasks.js +30 -7
- package/dist/bpmn/optimize/utils.js +2 -4
- package/dist/bpmn/optimize/variable-flow.js +58 -67
- package/dist/bpmn/semantic-hash.d.ts +93 -0
- package/dist/bpmn/semantic-hash.js +155 -0
- package/dist/bpmn/sha256.d.ts +17 -0
- package/dist/bpmn/sha256.js +95 -0
- package/dist/bpmn/zeebe-extensions.d.ts +56 -0
- package/dist/bpmn/zeebe-extensions.js +79 -0
- package/dist/bpmn/zeebe-placement.d.ts +12 -0
- package/dist/bpmn/zeebe-placement.js +140 -0
- package/dist/errors.d.ts +40 -1
- package/dist/errors.js +41 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +7 -3
- package/dist/layout/semantic/graph.d.ts +9 -1
- package/dist/layout/semantic/graph.js +42 -17
- package/dist/layout/semantic/route.js +102 -42
- package/dist/node/index.d.ts +10 -0
- package/dist/node/index.js +9 -0
- package/dist/node/write.d.ts +81 -0
- package/dist/node/write.js +167 -0
- package/dist/types/id-generator.js +11 -3
- package/dist/xml/index.d.ts +3 -1
- package/dist/xml/index.js +2 -1
- package/dist/xml/xml-parser.d.ts +32 -0
- package/dist/xml/xml-parser.js +394 -143
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://github.com/bpmnkit/monorepo)
|
|
10
10
|
[](https://github.com/bpmnkit/monorepo)
|
|
11
11
|
|
|
12
|
-
[Website](https://bpmnkit.com) · [Documentation](https://
|
|
12
|
+
[Website](https://bpmnkit.com) · [Documentation](https://bpmnkit.com/docs) · [GitHub](https://github.com/bpmnkit/monorepo) · [Changelog](https://github.com/bpmnkit/monorepo/blob/main/packages/core/CHANGELOG.md)
|
|
13
13
|
</div>
|
|
14
14
|
|
|
15
15
|
---
|
|
@@ -139,6 +139,35 @@ const outXml = Bpmn.export(restored)
|
|
|
139
139
|
| `Bpmn.makeEmpty(processId?, name?)` | Minimal BPMN XML with one start event |
|
|
140
140
|
| `Bpmn.SAMPLE_XML` | 3-node sample diagram string |
|
|
141
141
|
|
|
142
|
+
### Semantics
|
|
143
|
+
|
|
144
|
+
| Export | Description |
|
|
145
|
+
|--------|-------------|
|
|
146
|
+
| `semanticHash(defs)` | SHA-256 of the model, excluding the diagram. Unchanged by layout |
|
|
147
|
+
| `projectSemantics(defs)` | The canonical, presentation-free projection the hash covers |
|
|
148
|
+
| `diffSemantics(a, b)` | What changed between two models, keyed by element id |
|
|
149
|
+
|
|
150
|
+
### Editing
|
|
151
|
+
|
|
152
|
+
| Export | Description |
|
|
153
|
+
|--------|-------------|
|
|
154
|
+
| `applyBpmnOperations(defs, ops)` | Apply edit operations to the full model. Strict: unresolved ids throw |
|
|
155
|
+
| `reconcileCompact(defs, compact)` | Apply a compact diagram as changes, keeping what compact cannot carry |
|
|
156
|
+
| `compactify(defs)` | Read-only token-efficient view for LLM prompts. Lossy — not an edit path |
|
|
157
|
+
|
|
158
|
+
### Writing files (`@bpmnkit/core/node`)
|
|
159
|
+
|
|
160
|
+
| Export | Description |
|
|
161
|
+
|--------|-------------|
|
|
162
|
+
| `writeBpmn(defs, opts)` | Serialize, read back, verify the model survived, then write atomically |
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { writeBpmn } from "@bpmnkit/core/node"
|
|
166
|
+
|
|
167
|
+
// Refuses rather than overwrite; pass force: true to replace.
|
|
168
|
+
const { semanticHash, changes } = await writeBpmn(defs, { output: "flow.bpmn" })
|
|
169
|
+
```
|
|
170
|
+
|
|
142
171
|
### DMN
|
|
143
172
|
|
|
144
173
|
| Export | Description |
|
|
@@ -149,6 +149,52 @@ export interface GatewayOptions extends ElementOptions {
|
|
|
149
149
|
/** ID of the default sequence flow (set manually; prefer branch().defaultFlow()). */
|
|
150
150
|
defaultFlow?: string;
|
|
151
151
|
}
|
|
152
|
+
/** Options for {@link ProcessBuilder.build}. */
|
|
153
|
+
export interface BuildOptions {
|
|
154
|
+
/**
|
|
155
|
+
* Refuse to infer join gateways, so converging branches must be declared.
|
|
156
|
+
*
|
|
157
|
+
* Generated code should set this: the builder's inference is a help to someone
|
|
158
|
+
* reading the chain they just wrote, and a silent topology change to a model
|
|
159
|
+
* that cannot see what it did not emit.
|
|
160
|
+
*/
|
|
161
|
+
explicitJoins?: boolean;
|
|
162
|
+
/**
|
|
163
|
+
* The former name for {@link BuildOptions.explicitJoins}, still honoured.
|
|
164
|
+
*
|
|
165
|
+
* Renamed because "strict" says nothing about what it is strict *about*, and
|
|
166
|
+
* because `applyBpmnOperations` takes a `strict` that means something else
|
|
167
|
+
* entirely — whether to throw or report problems.
|
|
168
|
+
*
|
|
169
|
+
* @deprecated Use `explicitJoins`.
|
|
170
|
+
*/
|
|
171
|
+
strict?: boolean;
|
|
172
|
+
}
|
|
173
|
+
/** Options for a collaboration participant (a pool). */
|
|
174
|
+
export interface ParticipantOptions {
|
|
175
|
+
/** Pool label. */
|
|
176
|
+
name?: string;
|
|
177
|
+
/** Id of the process this pool executes. Omit for a black box. */
|
|
178
|
+
processId?: string;
|
|
179
|
+
}
|
|
180
|
+
/** Options for a root-level message declared on a diagram. */
|
|
181
|
+
export interface DiagramMessageOptions {
|
|
182
|
+
/** Message name, which is what Camunda 8 publishes against. */
|
|
183
|
+
name?: string;
|
|
184
|
+
/** FEEL expression Camunda 8 correlates published messages on (`zeebe:subscription`). */
|
|
185
|
+
correlationKey?: string;
|
|
186
|
+
}
|
|
187
|
+
/** Options for a message flow between two pools. */
|
|
188
|
+
export interface MessageFlowOptions {
|
|
189
|
+
/** Id of the participant, or of a flow node inside one, the message leaves. */
|
|
190
|
+
source: string;
|
|
191
|
+
/** Id of the participant, or of a flow node inside one, the message reaches. */
|
|
192
|
+
target: string;
|
|
193
|
+
/** Flow label. */
|
|
194
|
+
name?: string;
|
|
195
|
+
/** Id of a message declared with `.message()`. */
|
|
196
|
+
messageRef?: string;
|
|
197
|
+
}
|
|
152
198
|
/** Options for an intermediate catch event. */
|
|
153
199
|
export interface IntermediateCatchEventOptions extends ElementOptions {
|
|
154
200
|
/** Timer duration (ISO 8601) — creates a timer catch event. */
|
|
@@ -288,6 +334,8 @@ export interface AdHocSubProcessOptions extends ElementOptions {
|
|
|
288
334
|
export declare class BranchBuilder {
|
|
289
335
|
/** @internal */
|
|
290
336
|
readonly _elements: BpmnFlowElement[];
|
|
337
|
+
/** Ids in `_elements`, for O(1) duplicate checks. */
|
|
338
|
+
private readonly _ids;
|
|
291
339
|
/** @internal */
|
|
292
340
|
readonly _flows: BpmnSequenceFlow[];
|
|
293
341
|
/** @internal */
|
|
@@ -387,6 +435,8 @@ export declare class BranchBuilder {
|
|
|
387
435
|
export declare class SubProcessContentBuilder {
|
|
388
436
|
/** @internal */
|
|
389
437
|
readonly _elements: BpmnFlowElement[];
|
|
438
|
+
/** Ids in `_elements`, for O(1) duplicate checks. */
|
|
439
|
+
private readonly _ids;
|
|
390
440
|
/** @internal */
|
|
391
441
|
readonly _flows: BpmnSequenceFlow[];
|
|
392
442
|
/** @internal */
|
|
@@ -464,8 +514,12 @@ export declare class ProcessBuilder {
|
|
|
464
514
|
private readonly processId;
|
|
465
515
|
private processName?;
|
|
466
516
|
private _isExecutable;
|
|
517
|
+
/** Whether `executable()` was called, so continue-mode leaves it alone if not. */
|
|
518
|
+
private _executableSet;
|
|
467
519
|
private _versionTag?;
|
|
468
520
|
private readonly flowElements;
|
|
521
|
+
/** Ids in `flowElements`, for O(1) duplicate and existence checks. */
|
|
522
|
+
private readonly elementIds;
|
|
469
523
|
private readonly sequenceFlows;
|
|
470
524
|
private readonly rootErrors;
|
|
471
525
|
private readonly rootMessages;
|
|
@@ -481,7 +535,69 @@ export declare class ProcessBuilder {
|
|
|
481
535
|
private _executionPlatformVersion;
|
|
482
536
|
private _serviceTaskDefaults;
|
|
483
537
|
private _savedMainFlowId;
|
|
538
|
+
/** Set by {@link ProcessBuilder.from}; makes `build()` update rather than generate. */
|
|
539
|
+
private _source?;
|
|
540
|
+
/** Pre-existing flow endpoints, so `build()` can prove it did not rewire them. */
|
|
541
|
+
private _sourceFlowTargets;
|
|
542
|
+
/** An `insertAfter` flow waiting to be reattached to what gets built next. */
|
|
543
|
+
private _pendingSpliceFlowId;
|
|
544
|
+
/** Flows the caller deliberately spliced, exempt from the rewiring guard. */
|
|
545
|
+
private readonly _splicedFlowIds;
|
|
484
546
|
constructor(processId: string);
|
|
547
|
+
/**
|
|
548
|
+
* Continues an existing model rather than generating a new one.
|
|
549
|
+
*
|
|
550
|
+
* `build()` then returns *that document* with this process's contents
|
|
551
|
+
* replaced, so everything the builder has no opinion about — other processes,
|
|
552
|
+
* the collaboration, lanes, diagram interchange, root elements, imports,
|
|
553
|
+
* unmodelled content — is still there afterwards. Generating a replacement
|
|
554
|
+
* from scratch is what loses those.
|
|
555
|
+
*
|
|
556
|
+
* The input is not mutated; the builder works on a copy.
|
|
557
|
+
*
|
|
558
|
+
* @param definitions - The parsed model to continue.
|
|
559
|
+
* @param processId - Which process to continue. Named explicitly, because
|
|
560
|
+
* "the first process" is a guess that goes wrong on a collaboration.
|
|
561
|
+
* @example
|
|
562
|
+
* ```typescript
|
|
563
|
+
* const updated = ProcessBuilder.from(Bpmn.parse(xml), "order")
|
|
564
|
+
* .at("validate")
|
|
565
|
+
* .serviceTask("notify", { name: "Notify", taskType: "notify" })
|
|
566
|
+
* .build()
|
|
567
|
+
* ```
|
|
568
|
+
*/
|
|
569
|
+
static from(definitions: BpmnDefinitions, processId: string): ProcessBuilder;
|
|
570
|
+
/**
|
|
571
|
+
* Moves the cursor to an existing flow node, so the next call chains from it.
|
|
572
|
+
*
|
|
573
|
+
* @param nodeId - A flow node directly contained by this process. Nodes inside
|
|
574
|
+
* a sub-process are not reachable: continuing into one means building that
|
|
575
|
+
* sub-process, not this one.
|
|
576
|
+
*/
|
|
577
|
+
at(nodeId: string): this;
|
|
578
|
+
/**
|
|
579
|
+
* Splices what you build next into the path leaving an existing node.
|
|
580
|
+
*
|
|
581
|
+
* `insertAfter("validate")` followed by `.serviceTask("notify", …)` turns
|
|
582
|
+
* `validate → end` into `validate → notify → end`. The existing flow keeps its
|
|
583
|
+
* id and its target and only changes where it starts, so an edge nobody asked
|
|
584
|
+
* to move keeps its identity in the diagram and in a diff.
|
|
585
|
+
*
|
|
586
|
+
* This is the counterpart to {@link at}, which continues from a node whose
|
|
587
|
+
* path is open. Which one you mean is not guessable, so it is not guessed.
|
|
588
|
+
*
|
|
589
|
+
* @param nodeId - A flow node with exactly one outgoing sequence flow.
|
|
590
|
+
*/
|
|
591
|
+
insertAfter(nodeId: string): this;
|
|
592
|
+
/** Points the cursor at an existing node and forgets any branch state. */
|
|
593
|
+
private moveCursor;
|
|
594
|
+
/**
|
|
595
|
+
* Reattaches the flow a pending `insertAfter` detached, to whatever the cursor
|
|
596
|
+
* has reached. With nothing built in between the cursor has not moved and this
|
|
597
|
+
* is a no-op, which is the right answer for `insertAfter(x)` followed by
|
|
598
|
+
* nothing.
|
|
599
|
+
*/
|
|
600
|
+
private resolvePendingSplice;
|
|
485
601
|
/** Enable auto-layout: `build()` will run the layout engine and populate diagram interchange data. */
|
|
486
602
|
withAutoLayout(): this;
|
|
487
603
|
/** Set the Camunda execution platform version stamped into the BPMN definitions. Defaults to `"8.9.0"`. */
|
|
@@ -604,10 +720,50 @@ export declare class ProcessBuilder {
|
|
|
604
720
|
*
|
|
605
721
|
* Resolves all forward-referenced `incoming` / `outgoing` arrays and wraps
|
|
606
722
|
* the process in a {@link BpmnDefinitions} ready for XML serialization.
|
|
723
|
+
*
|
|
724
|
+
* **The join contract.** Branches built with `.branch()` converge implicitly:
|
|
725
|
+
* where several paths from one gateway reach the same element, a matching join
|
|
726
|
+
* gateway is inserted for you. That is convenient by hand and a trap for
|
|
727
|
+
* generated code, which cannot see the element it did not write. Pass
|
|
728
|
+
* `{ explicitJoins: true }` to be told instead of helped — the build throws,
|
|
729
|
+
* naming the gateways it would have inserted, and you declare them yourself
|
|
730
|
+
* with `.connectTo(joinId)`.
|
|
731
|
+
*
|
|
732
|
+
* A join you declare only counts if it *matches the split*: an exclusive split
|
|
733
|
+
* converging on a parallel gateway is not the gateway inference would have
|
|
734
|
+
* added, so it is still inferred — and with `explicitJoins` that refusal is the
|
|
735
|
+
* only thing that tells you.
|
|
736
|
+
*
|
|
737
|
+
* {@link ProcessBuilder.from} never infers joins at all, whatever this option
|
|
738
|
+
* says: inference reads the whole topology, and on a document you were handed
|
|
739
|
+
* that means rewriting edges you never touched.
|
|
740
|
+
*
|
|
741
|
+
* @param options - `explicitJoins` refuses inferred join gateways. `strict` is
|
|
742
|
+
* the former name for it and still works.
|
|
607
743
|
*/
|
|
608
|
-
build(options?:
|
|
609
|
-
|
|
610
|
-
|
|
744
|
+
build(options?: BuildOptions): BpmnDefinitions;
|
|
745
|
+
/**
|
|
746
|
+
* Writes this process's contents back into the document it came from.
|
|
747
|
+
*
|
|
748
|
+
* Everything not listed here is kept by identity — other processes, the
|
|
749
|
+
* collaboration, diagram interchange, root elements, the process's own lanes,
|
|
750
|
+
* documentation, extensions and unmodelled content. That is the whole point of
|
|
751
|
+
* continuing rather than regenerating.
|
|
752
|
+
*
|
|
753
|
+
* Diagram interchange is *not* regenerated: existing shapes keep their
|
|
754
|
+
* positions, and elements added here have none until `withAutoLayout()` or a
|
|
755
|
+
* later `applyAutoLayout()` gives them one.
|
|
756
|
+
*/
|
|
757
|
+
private buildOntoSource;
|
|
758
|
+
/**
|
|
759
|
+
* Refuses to rewire a flow that was already in the document.
|
|
760
|
+
*
|
|
761
|
+
* `insertJoinGateways` retargets converging flows, which is right for a
|
|
762
|
+
* topology this builder just created and wrong for one it was handed: a
|
|
763
|
+
* document would come back with edges the caller never touched pointing
|
|
764
|
+
* somewhere else. Continuing a model has to leave the model alone.
|
|
765
|
+
*/
|
|
766
|
+
private assertSourceTopologyIntact;
|
|
611
767
|
private validate;
|
|
612
768
|
private addFlowElement;
|
|
613
769
|
}
|
|
@@ -620,11 +776,61 @@ export declare class DiagramBuilder {
|
|
|
620
776
|
private readonly _processes;
|
|
621
777
|
private readonly _errors;
|
|
622
778
|
private readonly _messages;
|
|
779
|
+
private readonly _participants;
|
|
780
|
+
private readonly _messageFlows;
|
|
781
|
+
private _collaborationId;
|
|
623
782
|
private _executionPlatformVersion;
|
|
624
783
|
constructor(id: string);
|
|
625
784
|
/** Set the Camunda execution platform version stamped into the BPMN definitions. Defaults to `"8.9.0"`. */
|
|
626
785
|
executionPlatformVersion(version: string): this;
|
|
627
786
|
process(id: string, callback: (b: ProcessBuilder) => void): this;
|
|
787
|
+
/** Renames the collaboration element. Defaults to `"Collaboration_1"`. */
|
|
788
|
+
collaborationId(id: string): this;
|
|
789
|
+
/**
|
|
790
|
+
* Adds a pool.
|
|
791
|
+
*
|
|
792
|
+
* Omit `processId` for a black box — a participant whose internals are not
|
|
793
|
+
* modelled. That is a real BPMN construct, not an incomplete one: it is how
|
|
794
|
+
* you draw the counterparty you exchange messages with but do not execute.
|
|
795
|
+
*
|
|
796
|
+
* @param id - The participant's element id, used verbatim.
|
|
797
|
+
*/
|
|
798
|
+
participant(id: string, options?: ParticipantOptions): this;
|
|
799
|
+
/**
|
|
800
|
+
* Declares a root-level message, which a message flow may name and a Camunda 8
|
|
801
|
+
* message subscription correlates on.
|
|
802
|
+
*
|
|
803
|
+
* `ProcessBuilder` already creates messages by name for message events, so
|
|
804
|
+
* only call this for a message no event declared — typically one carried by a
|
|
805
|
+
* message flow between pools.
|
|
806
|
+
*
|
|
807
|
+
* @param id - The message's element id, used verbatim.
|
|
808
|
+
*/
|
|
809
|
+
message(id: string, options?: DiagramMessageOptions): this;
|
|
810
|
+
/**
|
|
811
|
+
* Connects two pools.
|
|
812
|
+
*
|
|
813
|
+
* `source` and `target` name either participants or flow nodes inside them.
|
|
814
|
+
* Both forms are valid BPMN and the layout engine reads either, but they must
|
|
815
|
+
* be in *different* pools — a message flow is what crosses a pool boundary,
|
|
816
|
+
* and one that does not is the error this catches.
|
|
817
|
+
*
|
|
818
|
+
* @param id - The message flow's element id, used verbatim.
|
|
819
|
+
*/
|
|
820
|
+
messageFlow(id: string, options: MessageFlowOptions): this;
|
|
821
|
+
/**
|
|
822
|
+
* Reports every way the declared collaboration would not survive contact with
|
|
823
|
+
* a modeler, so `build()` can refuse rather than emit a file that opens broken.
|
|
824
|
+
*/
|
|
825
|
+
private collaborationProblems;
|
|
826
|
+
/** Maps every participant id and every flow node id to its owning participant. */
|
|
827
|
+
private participantIndex;
|
|
628
828
|
build(): BpmnDefinitions;
|
|
829
|
+
/**
|
|
830
|
+
* A document with no participants has no collaboration — an empty
|
|
831
|
+
* `<bpmn:collaboration/>` is not a neutral addition, it makes every process a
|
|
832
|
+
* pool-less participant in a modeler.
|
|
833
|
+
*/
|
|
834
|
+
private buildCollaborations;
|
|
629
835
|
}
|
|
630
836
|
//# sourceMappingURL=bpmn-builder.d.ts.map
|