footprint-explainable-ui 0.25.0 → 0.25.2
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/flowchart.cjs +301 -120
- package/dist/flowchart.cjs.map +1 -1
- package/dist/flowchart.d.cts +87 -13
- package/dist/flowchart.d.ts +87 -13
- package/dist/flowchart.js +238 -57
- package/dist/flowchart.js.map +1 -1
- package/dist/index.cjs +326 -82
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +15 -16
- package/dist/index.d.ts +15 -16
- package/dist/index.js +255 -11
- package/dist/index.js.map +1 -1
- package/package.json +31 -12
package/dist/flowchart.cjs
CHANGED
|
@@ -572,7 +572,7 @@ var StageNode = (0, import_react3.memo)(function StageNode2({
|
|
|
572
572
|
background: bg,
|
|
573
573
|
border: `${isHero ? "2.5px" : isMuted ? "1px" : "2px"} ${isLazyUnresolved ? "dashed" : "solid"} ${borderColor}`,
|
|
574
574
|
borderRadius: theme.radius,
|
|
575
|
-
padding: description ? `${Math.round(
|
|
575
|
+
padding: description ? `${Math.round(6 * sizeScale)}px ${Math.round(12 * sizeScale)}px` : `${Math.round(7 * sizeScale)}px ${Math.round(14 * sizeScale)}px`,
|
|
576
576
|
display: "flex",
|
|
577
577
|
flexDirection: "column",
|
|
578
578
|
alignItems: "center",
|
|
@@ -687,7 +687,7 @@ var StageNode = (0, import_react3.memo)(function StageNode2({
|
|
|
687
687
|
});
|
|
688
688
|
|
|
689
689
|
// src/components/TimeTravelDebugger/TimeTravelDebugger.tsx
|
|
690
|
-
var
|
|
690
|
+
var import_react20 = require("react");
|
|
691
691
|
|
|
692
692
|
// src/components/MemoryInspector/MemoryInspector.tsx
|
|
693
693
|
var import_react5 = require("react");
|
|
@@ -1541,6 +1541,14 @@ function staggeredBendY(sourceBottom, targetTop, others, minGapFromTarget = 8) {
|
|
|
1541
1541
|
if (lowestSkippedBottom === -Infinity) return null;
|
|
1542
1542
|
return Math.min((lowestSkippedBottom + targetTop) / 2, targetTop - minGapFromTarget);
|
|
1543
1543
|
}
|
|
1544
|
+
function forkFanBendY(sourceBottom, childTops, minGapFromTarget = 8) {
|
|
1545
|
+
if (childTops.length < 2) return null;
|
|
1546
|
+
const nearestTop = Math.min(...childTops);
|
|
1547
|
+
return Math.min((sourceBottom + nearestTop) / 2, nearestTop - minGapFromTarget);
|
|
1548
|
+
}
|
|
1549
|
+
function resolveStepBendY(forkBend, staggeredBend) {
|
|
1550
|
+
return staggeredBend ?? forkBend;
|
|
1551
|
+
}
|
|
1544
1552
|
|
|
1545
1553
|
// src/components/SmartStepEdge/SmartStepEdge.tsx
|
|
1546
1554
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
@@ -1563,6 +1571,16 @@ function SmartStepEdge({
|
|
|
1563
1571
|
if (!src || !tgt) return null;
|
|
1564
1572
|
const sourceBottom = src.internals.positionAbsolute.y + (src.measured.height ?? 0);
|
|
1565
1573
|
const targetTop = tgt.internals.positionAbsolute.y;
|
|
1574
|
+
const childTops = [];
|
|
1575
|
+
for (const e of s.edges) {
|
|
1576
|
+
if (e.source !== source) continue;
|
|
1577
|
+
if (e.data?.kind === "loop") continue;
|
|
1578
|
+
const c = s.nodeLookup.get(e.target);
|
|
1579
|
+
if (c && c.type !== GROUP_CONTAINER_NODE_TYPE) {
|
|
1580
|
+
childTops.push(c.internals.positionAbsolute.y);
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
const fan = forkFanBendY(sourceBottom, childTops);
|
|
1566
1584
|
const others = [];
|
|
1567
1585
|
for (const n of s.nodeLookup.values()) {
|
|
1568
1586
|
if (n.id === source || n.id === target) continue;
|
|
@@ -1570,7 +1588,8 @@ function SmartStepEdge({
|
|
|
1570
1588
|
const top = n.internals.positionAbsolute.y;
|
|
1571
1589
|
others.push({ top, bottom: top + (n.measured.height ?? 0) });
|
|
1572
1590
|
}
|
|
1573
|
-
|
|
1591
|
+
const staggered = staggeredBendY(sourceBottom, targetTop, others);
|
|
1592
|
+
return resolveStepBendY(fan, staggered);
|
|
1574
1593
|
});
|
|
1575
1594
|
const [path] = (0, import_react9.getSmoothStepPath)({
|
|
1576
1595
|
sourceX,
|
|
@@ -1933,8 +1952,8 @@ function TraceFlow(props) {
|
|
|
1933
1952
|
}
|
|
1934
1953
|
|
|
1935
1954
|
// src/components/FlowchartView/TracedFlow.tsx
|
|
1936
|
-
var
|
|
1937
|
-
var
|
|
1955
|
+
var import_react18 = require("react");
|
|
1956
|
+
var import_react19 = require("@xyflow/react");
|
|
1938
1957
|
|
|
1939
1958
|
// src/components/FlowchartView/_internal/devWarn.ts
|
|
1940
1959
|
function isDevModeEnv() {
|
|
@@ -1946,6 +1965,150 @@ function devWarn(messageFn, ...extras) {
|
|
|
1946
1965
|
console.warn(messageFn(), ...extras);
|
|
1947
1966
|
}
|
|
1948
1967
|
|
|
1968
|
+
// src/components/FlowchartView/_internal/snapLinearSuccessors.ts
|
|
1969
|
+
function snapLinearSuccessors(graph, options = {}) {
|
|
1970
|
+
if (graph.nodes.length === 0) return graph;
|
|
1971
|
+
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
1972
|
+
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
1973
|
+
const byId = /* @__PURE__ */ new Map();
|
|
1974
|
+
const width = /* @__PURE__ */ new Map();
|
|
1975
|
+
for (const n of graph.nodes) {
|
|
1976
|
+
byId.set(n.id, n);
|
|
1977
|
+
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
1978
|
+
}
|
|
1979
|
+
const preds = /* @__PURE__ */ new Map();
|
|
1980
|
+
const outDegree = /* @__PURE__ */ new Map();
|
|
1981
|
+
const seenEdge = /* @__PURE__ */ new Set();
|
|
1982
|
+
for (const e of graph.edges) {
|
|
1983
|
+
if (e.data?.kind === "loop") continue;
|
|
1984
|
+
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
1985
|
+
const key = `${e.source}\0${e.target}`;
|
|
1986
|
+
if (seenEdge.has(key)) continue;
|
|
1987
|
+
seenEdge.add(key);
|
|
1988
|
+
const list = preds.get(e.target);
|
|
1989
|
+
if (list) list.push(e.source);
|
|
1990
|
+
else preds.set(e.target, [e.source]);
|
|
1991
|
+
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
1992
|
+
}
|
|
1993
|
+
const workingX = /* @__PURE__ */ new Map();
|
|
1994
|
+
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
1995
|
+
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
1996
|
+
const order = [...graph.nodes].sort(
|
|
1997
|
+
(a, b) => a.position.y - b.position.y || a.position.x - b.position.x || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
1998
|
+
);
|
|
1999
|
+
for (const n of order) {
|
|
2000
|
+
const p = preds.get(n.id);
|
|
2001
|
+
if (!p || p.length !== 1) continue;
|
|
2002
|
+
const pid = p[0];
|
|
2003
|
+
if ((outDegree.get(pid) ?? 0) !== 1) continue;
|
|
2004
|
+
const P = byId.get(pid);
|
|
2005
|
+
if ((n.parentId ?? void 0) !== (P.parentId ?? void 0)) continue;
|
|
2006
|
+
workingX.set(n.id, centerX(pid) - width.get(n.id) / 2);
|
|
2007
|
+
}
|
|
2008
|
+
const nodes = graph.nodes.map((n) => {
|
|
2009
|
+
const nx = workingX.get(n.id);
|
|
2010
|
+
return nx === n.position.x ? n : { ...n, position: { x: nx, y: n.position.y } };
|
|
2011
|
+
});
|
|
2012
|
+
return { nodes, edges: graph.edges };
|
|
2013
|
+
}
|
|
2014
|
+
function createSnappedDagreLayout(base, options = {}) {
|
|
2015
|
+
return (graph) => snapLinearSuccessors(base(graph), options);
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2018
|
+
// src/components/FlowchartView/_internal/centerForkParents.ts
|
|
2019
|
+
function centerForkParents(graph, options = {}) {
|
|
2020
|
+
if (graph.nodes.length === 0) return graph;
|
|
2021
|
+
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
2022
|
+
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
2023
|
+
const byId = /* @__PURE__ */ new Map();
|
|
2024
|
+
const width = /* @__PURE__ */ new Map();
|
|
2025
|
+
for (const n of graph.nodes) {
|
|
2026
|
+
byId.set(n.id, n);
|
|
2027
|
+
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
2028
|
+
}
|
|
2029
|
+
const childrenOf = /* @__PURE__ */ new Map();
|
|
2030
|
+
const predsOf = /* @__PURE__ */ new Map();
|
|
2031
|
+
const outDegree = /* @__PURE__ */ new Map();
|
|
2032
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
2033
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2034
|
+
for (const e of graph.edges) {
|
|
2035
|
+
if (e.data?.kind === "loop") continue;
|
|
2036
|
+
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
2037
|
+
const key = `${e.source} ${e.target}`;
|
|
2038
|
+
if (seen.has(key)) continue;
|
|
2039
|
+
seen.add(key);
|
|
2040
|
+
const cl = childrenOf.get(e.source);
|
|
2041
|
+
if (cl) cl.push(e.target);
|
|
2042
|
+
else childrenOf.set(e.source, [e.target]);
|
|
2043
|
+
const pl = predsOf.get(e.target);
|
|
2044
|
+
if (pl) pl.push(e.source);
|
|
2045
|
+
else predsOf.set(e.target, [e.source]);
|
|
2046
|
+
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
2047
|
+
inDegree.set(e.target, (inDegree.get(e.target) ?? 0) + 1);
|
|
2048
|
+
}
|
|
2049
|
+
const workingX = /* @__PURE__ */ new Map();
|
|
2050
|
+
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
2051
|
+
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
2052
|
+
const nodeSep = options.nodeSep ?? 60;
|
|
2053
|
+
const clampX = (id, desiredX) => {
|
|
2054
|
+
const w = width.get(id);
|
|
2055
|
+
const x0 = workingX.get(id);
|
|
2056
|
+
const self = byId.get(id);
|
|
2057
|
+
let minX = -Infinity;
|
|
2058
|
+
let maxX = Infinity;
|
|
2059
|
+
for (const m of graph.nodes) {
|
|
2060
|
+
if (m.id === id || m.parentId !== self.parentId) continue;
|
|
2061
|
+
if (Math.abs(m.position.y - self.position.y) > 1) continue;
|
|
2062
|
+
const mLeft = workingX.get(m.id);
|
|
2063
|
+
const mRight = mLeft + width.get(m.id);
|
|
2064
|
+
if (mRight <= x0) minX = Math.max(minX, mRight + nodeSep);
|
|
2065
|
+
else if (mLeft >= x0 + w) maxX = Math.min(maxX, mLeft - nodeSep - w);
|
|
2066
|
+
}
|
|
2067
|
+
return minX <= maxX ? Math.max(minX, Math.min(maxX, desiredX)) : x0;
|
|
2068
|
+
};
|
|
2069
|
+
const order = [...graph.nodes].sort(
|
|
2070
|
+
(a, b) => b.position.y - a.position.y || a.position.x - b.position.x || a.id.localeCompare(b.id)
|
|
2071
|
+
);
|
|
2072
|
+
for (const n of order) {
|
|
2073
|
+
const outD = outDegree.get(n.id) ?? 0;
|
|
2074
|
+
const inD = inDegree.get(n.id) ?? 0;
|
|
2075
|
+
const isFork = outD >= 2 && inD <= 1;
|
|
2076
|
+
const isMerge = inD >= 2 && outD <= 1;
|
|
2077
|
+
if (!isFork && !isMerge) continue;
|
|
2078
|
+
const kin = ((isFork ? childrenOf.get(n.id) : predsOf.get(n.id)) ?? []).filter(
|
|
2079
|
+
(k) => byId.get(k)?.parentId === n.parentId
|
|
2080
|
+
// same compound only
|
|
2081
|
+
);
|
|
2082
|
+
if (kin.length < 2) continue;
|
|
2083
|
+
const centers = kin.map(centerX);
|
|
2084
|
+
const wN = width.get(n.id);
|
|
2085
|
+
const span = (Math.min(...centers) + Math.max(...centers)) / 2;
|
|
2086
|
+
workingX.set(n.id, clampX(n.id, span - wN / 2));
|
|
2087
|
+
const stepOf = isFork ? predsOf : childrenOf;
|
|
2088
|
+
let curId = n.id;
|
|
2089
|
+
const walked = /* @__PURE__ */ new Set([curId]);
|
|
2090
|
+
for (; ; ) {
|
|
2091
|
+
const nexts = stepOf.get(curId);
|
|
2092
|
+
if (!nexts || nexts.length !== 1) break;
|
|
2093
|
+
const m = nexts[0];
|
|
2094
|
+
if (walked.has(m)) break;
|
|
2095
|
+
if ((outDegree.get(m) ?? 0) > 1) break;
|
|
2096
|
+
if ((inDegree.get(m) ?? 0) > 1) break;
|
|
2097
|
+
if (byId.get(m)?.parentId !== byId.get(curId)?.parentId) break;
|
|
2098
|
+
workingX.set(m, clampX(m, centerX(curId) - width.get(m) / 2));
|
|
2099
|
+
walked.add(m);
|
|
2100
|
+
curId = m;
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
const nodes = graph.nodes.map(
|
|
2104
|
+
(n) => workingX.get(n.id) === n.position.x ? n : { ...n, position: { x: workingX.get(n.id), y: n.position.y } }
|
|
2105
|
+
);
|
|
2106
|
+
return { nodes, edges: graph.edges };
|
|
2107
|
+
}
|
|
2108
|
+
function withForkCentering(base, options = {}) {
|
|
2109
|
+
return (graph) => centerForkParents(base(graph), options);
|
|
2110
|
+
}
|
|
2111
|
+
|
|
1949
2112
|
// src/components/FlowchartView/_internal/notifyChange.ts
|
|
1950
2113
|
function createNotifier(label = "notifier") {
|
|
1951
2114
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -2303,6 +2466,49 @@ function GroupContainerNode({ data }) {
|
|
|
2303
2466
|
);
|
|
2304
2467
|
}
|
|
2305
2468
|
|
|
2469
|
+
// src/components/FlowchartView/_internal/MeasuredNodeSizes.tsx
|
|
2470
|
+
var import_react16 = require("react");
|
|
2471
|
+
var import_react17 = require("@xyflow/react");
|
|
2472
|
+
|
|
2473
|
+
// src/components/FlowchartView/_internal/measuredFootprints.ts
|
|
2474
|
+
function extractMeasuredFootprints(entries) {
|
|
2475
|
+
const sizes = /* @__PURE__ */ new Map();
|
|
2476
|
+
for (const [id, node] of entries) {
|
|
2477
|
+
const width = node.measured?.width;
|
|
2478
|
+
const height = node.measured?.height;
|
|
2479
|
+
if (typeof width === "number" && typeof height === "number" && width > 0 && height > 0) {
|
|
2480
|
+
sizes.set(id, { width: Math.round(width), height: Math.round(height) });
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return sizes;
|
|
2484
|
+
}
|
|
2485
|
+
function sameFootprints(a, b) {
|
|
2486
|
+
if (a === b) return true;
|
|
2487
|
+
if (a.size !== b.size) return false;
|
|
2488
|
+
for (const [id, s] of a) {
|
|
2489
|
+
const t = b.get(id);
|
|
2490
|
+
if (!t || t.width !== s.width || t.height !== s.height) return false;
|
|
2491
|
+
}
|
|
2492
|
+
return true;
|
|
2493
|
+
}
|
|
2494
|
+
|
|
2495
|
+
// src/components/FlowchartView/_internal/MeasuredNodeSizes.tsx
|
|
2496
|
+
function MeasuredNodeSizes({
|
|
2497
|
+
onSizes,
|
|
2498
|
+
includeHiddenNodes = false
|
|
2499
|
+
}) {
|
|
2500
|
+
const initialized = (0, import_react17.useNodesInitialized)({ includeHiddenNodes });
|
|
2501
|
+
const sizes = (0, import_react17.useStore)(
|
|
2502
|
+
(s) => extractMeasuredFootprints(s.nodeLookup),
|
|
2503
|
+
sameFootprints
|
|
2504
|
+
);
|
|
2505
|
+
(0, import_react16.useEffect)(() => {
|
|
2506
|
+
if (!initialized || sizes.size === 0) return;
|
|
2507
|
+
onSizes(sizes);
|
|
2508
|
+
}, [initialized, sizes, onSizes]);
|
|
2509
|
+
return null;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2306
2512
|
// src/components/FlowchartView/TracedFlow.tsx
|
|
2307
2513
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2308
2514
|
var DEFAULT_COLORS = {
|
|
@@ -2412,7 +2618,7 @@ function styleEdgeWithOverlay(edge, doneStageIds, activeStageId, colors) {
|
|
|
2412
2618
|
type: kind === "loop" ? "loopBack" : "smartStep",
|
|
2413
2619
|
animated: isLeadingEdge,
|
|
2414
2620
|
style: { stroke: color, strokeWidth: traversed ? 2 : 1.5 },
|
|
2415
|
-
markerEnd: { type:
|
|
2621
|
+
markerEnd: { type: import_react19.MarkerType.ArrowClosed, color, width: 16, height: 16 }
|
|
2416
2622
|
};
|
|
2417
2623
|
if (kind === "loop") {
|
|
2418
2624
|
styled.style = { ...styled.style, strokeDasharray: "4 3" };
|
|
@@ -2442,21 +2648,28 @@ function TracedFlow({
|
|
|
2442
2648
|
style
|
|
2443
2649
|
}) {
|
|
2444
2650
|
const layout = layoutProp ?? dagreTraceLayout;
|
|
2445
|
-
|
|
2651
|
+
(0, import_react18.useEffect)(() => {
|
|
2652
|
+
if (layoutProp === dagreTraceLayout) {
|
|
2653
|
+
devWarn(
|
|
2654
|
+
() => "[footprint-explainable-ui] <TracedFlow layout={dagreTraceLayout}> bypasses the built-in measure-then-layout pipeline (content-exact sizing, fork/merge centering, straight spines). OMIT the `layout` prop to use it \u2014 passing the raw dagreTraceLayout silently forfeits every layout improvement eui ships."
|
|
2655
|
+
);
|
|
2656
|
+
}
|
|
2657
|
+
}, [layoutProp]);
|
|
2658
|
+
const colors = (0, import_react18.useMemo)(
|
|
2446
2659
|
() => ({ ...DEFAULT_COLORS, ...colorOverrides ?? {} }),
|
|
2447
2660
|
[colorOverrides]
|
|
2448
2661
|
);
|
|
2449
|
-
const mergedNodeTypes = (0,
|
|
2662
|
+
const mergedNodeTypes = (0, import_react18.useMemo)(
|
|
2450
2663
|
() => userNodeTypes ? { ...DEFAULT_NODE_TYPES2, ...userNodeTypes } : DEFAULT_NODE_TYPES2,
|
|
2451
2664
|
[userNodeTypes]
|
|
2452
2665
|
);
|
|
2453
|
-
const mergedEdgeTypes = (0,
|
|
2666
|
+
const mergedEdgeTypes = (0, import_react18.useMemo)(
|
|
2454
2667
|
() => userEdgeTypes ? { ...DEFAULT_EDGE_TYPES2, ...userEdgeTypes } : DEFAULT_EDGE_TYPES2,
|
|
2455
2668
|
[userEdgeTypes]
|
|
2456
2669
|
);
|
|
2457
2670
|
const drill = useSubflowDrill(graph, onSubflowChange);
|
|
2458
|
-
const groupedSet = (0,
|
|
2459
|
-
const filteredGraph = (0,
|
|
2671
|
+
const groupedSet = (0, import_react18.useMemo)(() => new Set(groupedSubflows ?? []), [groupedSubflows]);
|
|
2672
|
+
const filteredGraph = (0, import_react18.useMemo)(() => {
|
|
2460
2673
|
const base = filterGraphForDrill(graph, drill.currentSubflowId);
|
|
2461
2674
|
if (groupedSet.size === 0) return base;
|
|
2462
2675
|
const baseIds = new Set(base.nodes.map((n) => n.id));
|
|
@@ -2471,12 +2684,23 @@ function TracedFlow({
|
|
|
2471
2684
|
);
|
|
2472
2685
|
return { nodes: [...base.nodes, ...extraNodes], edges: [...base.edges, ...extraEdges] };
|
|
2473
2686
|
}, [graph, drill.currentSubflowId, groupedSet]);
|
|
2474
|
-
const breadcrumb = (0,
|
|
2687
|
+
const breadcrumb = (0, import_react18.useMemo)(
|
|
2475
2688
|
() => buildSubflowBreadcrumb(graph, drill.currentSubflowId),
|
|
2476
2689
|
[graph, drill.currentSubflowId]
|
|
2477
2690
|
);
|
|
2478
|
-
const
|
|
2479
|
-
|
|
2691
|
+
const [measuredSizes, setMeasuredSizes] = (0, import_react18.useState)(null);
|
|
2692
|
+
const positioned = (0, import_react18.useMemo)(() => {
|
|
2693
|
+
const nodeSize = measuredSizes ? (n) => measuredSizes.get(n.id) : void 0;
|
|
2694
|
+
const sizeOpts = nodeSize ? { nodeSize } : {};
|
|
2695
|
+
const dagreBase = withForkCentering(
|
|
2696
|
+
createSnappedDagreLayout(
|
|
2697
|
+
createDagreTraceLayout({ ...sizeOpts, rankSep: 52, nodeSep: 36 }),
|
|
2698
|
+
sizeOpts
|
|
2699
|
+
),
|
|
2700
|
+
{ ...sizeOpts, nodeSep: 36 }
|
|
2701
|
+
// same nodeSep → clamp preserves dagre's reserved gap
|
|
2702
|
+
);
|
|
2703
|
+
const realBase = layout === "passthrough" ? (g) => g : layoutProp === void 0 ? dagreBase : layout;
|
|
2480
2704
|
if (groupedSet.size > 0) {
|
|
2481
2705
|
const grouped = applyGroupLayout(filteredGraph, {
|
|
2482
2706
|
groupedSubflowIds: [...groupedSet],
|
|
@@ -2487,9 +2711,9 @@ function TracedFlow({
|
|
|
2487
2711
|
if (mainChartBox) {
|
|
2488
2712
|
return wrapInMainChartBox(filteredGraph, { baseLayout: realBase, ...mainChartBox });
|
|
2489
2713
|
}
|
|
2490
|
-
return
|
|
2491
|
-
}, [filteredGraph, layout, groupedSet, mainChartBox]);
|
|
2492
|
-
const slice = (0,
|
|
2714
|
+
return realBase(filteredGraph);
|
|
2715
|
+
}, [filteredGraph, layout, layoutProp, groupedSet, mainChartBox, measuredSizes]);
|
|
2716
|
+
const slice = (0, import_react18.useMemo)(() => {
|
|
2493
2717
|
const empty = {
|
|
2494
2718
|
doneStageIds: /* @__PURE__ */ new Set(),
|
|
2495
2719
|
activeStageId: null,
|
|
@@ -2501,7 +2725,7 @@ function TracedFlow({
|
|
|
2501
2725
|
const idx = scrubIndex ?? Math.max(0, overlay.executionOrder.length - 1);
|
|
2502
2726
|
return aggregateMountStatus(sliceOverlay(overlay, idx), graph, drill.currentSubflowId);
|
|
2503
2727
|
}, [overlay, scrubIndex, graph, drill.currentSubflowId]);
|
|
2504
|
-
const reactFlowNodes = (0,
|
|
2728
|
+
const reactFlowNodes = (0, import_react18.useMemo)(
|
|
2505
2729
|
() => positioned.nodes.map(
|
|
2506
2730
|
(n) => toStageNodeWithOverlay(
|
|
2507
2731
|
n,
|
|
@@ -2514,13 +2738,13 @@ function TracedFlow({
|
|
|
2514
2738
|
),
|
|
2515
2739
|
[positioned.nodes, slice, coActiveStageIds]
|
|
2516
2740
|
);
|
|
2517
|
-
const reactFlowEdges = (0,
|
|
2741
|
+
const reactFlowEdges = (0, import_react18.useMemo)(
|
|
2518
2742
|
() => positioned.edges.map(
|
|
2519
2743
|
(e) => styleEdgeWithOverlay(e, slice.doneStageIds, slice.activeStageId, colors)
|
|
2520
2744
|
),
|
|
2521
2745
|
[positioned.edges, slice, colors]
|
|
2522
2746
|
);
|
|
2523
|
-
const handleNodeClick = (0,
|
|
2747
|
+
const handleNodeClick = (0, import_react18.useCallback)(
|
|
2524
2748
|
(_, node) => {
|
|
2525
2749
|
const data = node.data ?? {};
|
|
2526
2750
|
if (data.isSubflow && data.subflowId && !groupedSet.has(data.subflowId)) {
|
|
@@ -2530,9 +2754,13 @@ function TracedFlow({
|
|
|
2530
2754
|
},
|
|
2531
2755
|
[drill, onNodeClick, groupedSet]
|
|
2532
2756
|
);
|
|
2533
|
-
const wrapperRef = (0,
|
|
2534
|
-
const [rfInstance, setRfInstance] = (0,
|
|
2535
|
-
useChartAutoRefit(wrapperRef, rfInstance, {
|
|
2757
|
+
const wrapperRef = (0, import_react18.useRef)(null);
|
|
2758
|
+
const [rfInstance, setRfInstance] = (0, import_react18.useState)(null);
|
|
2759
|
+
useChartAutoRefit(wrapperRef, rfInstance, {
|
|
2760
|
+
// Re-fit on drill AND after the measured-size re-layout settles.
|
|
2761
|
+
refitKey: `${drill.currentSubflowId ?? ""}:${measuredSizes ? "measured" : "estimated"}`,
|
|
2762
|
+
padding: 0.18
|
|
2763
|
+
});
|
|
2536
2764
|
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2537
2765
|
"div",
|
|
2538
2766
|
{
|
|
@@ -2555,7 +2783,7 @@ function TracedFlow({
|
|
|
2555
2783
|
}
|
|
2556
2784
|
),
|
|
2557
2785
|
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
2558
|
-
|
|
2786
|
+
import_react19.ReactFlow,
|
|
2559
2787
|
{
|
|
2560
2788
|
nodes: reactFlowNodes,
|
|
2561
2789
|
edges: reactFlowEdges,
|
|
@@ -2564,9 +2792,12 @@ function TracedFlow({
|
|
|
2564
2792
|
onNodeClick: handleNodeClick,
|
|
2565
2793
|
onInit: setRfInstance,
|
|
2566
2794
|
fitView: true,
|
|
2795
|
+
fitViewOptions: { padding: 0.18 },
|
|
2796
|
+
minZoom: 0.1,
|
|
2567
2797
|
proOptions: { hideAttribution: true },
|
|
2568
2798
|
children: [
|
|
2569
|
-
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2799
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(MeasuredNodeSizes, { onSizes: setMeasuredSizes }),
|
|
2800
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react19.Background, { variant: import_react19.BackgroundVariant.Dots, gap: 20, size: 1 }),
|
|
2570
2801
|
children
|
|
2571
2802
|
]
|
|
2572
2803
|
}
|
|
@@ -2590,7 +2821,7 @@ function TimeTravelDebugger({
|
|
|
2590
2821
|
className,
|
|
2591
2822
|
style
|
|
2592
2823
|
}) {
|
|
2593
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
2824
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react20.useState)(0);
|
|
2594
2825
|
const fs = fontSize[size];
|
|
2595
2826
|
const pad = padding[size];
|
|
2596
2827
|
if (snapshots.length === 0) {
|
|
@@ -2884,9 +3115,9 @@ function ScrubButton({
|
|
|
2884
3115
|
}
|
|
2885
3116
|
|
|
2886
3117
|
// src/components/FlowchartView/SubflowBreadcrumb.tsx
|
|
2887
|
-
var
|
|
3118
|
+
var import_react21 = require("react");
|
|
2888
3119
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2889
|
-
var SubflowBreadcrumb = (0,
|
|
3120
|
+
var SubflowBreadcrumb = (0, import_react21.memo)(function SubflowBreadcrumb2({
|
|
2890
3121
|
breadcrumbs,
|
|
2891
3122
|
onNavigate
|
|
2892
3123
|
}) {
|
|
@@ -2967,12 +3198,12 @@ var SubflowBreadcrumb = (0, import_react19.memo)(function SubflowBreadcrumb2({
|
|
|
2967
3198
|
});
|
|
2968
3199
|
|
|
2969
3200
|
// src/components/FlowchartView/useSubflowNavigation.ts
|
|
2970
|
-
var
|
|
3201
|
+
var import_react22 = require("react");
|
|
2971
3202
|
var EMPTY_GRAPH2 = { nodes: [], edges: [] };
|
|
2972
3203
|
function useSubflowNavigation(rootGraph) {
|
|
2973
|
-
const [stack, setStack] = (0,
|
|
3204
|
+
const [stack, setStack] = (0, import_react22.useState)([]);
|
|
2974
3205
|
const safeRootGraph = rootGraph ?? EMPTY_GRAPH2;
|
|
2975
|
-
const subflowMounts = (0,
|
|
3206
|
+
const subflowMounts = (0, import_react22.useMemo)(() => {
|
|
2976
3207
|
const map = /* @__PURE__ */ new Map();
|
|
2977
3208
|
for (const node of safeRootGraph.nodes) {
|
|
2978
3209
|
if (!node.data?.isSubflow) continue;
|
|
@@ -2990,12 +3221,12 @@ function useSubflowNavigation(rootGraph) {
|
|
|
2990
3221
|
}
|
|
2991
3222
|
return map;
|
|
2992
3223
|
}, [safeRootGraph]);
|
|
2993
|
-
const breadcrumbs = (0,
|
|
3224
|
+
const breadcrumbs = (0, import_react22.useMemo)(() => {
|
|
2994
3225
|
const rootLabel = "Flowchart";
|
|
2995
3226
|
const root = { label: rootLabel };
|
|
2996
3227
|
return [root, ...stack];
|
|
2997
3228
|
}, [stack]);
|
|
2998
|
-
const handleNodeClick = (0,
|
|
3229
|
+
const handleNodeClick = (0, import_react22.useCallback)(
|
|
2999
3230
|
(nodeId) => {
|
|
3000
3231
|
const mount = subflowMounts.get(nodeId);
|
|
3001
3232
|
if (!mount) return false;
|
|
@@ -3011,7 +3242,7 @@ function useSubflowNavigation(rootGraph) {
|
|
|
3011
3242
|
},
|
|
3012
3243
|
[subflowMounts]
|
|
3013
3244
|
);
|
|
3014
|
-
const navigateTo = (0,
|
|
3245
|
+
const navigateTo = (0, import_react22.useCallback)((level) => {
|
|
3015
3246
|
if (level === 0) {
|
|
3016
3247
|
setStack([]);
|
|
3017
3248
|
} else {
|
|
@@ -3033,7 +3264,7 @@ function useSubflowNavigation(rootGraph) {
|
|
|
3033
3264
|
}
|
|
3034
3265
|
|
|
3035
3266
|
// src/components/FlowchartView/SubflowTree.tsx
|
|
3036
|
-
var
|
|
3267
|
+
var import_react23 = require("react");
|
|
3037
3268
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
3038
3269
|
function graphToSubflowEntries(graph) {
|
|
3039
3270
|
if (!graph?.nodes?.length) return [];
|
|
@@ -3050,18 +3281,18 @@ function graphToSubflowEntries(graph) {
|
|
|
3050
3281
|
}
|
|
3051
3282
|
return entries;
|
|
3052
3283
|
}
|
|
3053
|
-
var TreeNode = (0,
|
|
3284
|
+
var TreeNode = (0, import_react23.memo)(function TreeNode2({
|
|
3054
3285
|
entry,
|
|
3055
3286
|
depth,
|
|
3056
3287
|
activeStage,
|
|
3057
3288
|
doneStages,
|
|
3058
3289
|
onNodeSelect
|
|
3059
3290
|
}) {
|
|
3060
|
-
const [expanded, setExpanded] = (0,
|
|
3291
|
+
const [expanded, setExpanded] = (0, import_react23.useState)(true);
|
|
3061
3292
|
const hasChildren = entry.children && entry.children.length > 0;
|
|
3062
3293
|
const isActive = activeStage === entry.name;
|
|
3063
3294
|
const isDone = doneStages?.has(entry.name);
|
|
3064
|
-
const handleClick = (0,
|
|
3295
|
+
const handleClick = (0, import_react23.useCallback)(() => {
|
|
3065
3296
|
if (hasChildren) {
|
|
3066
3297
|
setExpanded((prev) => !prev);
|
|
3067
3298
|
}
|
|
@@ -3174,7 +3405,7 @@ var TreeNode = (0, import_react21.memo)(function TreeNode2({
|
|
|
3174
3405
|
)) })
|
|
3175
3406
|
] });
|
|
3176
3407
|
});
|
|
3177
|
-
var SectionLabel = (0,
|
|
3408
|
+
var SectionLabel = (0, import_react23.memo)(function SectionLabel2({ children }) {
|
|
3178
3409
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
3179
3410
|
"div",
|
|
3180
3411
|
{
|
|
@@ -3190,7 +3421,7 @@ var SectionLabel = (0, import_react21.memo)(function SectionLabel2({ children })
|
|
|
3190
3421
|
}
|
|
3191
3422
|
);
|
|
3192
3423
|
});
|
|
3193
|
-
var SubflowTree = (0,
|
|
3424
|
+
var SubflowTree = (0, import_react23.memo)(function SubflowTree2({
|
|
3194
3425
|
graph,
|
|
3195
3426
|
activeStage,
|
|
3196
3427
|
doneStages,
|
|
@@ -3199,7 +3430,7 @@ var SubflowTree = (0, import_react21.memo)(function SubflowTree2({
|
|
|
3199
3430
|
className,
|
|
3200
3431
|
style
|
|
3201
3432
|
}) {
|
|
3202
|
-
const subflowStages = (0,
|
|
3433
|
+
const subflowStages = (0, import_react23.useMemo)(() => graphToSubflowEntries(graph), [graph]);
|
|
3203
3434
|
if (subflowStages.length === 0) return null;
|
|
3204
3435
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
3205
3436
|
"div",
|
|
@@ -3524,7 +3755,7 @@ function createTraceStructureRecorder(options = {}) {
|
|
|
3524
3755
|
}
|
|
3525
3756
|
|
|
3526
3757
|
// src/components/SlotPillNode/SlotPillNode.tsx
|
|
3527
|
-
var
|
|
3758
|
+
var import_react24 = require("@xyflow/react");
|
|
3528
3759
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
3529
3760
|
var C2 = rawDefaults.colors;
|
|
3530
3761
|
function SlotPillNode({ data }) {
|
|
@@ -3573,63 +3804,13 @@ function SlotPillNode({ data }) {
|
|
|
3573
3804
|
),
|
|
3574
3805
|
d.icon ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": true, style: { flexShrink: 0 }, children: d.icon }) : null,
|
|
3575
3806
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: d.label }),
|
|
3576
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3577
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
3807
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react24.Handle, { type: "target", position: import_react24.Position.Top, style: { opacity: 0 } }),
|
|
3808
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react24.Handle, { type: "source", position: import_react24.Position.Bottom, style: { opacity: 0 } })
|
|
3578
3809
|
]
|
|
3579
3810
|
}
|
|
3580
3811
|
);
|
|
3581
3812
|
}
|
|
3582
3813
|
|
|
3583
|
-
// src/components/FlowchartView/_internal/snapLinearSuccessors.ts
|
|
3584
|
-
function snapLinearSuccessors(graph, options = {}) {
|
|
3585
|
-
if (graph.nodes.length === 0) return graph;
|
|
3586
|
-
const fallbackW = options.nodeWidth ?? DEFAULT_NODE_W2;
|
|
3587
|
-
const fallbackH = options.nodeHeight ?? DEFAULT_NODE_H2;
|
|
3588
|
-
const byId = /* @__PURE__ */ new Map();
|
|
3589
|
-
const width = /* @__PURE__ */ new Map();
|
|
3590
|
-
for (const n of graph.nodes) {
|
|
3591
|
-
byId.set(n.id, n);
|
|
3592
|
-
width.set(n.id, sizeOf(n, fallbackW, fallbackH, options.nodeSize).width);
|
|
3593
|
-
}
|
|
3594
|
-
const preds = /* @__PURE__ */ new Map();
|
|
3595
|
-
const outDegree = /* @__PURE__ */ new Map();
|
|
3596
|
-
const seenEdge = /* @__PURE__ */ new Set();
|
|
3597
|
-
for (const e of graph.edges) {
|
|
3598
|
-
if (e.data?.kind === "loop") continue;
|
|
3599
|
-
if (!byId.has(e.source) || !byId.has(e.target)) continue;
|
|
3600
|
-
const key = `${e.source}\0${e.target}`;
|
|
3601
|
-
if (seenEdge.has(key)) continue;
|
|
3602
|
-
seenEdge.add(key);
|
|
3603
|
-
const list = preds.get(e.target);
|
|
3604
|
-
if (list) list.push(e.source);
|
|
3605
|
-
else preds.set(e.target, [e.source]);
|
|
3606
|
-
outDegree.set(e.source, (outDegree.get(e.source) ?? 0) + 1);
|
|
3607
|
-
}
|
|
3608
|
-
const workingX = /* @__PURE__ */ new Map();
|
|
3609
|
-
for (const n of graph.nodes) workingX.set(n.id, n.position.x);
|
|
3610
|
-
const centerX = (id) => workingX.get(id) + width.get(id) / 2;
|
|
3611
|
-
const order = [...graph.nodes].sort(
|
|
3612
|
-
(a, b) => a.position.y - b.position.y || a.position.x - b.position.x || (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
3613
|
-
);
|
|
3614
|
-
for (const n of order) {
|
|
3615
|
-
const p = preds.get(n.id);
|
|
3616
|
-
if (!p || p.length !== 1) continue;
|
|
3617
|
-
const pid = p[0];
|
|
3618
|
-
if ((outDegree.get(pid) ?? 0) !== 1) continue;
|
|
3619
|
-
const P = byId.get(pid);
|
|
3620
|
-
if ((n.parentId ?? void 0) !== (P.parentId ?? void 0)) continue;
|
|
3621
|
-
workingX.set(n.id, centerX(pid) - width.get(n.id) / 2);
|
|
3622
|
-
}
|
|
3623
|
-
const nodes = graph.nodes.map((n) => {
|
|
3624
|
-
const nx = workingX.get(n.id);
|
|
3625
|
-
return nx === n.position.x ? n : { ...n, position: { x: nx, y: n.position.y } };
|
|
3626
|
-
});
|
|
3627
|
-
return { nodes, edges: graph.edges };
|
|
3628
|
-
}
|
|
3629
|
-
function createSnappedDagreLayout(base, options = {}) {
|
|
3630
|
-
return (graph) => snapLinearSuccessors(base(graph), options);
|
|
3631
|
-
}
|
|
3632
|
-
|
|
3633
3814
|
// src/components/FlowchartView/_internal/traceGroupLayout.ts
|
|
3634
3815
|
function buildAdjacency(graph, fallbackW, fallbackH, nodeSize) {
|
|
3635
3816
|
const preds = /* @__PURE__ */ new Map();
|
|
@@ -4299,12 +4480,12 @@ function createTraceBundle(options = {}) {
|
|
|
4299
4480
|
}
|
|
4300
4481
|
|
|
4301
4482
|
// src/components/FlowchartView/_internal/useTranslator.ts
|
|
4302
|
-
var
|
|
4483
|
+
var import_react25 = require("react");
|
|
4303
4484
|
function useTranslator(handle, getSnapshot) {
|
|
4304
|
-
const subscribe = (0,
|
|
4305
|
-
const getVersion = (0,
|
|
4306
|
-
const version = (0,
|
|
4307
|
-
return (0,
|
|
4485
|
+
const subscribe = (0, import_react25.useMemo)(() => handle.subscribe.bind(handle), [handle]);
|
|
4486
|
+
const getVersion = (0, import_react25.useMemo)(() => handle.version.bind(handle), [handle]);
|
|
4487
|
+
const version = (0, import_react25.useSyncExternalStore)(subscribe, getVersion, getVersion);
|
|
4488
|
+
return (0, import_react25.useMemo)(() => getSnapshot(), [version, getSnapshot]);
|
|
4308
4489
|
}
|
|
4309
4490
|
|
|
4310
4491
|
// src/components/FlowchartView/walkHelpers.ts
|
|
@@ -4387,7 +4568,7 @@ function bfsWalk(index, startId, neighborsOf, options) {
|
|
|
4387
4568
|
}
|
|
4388
4569
|
|
|
4389
4570
|
// src/components/FlowchartView/NodeInspector.tsx
|
|
4390
|
-
var
|
|
4571
|
+
var import_react26 = require("react");
|
|
4391
4572
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
4392
4573
|
function NodeInspector({
|
|
4393
4574
|
index,
|
|
@@ -4398,11 +4579,11 @@ function NodeInspector({
|
|
|
4398
4579
|
style
|
|
4399
4580
|
}) {
|
|
4400
4581
|
const view = selectedId ? index.byStageId.get(selectedId) ?? null : null;
|
|
4401
|
-
const prevChain = (0,
|
|
4582
|
+
const prevChain = (0, import_react26.useMemo)(
|
|
4402
4583
|
() => view ? backtraceStructural(index, view.stageId, { onlyVisited }) : [],
|
|
4403
4584
|
[index, view, onlyVisited]
|
|
4404
4585
|
);
|
|
4405
|
-
const nextChain = (0,
|
|
4586
|
+
const nextChain = (0, import_react26.useMemo)(
|
|
4406
4587
|
() => view ? forwardtraceStructural(index, view.stageId, { onlyVisited }) : [],
|
|
4407
4588
|
[index, view, onlyVisited]
|
|
4408
4589
|
);
|
|
@@ -4528,7 +4709,7 @@ function Crumbs({ nodes, onClick }) {
|
|
|
4528
4709
|
}
|
|
4529
4710
|
|
|
4530
4711
|
// src/components/FlowchartView/CommitInspector.tsx
|
|
4531
|
-
var
|
|
4712
|
+
var import_react27 = require("react");
|
|
4532
4713
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
4533
4714
|
function CommitInspector({
|
|
4534
4715
|
index,
|
|
@@ -4538,7 +4719,7 @@ function CommitInspector({
|
|
|
4538
4719
|
style
|
|
4539
4720
|
}) {
|
|
4540
4721
|
const view = selectedRuntimeStageId ? index.byRuntimeStageId.get(selectedRuntimeStageId) ?? null : null;
|
|
4541
|
-
const lineage = (0,
|
|
4722
|
+
const lineage = (0, import_react27.useMemo)(
|
|
4542
4723
|
() => view ? backtraceDataFlow(index, view.runtimeStageId) : [],
|
|
4543
4724
|
[index, view]
|
|
4544
4725
|
);
|
|
@@ -5124,10 +5305,10 @@ var boxBaseStyle = {
|
|
|
5124
5305
|
};
|
|
5125
5306
|
|
|
5126
5307
|
// src/components/FlowchartView/TraceExplorerShell.tsx
|
|
5127
|
-
var
|
|
5308
|
+
var import_react29 = require("react");
|
|
5128
5309
|
|
|
5129
5310
|
// src/components/FlowchartView/RunSlider.tsx
|
|
5130
|
-
var
|
|
5311
|
+
var import_react28 = require("react");
|
|
5131
5312
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
5132
5313
|
function RunSlider({
|
|
5133
5314
|
index,
|
|
@@ -5138,12 +5319,12 @@ function RunSlider({
|
|
|
5138
5319
|
style
|
|
5139
5320
|
}) {
|
|
5140
5321
|
const total = index.commits.length;
|
|
5141
|
-
const cursorCommitIdx = (0,
|
|
5322
|
+
const cursorCommitIdx = (0, import_react28.useMemo)(() => {
|
|
5142
5323
|
if (!cursorRuntimeStageId) return 0;
|
|
5143
5324
|
const view = index.byRuntimeStageId.get(cursorRuntimeStageId);
|
|
5144
5325
|
return view ? view.commitIdx : 0;
|
|
5145
5326
|
}, [index, cursorRuntimeStageId]);
|
|
5146
|
-
const handleSliderChange = (0,
|
|
5327
|
+
const handleSliderChange = (0, import_react28.useCallback)(
|
|
5147
5328
|
(e) => {
|
|
5148
5329
|
const value = Number(e.target.value);
|
|
5149
5330
|
const view = index.commits[value];
|
|
@@ -5151,7 +5332,7 @@ function RunSlider({
|
|
|
5151
5332
|
},
|
|
5152
5333
|
[index, onCursorChange]
|
|
5153
5334
|
);
|
|
5154
|
-
const label = (0,
|
|
5335
|
+
const label = (0, import_react28.useMemo)(() => {
|
|
5155
5336
|
const commit = index.commits[cursorCommitIdx] ?? null;
|
|
5156
5337
|
const rsid = cursorRuntimeStageId ?? commit?.runtimeStageId ?? null;
|
|
5157
5338
|
if (renderLabel)
|
|
@@ -5235,39 +5416,39 @@ function TraceExplorerShell({
|
|
|
5235
5416
|
className,
|
|
5236
5417
|
style
|
|
5237
5418
|
}) {
|
|
5238
|
-
const [internalSel, setInternalSel] = (0,
|
|
5419
|
+
const [internalSel, setInternalSel] = (0, import_react29.useState)(null);
|
|
5239
5420
|
const isControlled = controlledSel !== void 0;
|
|
5240
5421
|
const selectedRuntimeStageId = isControlled ? controlledSel : internalSel;
|
|
5241
|
-
const handleSelect = (0,
|
|
5422
|
+
const handleSelect = (0, import_react29.useCallback)(
|
|
5242
5423
|
(rsid) => {
|
|
5243
5424
|
if (!isControlled) setInternalSel(rsid);
|
|
5244
5425
|
onSelectionChange?.(rsid);
|
|
5245
5426
|
},
|
|
5246
5427
|
[isControlled, onSelectionChange]
|
|
5247
5428
|
);
|
|
5248
|
-
const handleSelectCommit = (0,
|
|
5429
|
+
const handleSelectCommit = (0, import_react29.useCallback)(
|
|
5249
5430
|
(rsid) => handleSelect(rsid),
|
|
5250
5431
|
[handleSelect]
|
|
5251
5432
|
);
|
|
5252
|
-
const selectedStageId = (0,
|
|
5433
|
+
const selectedStageId = (0, import_react29.useMemo)(() => {
|
|
5253
5434
|
if (!selectedRuntimeStageId) return null;
|
|
5254
5435
|
const hashIdx = selectedRuntimeStageId.lastIndexOf("#");
|
|
5255
5436
|
if (hashIdx <= 0) return null;
|
|
5256
5437
|
return asStageId(selectedRuntimeStageId.slice(0, hashIdx));
|
|
5257
5438
|
}, [selectedRuntimeStageId]);
|
|
5258
|
-
const ChainPane = (0,
|
|
5439
|
+
const ChainPane = (0, import_react29.useMemo)(
|
|
5259
5440
|
() => slots?.chain ?? DefaultChainPane,
|
|
5260
5441
|
[slots?.chain]
|
|
5261
5442
|
);
|
|
5262
|
-
const CommitPane = (0,
|
|
5443
|
+
const CommitPane = (0, import_react29.useMemo)(
|
|
5263
5444
|
() => slots?.commitInspector ?? DefaultCommitPane,
|
|
5264
5445
|
[slots?.commitInspector]
|
|
5265
5446
|
);
|
|
5266
|
-
const NodePane = (0,
|
|
5447
|
+
const NodePane = (0, import_react29.useMemo)(
|
|
5267
5448
|
() => slots?.nodeInspector ?? DefaultNodePane,
|
|
5268
5449
|
[slots?.nodeInspector]
|
|
5269
5450
|
);
|
|
5270
|
-
const SliderPane = (0,
|
|
5451
|
+
const SliderPane = (0, import_react29.useMemo)(() => {
|
|
5271
5452
|
if (slots && "slider" in slots) {
|
|
5272
5453
|
return slots.slider ?? null;
|
|
5273
5454
|
}
|
|
@@ -5282,7 +5463,7 @@ function TraceExplorerShell({
|
|
|
5282
5463
|
() => bundle.commitFlow.getIndex()
|
|
5283
5464
|
);
|
|
5284
5465
|
const nodeIndex = useTranslator(bundle.nodeView, () => bundle.nodeView.getIndex());
|
|
5285
|
-
const handleStageNavigate = (0,
|
|
5466
|
+
const handleStageNavigate = (0, import_react29.useCallback)(
|
|
5286
5467
|
(stageId) => {
|
|
5287
5468
|
const candidates = commitIndex.commits.filter((c) => c.stageId === stageId);
|
|
5288
5469
|
const first = candidates[0];
|
|
@@ -5290,12 +5471,12 @@ function TraceExplorerShell({
|
|
|
5290
5471
|
},
|
|
5291
5472
|
[commitIndex, handleSelect]
|
|
5292
5473
|
);
|
|
5293
|
-
const revealedThroughCommitIdx = (0,
|
|
5474
|
+
const revealedThroughCommitIdx = (0, import_react29.useMemo)(() => {
|
|
5294
5475
|
if (!selectedRuntimeStageId) return null;
|
|
5295
5476
|
const view = commitIndex.byRuntimeStageId.get(selectedRuntimeStageId);
|
|
5296
5477
|
return view ? view.commitIdx : -1;
|
|
5297
5478
|
}, [selectedRuntimeStageId, commitIndex]);
|
|
5298
|
-
const layoutStyle = (0,
|
|
5479
|
+
const layoutStyle = (0, import_react29.useMemo)(
|
|
5299
5480
|
() => SliderPane ? SHELL_STYLE_WITH_SLIDER : SHELL_STYLE_NO_SLIDER,
|
|
5300
5481
|
[SliderPane]
|
|
5301
5482
|
);
|