@bpmnkit/plugins 0.0.11 → 0.0.13

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.
@@ -53,22 +53,63 @@ export function createTokenHighlightPlugin() {
53
53
  }
54
54
  }
55
55
  // Edge highlights
56
- // active edge : source visited, target active (token just left source, entering target)
57
- // visited edge : source visited, target visited (token has fully traversed this edge)
58
- // This correctly handles exclusive gateways: only the taken branch's target enters
59
- // visited/active, so only the taken edge is highlighted.
60
- for (const [flowId, { sourceRef, targetRef }] of flowIndex) {
61
- const el = edgeEl(flowId);
62
- if (el === undefined)
63
- continue;
64
- const srcVisited = visitedIds.has(sourceRef);
65
- if (!srcVisited)
66
- continue;
67
- if (activeIds.has(targetRef)) {
68
- el.classList.add("bpmnkit-token-edge-active");
56
+ // Prefer direct sequence-flow tracking: Camunda's element-instances API returns
57
+ // sequence flow element instances (with their flow ID), so visitedIds/activeIds
58
+ // will contain the actual flow IDs that were traversed.
59
+ // Fallback to source/target heuristic only when no flow IDs are present (older
60
+ // engines or environments that don't track sequence flows as element instances).
61
+ // The heuristic is deliberately disabled when direct tracking is available because
62
+ // it over-highlights: when a gateway's default path leads to a node that was
63
+ // reached via a different branch, both edges appear highlighted incorrectly.
64
+ let hasFlowTracking = false;
65
+ for (const flowId of flowIndex.keys()) {
66
+ if (visitedIds.has(flowId) || activeIds.has(flowId)) {
67
+ hasFlowTracking = true;
68
+ break;
69
69
  }
70
- else if (visitedIds.has(targetRef)) {
71
- el.classList.add("bpmnkit-token-edge-visited");
70
+ }
71
+ if (hasFlowTracking) {
72
+ // Direct mode: flow IDs are in visitedIds/activeIds — highlight exactly what was traversed.
73
+ for (const [flowId] of flowIndex) {
74
+ const el = edgeEl(flowId);
75
+ if (el === undefined)
76
+ continue;
77
+ if (activeIds.has(flowId)) {
78
+ el.classList.add("bpmnkit-token-edge-active");
79
+ }
80
+ else if (visitedIds.has(flowId)) {
81
+ el.classList.add("bpmnkit-token-edge-visited");
82
+ }
83
+ }
84
+ }
85
+ else {
86
+ // Heuristic fallback for engines that don't return sequence-flow element instances.
87
+ //
88
+ // "Unique winner" rule: group outgoing flows by source and only highlight an
89
+ // edge when it is the SOLE outgoing flow from that source whose target is
90
+ // visited/active. If multiple candidates exist we cannot determine which path
91
+ // was actually taken (e.g. both branches of an exclusive gateway converge on
92
+ // the same downstream node), so we highlight none to avoid false positives.
93
+ const bySource = new Map();
94
+ for (const [flowId, { sourceRef, targetRef }] of flowIndex) {
95
+ if (!visitedIds.has(sourceRef))
96
+ continue;
97
+ const isActive = activeIds.has(targetRef);
98
+ if (!isActive && !visitedIds.has(targetRef))
99
+ continue;
100
+ const list = bySource.get(sourceRef) ?? [];
101
+ list.push({ flowId, isActive });
102
+ bySource.set(sourceRef, list);
103
+ }
104
+ for (const candidates of bySource.values()) {
105
+ if (candidates.length !== 1)
106
+ continue;
107
+ for (const { flowId, isActive } of candidates) {
108
+ const el = edgeEl(flowId);
109
+ if (el === undefined)
110
+ continue;
111
+ el.classList.add(isActive ? "bpmnkit-token-edge-active" : "bpmnkit-token-edge-visited");
112
+ }
72
113
  }
73
114
  }
74
115
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bpmnkit/plugins",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "exports": {
@@ -104,11 +104,11 @@
104
104
  "dist/**/*.d.ts"
105
105
  ],
106
106
  "dependencies": {
107
- "@bpmnkit/ascii": "0.0.11",
108
- "@bpmnkit/canvas": "0.0.11",
109
- "@bpmnkit/core": "0.0.11",
110
- "@bpmnkit/editor": "0.0.11",
111
- "@bpmnkit/feel": "0.0.11"
107
+ "@bpmnkit/ascii": "0.0.13",
108
+ "@bpmnkit/canvas": "0.0.13",
109
+ "@bpmnkit/core": "0.0.13",
110
+ "@bpmnkit/editor": "0.0.13",
111
+ "@bpmnkit/feel": "0.0.12"
112
112
  },
113
113
  "description": "22 composable canvas plugins for BPMN editors and viewers — minimap, AI chat, process simulation, storage, and more",
114
114
  "keywords": [