footprint-explainable-ui 0.3.2 → 0.5.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 +42 -3
- package/dist/adapters/fromRuntimeSnapshot.d.ts +52 -0
- package/dist/adapters/fromRuntimeSnapshot.d.ts.map +1 -0
- package/dist/adapters/fromRuntimeSnapshot.js +97 -0
- package/dist/adapters/fromRuntimeSnapshot.js.map +1 -0
- package/dist/components/ExplainableShell/ExplainableShell.d.ts +26 -0
- package/dist/components/ExplainableShell/ExplainableShell.d.ts.map +1 -0
- package/dist/components/ExplainableShell/ExplainableShell.js +94 -0
- package/dist/components/ExplainableShell/ExplainableShell.js.map +1 -0
- package/dist/components/ExplainableShell/index.d.ts +3 -0
- package/dist/components/ExplainableShell/index.d.ts.map +1 -0
- package/dist/components/ExplainableShell/index.js +2 -0
- package/dist/components/ExplainableShell/index.js.map +1 -0
- package/dist/components/FlowchartView/FlowchartView.d.ts +20 -0
- package/dist/components/FlowchartView/FlowchartView.d.ts.map +1 -0
- package/dist/components/FlowchartView/FlowchartView.js +80 -0
- package/dist/components/FlowchartView/FlowchartView.js.map +1 -0
- package/dist/components/FlowchartView/SubflowBreadcrumb.d.ts +11 -0
- package/dist/components/FlowchartView/SubflowBreadcrumb.d.ts.map +1 -0
- package/dist/components/FlowchartView/SubflowBreadcrumb.js +49 -0
- package/dist/components/FlowchartView/SubflowBreadcrumb.js.map +1 -0
- package/dist/components/FlowchartView/SubflowTree.d.ts +36 -0
- package/dist/components/FlowchartView/SubflowTree.d.ts.map +1 -0
- package/dist/components/FlowchartView/SubflowTree.js +143 -0
- package/dist/components/FlowchartView/SubflowTree.js.map +1 -0
- package/dist/components/FlowchartView/TracedFlowchartView.d.ts +20 -0
- package/dist/components/FlowchartView/TracedFlowchartView.d.ts.map +1 -0
- package/dist/components/FlowchartView/TracedFlowchartView.js +101 -0
- package/dist/components/FlowchartView/TracedFlowchartView.js.map +1 -0
- package/dist/components/FlowchartView/index.d.ts +11 -0
- package/dist/components/FlowchartView/index.d.ts.map +1 -0
- package/dist/components/FlowchartView/index.js +6 -0
- package/dist/components/FlowchartView/index.js.map +1 -0
- package/dist/components/FlowchartView/specToReactFlow.d.ts +56 -0
- package/dist/components/FlowchartView/specToReactFlow.d.ts.map +1 -0
- package/dist/components/FlowchartView/specToReactFlow.js +202 -0
- package/dist/components/FlowchartView/specToReactFlow.js.map +1 -0
- package/dist/components/FlowchartView/useSubflowNavigation.d.ts +35 -0
- package/dist/components/FlowchartView/useSubflowNavigation.d.ts.map +1 -0
- package/dist/components/FlowchartView/useSubflowNavigation.js +80 -0
- package/dist/components/FlowchartView/useSubflowNavigation.js.map +1 -0
- package/dist/components/GanttTimeline/GanttTimeline.d.ts +18 -0
- package/dist/components/GanttTimeline/GanttTimeline.d.ts.map +1 -0
- package/dist/components/GanttTimeline/GanttTimeline.js +123 -0
- package/dist/components/GanttTimeline/GanttTimeline.js.map +1 -0
- package/dist/components/GanttTimeline/index.d.ts +3 -0
- package/dist/components/GanttTimeline/index.d.ts.map +1 -0
- package/dist/components/GanttTimeline/index.js +2 -0
- package/dist/components/GanttTimeline/index.js.map +1 -0
- package/dist/components/MemoryInspector/MemoryInspector.d.ts +19 -0
- package/dist/components/MemoryInspector/MemoryInspector.d.ts.map +1 -0
- package/dist/components/MemoryInspector/MemoryInspector.js +95 -0
- package/dist/components/MemoryInspector/MemoryInspector.js.map +1 -0
- package/dist/components/MemoryInspector/index.d.ts +3 -0
- package/dist/components/MemoryInspector/index.d.ts.map +1 -0
- package/dist/components/MemoryInspector/index.js +2 -0
- package/dist/components/MemoryInspector/index.js.map +1 -0
- package/dist/components/NarrativeLog/NarrativeLog.d.ts +15 -0
- package/dist/components/NarrativeLog/NarrativeLog.d.ts.map +1 -0
- package/dist/components/NarrativeLog/NarrativeLog.js +65 -0
- package/dist/components/NarrativeLog/NarrativeLog.js.map +1 -0
- package/dist/components/NarrativeLog/index.d.ts +3 -0
- package/dist/components/NarrativeLog/index.d.ts.map +1 -0
- package/dist/components/NarrativeLog/index.js +2 -0
- package/dist/components/NarrativeLog/index.js.map +1 -0
- package/dist/components/NarrativeTrace/NarrativeTrace.d.ts +13 -0
- package/dist/components/NarrativeTrace/NarrativeTrace.d.ts.map +1 -0
- package/dist/components/NarrativeTrace/NarrativeTrace.js +127 -0
- package/dist/components/NarrativeTrace/NarrativeTrace.js.map +1 -0
- package/dist/components/NarrativeTrace/index.d.ts +3 -0
- package/dist/components/NarrativeTrace/index.d.ts.map +1 -0
- package/dist/components/NarrativeTrace/index.js +2 -0
- package/dist/components/NarrativeTrace/index.js.map +1 -0
- package/dist/components/ResultPanel/ResultPanel.d.ts +11 -0
- package/dist/components/ResultPanel/ResultPanel.d.ts.map +1 -0
- package/dist/components/ResultPanel/ResultPanel.js +54 -0
- package/dist/components/ResultPanel/ResultPanel.js.map +1 -0
- package/dist/components/ResultPanel/index.d.ts +3 -0
- package/dist/components/ResultPanel/index.d.ts.map +1 -0
- package/dist/components/ResultPanel/index.js +2 -0
- package/dist/components/ResultPanel/index.js.map +1 -0
- package/dist/components/ScopeDiff/ScopeDiff.d.ts +17 -0
- package/dist/components/ScopeDiff/ScopeDiff.d.ts.map +1 -0
- package/dist/components/ScopeDiff/ScopeDiff.js +87 -0
- package/dist/components/ScopeDiff/ScopeDiff.js.map +1 -0
- package/dist/components/ScopeDiff/index.d.ts +3 -0
- package/dist/components/ScopeDiff/index.d.ts.map +1 -0
- package/dist/components/ScopeDiff/index.js +2 -0
- package/dist/components/ScopeDiff/index.js.map +1 -0
- package/dist/components/SnapshotPanel/SnapshotPanel.d.ts +17 -0
- package/dist/components/SnapshotPanel/SnapshotPanel.d.ts.map +1 -0
- package/dist/components/SnapshotPanel/SnapshotPanel.js +85 -0
- package/dist/components/SnapshotPanel/SnapshotPanel.js.map +1 -0
- package/dist/components/SnapshotPanel/index.d.ts +3 -0
- package/dist/components/SnapshotPanel/index.d.ts.map +1 -0
- package/dist/components/SnapshotPanel/index.js +2 -0
- package/dist/components/SnapshotPanel/index.js.map +1 -0
- package/dist/components/StageNode/StageNode.d.ts +31 -0
- package/dist/components/StageNode/StageNode.d.ts.map +1 -0
- package/dist/components/StageNode/StageNode.js +134 -0
- package/dist/components/StageNode/StageNode.js.map +1 -0
- package/dist/components/StageNode/index.d.ts +3 -0
- package/dist/components/StageNode/index.d.ts.map +1 -0
- package/dist/components/StageNode/index.js +2 -0
- package/dist/components/StageNode/index.js.map +1 -0
- package/dist/components/TimeTravelControls/TimeTravelControls.d.ts +13 -0
- package/dist/components/TimeTravelControls/TimeTravelControls.d.ts.map +1 -0
- package/dist/components/TimeTravelControls/TimeTravelControls.js +104 -0
- package/dist/components/TimeTravelControls/TimeTravelControls.js.map +1 -0
- package/dist/components/TimeTravelControls/index.d.ts +3 -0
- package/dist/components/TimeTravelControls/index.d.ts.map +1 -0
- package/dist/components/TimeTravelControls/index.js +2 -0
- package/dist/components/TimeTravelControls/index.js.map +1 -0
- package/dist/components/TimeTravelDebugger/TimeTravelDebugger.d.ts +22 -0
- package/dist/components/TimeTravelDebugger/TimeTravelDebugger.d.ts.map +1 -0
- package/dist/components/TimeTravelDebugger/TimeTravelDebugger.js +104 -0
- package/dist/components/TimeTravelDebugger/TimeTravelDebugger.js.map +1 -0
- package/dist/components/TimeTravelDebugger/index.d.ts +3 -0
- package/dist/components/TimeTravelDebugger/index.d.ts.map +1 -0
- package/dist/components/TimeTravelDebugger/index.js +2 -0
- package/dist/components/TimeTravelDebugger/index.js.map +1 -0
- package/dist/flowchart.cjs +704 -220
- package/dist/flowchart.cjs.map +1 -1
- package/dist/flowchart.d.cts +55 -1
- package/dist/flowchart.d.ts +55 -1
- package/dist/flowchart.d.ts.map +1 -0
- package/dist/flowchart.js +700 -214
- package/dist/flowchart.js.map +1 -1
- package/dist/index.cjs +849 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +95 -3
- package/dist/index.d.ts +95 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +851 -80
- package/dist/index.js.map +1 -1
- package/dist/theme/ThemeProvider.d.ts +13 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +16 -0
- package/dist/theme/ThemeProvider.js.map +1 -0
- package/dist/theme/index.d.ts +7 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +5 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/presets.d.ts +15 -0
- package/dist/theme/presets.d.ts.map +1 -0
- package/dist/theme/presets.js +70 -0
- package/dist/theme/presets.js.map +1 -0
- package/dist/theme/styles.d.ts +32 -0
- package/dist/theme/styles.d.ts.map +1 -0
- package/dist/theme/styles.js +37 -0
- package/dist/theme/styles.js.map +1 -0
- package/dist/theme/tokens.d.ts +28 -0
- package/dist/theme/tokens.d.ts.map +1 -0
- package/dist/theme/tokens.js +58 -0
- package/dist/theme/tokens.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +10 -4
package/dist/index.js
CHANGED
|
@@ -644,7 +644,7 @@ function NarrativeTrace({
|
|
|
644
644
|
}
|
|
645
645
|
|
|
646
646
|
// src/components/GanttTimeline/GanttTimeline.tsx
|
|
647
|
-
import { useMemo as useMemo4 } from "react";
|
|
647
|
+
import { useState as useState2, useMemo as useMemo4, useRef as useRef2, useEffect as useEffect2 } from "react";
|
|
648
648
|
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
649
649
|
function GanttTimeline({
|
|
650
650
|
snapshots,
|
|
@@ -653,8 +653,12 @@ function GanttTimeline({
|
|
|
653
653
|
size = "default",
|
|
654
654
|
unstyled = false,
|
|
655
655
|
className,
|
|
656
|
-
style
|
|
656
|
+
style,
|
|
657
|
+
maxVisibleRows = 5
|
|
657
658
|
}) {
|
|
659
|
+
const [expanded, setExpanded] = useState2(false);
|
|
660
|
+
const activeRowRef = useRef2(null);
|
|
661
|
+
const scrollContainerRef = useRef2(null);
|
|
658
662
|
const totalWallTime = useMemo4(
|
|
659
663
|
() => Math.max(...snapshots.map((s) => s.startMs + s.durationMs), 1),
|
|
660
664
|
[snapshots]
|
|
@@ -663,6 +667,17 @@ function GanttTimeline({
|
|
|
663
667
|
const pad = padding[size];
|
|
664
668
|
const labelWidth = size === "compact" ? 50 : size === "detailed" ? 100 : 80;
|
|
665
669
|
const msWidth = size === "compact" ? 28 : 36;
|
|
670
|
+
const rowHeight = size === "compact" ? 18 : 22;
|
|
671
|
+
const collapsible = maxVisibleRows > 0 && snapshots.length > maxVisibleRows;
|
|
672
|
+
const showAll = expanded || !collapsible;
|
|
673
|
+
useEffect2(() => {
|
|
674
|
+
if (!showAll && activeRowRef.current && scrollContainerRef.current) {
|
|
675
|
+
activeRowRef.current.scrollIntoView({
|
|
676
|
+
block: "nearest",
|
|
677
|
+
behavior: "smooth"
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
}, [selectedIndex, showAll]);
|
|
666
681
|
if (unstyled) {
|
|
667
682
|
return /* @__PURE__ */ jsx5("div", { className, style, "data-fp": "gantt-timeline", children: snapshots.map((snap, idx) => /* @__PURE__ */ jsxs4(
|
|
668
683
|
"div",
|
|
@@ -689,27 +704,62 @@ function GanttTimeline({
|
|
|
689
704
|
style: { padding: pad, fontFamily: theme.fontSans, ...style },
|
|
690
705
|
"data-fp": "gantt-timeline",
|
|
691
706
|
children: [
|
|
692
|
-
/* @__PURE__ */
|
|
693
|
-
"
|
|
707
|
+
/* @__PURE__ */ jsxs4(
|
|
708
|
+
"div",
|
|
694
709
|
{
|
|
695
710
|
style: {
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
textTransform: "uppercase",
|
|
700
|
-
letterSpacing: "0.08em"
|
|
711
|
+
display: "flex",
|
|
712
|
+
alignItems: "center",
|
|
713
|
+
justifyContent: "space-between"
|
|
701
714
|
},
|
|
702
|
-
children:
|
|
715
|
+
children: [
|
|
716
|
+
/* @__PURE__ */ jsx5(
|
|
717
|
+
"span",
|
|
718
|
+
{
|
|
719
|
+
style: {
|
|
720
|
+
fontSize: fs.label,
|
|
721
|
+
fontWeight: 600,
|
|
722
|
+
color: theme.textMuted,
|
|
723
|
+
textTransform: "uppercase",
|
|
724
|
+
letterSpacing: "0.08em"
|
|
725
|
+
},
|
|
726
|
+
children: size === "compact" ? "Timeline" : "Execution Timeline"
|
|
727
|
+
}
|
|
728
|
+
),
|
|
729
|
+
collapsible && /* @__PURE__ */ jsx5(
|
|
730
|
+
"button",
|
|
731
|
+
{
|
|
732
|
+
onClick: () => setExpanded((e) => !e),
|
|
733
|
+
style: {
|
|
734
|
+
background: "none",
|
|
735
|
+
border: `1px solid ${theme.border}`,
|
|
736
|
+
borderRadius: 4,
|
|
737
|
+
color: theme.textSecondary,
|
|
738
|
+
fontSize: fs.small,
|
|
739
|
+
padding: "2px 8px",
|
|
740
|
+
cursor: "pointer",
|
|
741
|
+
fontFamily: theme.fontSans
|
|
742
|
+
},
|
|
743
|
+
children: expanded ? "Collapse" : `${snapshots.length - maxVisibleRows} more...`
|
|
744
|
+
}
|
|
745
|
+
)
|
|
746
|
+
]
|
|
703
747
|
}
|
|
704
748
|
),
|
|
705
749
|
/* @__PURE__ */ jsx5(
|
|
706
750
|
"div",
|
|
707
751
|
{
|
|
752
|
+
ref: scrollContainerRef,
|
|
708
753
|
style: {
|
|
709
754
|
marginTop: 8,
|
|
710
755
|
display: "flex",
|
|
711
756
|
flexDirection: "column",
|
|
712
|
-
gap: 4
|
|
757
|
+
gap: 4,
|
|
758
|
+
...showAll ? {} : {
|
|
759
|
+
maxHeight: maxVisibleRows * (rowHeight + 4),
|
|
760
|
+
overflowY: "auto",
|
|
761
|
+
scrollbarWidth: "thin"
|
|
762
|
+
}
|
|
713
763
|
},
|
|
714
764
|
children: snapshots.map((snap, idx) => {
|
|
715
765
|
const leftPct = snap.startMs / totalWallTime * 100;
|
|
@@ -719,6 +769,7 @@ function GanttTimeline({
|
|
|
719
769
|
return /* @__PURE__ */ jsxs4(
|
|
720
770
|
"div",
|
|
721
771
|
{
|
|
772
|
+
ref: isSelected ? activeRowRef : void 0,
|
|
722
773
|
onClick: () => onSelect?.(idx),
|
|
723
774
|
style: {
|
|
724
775
|
display: "flex",
|
|
@@ -726,7 +777,9 @@ function GanttTimeline({
|
|
|
726
777
|
gap: size === "compact" ? 4 : 8,
|
|
727
778
|
cursor: onSelect ? "pointer" : "default",
|
|
728
779
|
opacity: isVisible ? 1 : 0.3,
|
|
729
|
-
transition: "opacity 0.3s ease"
|
|
780
|
+
transition: "opacity 0.3s ease",
|
|
781
|
+
height: rowHeight,
|
|
782
|
+
flexShrink: 0
|
|
730
783
|
},
|
|
731
784
|
children: [
|
|
732
785
|
/* @__PURE__ */ jsx5(
|
|
@@ -828,7 +881,7 @@ function GanttTimeline({
|
|
|
828
881
|
}
|
|
829
882
|
|
|
830
883
|
// src/components/SnapshotPanel/SnapshotPanel.tsx
|
|
831
|
-
import { useState as
|
|
884
|
+
import { useState as useState3 } from "react";
|
|
832
885
|
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
833
886
|
function SnapshotPanel({
|
|
834
887
|
snapshots,
|
|
@@ -840,7 +893,7 @@ function SnapshotPanel({
|
|
|
840
893
|
className,
|
|
841
894
|
style
|
|
842
895
|
}) {
|
|
843
|
-
const [selectedIndex, setSelectedIndex] =
|
|
896
|
+
const [selectedIndex, setSelectedIndex] = useState3(0);
|
|
844
897
|
const fs = fontSize[size];
|
|
845
898
|
const pad = padding[size];
|
|
846
899
|
if (snapshots.length === 0) {
|
|
@@ -1330,9 +1383,487 @@ function ResultPanel({
|
|
|
1330
1383
|
);
|
|
1331
1384
|
}
|
|
1332
1385
|
|
|
1386
|
+
// src/components/StageDetailPanel/StageDetailPanel.tsx
|
|
1387
|
+
import { useState as useState4, useMemo as useMemo6, useCallback as useCallback2 } from "react";
|
|
1388
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1389
|
+
function computeChanges(prev, curr) {
|
|
1390
|
+
const changes = [];
|
|
1391
|
+
const allKeys = /* @__PURE__ */ new Set([...Object.keys(prev ?? {}), ...Object.keys(curr)]);
|
|
1392
|
+
for (const key of allKeys) {
|
|
1393
|
+
const inPrev = prev != null && key in prev;
|
|
1394
|
+
const inCurr = key in curr;
|
|
1395
|
+
const oldVal = prev?.[key];
|
|
1396
|
+
const newVal = curr[key];
|
|
1397
|
+
if (!inPrev && inCurr) {
|
|
1398
|
+
changes.push({ key, type: "added", newValue: newVal });
|
|
1399
|
+
} else if (inPrev && !inCurr) {
|
|
1400
|
+
changes.push({ key, type: "removed", oldValue: oldVal });
|
|
1401
|
+
} else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
|
|
1402
|
+
changes.push({ key, type: "updated", oldValue: oldVal, newValue: newVal });
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
const order = { added: 0, updated: 1, removed: 2 };
|
|
1406
|
+
changes.sort((a, b) => order[a.type] - order[b.type]);
|
|
1407
|
+
return changes;
|
|
1408
|
+
}
|
|
1409
|
+
function fmt2(v2) {
|
|
1410
|
+
if (typeof v2 === "string") return `"${v2}"`;
|
|
1411
|
+
if (typeof v2 === "object" && v2 !== null) return JSON.stringify(v2, null, 2);
|
|
1412
|
+
return String(v2);
|
|
1413
|
+
}
|
|
1414
|
+
var changeBadge = {
|
|
1415
|
+
added: { bg: "rgba(34,197,94,0.12)", fg: "#22c55e", label: "ADD" },
|
|
1416
|
+
updated: { bg: "rgba(245,158,11,0.12)", fg: "#f59e0b", label: "UPD" },
|
|
1417
|
+
removed: { bg: "rgba(239,68,68,0.12)", fg: "#ef4444", label: "DEL" }
|
|
1418
|
+
};
|
|
1419
|
+
function SimpleView({
|
|
1420
|
+
snapshot,
|
|
1421
|
+
fs,
|
|
1422
|
+
pad
|
|
1423
|
+
}) {
|
|
1424
|
+
return /* @__PURE__ */ jsxs8("div", { style: { display: "flex", flexDirection: "column", gap: 16 }, children: [
|
|
1425
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
1426
|
+
/* @__PURE__ */ jsx9(
|
|
1427
|
+
"div",
|
|
1428
|
+
{
|
|
1429
|
+
style: {
|
|
1430
|
+
fontSize: fs.label + 2,
|
|
1431
|
+
fontWeight: 700,
|
|
1432
|
+
color: theme.textPrimary
|
|
1433
|
+
},
|
|
1434
|
+
children: snapshot.stageLabel
|
|
1435
|
+
}
|
|
1436
|
+
),
|
|
1437
|
+
snapshot.description && /* @__PURE__ */ jsx9(
|
|
1438
|
+
"div",
|
|
1439
|
+
{
|
|
1440
|
+
style: {
|
|
1441
|
+
fontSize: fs.body,
|
|
1442
|
+
color: theme.textSecondary,
|
|
1443
|
+
marginTop: 4,
|
|
1444
|
+
lineHeight: 1.5
|
|
1445
|
+
},
|
|
1446
|
+
children: snapshot.description
|
|
1447
|
+
}
|
|
1448
|
+
)
|
|
1449
|
+
] }),
|
|
1450
|
+
snapshot.status && /* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
1451
|
+
/* @__PURE__ */ jsx9(
|
|
1452
|
+
"div",
|
|
1453
|
+
{
|
|
1454
|
+
style: {
|
|
1455
|
+
width: 8,
|
|
1456
|
+
height: 8,
|
|
1457
|
+
borderRadius: "50%",
|
|
1458
|
+
background: snapshot.status === "done" ? theme.success : snapshot.status === "active" ? theme.primary : snapshot.status === "error" ? theme.error : theme.textMuted
|
|
1459
|
+
}
|
|
1460
|
+
}
|
|
1461
|
+
),
|
|
1462
|
+
/* @__PURE__ */ jsx9(
|
|
1463
|
+
"span",
|
|
1464
|
+
{
|
|
1465
|
+
style: {
|
|
1466
|
+
fontSize: fs.small,
|
|
1467
|
+
color: theme.textMuted,
|
|
1468
|
+
textTransform: "uppercase",
|
|
1469
|
+
letterSpacing: "0.05em"
|
|
1470
|
+
},
|
|
1471
|
+
children: snapshot.status
|
|
1472
|
+
}
|
|
1473
|
+
)
|
|
1474
|
+
] }),
|
|
1475
|
+
snapshot.narrative && /* @__PURE__ */ jsxs8("div", { children: [
|
|
1476
|
+
/* @__PURE__ */ jsx9(
|
|
1477
|
+
"div",
|
|
1478
|
+
{
|
|
1479
|
+
style: {
|
|
1480
|
+
fontSize: fs.label,
|
|
1481
|
+
fontWeight: 600,
|
|
1482
|
+
color: theme.textMuted,
|
|
1483
|
+
textTransform: "uppercase",
|
|
1484
|
+
letterSpacing: "0.08em",
|
|
1485
|
+
marginBottom: 6
|
|
1486
|
+
},
|
|
1487
|
+
children: "What happened"
|
|
1488
|
+
}
|
|
1489
|
+
),
|
|
1490
|
+
/* @__PURE__ */ jsx9(
|
|
1491
|
+
"div",
|
|
1492
|
+
{
|
|
1493
|
+
style: {
|
|
1494
|
+
fontSize: fs.body,
|
|
1495
|
+
lineHeight: 1.6,
|
|
1496
|
+
color: theme.textPrimary,
|
|
1497
|
+
background: theme.bgSecondary,
|
|
1498
|
+
border: `1px solid ${theme.border}`,
|
|
1499
|
+
borderRadius: theme.radius,
|
|
1500
|
+
padding: pad
|
|
1501
|
+
},
|
|
1502
|
+
children: snapshot.narrative
|
|
1503
|
+
}
|
|
1504
|
+
)
|
|
1505
|
+
] }),
|
|
1506
|
+
snapshot.durationMs > 0 && /* @__PURE__ */ jsxs8(
|
|
1507
|
+
"div",
|
|
1508
|
+
{
|
|
1509
|
+
style: {
|
|
1510
|
+
fontSize: fs.small,
|
|
1511
|
+
color: theme.textMuted
|
|
1512
|
+
},
|
|
1513
|
+
children: [
|
|
1514
|
+
"Completed in ",
|
|
1515
|
+
snapshot.durationMs < 1 ? "<1" : snapshot.durationMs,
|
|
1516
|
+
"ms"
|
|
1517
|
+
]
|
|
1518
|
+
}
|
|
1519
|
+
)
|
|
1520
|
+
] });
|
|
1521
|
+
}
|
|
1522
|
+
function buildMemoryRows(currMemory, changes) {
|
|
1523
|
+
const changeMap = new Map(changes.map((c) => [c.key, c]));
|
|
1524
|
+
const rows = [];
|
|
1525
|
+
for (const change of changes) {
|
|
1526
|
+
rows.push({ kind: "change", change });
|
|
1527
|
+
}
|
|
1528
|
+
const unchangedKeys = Object.keys(currMemory).filter((k) => !changeMap.has(k)).sort();
|
|
1529
|
+
for (const key of unchangedKeys) {
|
|
1530
|
+
rows.push({ kind: "unchanged", key, value: currMemory[key] });
|
|
1531
|
+
}
|
|
1532
|
+
return rows;
|
|
1533
|
+
}
|
|
1534
|
+
function DevView({
|
|
1535
|
+
snapshot,
|
|
1536
|
+
changes,
|
|
1537
|
+
currMemory,
|
|
1538
|
+
fs,
|
|
1539
|
+
pad
|
|
1540
|
+
}) {
|
|
1541
|
+
const rows = useMemo6(() => buildMemoryRows(currMemory, changes), [currMemory, changes]);
|
|
1542
|
+
const totalKeys = Object.keys(currMemory).length;
|
|
1543
|
+
return /* @__PURE__ */ jsxs8("div", { style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
|
|
1544
|
+
/* @__PURE__ */ jsxs8("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
1545
|
+
/* @__PURE__ */ jsx9(
|
|
1546
|
+
"span",
|
|
1547
|
+
{
|
|
1548
|
+
style: {
|
|
1549
|
+
fontSize: fs.label + 2,
|
|
1550
|
+
fontWeight: 700,
|
|
1551
|
+
color: theme.textPrimary,
|
|
1552
|
+
fontFamily: theme.fontMono
|
|
1553
|
+
},
|
|
1554
|
+
children: snapshot.stageLabel
|
|
1555
|
+
}
|
|
1556
|
+
),
|
|
1557
|
+
snapshot.durationMs > 0 && /* @__PURE__ */ jsxs8(
|
|
1558
|
+
"span",
|
|
1559
|
+
{
|
|
1560
|
+
style: {
|
|
1561
|
+
fontSize: fs.small,
|
|
1562
|
+
color: theme.textMuted,
|
|
1563
|
+
fontFamily: theme.fontMono
|
|
1564
|
+
},
|
|
1565
|
+
children: [
|
|
1566
|
+
snapshot.durationMs,
|
|
1567
|
+
"ms"
|
|
1568
|
+
]
|
|
1569
|
+
}
|
|
1570
|
+
)
|
|
1571
|
+
] }),
|
|
1572
|
+
/* @__PURE__ */ jsxs8(
|
|
1573
|
+
"div",
|
|
1574
|
+
{
|
|
1575
|
+
style: {
|
|
1576
|
+
fontSize: fs.label,
|
|
1577
|
+
fontWeight: 600,
|
|
1578
|
+
color: theme.textMuted,
|
|
1579
|
+
textTransform: "uppercase",
|
|
1580
|
+
letterSpacing: "0.08em"
|
|
1581
|
+
},
|
|
1582
|
+
children: [
|
|
1583
|
+
"Memory",
|
|
1584
|
+
/* @__PURE__ */ jsxs8("span", { style: { fontWeight: 400, marginLeft: 6 }, children: [
|
|
1585
|
+
"(",
|
|
1586
|
+
totalKeys,
|
|
1587
|
+
" key",
|
|
1588
|
+
totalKeys !== 1 ? "s" : "",
|
|
1589
|
+
changes.length > 0 && `, ${changes.length} changed`,
|
|
1590
|
+
")"
|
|
1591
|
+
] })
|
|
1592
|
+
]
|
|
1593
|
+
}
|
|
1594
|
+
),
|
|
1595
|
+
rows.length === 0 ? /* @__PURE__ */ jsx9(
|
|
1596
|
+
"div",
|
|
1597
|
+
{
|
|
1598
|
+
style: {
|
|
1599
|
+
fontSize: fs.body,
|
|
1600
|
+
color: theme.textMuted,
|
|
1601
|
+
fontStyle: "italic",
|
|
1602
|
+
fontFamily: theme.fontMono,
|
|
1603
|
+
padding: `${pad}px`,
|
|
1604
|
+
background: theme.bgSecondary,
|
|
1605
|
+
borderRadius: theme.radius
|
|
1606
|
+
},
|
|
1607
|
+
children: "Empty memory"
|
|
1608
|
+
}
|
|
1609
|
+
) : /* @__PURE__ */ jsx9(
|
|
1610
|
+
"div",
|
|
1611
|
+
{
|
|
1612
|
+
style: {
|
|
1613
|
+
fontFamily: theme.fontMono,
|
|
1614
|
+
fontSize: fs.body,
|
|
1615
|
+
background: theme.bgSecondary,
|
|
1616
|
+
border: `1px solid ${theme.border}`,
|
|
1617
|
+
borderRadius: theme.radius,
|
|
1618
|
+
overflow: "hidden"
|
|
1619
|
+
},
|
|
1620
|
+
children: rows.map((row) => {
|
|
1621
|
+
if (row.kind === "change") {
|
|
1622
|
+
const { change } = row;
|
|
1623
|
+
const badge = changeBadge[change.type];
|
|
1624
|
+
return /* @__PURE__ */ jsxs8(
|
|
1625
|
+
"div",
|
|
1626
|
+
{
|
|
1627
|
+
style: {
|
|
1628
|
+
display: "flex",
|
|
1629
|
+
alignItems: "flex-start",
|
|
1630
|
+
gap: 8,
|
|
1631
|
+
padding: `6px ${pad}px`,
|
|
1632
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
1633
|
+
background: badge.bg
|
|
1634
|
+
},
|
|
1635
|
+
"data-fp": "memory-change",
|
|
1636
|
+
"data-type": change.type,
|
|
1637
|
+
children: [
|
|
1638
|
+
/* @__PURE__ */ jsx9(
|
|
1639
|
+
"span",
|
|
1640
|
+
{
|
|
1641
|
+
style: {
|
|
1642
|
+
fontSize: fs.small,
|
|
1643
|
+
fontWeight: 700,
|
|
1644
|
+
color: badge.fg,
|
|
1645
|
+
width: 28,
|
|
1646
|
+
flexShrink: 0,
|
|
1647
|
+
textAlign: "center",
|
|
1648
|
+
lineHeight: 1.8
|
|
1649
|
+
},
|
|
1650
|
+
children: badge.label
|
|
1651
|
+
}
|
|
1652
|
+
),
|
|
1653
|
+
/* @__PURE__ */ jsx9(
|
|
1654
|
+
"span",
|
|
1655
|
+
{
|
|
1656
|
+
style: {
|
|
1657
|
+
color: theme.primary,
|
|
1658
|
+
fontWeight: 600,
|
|
1659
|
+
flexShrink: 0,
|
|
1660
|
+
lineHeight: 1.8
|
|
1661
|
+
},
|
|
1662
|
+
children: change.key
|
|
1663
|
+
}
|
|
1664
|
+
),
|
|
1665
|
+
/* @__PURE__ */ jsx9("div", { style: { flex: 1, minWidth: 0, lineHeight: 1.8 }, children: change.type === "updated" ? /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1666
|
+
/* @__PURE__ */ jsx9(
|
|
1667
|
+
"span",
|
|
1668
|
+
{
|
|
1669
|
+
style: {
|
|
1670
|
+
color: theme.error,
|
|
1671
|
+
textDecoration: "line-through",
|
|
1672
|
+
opacity: 0.7
|
|
1673
|
+
},
|
|
1674
|
+
children: fmt2(change.oldValue)
|
|
1675
|
+
}
|
|
1676
|
+
),
|
|
1677
|
+
/* @__PURE__ */ jsx9("span", { style: { color: theme.textMuted, margin: "0 4px" }, children: "\u2192" }),
|
|
1678
|
+
/* @__PURE__ */ jsx9("span", { style: { color: theme.success }, children: fmt2(change.newValue) })
|
|
1679
|
+
] }) : change.type === "added" ? /* @__PURE__ */ jsx9("span", { style: { color: theme.success }, children: fmt2(change.newValue) }) : /* @__PURE__ */ jsx9("span", { style: { color: theme.error, textDecoration: "line-through" }, children: fmt2(change.oldValue) }) })
|
|
1680
|
+
]
|
|
1681
|
+
},
|
|
1682
|
+
change.key
|
|
1683
|
+
);
|
|
1684
|
+
}
|
|
1685
|
+
return /* @__PURE__ */ jsxs8(
|
|
1686
|
+
"div",
|
|
1687
|
+
{
|
|
1688
|
+
style: {
|
|
1689
|
+
display: "flex",
|
|
1690
|
+
alignItems: "flex-start",
|
|
1691
|
+
gap: 8,
|
|
1692
|
+
padding: `6px ${pad}px`,
|
|
1693
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
1694
|
+
opacity: 0.5
|
|
1695
|
+
},
|
|
1696
|
+
"data-fp": "memory-unchanged",
|
|
1697
|
+
children: [
|
|
1698
|
+
/* @__PURE__ */ jsx9(
|
|
1699
|
+
"span",
|
|
1700
|
+
{
|
|
1701
|
+
style: {
|
|
1702
|
+
width: 28,
|
|
1703
|
+
flexShrink: 0,
|
|
1704
|
+
lineHeight: 1.8
|
|
1705
|
+
}
|
|
1706
|
+
}
|
|
1707
|
+
),
|
|
1708
|
+
/* @__PURE__ */ jsx9(
|
|
1709
|
+
"span",
|
|
1710
|
+
{
|
|
1711
|
+
style: {
|
|
1712
|
+
color: theme.textSecondary,
|
|
1713
|
+
fontWeight: 500,
|
|
1714
|
+
flexShrink: 0,
|
|
1715
|
+
lineHeight: 1.8
|
|
1716
|
+
},
|
|
1717
|
+
children: row.key
|
|
1718
|
+
}
|
|
1719
|
+
),
|
|
1720
|
+
/* @__PURE__ */ jsx9("div", { style: { flex: 1, minWidth: 0, lineHeight: 1.8, color: theme.textMuted }, children: fmt2(row.value) })
|
|
1721
|
+
]
|
|
1722
|
+
},
|
|
1723
|
+
row.key
|
|
1724
|
+
);
|
|
1725
|
+
})
|
|
1726
|
+
}
|
|
1727
|
+
)
|
|
1728
|
+
] });
|
|
1729
|
+
}
|
|
1730
|
+
function UnstyledSimpleView({ snapshot }) {
|
|
1731
|
+
return /* @__PURE__ */ jsxs8("div", { "data-fp": "stage-detail-simple", children: [
|
|
1732
|
+
/* @__PURE__ */ jsx9("div", { "data-fp": "stage-label", children: snapshot.stageLabel }),
|
|
1733
|
+
snapshot.description && /* @__PURE__ */ jsx9("div", { "data-fp": "stage-description", children: snapshot.description }),
|
|
1734
|
+
snapshot.status && /* @__PURE__ */ jsx9("div", { "data-fp": "stage-status", children: snapshot.status }),
|
|
1735
|
+
snapshot.narrative && /* @__PURE__ */ jsx9("div", { "data-fp": "stage-narrative", children: snapshot.narrative })
|
|
1736
|
+
] });
|
|
1737
|
+
}
|
|
1738
|
+
function UnstyledDevView({
|
|
1739
|
+
snapshot,
|
|
1740
|
+
changes,
|
|
1741
|
+
currMemory
|
|
1742
|
+
}) {
|
|
1743
|
+
const rows = useMemo6(() => buildMemoryRows(currMemory, changes), [currMemory, changes]);
|
|
1744
|
+
return /* @__PURE__ */ jsxs8("div", { "data-fp": "stage-detail-dev", children: [
|
|
1745
|
+
/* @__PURE__ */ jsx9("div", { "data-fp": "stage-label", children: snapshot.stageLabel }),
|
|
1746
|
+
rows.map((row) => {
|
|
1747
|
+
if (row.kind === "change") {
|
|
1748
|
+
const c = row.change;
|
|
1749
|
+
return /* @__PURE__ */ jsxs8("div", { "data-fp": "memory-change", "data-type": c.type, children: [
|
|
1750
|
+
/* @__PURE__ */ jsx9("span", { "data-fp": "change-key", children: c.key }),
|
|
1751
|
+
c.type === "updated" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
1752
|
+
/* @__PURE__ */ jsx9("span", { "data-fp": "change-old", children: fmt2(c.oldValue) }),
|
|
1753
|
+
/* @__PURE__ */ jsx9("span", { "data-fp": "change-new", children: fmt2(c.newValue) })
|
|
1754
|
+
] }),
|
|
1755
|
+
c.type === "added" && /* @__PURE__ */ jsx9("span", { "data-fp": "change-value", children: fmt2(c.newValue) }),
|
|
1756
|
+
c.type === "removed" && /* @__PURE__ */ jsx9("span", { "data-fp": "change-value", children: fmt2(c.oldValue) })
|
|
1757
|
+
] }, c.key);
|
|
1758
|
+
}
|
|
1759
|
+
return /* @__PURE__ */ jsxs8("div", { "data-fp": "memory-unchanged", children: [
|
|
1760
|
+
/* @__PURE__ */ jsx9("span", { "data-fp": "unchanged-key", children: row.key }),
|
|
1761
|
+
/* @__PURE__ */ jsx9("span", { "data-fp": "unchanged-value", children: fmt2(row.value) })
|
|
1762
|
+
] }, row.key);
|
|
1763
|
+
})
|
|
1764
|
+
] });
|
|
1765
|
+
}
|
|
1766
|
+
function ModeToggle({
|
|
1767
|
+
activeMode,
|
|
1768
|
+
onToggle,
|
|
1769
|
+
fs,
|
|
1770
|
+
unstyled
|
|
1771
|
+
}) {
|
|
1772
|
+
if (unstyled) {
|
|
1773
|
+
return /* @__PURE__ */ jsx9("button", { "data-fp": "mode-toggle", "data-mode": activeMode, onClick: onToggle, children: activeMode === "simple" ? "Dev" : "Simple" });
|
|
1774
|
+
}
|
|
1775
|
+
return /* @__PURE__ */ jsx9(
|
|
1776
|
+
"div",
|
|
1777
|
+
{
|
|
1778
|
+
style: {
|
|
1779
|
+
display: "inline-flex",
|
|
1780
|
+
borderRadius: 6,
|
|
1781
|
+
border: `1px solid ${theme.border}`,
|
|
1782
|
+
overflow: "hidden",
|
|
1783
|
+
flexShrink: 0
|
|
1784
|
+
},
|
|
1785
|
+
"data-fp": "mode-toggle",
|
|
1786
|
+
children: ["simple", "dev"].map((m) => /* @__PURE__ */ jsx9(
|
|
1787
|
+
"button",
|
|
1788
|
+
{
|
|
1789
|
+
onClick: m !== activeMode ? onToggle : void 0,
|
|
1790
|
+
style: {
|
|
1791
|
+
padding: "4px 10px",
|
|
1792
|
+
fontSize: fs.small,
|
|
1793
|
+
fontWeight: m === activeMode ? 700 : 400,
|
|
1794
|
+
textTransform: "uppercase",
|
|
1795
|
+
letterSpacing: "0.05em",
|
|
1796
|
+
color: m === activeMode ? theme.textPrimary : theme.textMuted,
|
|
1797
|
+
background: m === activeMode ? theme.bgTertiary : "transparent",
|
|
1798
|
+
border: "none",
|
|
1799
|
+
cursor: m === activeMode ? "default" : "pointer"
|
|
1800
|
+
},
|
|
1801
|
+
children: m === "simple" ? "Simple" : "Dev"
|
|
1802
|
+
},
|
|
1803
|
+
m
|
|
1804
|
+
))
|
|
1805
|
+
}
|
|
1806
|
+
);
|
|
1807
|
+
}
|
|
1808
|
+
function StageDetailPanel({
|
|
1809
|
+
snapshots,
|
|
1810
|
+
selectedIndex,
|
|
1811
|
+
mode: controlledMode,
|
|
1812
|
+
showToggle = false,
|
|
1813
|
+
onModeChange,
|
|
1814
|
+
size = "default",
|
|
1815
|
+
unstyled = false,
|
|
1816
|
+
className,
|
|
1817
|
+
style
|
|
1818
|
+
}) {
|
|
1819
|
+
const [internalMode, setInternalMode] = useState4(controlledMode ?? "simple");
|
|
1820
|
+
const activeMode = controlledMode ?? internalMode;
|
|
1821
|
+
const handleToggle = useCallback2(() => {
|
|
1822
|
+
const next = activeMode === "simple" ? "dev" : "simple";
|
|
1823
|
+
setInternalMode(next);
|
|
1824
|
+
onModeChange?.(next);
|
|
1825
|
+
}, [activeMode, onModeChange]);
|
|
1826
|
+
const snapshot = snapshots[selectedIndex];
|
|
1827
|
+
const prevMemory = selectedIndex > 0 ? snapshots[selectedIndex - 1]?.memory ?? null : null;
|
|
1828
|
+
const currMemory = snapshot?.memory ?? {};
|
|
1829
|
+
const changes = useMemo6(
|
|
1830
|
+
() => computeChanges(prevMemory, currMemory),
|
|
1831
|
+
[prevMemory, currMemory]
|
|
1832
|
+
);
|
|
1833
|
+
const fs = fontSize[size];
|
|
1834
|
+
const pad = padding[size];
|
|
1835
|
+
if (!snapshot) {
|
|
1836
|
+
return /* @__PURE__ */ jsx9("div", { className, style, "data-fp": "stage-detail-panel", children: /* @__PURE__ */ jsx9("div", { style: unstyled ? {} : { color: theme.textMuted, fontSize: fs.body, fontStyle: "italic", padding: pad }, children: "No stage selected" }) });
|
|
1837
|
+
}
|
|
1838
|
+
if (unstyled) {
|
|
1839
|
+
return /* @__PURE__ */ jsxs8("div", { className, style, "data-fp": "stage-detail-panel", "data-mode": activeMode, children: [
|
|
1840
|
+
showToggle && /* @__PURE__ */ jsx9(ModeToggle, { activeMode, onToggle: handleToggle, fs, unstyled: true }),
|
|
1841
|
+
activeMode === "simple" ? /* @__PURE__ */ jsx9(UnstyledSimpleView, { snapshot }) : /* @__PURE__ */ jsx9(UnstyledDevView, { snapshot, changes, currMemory })
|
|
1842
|
+
] });
|
|
1843
|
+
}
|
|
1844
|
+
return /* @__PURE__ */ jsxs8(
|
|
1845
|
+
"div",
|
|
1846
|
+
{
|
|
1847
|
+
className,
|
|
1848
|
+
style: {
|
|
1849
|
+
padding: pad,
|
|
1850
|
+
fontFamily: theme.fontSans,
|
|
1851
|
+
overflow: "auto",
|
|
1852
|
+
...style
|
|
1853
|
+
},
|
|
1854
|
+
"data-fp": "stage-detail-panel",
|
|
1855
|
+
"data-mode": activeMode,
|
|
1856
|
+
children: [
|
|
1857
|
+
showToggle && /* @__PURE__ */ jsx9("div", { style: { display: "flex", justifyContent: "flex-end", marginBottom: 12 }, children: /* @__PURE__ */ jsx9(ModeToggle, { activeMode, onToggle: handleToggle, fs, unstyled: false }) }),
|
|
1858
|
+
activeMode === "simple" ? /* @__PURE__ */ jsx9(SimpleView, { snapshot, fs, pad }) : /* @__PURE__ */ jsx9(DevView, { snapshot, changes, currMemory, fs, pad })
|
|
1859
|
+
]
|
|
1860
|
+
}
|
|
1861
|
+
);
|
|
1862
|
+
}
|
|
1863
|
+
|
|
1333
1864
|
// src/components/TimeTravelControls/TimeTravelControls.tsx
|
|
1334
|
-
import { useState as
|
|
1335
|
-
import { jsx as
|
|
1865
|
+
import { useState as useState5, useEffect as useEffect3, useRef as useRef3, useCallback as useCallback3 } from "react";
|
|
1866
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1336
1867
|
function TimeTravelControls({
|
|
1337
1868
|
snapshots,
|
|
1338
1869
|
selectedIndex,
|
|
@@ -1343,12 +1874,12 @@ function TimeTravelControls({
|
|
|
1343
1874
|
className,
|
|
1344
1875
|
style
|
|
1345
1876
|
}) {
|
|
1346
|
-
const [playing, setPlaying] =
|
|
1347
|
-
const playRef =
|
|
1877
|
+
const [playing, setPlaying] = useState5(false);
|
|
1878
|
+
const playRef = useRef3(null);
|
|
1348
1879
|
const total = snapshots.length;
|
|
1349
1880
|
const canPrev = selectedIndex > 0;
|
|
1350
1881
|
const canNext = selectedIndex < total - 1;
|
|
1351
|
-
|
|
1882
|
+
useEffect3(() => {
|
|
1352
1883
|
if (!playing || !autoPlayable) return;
|
|
1353
1884
|
if (selectedIndex >= total - 1) {
|
|
1354
1885
|
setPlaying(false);
|
|
@@ -1366,7 +1897,7 @@ function TimeTravelControls({
|
|
|
1366
1897
|
if (playRef.current) clearTimeout(playRef.current);
|
|
1367
1898
|
};
|
|
1368
1899
|
}, [playing, selectedIndex, snapshots, total, onIndexChange, autoPlayable]);
|
|
1369
|
-
const togglePlay =
|
|
1900
|
+
const togglePlay = useCallback3(() => {
|
|
1370
1901
|
if (playing) {
|
|
1371
1902
|
setPlaying(false);
|
|
1372
1903
|
} else {
|
|
@@ -1376,8 +1907,8 @@ function TimeTravelControls({
|
|
|
1376
1907
|
}, [playing, selectedIndex, total, onIndexChange]);
|
|
1377
1908
|
const fs = fontSize[size];
|
|
1378
1909
|
if (unstyled) {
|
|
1379
|
-
return /* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1910
|
+
return /* @__PURE__ */ jsxs9("div", { className, style, "data-fp": "time-travel-controls", children: [
|
|
1911
|
+
/* @__PURE__ */ jsx10(
|
|
1381
1912
|
"button",
|
|
1382
1913
|
{
|
|
1383
1914
|
"data-fp": "tt-prev",
|
|
@@ -1389,8 +1920,8 @@ function TimeTravelControls({
|
|
|
1389
1920
|
children: "Prev"
|
|
1390
1921
|
}
|
|
1391
1922
|
),
|
|
1392
|
-
autoPlayable && /* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1923
|
+
autoPlayable && /* @__PURE__ */ jsx10("button", { "data-fp": "tt-play", onClick: togglePlay, children: playing ? "Pause" : "Play" }),
|
|
1924
|
+
/* @__PURE__ */ jsx10(
|
|
1394
1925
|
"button",
|
|
1395
1926
|
{
|
|
1396
1927
|
"data-fp": "tt-next",
|
|
@@ -1402,7 +1933,7 @@ function TimeTravelControls({
|
|
|
1402
1933
|
children: "Next"
|
|
1403
1934
|
}
|
|
1404
1935
|
),
|
|
1405
|
-
/* @__PURE__ */
|
|
1936
|
+
/* @__PURE__ */ jsx10("div", { "data-fp": "tt-ticks", children: snapshots.map((snap, i) => /* @__PURE__ */ jsx10(
|
|
1406
1937
|
"button",
|
|
1407
1938
|
{
|
|
1408
1939
|
"data-fp": "tt-tick",
|
|
@@ -1430,7 +1961,7 @@ function TimeTravelControls({
|
|
|
1430
1961
|
opacity: disabled ? 0.5 : 1,
|
|
1431
1962
|
flexShrink: 0
|
|
1432
1963
|
});
|
|
1433
|
-
return /* @__PURE__ */
|
|
1964
|
+
return /* @__PURE__ */ jsxs9(
|
|
1434
1965
|
"div",
|
|
1435
1966
|
{
|
|
1436
1967
|
className,
|
|
@@ -1446,7 +1977,7 @@ function TimeTravelControls({
|
|
|
1446
1977
|
},
|
|
1447
1978
|
"data-fp": "time-travel-controls",
|
|
1448
1979
|
children: [
|
|
1449
|
-
/* @__PURE__ */
|
|
1980
|
+
/* @__PURE__ */ jsx10(
|
|
1450
1981
|
"button",
|
|
1451
1982
|
{
|
|
1452
1983
|
style: btnStyle(!canPrev || playing),
|
|
@@ -1458,7 +1989,7 @@ function TimeTravelControls({
|
|
|
1458
1989
|
children: "\u25C0"
|
|
1459
1990
|
}
|
|
1460
1991
|
),
|
|
1461
|
-
autoPlayable && /* @__PURE__ */
|
|
1992
|
+
autoPlayable && /* @__PURE__ */ jsx10(
|
|
1462
1993
|
"button",
|
|
1463
1994
|
{
|
|
1464
1995
|
onClick: togglePlay,
|
|
@@ -1480,7 +2011,7 @@ function TimeTravelControls({
|
|
|
1480
2011
|
children: playing ? "\u23F8" : "\u25B6"
|
|
1481
2012
|
}
|
|
1482
2013
|
),
|
|
1483
|
-
/* @__PURE__ */
|
|
2014
|
+
/* @__PURE__ */ jsx10(
|
|
1484
2015
|
"button",
|
|
1485
2016
|
{
|
|
1486
2017
|
style: btnStyle(!canNext || playing),
|
|
@@ -1492,7 +2023,7 @@ function TimeTravelControls({
|
|
|
1492
2023
|
children: "\u25B6"
|
|
1493
2024
|
}
|
|
1494
2025
|
),
|
|
1495
|
-
/* @__PURE__ */
|
|
2026
|
+
/* @__PURE__ */ jsx10(
|
|
1496
2027
|
"div",
|
|
1497
2028
|
{
|
|
1498
2029
|
style: {
|
|
@@ -1505,7 +2036,7 @@ function TimeTravelControls({
|
|
|
1505
2036
|
children: snapshots.map((snap, i) => {
|
|
1506
2037
|
const isActive = i === selectedIndex;
|
|
1507
2038
|
const isDone = i < selectedIndex;
|
|
1508
|
-
return /* @__PURE__ */
|
|
2039
|
+
return /* @__PURE__ */ jsx10(
|
|
1509
2040
|
"button",
|
|
1510
2041
|
{
|
|
1511
2042
|
onClick: () => {
|
|
@@ -1535,8 +2066,8 @@ function TimeTravelControls({
|
|
|
1535
2066
|
}
|
|
1536
2067
|
|
|
1537
2068
|
// src/components/ExplainableShell/ExplainableShell.tsx
|
|
1538
|
-
import { useState as
|
|
1539
|
-
import { Fragment as
|
|
2069
|
+
import { useState as useState6, useCallback as useCallback4, useMemo as useMemo7 } from "react";
|
|
2070
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1540
2071
|
function ExplainableShell({
|
|
1541
2072
|
snapshots,
|
|
1542
2073
|
resultData,
|
|
@@ -1551,14 +2082,14 @@ function ExplainableShell({
|
|
|
1551
2082
|
className,
|
|
1552
2083
|
style
|
|
1553
2084
|
}) {
|
|
1554
|
-
const [activeTab, setActiveTab] =
|
|
1555
|
-
const [snapshotIdx, setSnapshotIdx] =
|
|
2085
|
+
const [activeTab, setActiveTab] = useState6(defaultTab ?? tabs[0]);
|
|
2086
|
+
const [snapshotIdx, setSnapshotIdx] = useState6(0);
|
|
1556
2087
|
const fs = fontSize[size];
|
|
1557
2088
|
const pad = padding[size];
|
|
1558
|
-
const handleSnapshotChange =
|
|
2089
|
+
const handleSnapshotChange = useCallback4((idx) => {
|
|
1559
2090
|
setSnapshotIdx(Math.max(0, Math.min(idx, snapshots.length - 1)));
|
|
1560
2091
|
}, [snapshots.length]);
|
|
1561
|
-
const revealedCount =
|
|
2092
|
+
const revealedCount = useMemo7(() => {
|
|
1562
2093
|
if (snapshots.length === 0 || narrative.length === 0) return narrative.length;
|
|
1563
2094
|
const boundaries = [];
|
|
1564
2095
|
for (let i = 0; i < narrative.length; i++) {
|
|
@@ -1589,8 +2120,8 @@ function ExplainableShell({
|
|
|
1589
2120
|
"ai-compatible": "AI-Compatible"
|
|
1590
2121
|
};
|
|
1591
2122
|
if (unstyled) {
|
|
1592
|
-
return /* @__PURE__ */
|
|
1593
|
-
/* @__PURE__ */
|
|
2123
|
+
return /* @__PURE__ */ jsxs10("div", { className, style, "data-fp": "explainable-shell", children: [
|
|
2124
|
+
/* @__PURE__ */ jsx11("div", { "data-fp": "shell-tabs", children: tabs.map((tab) => /* @__PURE__ */ jsx11(
|
|
1594
2125
|
"button",
|
|
1595
2126
|
{
|
|
1596
2127
|
"data-fp": "shell-tab",
|
|
@@ -1600,8 +2131,8 @@ function ExplainableShell({
|
|
|
1600
2131
|
},
|
|
1601
2132
|
tab
|
|
1602
2133
|
)) }),
|
|
1603
|
-
/* @__PURE__ */
|
|
1604
|
-
activeTab === "result" && /* @__PURE__ */
|
|
2134
|
+
/* @__PURE__ */ jsxs10("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
|
|
2135
|
+
activeTab === "result" && /* @__PURE__ */ jsx11(
|
|
1605
2136
|
ResultPanel,
|
|
1606
2137
|
{
|
|
1607
2138
|
data: resultData ?? null,
|
|
@@ -1610,8 +2141,8 @@ function ExplainableShell({
|
|
|
1610
2141
|
unstyled: true
|
|
1611
2142
|
}
|
|
1612
2143
|
),
|
|
1613
|
-
activeTab === "explainable" && /* @__PURE__ */
|
|
1614
|
-
/* @__PURE__ */
|
|
2144
|
+
activeTab === "explainable" && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2145
|
+
/* @__PURE__ */ jsx11(
|
|
1615
2146
|
TimeTravelControls,
|
|
1616
2147
|
{
|
|
1617
2148
|
snapshots,
|
|
@@ -1621,9 +2152,9 @@ function ExplainableShell({
|
|
|
1621
2152
|
}
|
|
1622
2153
|
),
|
|
1623
2154
|
renderFlowchart?.({ snapshots, selectedIndex: snapshotIdx, onNodeClick: handleSnapshotChange }),
|
|
1624
|
-
/* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1626
|
-
/* @__PURE__ */
|
|
2155
|
+
/* @__PURE__ */ jsx11(MemoryInspector, { snapshots, selectedIndex: snapshotIdx, unstyled: true }),
|
|
2156
|
+
/* @__PURE__ */ jsx11(ScopeDiff, { previous: prevMemory, current: currMemory, unstyled: true }),
|
|
2157
|
+
/* @__PURE__ */ jsx11(
|
|
1627
2158
|
GanttTimeline,
|
|
1628
2159
|
{
|
|
1629
2160
|
snapshots,
|
|
@@ -1633,8 +2164,8 @@ function ExplainableShell({
|
|
|
1633
2164
|
}
|
|
1634
2165
|
)
|
|
1635
2166
|
] }),
|
|
1636
|
-
activeTab === "ai-compatible" && /* @__PURE__ */
|
|
1637
|
-
/* @__PURE__ */
|
|
2167
|
+
activeTab === "ai-compatible" && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2168
|
+
/* @__PURE__ */ jsx11(
|
|
1638
2169
|
TimeTravelControls,
|
|
1639
2170
|
{
|
|
1640
2171
|
snapshots,
|
|
@@ -1644,7 +2175,7 @@ function ExplainableShell({
|
|
|
1644
2175
|
}
|
|
1645
2176
|
),
|
|
1646
2177
|
renderFlowchart?.({ snapshots, selectedIndex: snapshotIdx, onNodeClick: handleSnapshotChange }),
|
|
1647
|
-
/* @__PURE__ */
|
|
2178
|
+
/* @__PURE__ */ jsx11(
|
|
1648
2179
|
NarrativeTrace,
|
|
1649
2180
|
{
|
|
1650
2181
|
narrative,
|
|
@@ -1656,7 +2187,7 @@ function ExplainableShell({
|
|
|
1656
2187
|
] })
|
|
1657
2188
|
] });
|
|
1658
2189
|
}
|
|
1659
|
-
return /* @__PURE__ */
|
|
2190
|
+
return /* @__PURE__ */ jsxs10(
|
|
1660
2191
|
"div",
|
|
1661
2192
|
{
|
|
1662
2193
|
className,
|
|
@@ -1672,7 +2203,7 @@ function ExplainableShell({
|
|
|
1672
2203
|
},
|
|
1673
2204
|
"data-fp": "explainable-shell",
|
|
1674
2205
|
children: [
|
|
1675
|
-
/* @__PURE__ */
|
|
2206
|
+
/* @__PURE__ */ jsx11(
|
|
1676
2207
|
"div",
|
|
1677
2208
|
{
|
|
1678
2209
|
style: {
|
|
@@ -1684,7 +2215,7 @@ function ExplainableShell({
|
|
|
1684
2215
|
},
|
|
1685
2216
|
children: tabs.map((tab) => {
|
|
1686
2217
|
const active = tab === activeTab;
|
|
1687
|
-
return /* @__PURE__ */
|
|
2218
|
+
return /* @__PURE__ */ jsx11(
|
|
1688
2219
|
"button",
|
|
1689
2220
|
{
|
|
1690
2221
|
onClick: () => setActiveTab(tab),
|
|
@@ -1708,8 +2239,8 @@ function ExplainableShell({
|
|
|
1708
2239
|
})
|
|
1709
2240
|
}
|
|
1710
2241
|
),
|
|
1711
|
-
/* @__PURE__ */
|
|
1712
|
-
activeTab === "result" && /* @__PURE__ */
|
|
2242
|
+
/* @__PURE__ */ jsxs10("div", { style: { flex: 1, overflow: "hidden", display: "flex", flexDirection: "column" }, children: [
|
|
2243
|
+
activeTab === "result" && /* @__PURE__ */ jsx11(
|
|
1713
2244
|
ResultPanel,
|
|
1714
2245
|
{
|
|
1715
2246
|
data: resultData ?? null,
|
|
@@ -1718,8 +2249,8 @@ function ExplainableShell({
|
|
|
1718
2249
|
size
|
|
1719
2250
|
}
|
|
1720
2251
|
),
|
|
1721
|
-
activeTab === "explainable" && /* @__PURE__ */
|
|
1722
|
-
/* @__PURE__ */
|
|
2252
|
+
activeTab === "explainable" && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2253
|
+
/* @__PURE__ */ jsx11(
|
|
1723
2254
|
TimeTravelControls,
|
|
1724
2255
|
{
|
|
1725
2256
|
snapshots,
|
|
@@ -1728,9 +2259,9 @@ function ExplainableShell({
|
|
|
1728
2259
|
size
|
|
1729
2260
|
}
|
|
1730
2261
|
),
|
|
1731
|
-
/* @__PURE__ */
|
|
1732
|
-
renderFlowchart && /* @__PURE__ */
|
|
1733
|
-
/* @__PURE__ */
|
|
2262
|
+
/* @__PURE__ */ jsxs10("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
|
|
2263
|
+
renderFlowchart && /* @__PURE__ */ jsx11("div", { style: { flex: 1, overflow: "hidden", borderRight: `1px solid ${theme.border}` }, children: renderFlowchart({ snapshots, selectedIndex: snapshotIdx, onNodeClick: handleSnapshotChange }) }),
|
|
2264
|
+
/* @__PURE__ */ jsxs10(
|
|
1734
2265
|
"div",
|
|
1735
2266
|
{
|
|
1736
2267
|
style: {
|
|
@@ -1741,7 +2272,7 @@ function ExplainableShell({
|
|
|
1741
2272
|
flexDirection: "column"
|
|
1742
2273
|
},
|
|
1743
2274
|
children: [
|
|
1744
|
-
/* @__PURE__ */
|
|
2275
|
+
/* @__PURE__ */ jsx11(
|
|
1745
2276
|
MemoryInspector,
|
|
1746
2277
|
{
|
|
1747
2278
|
snapshots,
|
|
@@ -1749,7 +2280,7 @@ function ExplainableShell({
|
|
|
1749
2280
|
size
|
|
1750
2281
|
}
|
|
1751
2282
|
),
|
|
1752
|
-
/* @__PURE__ */
|
|
2283
|
+
/* @__PURE__ */ jsx11("div", { style: { borderTop: `1px solid ${theme.border}` }, children: /* @__PURE__ */ jsx11(
|
|
1753
2284
|
ScopeDiff,
|
|
1754
2285
|
{
|
|
1755
2286
|
previous: prevMemory,
|
|
@@ -1762,7 +2293,7 @@ function ExplainableShell({
|
|
|
1762
2293
|
}
|
|
1763
2294
|
)
|
|
1764
2295
|
] }),
|
|
1765
|
-
/* @__PURE__ */
|
|
2296
|
+
/* @__PURE__ */ jsx11("div", { style: { borderTop: `1px solid ${theme.border}`, flexShrink: 0 }, children: /* @__PURE__ */ jsx11(
|
|
1766
2297
|
GanttTimeline,
|
|
1767
2298
|
{
|
|
1768
2299
|
snapshots,
|
|
@@ -1772,8 +2303,8 @@ function ExplainableShell({
|
|
|
1772
2303
|
}
|
|
1773
2304
|
) })
|
|
1774
2305
|
] }),
|
|
1775
|
-
activeTab === "ai-compatible" && /* @__PURE__ */
|
|
1776
|
-
/* @__PURE__ */
|
|
2306
|
+
activeTab === "ai-compatible" && /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2307
|
+
/* @__PURE__ */ jsx11(
|
|
1777
2308
|
TimeTravelControls,
|
|
1778
2309
|
{
|
|
1779
2310
|
snapshots,
|
|
@@ -1782,9 +2313,9 @@ function ExplainableShell({
|
|
|
1782
2313
|
size
|
|
1783
2314
|
}
|
|
1784
2315
|
),
|
|
1785
|
-
/* @__PURE__ */
|
|
1786
|
-
renderFlowchart && /* @__PURE__ */
|
|
1787
|
-
/* @__PURE__ */
|
|
2316
|
+
/* @__PURE__ */ jsxs10("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
|
|
2317
|
+
renderFlowchart && /* @__PURE__ */ jsx11("div", { style: { flex: 1, overflow: "hidden", borderRight: `1px solid ${theme.border}` }, children: renderFlowchart({ snapshots, selectedIndex: snapshotIdx, onNodeClick: handleSnapshotChange }) }),
|
|
2318
|
+
/* @__PURE__ */ jsx11(
|
|
1788
2319
|
NarrativeTrace,
|
|
1789
2320
|
{
|
|
1790
2321
|
narrative,
|
|
@@ -1804,40 +2335,276 @@ function ExplainableShell({
|
|
|
1804
2335
|
);
|
|
1805
2336
|
}
|
|
1806
2337
|
|
|
2338
|
+
// src/components/FlowchartView/SubflowTree.tsx
|
|
2339
|
+
import { memo, useState as useState7, useCallback as useCallback5, useMemo as useMemo8 } from "react";
|
|
2340
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2341
|
+
function specToTree(node) {
|
|
2342
|
+
const entries = [];
|
|
2343
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2344
|
+
function walk(n) {
|
|
2345
|
+
const id = n.name || n.id || "";
|
|
2346
|
+
if (seen.has(id)) return;
|
|
2347
|
+
seen.add(id);
|
|
2348
|
+
const entry = {
|
|
2349
|
+
name: n.name,
|
|
2350
|
+
description: n.description,
|
|
2351
|
+
subflowId: n.subflowId,
|
|
2352
|
+
isSubflow: !!n.isSubflowRoot
|
|
2353
|
+
};
|
|
2354
|
+
if (n.isSubflowRoot && n.subflowStructure) {
|
|
2355
|
+
entry.children = specToTree(n.subflowStructure);
|
|
2356
|
+
}
|
|
2357
|
+
entries.push(entry);
|
|
2358
|
+
if (n.children) {
|
|
2359
|
+
for (const child of n.children) {
|
|
2360
|
+
walk(child);
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
if (n.next) {
|
|
2364
|
+
walk(n.next);
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
walk(node);
|
|
2368
|
+
return entries;
|
|
2369
|
+
}
|
|
2370
|
+
var TreeNode = memo(function TreeNode2({
|
|
2371
|
+
entry,
|
|
2372
|
+
depth,
|
|
2373
|
+
activeStage,
|
|
2374
|
+
doneStages,
|
|
2375
|
+
onNodeSelect
|
|
2376
|
+
}) {
|
|
2377
|
+
const [expanded, setExpanded] = useState7(true);
|
|
2378
|
+
const hasChildren = entry.children && entry.children.length > 0;
|
|
2379
|
+
const isActive = activeStage === entry.name;
|
|
2380
|
+
const isDone = doneStages?.has(entry.name);
|
|
2381
|
+
const handleClick = useCallback5(() => {
|
|
2382
|
+
if (hasChildren) {
|
|
2383
|
+
setExpanded((prev) => !prev);
|
|
2384
|
+
}
|
|
2385
|
+
onNodeSelect?.(entry.name, !!entry.isSubflow);
|
|
2386
|
+
}, [hasChildren, onNodeSelect, entry.name, entry.isSubflow]);
|
|
2387
|
+
return /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2388
|
+
/* @__PURE__ */ jsxs11(
|
|
2389
|
+
"button",
|
|
2390
|
+
{
|
|
2391
|
+
onClick: handleClick,
|
|
2392
|
+
"data-fp": "subflow-tree-node",
|
|
2393
|
+
style: {
|
|
2394
|
+
display: "flex",
|
|
2395
|
+
alignItems: "center",
|
|
2396
|
+
gap: 6,
|
|
2397
|
+
width: "100%",
|
|
2398
|
+
border: "none",
|
|
2399
|
+
background: isActive ? `color-mix(in srgb, ${theme.primary} 15%, transparent)` : "transparent",
|
|
2400
|
+
cursor: "pointer",
|
|
2401
|
+
padding: `4px 8px 4px ${8 + depth * 16}px`,
|
|
2402
|
+
fontFamily: theme.fontSans,
|
|
2403
|
+
fontSize: 12,
|
|
2404
|
+
textAlign: "left",
|
|
2405
|
+
borderRadius: 4,
|
|
2406
|
+
transition: "background 0.15s"
|
|
2407
|
+
},
|
|
2408
|
+
onMouseEnter: (e) => {
|
|
2409
|
+
if (!isActive) {
|
|
2410
|
+
e.currentTarget.style.background = `color-mix(in srgb, ${theme.textMuted} 10%, transparent)`;
|
|
2411
|
+
}
|
|
2412
|
+
},
|
|
2413
|
+
onMouseLeave: (e) => {
|
|
2414
|
+
if (!isActive) {
|
|
2415
|
+
e.currentTarget.style.background = "transparent";
|
|
2416
|
+
}
|
|
2417
|
+
},
|
|
2418
|
+
children: [
|
|
2419
|
+
hasChildren ? /* @__PURE__ */ jsx12(
|
|
2420
|
+
"span",
|
|
2421
|
+
{
|
|
2422
|
+
style: {
|
|
2423
|
+
fontSize: 10,
|
|
2424
|
+
color: theme.textMuted,
|
|
2425
|
+
width: 12,
|
|
2426
|
+
textAlign: "center",
|
|
2427
|
+
flexShrink: 0,
|
|
2428
|
+
transition: "transform 0.15s",
|
|
2429
|
+
transform: expanded ? "rotate(90deg)" : "rotate(0deg)",
|
|
2430
|
+
display: "inline-block"
|
|
2431
|
+
},
|
|
2432
|
+
children: "\u25B6"
|
|
2433
|
+
}
|
|
2434
|
+
) : /* @__PURE__ */ jsx12("span", { style: { width: 12, flexShrink: 0 } }),
|
|
2435
|
+
/* @__PURE__ */ jsx12(
|
|
2436
|
+
"span",
|
|
2437
|
+
{
|
|
2438
|
+
style: {
|
|
2439
|
+
width: 6,
|
|
2440
|
+
height: 6,
|
|
2441
|
+
borderRadius: "50%",
|
|
2442
|
+
flexShrink: 0,
|
|
2443
|
+
background: isActive ? theme.primary : isDone ? theme.success : theme.border
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
),
|
|
2447
|
+
/* @__PURE__ */ jsxs11("span", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
|
|
2448
|
+
/* @__PURE__ */ jsxs11(
|
|
2449
|
+
"span",
|
|
2450
|
+
{
|
|
2451
|
+
style: {
|
|
2452
|
+
color: isActive ? theme.primary : isDone ? theme.textPrimary : theme.textSecondary,
|
|
2453
|
+
fontWeight: isActive ? 600 : entry.isSubflow ? 500 : 400,
|
|
2454
|
+
whiteSpace: "nowrap",
|
|
2455
|
+
overflow: "hidden",
|
|
2456
|
+
textOverflow: "ellipsis"
|
|
2457
|
+
},
|
|
2458
|
+
children: [
|
|
2459
|
+
entry.name,
|
|
2460
|
+
entry.isSubflow && /* @__PURE__ */ jsx12("span", { style: { opacity: 0.5, marginLeft: 4, fontSize: 10 }, children: "\u229E" })
|
|
2461
|
+
]
|
|
2462
|
+
}
|
|
2463
|
+
),
|
|
2464
|
+
entry.description && /* @__PURE__ */ jsx12(
|
|
2465
|
+
"span",
|
|
2466
|
+
{
|
|
2467
|
+
style: {
|
|
2468
|
+
color: theme.textMuted,
|
|
2469
|
+
fontSize: 10,
|
|
2470
|
+
whiteSpace: "nowrap",
|
|
2471
|
+
overflow: "hidden",
|
|
2472
|
+
textOverflow: "ellipsis"
|
|
2473
|
+
},
|
|
2474
|
+
children: entry.description
|
|
2475
|
+
}
|
|
2476
|
+
)
|
|
2477
|
+
] })
|
|
2478
|
+
]
|
|
2479
|
+
}
|
|
2480
|
+
),
|
|
2481
|
+
hasChildren && expanded && /* @__PURE__ */ jsx12("div", { children: entry.children.map((child, i) => /* @__PURE__ */ jsx12(
|
|
2482
|
+
TreeNode2,
|
|
2483
|
+
{
|
|
2484
|
+
entry: child,
|
|
2485
|
+
depth: depth + 1,
|
|
2486
|
+
activeStage,
|
|
2487
|
+
doneStages,
|
|
2488
|
+
onNodeSelect
|
|
2489
|
+
},
|
|
2490
|
+
`${child.name}-${i}`
|
|
2491
|
+
)) })
|
|
2492
|
+
] });
|
|
2493
|
+
});
|
|
2494
|
+
var SectionLabel = memo(function SectionLabel2({ children }) {
|
|
2495
|
+
return /* @__PURE__ */ jsx12(
|
|
2496
|
+
"div",
|
|
2497
|
+
{
|
|
2498
|
+
style: {
|
|
2499
|
+
padding: "4px 12px 8px",
|
|
2500
|
+
fontSize: 10,
|
|
2501
|
+
fontWeight: 600,
|
|
2502
|
+
textTransform: "uppercase",
|
|
2503
|
+
letterSpacing: "0.05em",
|
|
2504
|
+
color: theme.textMuted
|
|
2505
|
+
},
|
|
2506
|
+
children
|
|
2507
|
+
}
|
|
2508
|
+
);
|
|
2509
|
+
});
|
|
2510
|
+
var SubflowTree = memo(function SubflowTree2({
|
|
2511
|
+
spec,
|
|
2512
|
+
activeStage,
|
|
2513
|
+
doneStages,
|
|
2514
|
+
onNodeSelect,
|
|
2515
|
+
unstyled = false,
|
|
2516
|
+
className,
|
|
2517
|
+
style
|
|
2518
|
+
}) {
|
|
2519
|
+
const tree = useMemo8(() => specToTree(spec), [spec]);
|
|
2520
|
+
const mainStages = useMemo8(() => tree.filter((e) => !e.isSubflow), [tree]);
|
|
2521
|
+
const subflowStages = useMemo8(() => tree.filter((e) => e.isSubflow), [tree]);
|
|
2522
|
+
const renderEntries = (entries) => entries.map((entry, i) => /* @__PURE__ */ jsx12(
|
|
2523
|
+
TreeNode,
|
|
2524
|
+
{
|
|
2525
|
+
entry,
|
|
2526
|
+
depth: 0,
|
|
2527
|
+
activeStage,
|
|
2528
|
+
doneStages,
|
|
2529
|
+
onNodeSelect
|
|
2530
|
+
},
|
|
2531
|
+
`${entry.name}-${i}`
|
|
2532
|
+
));
|
|
2533
|
+
return /* @__PURE__ */ jsxs11(
|
|
2534
|
+
"div",
|
|
2535
|
+
{
|
|
2536
|
+
className,
|
|
2537
|
+
"data-fp": "subflow-tree",
|
|
2538
|
+
style: {
|
|
2539
|
+
...unstyled ? {} : {
|
|
2540
|
+
fontFamily: theme.fontSans,
|
|
2541
|
+
fontSize: 12,
|
|
2542
|
+
background: theme.bgPrimary,
|
|
2543
|
+
borderRight: `1px solid ${theme.border}`,
|
|
2544
|
+
overflowY: "auto",
|
|
2545
|
+
overflowX: "hidden",
|
|
2546
|
+
padding: "8px 0"
|
|
2547
|
+
},
|
|
2548
|
+
...style
|
|
2549
|
+
},
|
|
2550
|
+
children: [
|
|
2551
|
+
!unstyled && /* @__PURE__ */ jsx12(SectionLabel, { children: "Flowchart" }),
|
|
2552
|
+
renderEntries(mainStages),
|
|
2553
|
+
subflowStages.length > 0 && /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2554
|
+
!unstyled && /* @__PURE__ */ jsx12("div", { style: { height: 1, background: theme.border, margin: "8px 12px" } }),
|
|
2555
|
+
!unstyled && /* @__PURE__ */ jsx12(SectionLabel, { children: "Subflows" }),
|
|
2556
|
+
renderEntries(subflowStages)
|
|
2557
|
+
] })
|
|
2558
|
+
]
|
|
2559
|
+
}
|
|
2560
|
+
);
|
|
2561
|
+
});
|
|
2562
|
+
|
|
1807
2563
|
// src/adapters/fromRuntimeSnapshot.ts
|
|
1808
2564
|
function toVisualizationSnapshots(runtime) {
|
|
1809
2565
|
const snapshots = [];
|
|
1810
|
-
flattenTree(runtime.executionTree, snapshots, runtime.sharedState);
|
|
2566
|
+
flattenTree(runtime.executionTree, snapshots, runtime.sharedState, 0, runtime.subflowResults, {});
|
|
1811
2567
|
return snapshots;
|
|
1812
2568
|
}
|
|
1813
|
-
function flattenTree(node, out, sharedState, accumulatedMs = 0) {
|
|
2569
|
+
function flattenTree(node, out, sharedState, accumulatedMs = 0, subflowResults, cumulativeMemory = {}) {
|
|
1814
2570
|
const durationMs = typeof node.metrics?.durationMs === "number" ? node.metrics.durationMs : 1;
|
|
1815
2571
|
const startMs = accumulatedMs;
|
|
1816
2572
|
const narrative = buildNarrative(node);
|
|
1817
|
-
const memory = {};
|
|
1818
|
-
if (node.
|
|
1819
|
-
Object.
|
|
2573
|
+
const memory = { ...cumulativeMemory };
|
|
2574
|
+
if (node.stageWrites) {
|
|
2575
|
+
for (const [key, value] of Object.entries(node.stageWrites)) {
|
|
2576
|
+
if (value === void 0) {
|
|
2577
|
+
delete memory[key];
|
|
2578
|
+
} else {
|
|
2579
|
+
memory[key] = value;
|
|
2580
|
+
}
|
|
2581
|
+
}
|
|
1820
2582
|
}
|
|
2583
|
+
const stageId = node.name || node.id;
|
|
2584
|
+
const sfResult = subflowResults?.[node.subflowId ?? stageId];
|
|
1821
2585
|
out.push({
|
|
1822
|
-
stageName:
|
|
1823
|
-
stageLabel:
|
|
2586
|
+
stageName: stageId,
|
|
2587
|
+
stageLabel: stageId,
|
|
1824
2588
|
memory,
|
|
1825
2589
|
narrative,
|
|
1826
2590
|
startMs,
|
|
1827
2591
|
durationMs,
|
|
1828
|
-
status: "done"
|
|
2592
|
+
status: "done",
|
|
2593
|
+
...node.description ? { description: node.description } : void 0,
|
|
2594
|
+
...node.subflowId ? { subflowId: node.subflowId } : void 0,
|
|
2595
|
+
...sfResult ? { subflowResult: sfResult } : void 0
|
|
1829
2596
|
});
|
|
1830
2597
|
let nextMs = startMs + durationMs;
|
|
1831
2598
|
if (node.children && node.children.length > 0) {
|
|
1832
2599
|
let maxChildEnd = nextMs;
|
|
1833
2600
|
for (const child of node.children) {
|
|
1834
|
-
const childEnd = flattenTree(child, out, sharedState, nextMs);
|
|
2601
|
+
const childEnd = flattenTree(child, out, sharedState, nextMs, subflowResults, memory);
|
|
1835
2602
|
maxChildEnd = Math.max(maxChildEnd, childEnd);
|
|
1836
2603
|
}
|
|
1837
2604
|
nextMs = maxChildEnd;
|
|
1838
2605
|
}
|
|
1839
2606
|
if (node.next) {
|
|
1840
|
-
nextMs = flattenTree(node.next, out, sharedState, nextMs);
|
|
2607
|
+
nextMs = flattenTree(node.next, out, sharedState, nextMs, subflowResults, memory);
|
|
1841
2608
|
}
|
|
1842
2609
|
return nextMs;
|
|
1843
2610
|
}
|
|
@@ -1846,8 +2613,8 @@ function buildNarrative(node) {
|
|
|
1846
2613
|
if (node.name) {
|
|
1847
2614
|
parts.push(`Stage "${node.name}" executed.`);
|
|
1848
2615
|
}
|
|
1849
|
-
if (node.
|
|
1850
|
-
const keys = Object.keys(node.
|
|
2616
|
+
if (node.stageWrites && Object.keys(node.stageWrites).length > 0) {
|
|
2617
|
+
const keys = Object.keys(node.stageWrites);
|
|
1851
2618
|
parts.push(`Wrote ${keys.length} key(s): ${keys.join(", ")}.`);
|
|
1852
2619
|
}
|
|
1853
2620
|
if (node.errors && Object.keys(node.errors).length > 0) {
|
|
@@ -1871,7 +2638,9 @@ function createSnapshots(stages) {
|
|
|
1871
2638
|
narrative: s.narrative ?? `${s.label ?? s.name} completed.`,
|
|
1872
2639
|
startMs: accMs,
|
|
1873
2640
|
durationMs: duration,
|
|
1874
|
-
status: "done"
|
|
2641
|
+
status: "done",
|
|
2642
|
+
...s.description ? { description: s.description } : void 0,
|
|
2643
|
+
...s.subflowId ? { subflowId: s.subflowId } : void 0
|
|
1875
2644
|
};
|
|
1876
2645
|
accMs += duration;
|
|
1877
2646
|
return snap;
|
|
@@ -1887,6 +2656,8 @@ export {
|
|
|
1887
2656
|
ResultPanel,
|
|
1888
2657
|
ScopeDiff,
|
|
1889
2658
|
SnapshotPanel,
|
|
2659
|
+
StageDetailPanel,
|
|
2660
|
+
SubflowTree,
|
|
1890
2661
|
TimeTravelControls,
|
|
1891
2662
|
coolDark,
|
|
1892
2663
|
createSnapshots,
|