footprint-explainable-ui 0.27.0 → 0.28.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/dist/flowchart.cjs +35 -2
- package/dist/flowchart.cjs.map +1 -1
- package/dist/flowchart.d.cts +12 -1
- package/dist/flowchart.d.ts +12 -1
- package/dist/flowchart.js +35 -2
- package/dist/flowchart.js.map +1 -1
- package/dist/index.cjs +71 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +71 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -731,6 +731,9 @@ interface ExplainableShellProps extends BaseComponentProps {
|
|
|
731
731
|
selectedIndex: number;
|
|
732
732
|
onNodeClick?: (indexOrId: number | string) => void;
|
|
733
733
|
showStageId?: boolean;
|
|
734
|
+
/** Dependency-cone overlay (chart node id → BFS depth) — painted while
|
|
735
|
+
* the Inspector's Data Trace tab is open. Custom renderers may ignore it. */
|
|
736
|
+
sliceCone?: ReadonlyMap<string, number>;
|
|
734
737
|
}) => React.ReactNode;
|
|
735
738
|
/**
|
|
736
739
|
* When true, render each node's stable `stageId` as a small monospace
|
|
@@ -1103,6 +1106,9 @@ interface InspectorPanelProps {
|
|
|
1103
1106
|
selectedStageId?: string;
|
|
1104
1107
|
/** Navigate to a stage when clicking a Data Trace frame. */
|
|
1105
1108
|
onNavigateToStage?: (runtimeStageId: string) => void;
|
|
1109
|
+
/** Fires when the user switches tabs — lets the shell paint the chart's
|
|
1110
|
+
* dependency cone while the Data Trace tab is open. */
|
|
1111
|
+
onTabChange?: (tab: "state" | "trace") => void;
|
|
1106
1112
|
}
|
|
1107
1113
|
declare const InspectorPanel: react.NamedExoticComponent<InspectorPanelProps>;
|
|
1108
1114
|
|
package/dist/index.d.ts
CHANGED
|
@@ -731,6 +731,9 @@ interface ExplainableShellProps extends BaseComponentProps {
|
|
|
731
731
|
selectedIndex: number;
|
|
732
732
|
onNodeClick?: (indexOrId: number | string) => void;
|
|
733
733
|
showStageId?: boolean;
|
|
734
|
+
/** Dependency-cone overlay (chart node id → BFS depth) — painted while
|
|
735
|
+
* the Inspector's Data Trace tab is open. Custom renderers may ignore it. */
|
|
736
|
+
sliceCone?: ReadonlyMap<string, number>;
|
|
734
737
|
}) => React.ReactNode;
|
|
735
738
|
/**
|
|
736
739
|
* When true, render each node's stable `stageId` as a small monospace
|
|
@@ -1103,6 +1106,9 @@ interface InspectorPanelProps {
|
|
|
1103
1106
|
selectedStageId?: string;
|
|
1104
1107
|
/** Navigate to a stage when clicking a Data Trace frame. */
|
|
1105
1108
|
onNavigateToStage?: (runtimeStageId: string) => void;
|
|
1109
|
+
/** Fires when the user switches tabs — lets the shell paint the chart's
|
|
1110
|
+
* dependency cone while the Data Trace tab is open. */
|
|
1111
|
+
onTabChange?: (tab: "state" | "trace") => void;
|
|
1106
1112
|
}
|
|
1107
1113
|
declare const InspectorPanel: react.NamedExoticComponent<InspectorPanelProps>;
|
|
1108
1114
|
|
package/dist/index.js
CHANGED
|
@@ -5025,6 +5025,7 @@ function TracedFlow({
|
|
|
5025
5025
|
nodeTypes: userNodeTypes,
|
|
5026
5026
|
edgeTypes: userEdgeTypes,
|
|
5027
5027
|
coActiveStageIds,
|
|
5028
|
+
sliceCone,
|
|
5028
5029
|
children,
|
|
5029
5030
|
className,
|
|
5030
5031
|
style
|
|
@@ -5126,6 +5127,38 @@ function TracedFlow({
|
|
|
5126
5127
|
),
|
|
5127
5128
|
[positioned.edges, slice, colors]
|
|
5128
5129
|
);
|
|
5130
|
+
const [coneRevealed, setConeRevealed] = useState10(false);
|
|
5131
|
+
useEffect10(() => {
|
|
5132
|
+
if (!sliceCone) return;
|
|
5133
|
+
setConeRevealed(false);
|
|
5134
|
+
const raf = requestAnimationFrame(() => setConeRevealed(true));
|
|
5135
|
+
return () => cancelAnimationFrame(raf);
|
|
5136
|
+
}, [sliceCone]);
|
|
5137
|
+
const conedNodes = useMemo10(() => {
|
|
5138
|
+
if (!sliceCone || sliceCone.size === 0) return reactFlowNodes;
|
|
5139
|
+
return reactFlowNodes.map((n) => {
|
|
5140
|
+
const depth = sliceCone.get(n.id);
|
|
5141
|
+
if (depth === void 0) {
|
|
5142
|
+
return { ...n, style: { ...n.style, opacity: 0.22, transition: "opacity 260ms ease" } };
|
|
5143
|
+
}
|
|
5144
|
+
return {
|
|
5145
|
+
...n,
|
|
5146
|
+
style: {
|
|
5147
|
+
...n.style,
|
|
5148
|
+
opacity: coneRevealed ? 1 : 0.22,
|
|
5149
|
+
transition: "opacity 320ms ease",
|
|
5150
|
+
transitionDelay: `${depth * 90}ms`
|
|
5151
|
+
}
|
|
5152
|
+
};
|
|
5153
|
+
});
|
|
5154
|
+
}, [reactFlowNodes, sliceCone, coneRevealed]);
|
|
5155
|
+
const conedEdges = useMemo10(() => {
|
|
5156
|
+
if (!sliceCone || sliceCone.size === 0) return reactFlowEdges;
|
|
5157
|
+
return reactFlowEdges.map((e) => {
|
|
5158
|
+
const inCone = sliceCone.has(e.source) && sliceCone.has(e.target);
|
|
5159
|
+
return inCone ? e : { ...e, style: { ...e.style, opacity: 0.12, transition: "opacity 260ms ease" } };
|
|
5160
|
+
});
|
|
5161
|
+
}, [reactFlowEdges, sliceCone]);
|
|
5129
5162
|
const handleNodeClick = useCallback7(
|
|
5130
5163
|
(_, node) => {
|
|
5131
5164
|
const data = node.data ?? {};
|
|
@@ -5167,8 +5200,8 @@ function TracedFlow({
|
|
|
5167
5200
|
/* @__PURE__ */ jsx21("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsxs18(
|
|
5168
5201
|
ReactFlow,
|
|
5169
5202
|
{
|
|
5170
|
-
nodes:
|
|
5171
|
-
edges:
|
|
5203
|
+
nodes: conedNodes,
|
|
5204
|
+
edges: conedEdges,
|
|
5172
5205
|
nodeTypes: mergedNodeTypes,
|
|
5173
5206
|
edgeTypes: mergedEdgeTypes,
|
|
5174
5207
|
onNodeClick: handleNodeClick,
|
|
@@ -5361,9 +5394,14 @@ var InspectorPanel = memo5(function InspectorPanel2({
|
|
|
5361
5394
|
dataTraceFrames,
|
|
5362
5395
|
dataTraceNote,
|
|
5363
5396
|
selectedStageId,
|
|
5364
|
-
onNavigateToStage
|
|
5397
|
+
onNavigateToStage,
|
|
5398
|
+
onTabChange
|
|
5365
5399
|
}) {
|
|
5366
|
-
const [tab,
|
|
5400
|
+
const [tab, setTabState] = useState11("state");
|
|
5401
|
+
const setTab = (t) => {
|
|
5402
|
+
setTabState(t);
|
|
5403
|
+
onTabChange?.(t);
|
|
5404
|
+
};
|
|
5367
5405
|
const currentSnapshot = snapshots[selectedIndex];
|
|
5368
5406
|
return /* @__PURE__ */ jsxs20(
|
|
5369
5407
|
"div",
|
|
@@ -6020,12 +6058,10 @@ var RightPanel = memo8(function RightPanel2({
|
|
|
6020
6058
|
recorderViews,
|
|
6021
6059
|
autoRecorderViews,
|
|
6022
6060
|
size,
|
|
6023
|
-
onNavigateToStage
|
|
6061
|
+
onNavigateToStage,
|
|
6062
|
+
dataTrace,
|
|
6063
|
+
onInspectorTabChange
|
|
6024
6064
|
}) {
|
|
6025
|
-
const dataTrace = useMemo12(
|
|
6026
|
-
() => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, snapshots[selectedIndex]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
|
|
6027
|
-
[runtimeSnapshot, snapshots, selectedIndex]
|
|
6028
|
-
);
|
|
6029
6065
|
return /* @__PURE__ */ jsxs23(Fragment6, { children: [
|
|
6030
6066
|
/* @__PURE__ */ jsx26("div", { style: {
|
|
6031
6067
|
display: "flex",
|
|
@@ -6079,6 +6115,7 @@ var RightPanel = memo8(function RightPanel2({
|
|
|
6079
6115
|
selectedIndex,
|
|
6080
6116
|
dataTraceFrames: dataTrace.frames,
|
|
6081
6117
|
dataTraceNote: dataTrace.readsAvailable ? void 0 : "\u26A0 reads were not recorded (readTracking off) \u2014 dependencies are unknowable, not absent.",
|
|
6118
|
+
onTabChange: onInspectorTabChange,
|
|
6082
6119
|
selectedStageId: snapshots[selectedIndex]?.runtimeStageId,
|
|
6083
6120
|
onNavigateToStage
|
|
6084
6121
|
}
|
|
@@ -6132,7 +6169,7 @@ function ExplainableShell({
|
|
|
6132
6169
|
const resultData = resultDataProp ?? derivedFromRuntime?.resultData ?? null;
|
|
6133
6170
|
const tracedFlowRenderer = useMemo12(() => {
|
|
6134
6171
|
if (!traceGraph) return void 0;
|
|
6135
|
-
return ({ selectedIndex, snapshots: snapshots2, onNodeClick }) => {
|
|
6172
|
+
return ({ selectedIndex, snapshots: snapshots2, onNodeClick, sliceCone: sliceCone2 }) => {
|
|
6136
6173
|
const activeRsid = snapshots2[selectedIndex]?.runtimeStageId;
|
|
6137
6174
|
let overlayIdx = selectedIndex;
|
|
6138
6175
|
if (activeRsid && runtimeOverlay) {
|
|
@@ -6156,6 +6193,7 @@ function ExplainableShell({
|
|
|
6156
6193
|
{
|
|
6157
6194
|
graph: traceGraph,
|
|
6158
6195
|
overlay: runtimeOverlay ?? void 0,
|
|
6196
|
+
sliceCone: sliceCone2 ?? void 0,
|
|
6159
6197
|
colors: traceColors || void 0,
|
|
6160
6198
|
scrubIndex: overlayIdx,
|
|
6161
6199
|
onNodeClick: (stageId) => onNodeClick?.(stageId),
|
|
@@ -6216,6 +6254,7 @@ function ExplainableShell({
|
|
|
6216
6254
|
const [drillDownStack, setDrillDownStack] = useState14([]);
|
|
6217
6255
|
const [rightExpanded, setRightExpanded] = useState14(defaultExpanded?.details ?? true);
|
|
6218
6256
|
const [rightPanelMode, setRightPanelMode] = useState14("insights");
|
|
6257
|
+
const [inspectorTab, setInspectorTab] = useState14("state");
|
|
6219
6258
|
const [leftExpanded, setLeftExpanded] = useState14(defaultExpanded?.topology ?? false);
|
|
6220
6259
|
const [timelineExpanded, setTimelineExpanded] = useState14(defaultExpanded?.timeline ?? false);
|
|
6221
6260
|
useEffect11(() => {
|
|
@@ -6251,6 +6290,21 @@ function ExplainableShell({
|
|
|
6251
6290
|
}, [drillDownStack, snapshots]);
|
|
6252
6291
|
const activeSnapshots = currentLevel.snapshots;
|
|
6253
6292
|
const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
|
|
6293
|
+
const shellDataTrace = useMemo12(
|
|
6294
|
+
() => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, activeSnapshots[safeIdx]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
|
|
6295
|
+
[runtimeSnapshot, activeSnapshots, safeIdx]
|
|
6296
|
+
);
|
|
6297
|
+
const sliceCone = useMemo12(() => {
|
|
6298
|
+
if (rightPanelMode !== "what" || inspectorTab !== "trace") return void 0;
|
|
6299
|
+
if (shellDataTrace.frames.length < 2) return void 0;
|
|
6300
|
+
const cone = /* @__PURE__ */ new Map();
|
|
6301
|
+
for (const f of shellDataTrace.frames) {
|
|
6302
|
+
const stagePart = f.runtimeStageId.split("#")[0];
|
|
6303
|
+
const prev = cone.get(stagePart);
|
|
6304
|
+
if (prev === void 0 || f.depth < prev) cone.set(stagePart, f.depth);
|
|
6305
|
+
}
|
|
6306
|
+
return cone;
|
|
6307
|
+
}, [rightPanelMode, inspectorTab, shellDataTrace]);
|
|
6254
6308
|
const activeNarrativeEntries = isInSubflow ? currentLevel.narrative : narrativeEntries;
|
|
6255
6309
|
const breadcrumbs = useMemo12(() => {
|
|
6256
6310
|
const root = { label: title || "Flowchart", spec: null, description: void 0 };
|
|
@@ -6334,7 +6388,7 @@ function ExplainableShell({
|
|
|
6334
6388
|
(activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ jsxs23(Fragment6, { children: [
|
|
6335
6389
|
/* @__PURE__ */ jsx26(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
|
|
6336
6390
|
isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
6337
|
-
traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId }),
|
|
6391
|
+
traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId, ...sliceCone && { sliceCone } }),
|
|
6338
6392
|
/* @__PURE__ */ jsx26(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
|
|
6339
6393
|
/* @__PURE__ */ jsx26(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
|
|
6340
6394
|
/* @__PURE__ */ jsx26(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
|
|
@@ -6453,7 +6507,8 @@ function ExplainableShell({
|
|
|
6453
6507
|
snapshots: activeSnapshots,
|
|
6454
6508
|
selectedIndex: safeIdx,
|
|
6455
6509
|
onNodeClick: handleNodeClick,
|
|
6456
|
-
showStageId
|
|
6510
|
+
showStageId,
|
|
6511
|
+
...sliceCone && { sliceCone }
|
|
6457
6512
|
}) }),
|
|
6458
6513
|
showTreeSidebar && /* @__PURE__ */ jsxs23(Fragment6, { children: [
|
|
6459
6514
|
/* @__PURE__ */ jsx26(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
|
|
@@ -6493,7 +6548,8 @@ function ExplainableShell({
|
|
|
6493
6548
|
snapshots: activeSnapshots,
|
|
6494
6549
|
selectedIndex: safeIdx,
|
|
6495
6550
|
onNodeClick: handleNodeClick,
|
|
6496
|
-
showStageId
|
|
6551
|
+
showStageId,
|
|
6552
|
+
...sliceCone && { sliceCone }
|
|
6497
6553
|
}) }) : /* @__PURE__ */ jsx26("div", { style: { flex: 1 } }),
|
|
6498
6554
|
/* @__PURE__ */ jsx26(VLinePill, { label: "Details", expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
|
|
6499
6555
|
rightExpanded && /* @__PURE__ */ jsx26("div", { style: { width: "42%", minWidth: 320, maxWidth: 550, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx26(
|
|
@@ -6501,6 +6557,8 @@ function ExplainableShell({
|
|
|
6501
6557
|
{
|
|
6502
6558
|
mode: rightPanelMode,
|
|
6503
6559
|
onModeChange: setRightPanelMode,
|
|
6560
|
+
dataTrace: shellDataTrace,
|
|
6561
|
+
onInspectorTabChange: setInspectorTab,
|
|
6504
6562
|
snapshots: activeSnapshots,
|
|
6505
6563
|
selectedIndex: safeIdx,
|
|
6506
6564
|
runtimeSnapshot,
|