@benchkit/chart 0.1.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 +640 -0
- package/dist/ComparisonSummaryTable.test.d.ts +2 -0
- package/dist/ComparisonSummaryTable.test.d.ts.map +1 -0
- package/dist/ComparisonSummaryTable.test.js +53 -0
- package/dist/ComparisonSummaryTable.test.js.map +1 -0
- package/dist/Dashboard.d.ts +25 -0
- package/dist/Dashboard.d.ts.map +1 -0
- package/dist/Dashboard.js +87 -0
- package/dist/Dashboard.js.map +1 -0
- package/dist/Dashboard.test.d.ts +2 -0
- package/dist/Dashboard.test.d.ts.map +1 -0
- package/dist/Dashboard.test.js +49 -0
- package/dist/Dashboard.test.js.map +1 -0
- package/dist/RunDashboard.d.ts +20 -0
- package/dist/RunDashboard.d.ts.map +1 -0
- package/dist/RunDashboard.js +174 -0
- package/dist/RunDashboard.js.map +1 -0
- package/dist/RunDashboard.test.d.ts +2 -0
- package/dist/RunDashboard.test.d.ts.map +1 -0
- package/dist/RunDashboard.test.js +58 -0
- package/dist/RunDashboard.test.js.map +1 -0
- package/dist/RunDetail.d.ts +26 -0
- package/dist/RunDetail.d.ts.map +1 -0
- package/dist/RunDetail.js +100 -0
- package/dist/RunDetail.js.map +1 -0
- package/dist/RunDetail.test.d.ts +2 -0
- package/dist/RunDetail.test.d.ts.map +1 -0
- package/dist/RunDetail.test.js +168 -0
- package/dist/RunDetail.test.js.map +1 -0
- package/dist/RunSelector.test.d.ts +2 -0
- package/dist/RunSelector.test.d.ts.map +1 -0
- package/dist/RunSelector.test.js +45 -0
- package/dist/RunSelector.test.js.map +1 -0
- package/dist/SampleChart.test.d.ts +2 -0
- package/dist/SampleChart.test.d.ts.map +1 -0
- package/dist/SampleChart.test.js +48 -0
- package/dist/SampleChart.test.js.map +1 -0
- package/dist/TagFilter.test.d.ts +2 -0
- package/dist/TagFilter.test.d.ts.map +1 -0
- package/dist/TagFilter.test.js +106 -0
- package/dist/TagFilter.test.js.map +1 -0
- package/dist/VerdictBanner.test.d.ts +2 -0
- package/dist/VerdictBanner.test.d.ts.map +1 -0
- package/dist/VerdictBanner.test.js +56 -0
- package/dist/VerdictBanner.test.js.map +1 -0
- package/dist/chart-config.d.ts +100 -0
- package/dist/chart-config.d.ts.map +1 -0
- package/dist/chart-config.js +81 -0
- package/dist/chart-config.js.map +1 -0
- package/dist/colors.d.ts +11 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +16 -0
- package/dist/colors.js.map +1 -0
- package/dist/comparison-transforms.d.ts +22 -0
- package/dist/comparison-transforms.d.ts.map +1 -0
- package/dist/comparison-transforms.js +20 -0
- package/dist/comparison-transforms.js.map +1 -0
- package/dist/comparison-transforms.test.d.ts +2 -0
- package/dist/comparison-transforms.test.d.ts.map +1 -0
- package/dist/comparison-transforms.test.js +75 -0
- package/dist/comparison-transforms.test.js.map +1 -0
- package/dist/components/ComparisonBar.d.ts +13 -0
- package/dist/components/ComparisonBar.d.ts.map +1 -0
- package/dist/components/ComparisonBar.js +94 -0
- package/dist/components/ComparisonBar.js.map +1 -0
- package/dist/components/ComparisonChart.d.ts +31 -0
- package/dist/components/ComparisonChart.d.ts.map +1 -0
- package/dist/components/ComparisonChart.js +118 -0
- package/dist/components/ComparisonChart.js.map +1 -0
- package/dist/components/ComparisonSummaryTable.d.ts +29 -0
- package/dist/components/ComparisonSummaryTable.d.ts.map +1 -0
- package/dist/components/ComparisonSummaryTable.js +41 -0
- package/dist/components/ComparisonSummaryTable.js.map +1 -0
- package/dist/components/DashboardToolbar.d.ts +21 -0
- package/dist/components/DashboardToolbar.d.ts.map +1 -0
- package/dist/components/DashboardToolbar.js +14 -0
- package/dist/components/DashboardToolbar.js.map +1 -0
- package/dist/components/DateRangeFilter.d.ts +19 -0
- package/dist/components/DateRangeFilter.d.ts.map +1 -0
- package/dist/components/DateRangeFilter.js +44 -0
- package/dist/components/DateRangeFilter.js.map +1 -0
- package/dist/components/HeroSection.d.ts +12 -0
- package/dist/components/HeroSection.d.ts.map +1 -0
- package/dist/components/HeroSection.js +6 -0
- package/dist/components/HeroSection.js.map +1 -0
- package/dist/components/Leaderboard.d.ts +9 -0
- package/dist/components/Leaderboard.d.ts.map +1 -0
- package/dist/components/Leaderboard.js +41 -0
- package/dist/components/Leaderboard.js.map +1 -0
- package/dist/components/MetricCard.d.ts +16 -0
- package/dist/components/MetricCard.d.ts.map +1 -0
- package/dist/components/MetricCard.js +25 -0
- package/dist/components/MetricCard.js.map +1 -0
- package/dist/components/MetricDetailView.d.ts +15 -0
- package/dist/components/MetricDetailView.d.ts.map +1 -0
- package/dist/components/MetricDetailView.js +11 -0
- package/dist/components/MetricDetailView.js.map +1 -0
- package/dist/components/MonitorSection.d.ts +21 -0
- package/dist/components/MonitorSection.d.ts.map +1 -0
- package/dist/components/MonitorSection.js +38 -0
- package/dist/components/MonitorSection.js.map +1 -0
- package/dist/components/OverviewGrid.d.ts +17 -0
- package/dist/components/OverviewGrid.d.ts.map +1 -0
- package/dist/components/OverviewGrid.js +15 -0
- package/dist/components/OverviewGrid.js.map +1 -0
- package/dist/components/RunSelector.d.ts +20 -0
- package/dist/components/RunSelector.d.ts.map +1 -0
- package/dist/components/RunSelector.js +53 -0
- package/dist/components/RunSelector.js.map +1 -0
- package/dist/components/RunTable.d.ts +13 -0
- package/dist/components/RunTable.d.ts.map +1 -0
- package/dist/components/RunTable.js +24 -0
- package/dist/components/RunTable.js.map +1 -0
- package/dist/components/SampleChart.d.ts +21 -0
- package/dist/components/SampleChart.d.ts.map +1 -0
- package/dist/components/SampleChart.js +77 -0
- package/dist/components/SampleChart.js.map +1 -0
- package/dist/components/TagFilter.d.ts +12 -0
- package/dist/components/TagFilter.d.ts.map +1 -0
- package/dist/components/TagFilter.js +59 -0
- package/dist/components/TagFilter.js.map +1 -0
- package/dist/components/TrendChart.d.ts +25 -0
- package/dist/components/TrendChart.d.ts.map +1 -0
- package/dist/components/TrendChart.js +95 -0
- package/dist/components/TrendChart.js.map +1 -0
- package/dist/components/VerdictBanner.d.ts +13 -0
- package/dist/components/VerdictBanner.d.ts.map +1 -0
- package/dist/components/VerdictBanner.js +22 -0
- package/dist/components/VerdictBanner.js.map +1 -0
- package/dist/dashboard-labels.d.ts +47 -0
- package/dist/dashboard-labels.d.ts.map +1 -0
- package/dist/dashboard-labels.js +44 -0
- package/dist/dashboard-labels.js.map +1 -0
- package/dist/dashboard-labels.test.d.ts +2 -0
- package/dist/dashboard-labels.test.d.ts.map +1 -0
- package/dist/dashboard-labels.test.js +34 -0
- package/dist/dashboard-labels.test.js.map +1 -0
- package/dist/dataset-transforms.d.ts +41 -0
- package/dist/dataset-transforms.d.ts.map +1 -0
- package/dist/dataset-transforms.js +132 -0
- package/dist/dataset-transforms.js.map +1 -0
- package/dist/dataset-transforms.test.d.ts +2 -0
- package/dist/dataset-transforms.test.d.ts.map +1 -0
- package/dist/dataset-transforms.test.js +208 -0
- package/dist/dataset-transforms.test.js.map +1 -0
- package/dist/date-range.test.d.ts +2 -0
- package/dist/date-range.test.d.ts.map +1 -0
- package/dist/date-range.test.js +116 -0
- package/dist/date-range.test.js.map +1 -0
- package/dist/embed.d.ts +45 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +170 -0
- package/dist/embed.js.map +1 -0
- package/dist/embed.test.d.ts +2 -0
- package/dist/embed.test.d.ts.map +1 -0
- package/dist/embed.test.js +15 -0
- package/dist/embed.test.js.map +1 -0
- package/dist/fetch.d.ts +27 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +73 -0
- package/dist/fetch.js.map +1 -0
- package/dist/fetch.test.d.ts +2 -0
- package/dist/fetch.test.d.ts.map +1 -0
- package/dist/fetch.test.js +75 -0
- package/dist/fetch.test.js.map +1 -0
- package/dist/format-utils.d.ts +48 -0
- package/dist/format-utils.d.ts.map +1 -0
- package/dist/format-utils.js +98 -0
- package/dist/format-utils.js.map +1 -0
- package/dist/format-utils.test.d.ts +2 -0
- package/dist/format-utils.test.d.ts.map +1 -0
- package/dist/format-utils.test.js +103 -0
- package/dist/format-utils.test.js.map +1 -0
- package/dist/hooks/useChartLifecycle.d.ts +20 -0
- package/dist/hooks/useChartLifecycle.d.ts.map +1 -0
- package/dist/hooks/useChartLifecycle.js +46 -0
- package/dist/hooks/useChartLifecycle.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +10 -0
- package/dist/index.test.js.map +1 -0
- package/dist/labels.d.ts +5 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +41 -0
- package/dist/labels.js.map +1 -0
- package/dist/labels.test.d.ts +2 -0
- package/dist/labels.test.d.ts.map +1 -0
- package/dist/labels.test.js +28 -0
- package/dist/labels.test.js.map +1 -0
- package/dist/leaderboard.d.ts +29 -0
- package/dist/leaderboard.d.ts.map +1 -0
- package/dist/leaderboard.js +40 -0
- package/dist/leaderboard.js.map +1 -0
- package/dist/leaderboard.test.d.ts +2 -0
- package/dist/leaderboard.test.d.ts.map +1 -0
- package/dist/leaderboard.test.js +105 -0
- package/dist/leaderboard.test.js.map +1 -0
- package/dist/sample-utils.d.ts +4 -0
- package/dist/sample-utils.d.ts.map +1 -0
- package/dist/sample-utils.js +12 -0
- package/dist/sample-utils.js.map +1 -0
- package/dist/style.css +912 -0
- package/dist/theme.d.ts +12 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +17 -0
- package/dist/theme.js.map +1 -0
- package/dist/utils.d.ts +37 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +63 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +196 -0
- package/dist/utils.test.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComparisonSummaryTable.test.js","sourceRoot":"","sources":["../src/ComparisonSummaryTable.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SeriesEntry, RunEntry } from "@benchkit/format";
|
|
2
|
+
import { type DataSource } from "./fetch.js";
|
|
3
|
+
import { type DashboardLabels } from "./dashboard-labels.js";
|
|
4
|
+
export interface DashboardProps {
|
|
5
|
+
source: DataSource;
|
|
6
|
+
class?: string;
|
|
7
|
+
/** Max data points per sparkline (default: 20) */
|
|
8
|
+
maxPoints?: number;
|
|
9
|
+
/** Max run rows in the table (default: 20) */
|
|
10
|
+
maxRuns?: number;
|
|
11
|
+
/** Custom metric label renderer */
|
|
12
|
+
metricLabelFormatter?: (metric: string) => string;
|
|
13
|
+
/** Custom series name renderer */
|
|
14
|
+
seriesNameFormatter?: (name: string, entry: SeriesEntry) => string;
|
|
15
|
+
/** Link commits to GitHub or other VCS */
|
|
16
|
+
commitHref?: (commit: string, run: RunEntry) => string | undefined;
|
|
17
|
+
/** Percentage change that triggers a regression warning (default: 10) */
|
|
18
|
+
regressionThreshold?: number;
|
|
19
|
+
/** Number of preceding data points to average for regression detection (default: 5) */
|
|
20
|
+
regressionWindow?: number;
|
|
21
|
+
/** Override any user-facing label/text string in the dashboard */
|
|
22
|
+
labels?: Partial<DashboardLabels>;
|
|
23
|
+
}
|
|
24
|
+
export declare function Dashboard({ source, class: className, maxPoints, maxRuns, metricLabelFormatter, seriesNameFormatter, commitHref, regressionThreshold, regressionWindow, labels: labelOverrides, }: DashboardProps): import("preact").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=Dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../src/Dashboard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAyB,WAAW,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAA2B,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,KAAK,eAAe,EAAiB,MAAM,uBAAuB,CAAC;AAa5E,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IACnE,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,CAAC;IACnE,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uFAAuF;IACvF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;CACnC;AAID,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,KAAK,EAAE,SAAS,EAChB,SAAc,EACd,OAAY,EACZ,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,mBAAwB,EACxB,gBAAoB,EACpB,MAAM,EAAE,cAAc,GACvB,EAAE,cAAc,gCAmMhB"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback, useMemo } from "preact/hooks";
|
|
3
|
+
import { fetchIndex, fetchSeries } from "./fetch.js";
|
|
4
|
+
import { resolveLabels } from "./dashboard-labels.js";
|
|
5
|
+
import { HeroSection } from "./components/HeroSection.js";
|
|
6
|
+
import { DashboardToolbar } from "./components/DashboardToolbar.js";
|
|
7
|
+
import { OverviewGrid } from "./components/OverviewGrid.js";
|
|
8
|
+
import { MetricDetailView } from "./components/MetricDetailView.js";
|
|
9
|
+
import { RunTable } from "./components/RunTable.js";
|
|
10
|
+
import { MonitorSection } from "./components/MonitorSection.js";
|
|
11
|
+
import { filterSeriesFile } from "./components/TagFilter.js";
|
|
12
|
+
import { presetToDateRange } from "./components/DateRangeFilter.js";
|
|
13
|
+
import { defaultMetricLabel, isMonitorMetric } from "./labels.js";
|
|
14
|
+
import { partitionSeriesMap, applyDateRangeToMap, detectAllRegressions } from "./dataset-transforms.js";
|
|
15
|
+
export function Dashboard({ source, class: className, maxPoints = 20, maxRuns = 20, metricLabelFormatter, seriesNameFormatter, commitHref, regressionThreshold = 10, regressionWindow = 5, labels: labelOverrides, }) {
|
|
16
|
+
const labels = resolveLabels(labelOverrides);
|
|
17
|
+
const [index, setIndex] = useState(null);
|
|
18
|
+
const [seriesMap, setSeriesMap] = useState(new Map());
|
|
19
|
+
const [seriesErrors, setSeriesErrors] = useState(new Map());
|
|
20
|
+
const [view, setView] = useState("overview");
|
|
21
|
+
const [activeFilters, setActiveFilters] = useState({});
|
|
22
|
+
const [dateRange, setDateRange] = useState("all");
|
|
23
|
+
const [error, setError] = useState(null);
|
|
24
|
+
const [loading, setLoading] = useState(true);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const { signal } = controller;
|
|
28
|
+
setLoading(true);
|
|
29
|
+
setError(null);
|
|
30
|
+
fetchIndex(source, signal)
|
|
31
|
+
.then(async (idx) => {
|
|
32
|
+
setIndex(idx);
|
|
33
|
+
if (idx.metrics) {
|
|
34
|
+
const results = await Promise.allSettled(idx.metrics.map(async (m) => {
|
|
35
|
+
const s = await fetchSeries(source, m, signal);
|
|
36
|
+
return [m, s];
|
|
37
|
+
}));
|
|
38
|
+
const map = new Map();
|
|
39
|
+
const errs = new Map();
|
|
40
|
+
results.forEach((r, i) => {
|
|
41
|
+
const metric = idx.metrics[i];
|
|
42
|
+
if (r.status === "fulfilled")
|
|
43
|
+
map.set(metric, r.value[1]);
|
|
44
|
+
else
|
|
45
|
+
errs.set(metric, String(r.reason));
|
|
46
|
+
});
|
|
47
|
+
setSeriesMap(map);
|
|
48
|
+
setSeriesErrors(errs);
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
.catch((err) => {
|
|
52
|
+
if (!signal.aborted)
|
|
53
|
+
setError(String(err));
|
|
54
|
+
})
|
|
55
|
+
.finally(() => {
|
|
56
|
+
if (!signal.aborted)
|
|
57
|
+
setLoading(false);
|
|
58
|
+
});
|
|
59
|
+
return () => controller.abort();
|
|
60
|
+
}, [source.owner, source.repo, source.branch, source.baseUrl]);
|
|
61
|
+
const handleMetricClick = useCallback((metric) => {
|
|
62
|
+
setView((v) => (typeof v === "object" && v.metric === metric ? "overview" : { metric }));
|
|
63
|
+
}, []);
|
|
64
|
+
const handleOverview = useCallback(() => setView("overview"), []);
|
|
65
|
+
// Apply date range filter to all series data.
|
|
66
|
+
const dateFilteredSeriesMap = useMemo(() => applyDateRangeToMap(seriesMap, presetToDateRange(dateRange)), [seriesMap, dateRange]);
|
|
67
|
+
const regressionMap = useMemo(() => detectAllRegressions(dateFilteredSeriesMap, regressionThreshold, regressionWindow), [dateFilteredSeriesMap, regressionThreshold, regressionWindow]);
|
|
68
|
+
const rootClassName = ["bk-dashboard", className].filter(Boolean).join(" ");
|
|
69
|
+
const formatMetric = metricLabelFormatter ?? defaultMetricLabel;
|
|
70
|
+
if (loading) {
|
|
71
|
+
return (_jsx("div", { class: rootClassName, children: _jsxs("div", { class: "bk-loading", children: [_jsx("h2", { class: "bk-loading__title", children: labels.loadingTitle }), _jsx("p", { class: "bk-loading__body", children: labels.loadingBody })] }) }));
|
|
72
|
+
}
|
|
73
|
+
if (error) {
|
|
74
|
+
return (_jsx("div", { class: rootClassName, children: _jsxs("div", { class: "bk-state", children: [_jsx("h2", { class: "bk-state__title", children: labels.errorTitle }), _jsx("p", { class: "bk-state__body", children: error })] }) }));
|
|
75
|
+
}
|
|
76
|
+
if (!index) {
|
|
77
|
+
return (_jsx("div", { class: rootClassName, children: _jsxs("div", { class: "bk-state", children: [_jsx("h2", { class: "bk-state__title", children: labels.emptyTitle }), _jsx("p", { class: "bk-state__body", children: labels.emptyBody })] }) }));
|
|
78
|
+
}
|
|
79
|
+
const [monitorSeriesMap, userMetrics] = useMemo(() => partitionSeriesMap(dateFilteredSeriesMap, isMonitorMetric), [dateFilteredSeriesMap]);
|
|
80
|
+
const userMetricNames = (index.metrics ?? []).filter((m) => !isMonitorMetric(m));
|
|
81
|
+
const selectedMetric = typeof view === "object" ? view.metric : null;
|
|
82
|
+
const selectedSeries = selectedMetric ? dateFilteredSeriesMap.get(selectedMetric) : null;
|
|
83
|
+
const selectedMetricError = selectedMetric ? (seriesErrors.get(selectedMetric) ?? null) : null;
|
|
84
|
+
const visibleSeriesCount = [...userMetrics.values()].reduce((sum, sf) => sum + Object.keys(filterSeriesFile(sf, activeFilters).series).length, 0);
|
|
85
|
+
return (_jsx("div", { class: rootClassName, children: _jsxs("div", { class: "bk-shell", children: [_jsx(HeroSection, { userMetricCount: userMetricNames.length, runCount: index.runs.length, visibleSeriesCount: visibleSeriesCount, monitorMetricCount: monitorSeriesMap.size, latestRun: index.runs[0], labels: labels }), _jsx(DashboardToolbar, { metricNames: userMetricNames, selectedMetric: selectedMetric, userSeriesMap: userMetrics, activeFilters: activeFilters, dateRange: dateRange, formatMetric: formatMetric, onMetricClick: handleMetricClick, onOverview: handleOverview, onFilterChange: setActiveFilters, onDateRangeChange: setDateRange, labels: labels }), selectedMetricError ? (_jsxs("div", { class: "bk-state", children: [_jsxs("h2", { class: "bk-state__title", children: ["Could not load ", selectedMetric ? formatMetric(selectedMetric) : "metric"] }), _jsx("p", { class: "bk-state__body", children: selectedMetricError })] })) : selectedSeries ? (_jsx(MetricDetailView, { seriesFile: selectedSeries, activeFilters: activeFilters, regressions: regressionMap.get(selectedMetric) ?? [], maxPoints: maxPoints, formatMetric: formatMetric, seriesNameFormatter: seriesNameFormatter, onBack: handleOverview, labels: labels })) : (_jsx(OverviewGrid, { metricNames: userMetricNames, seriesMap: dateFilteredSeriesMap, seriesErrors: seriesErrors, activeFilters: activeFilters, regressionMap: regressionMap, maxPoints: maxPoints, formatMetric: formatMetric, seriesNameFormatter: seriesNameFormatter, onMetricClick: handleMetricClick, labels: labels })), !selectedSeries && (_jsx(MonitorSection, { monitorSeriesMap: monitorSeriesMap, index: index, maxPoints: maxPoints, metricLabelFormatter: formatMetric, seriesNameFormatter: seriesNameFormatter, onMetricClick: handleMetricClick, labels: labels })), _jsxs("section", { class: "bk-section", "aria-labelledby": "bk-recent-runs-title", children: [_jsx("div", { class: "bk-section__header", children: _jsxs("div", { children: [_jsx("h3", { class: "bk-section__title", id: "bk-recent-runs-title", children: labels.recentRunsTitle }), _jsx("p", { class: "bk-section__description", children: labels.recentRunsDescription })] }) }), _jsx(RunTable, { index: index, maxRows: maxRuns, commitHref: commitHref, labels: labels })] })] }) }));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=Dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../src/Dashboard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.test.d.ts","sourceRoot":"","sources":["../src/Dashboard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import * as assert from "node:assert/strict";
|
|
3
|
+
import { isMonitorMetric } from "./labels.js";
|
|
4
|
+
describe("isMonitorMetric", () => {
|
|
5
|
+
it("returns true for _monitor/ prefixed metrics", () => {
|
|
6
|
+
assert.equal(isMonitorMetric("_monitor/system"), true);
|
|
7
|
+
assert.equal(isMonitorMetric("_monitor/process/worker"), true);
|
|
8
|
+
assert.equal(isMonitorMetric("_monitor/cpu_user_pct"), true);
|
|
9
|
+
});
|
|
10
|
+
it("returns false for regular metrics", () => {
|
|
11
|
+
assert.equal(isMonitorMetric("ns_per_op"), false);
|
|
12
|
+
assert.equal(isMonitorMetric("bytes_per_op"), false);
|
|
13
|
+
assert.equal(isMonitorMetric("eps"), false);
|
|
14
|
+
});
|
|
15
|
+
it("returns false for metrics that contain but do not start with _monitor/", () => {
|
|
16
|
+
assert.equal(isMonitorMetric("my_monitor/metric"), false);
|
|
17
|
+
assert.equal(isMonitorMetric("benchmark/_monitor/foo"), false);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe("metric partitioning", () => {
|
|
21
|
+
const allMetrics = [
|
|
22
|
+
"ns_per_op",
|
|
23
|
+
"bytes_per_op",
|
|
24
|
+
"_monitor/system",
|
|
25
|
+
"_monitor/process/worker",
|
|
26
|
+
"allocs_per_op",
|
|
27
|
+
];
|
|
28
|
+
it("correctly separates user metrics from monitor metrics", () => {
|
|
29
|
+
const userMetrics = allMetrics.filter((m) => !isMonitorMetric(m));
|
|
30
|
+
const monitorMetrics = allMetrics.filter((m) => isMonitorMetric(m));
|
|
31
|
+
assert.deepEqual(userMetrics, ["ns_per_op", "bytes_per_op", "allocs_per_op"]);
|
|
32
|
+
assert.deepEqual(monitorMetrics, ["_monitor/system", "_monitor/process/worker"]);
|
|
33
|
+
});
|
|
34
|
+
it("returns all metrics as user metrics when no monitor metrics present", () => {
|
|
35
|
+
const metrics = ["ns_per_op", "bytes_per_op"];
|
|
36
|
+
const userMetrics = metrics.filter((m) => !isMonitorMetric(m));
|
|
37
|
+
const monitorMetrics = metrics.filter((m) => isMonitorMetric(m));
|
|
38
|
+
assert.deepEqual(userMetrics, ["ns_per_op", "bytes_per_op"]);
|
|
39
|
+
assert.deepEqual(monitorMetrics, []);
|
|
40
|
+
});
|
|
41
|
+
it("returns all metrics as monitor metrics when all are monitor metrics", () => {
|
|
42
|
+
const metrics = ["_monitor/system", "_monitor/process/worker"];
|
|
43
|
+
const userMetrics = metrics.filter((m) => !isMonitorMetric(m));
|
|
44
|
+
const monitorMetrics = metrics.filter((m) => isMonitorMetric(m));
|
|
45
|
+
assert.deepEqual(userMetrics, []);
|
|
46
|
+
assert.deepEqual(monitorMetrics, ["_monitor/system", "_monitor/process/worker"]);
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=Dashboard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.test.js","sourceRoot":"","sources":["../src/Dashboard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IndexFile, PrIndexEntry, RefIndexEntry } from "@benchkit/format";
|
|
2
|
+
import { type DataSource } from "./fetch.js";
|
|
3
|
+
export interface RunDashboardProps {
|
|
4
|
+
source: DataSource;
|
|
5
|
+
/** Branch used for baseline resolution. Default: "main" */
|
|
6
|
+
defaultBranch?: string;
|
|
7
|
+
/** Percentage change threshold for regressions. Default: 5 */
|
|
8
|
+
regressionThreshold?: number;
|
|
9
|
+
/** Link builder for commit hashes */
|
|
10
|
+
commitHref?: (commit: string) => string | undefined;
|
|
11
|
+
/** Custom metric label renderer */
|
|
12
|
+
metricLabelFormatter?: (metric: string) => string;
|
|
13
|
+
class?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Resolved baseline from refIndex or direct run. */
|
|
16
|
+
export declare function resolveBaseline(refIndex: RefIndexEntry[], defaultBranch: string): string | null;
|
|
17
|
+
/** Auto-select the latest run: first PR, or first ref, or first index run. */
|
|
18
|
+
export declare function autoSelectRun(prIndex?: PrIndexEntry[], refIndex?: RefIndexEntry[], index?: IndexFile): string | null;
|
|
19
|
+
export declare function RunDashboard({ source, defaultBranch, regressionThreshold, commitHref: _commitHref, metricLabelFormatter, class: className, }: RunDashboardProps): import("preact").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=RunDashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDashboard.d.ts","sourceRoot":"","sources":["../src/RunDashboard.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EAGd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAMpB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,UAAU,CAAC;IACnB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qCAAqC;IACrC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACpD,mCAAmC;IACnC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EAAE,EACzB,aAAa,EAAE,MAAM,GACpB,MAAM,GAAG,IAAI,CAIf;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,YAAY,EAAE,EACxB,QAAQ,CAAC,EAAE,aAAa,EAAE,EAC1B,KAAK,CAAC,EAAE,SAAS,GAChB,MAAM,GAAG,IAAI,CAiBf;AA8BD,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,aAAsB,EACtB,mBAAuB,EACvB,UAAU,EAAE,WAAW,EACvB,oBAAoB,EACpB,KAAK,EAAE,SAAS,GACjB,EAAE,iBAAiB,gCAyMnB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "preact/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback } from "preact/hooks";
|
|
3
|
+
import { fetchIndex, fetchPrIndex, fetchRefIndex, fetchRunDetail, compareRuns, } from "./fetch.js";
|
|
4
|
+
import { RunSelector } from "./components/RunSelector.js";
|
|
5
|
+
import { VerdictBanner } from "./components/VerdictBanner.js";
|
|
6
|
+
import { ComparisonSummaryTable } from "./components/ComparisonSummaryTable.js";
|
|
7
|
+
import { formatRef } from "./format-utils.js";
|
|
8
|
+
/** Resolved baseline from refIndex or direct run. */
|
|
9
|
+
export function resolveBaseline(refIndex, defaultBranch) {
|
|
10
|
+
const fullRef = `refs/heads/${defaultBranch}`;
|
|
11
|
+
const match = refIndex.find((r) => r.ref === fullRef);
|
|
12
|
+
return match?.latestRunId ?? null;
|
|
13
|
+
}
|
|
14
|
+
/** Auto-select the latest run: first PR, or first ref, or first index run. */
|
|
15
|
+
export function autoSelectRun(prIndex, refIndex, index) {
|
|
16
|
+
if (prIndex && prIndex.length > 0) {
|
|
17
|
+
const sorted = [...prIndex].sort((a, b) => b.latestTimestamp.localeCompare(a.latestTimestamp));
|
|
18
|
+
return sorted[0].latestRunId;
|
|
19
|
+
}
|
|
20
|
+
if (refIndex && refIndex.length > 0) {
|
|
21
|
+
const sorted = [...refIndex].sort((a, b) => b.latestTimestamp.localeCompare(a.latestTimestamp));
|
|
22
|
+
return sorted[0].latestRunId;
|
|
23
|
+
}
|
|
24
|
+
if (index && index.runs.length > 0) {
|
|
25
|
+
return index.runs[0].id;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const INITIAL_STATE = {
|
|
30
|
+
index: null,
|
|
31
|
+
prIndex: [],
|
|
32
|
+
refIndex: [],
|
|
33
|
+
selectedRunId: null,
|
|
34
|
+
baselineRunId: null,
|
|
35
|
+
comparison: null,
|
|
36
|
+
currentDetail: null,
|
|
37
|
+
baselineDetail: null,
|
|
38
|
+
loading: true,
|
|
39
|
+
error: null,
|
|
40
|
+
focusedEntry: null,
|
|
41
|
+
};
|
|
42
|
+
export function RunDashboard({ source, defaultBranch = "main", regressionThreshold = 5, commitHref: _commitHref, metricLabelFormatter, class: className, }) {
|
|
43
|
+
const [state, setState] = useState(INITIAL_STATE);
|
|
44
|
+
// Phase 1: Load indices
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
const ctrl = new AbortController();
|
|
47
|
+
setState((s) => ({ ...s, loading: true, error: null }));
|
|
48
|
+
Promise.all([
|
|
49
|
+
fetchIndex(source, ctrl.signal),
|
|
50
|
+
fetchPrIndex(source, ctrl.signal).catch(() => []),
|
|
51
|
+
fetchRefIndex(source, ctrl.signal).catch(() => []),
|
|
52
|
+
])
|
|
53
|
+
.then(([index, prIndex, refIndex]) => {
|
|
54
|
+
const selectedRunId = autoSelectRun(prIndex, refIndex, index);
|
|
55
|
+
const baselineRunId = resolveBaseline(refIndex, defaultBranch);
|
|
56
|
+
setState((s) => ({
|
|
57
|
+
...s,
|
|
58
|
+
index,
|
|
59
|
+
prIndex,
|
|
60
|
+
refIndex,
|
|
61
|
+
selectedRunId,
|
|
62
|
+
baselineRunId,
|
|
63
|
+
loading: !selectedRunId,
|
|
64
|
+
error: selectedRunId ? null : "No runs available.",
|
|
65
|
+
}));
|
|
66
|
+
})
|
|
67
|
+
.catch((err) => {
|
|
68
|
+
if (!ctrl.signal.aborted) {
|
|
69
|
+
setState((s) => ({
|
|
70
|
+
...s,
|
|
71
|
+
loading: false,
|
|
72
|
+
error: `Failed to load index: ${err instanceof Error ? err.message : String(err)}`,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return () => ctrl.abort();
|
|
77
|
+
}, [source, defaultBranch]);
|
|
78
|
+
// Phase 2: Load run details and compare
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const { selectedRunId, baselineRunId } = state;
|
|
81
|
+
if (!selectedRunId)
|
|
82
|
+
return;
|
|
83
|
+
const ctrl = new AbortController();
|
|
84
|
+
setState((s) => ({ ...s, loading: true, comparison: null, focusedEntry: null }));
|
|
85
|
+
const hasBaseline = baselineRunId && baselineRunId !== selectedRunId;
|
|
86
|
+
if (hasBaseline) {
|
|
87
|
+
compareRuns(source, selectedRunId, baselineRunId, {
|
|
88
|
+
test: "percentage",
|
|
89
|
+
threshold: regressionThreshold,
|
|
90
|
+
}, ctrl.signal)
|
|
91
|
+
.then(({ comparison, currentDetail, baselineDetail }) => {
|
|
92
|
+
setState((s) => ({
|
|
93
|
+
...s,
|
|
94
|
+
currentDetail,
|
|
95
|
+
baselineDetail,
|
|
96
|
+
comparison,
|
|
97
|
+
loading: false,
|
|
98
|
+
error: null,
|
|
99
|
+
}));
|
|
100
|
+
})
|
|
101
|
+
.catch((err) => {
|
|
102
|
+
if (!ctrl.signal.aborted) {
|
|
103
|
+
setState((s) => ({
|
|
104
|
+
...s,
|
|
105
|
+
loading: false,
|
|
106
|
+
error: `Failed to load run details: ${err instanceof Error ? err.message : String(err)}`,
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
fetchRunDetail(source, selectedRunId, ctrl.signal)
|
|
113
|
+
.then((currentDetail) => {
|
|
114
|
+
setState((s) => ({
|
|
115
|
+
...s,
|
|
116
|
+
currentDetail,
|
|
117
|
+
baselineDetail: null,
|
|
118
|
+
comparison: null,
|
|
119
|
+
loading: false,
|
|
120
|
+
error: null,
|
|
121
|
+
}));
|
|
122
|
+
})
|
|
123
|
+
.catch((err) => {
|
|
124
|
+
if (!ctrl.signal.aborted) {
|
|
125
|
+
setState((s) => ({
|
|
126
|
+
...s,
|
|
127
|
+
loading: false,
|
|
128
|
+
error: `Failed to load run detail: ${err instanceof Error ? err.message : String(err)}`,
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return () => ctrl.abort();
|
|
134
|
+
}, [state.selectedRunId, state.baselineRunId, source, regressionThreshold]);
|
|
135
|
+
const onSelectRun = useCallback((runId) => setState((s) => ({ ...s, selectedRunId: runId })), []);
|
|
136
|
+
const onSelectBaseline = useCallback((runId) => setState((s) => ({ ...s, baselineRunId: runId })), []);
|
|
137
|
+
const onSelectEntry = useCallback((benchmark, metric) => setState((s) => ({
|
|
138
|
+
...s,
|
|
139
|
+
focusedEntry: s.focusedEntry?.benchmark === benchmark &&
|
|
140
|
+
s.focusedEntry?.metric === metric
|
|
141
|
+
? null
|
|
142
|
+
: { benchmark, metric },
|
|
143
|
+
})), []);
|
|
144
|
+
const { index, prIndex, refIndex, comparison, loading, error, focusedEntry } = state;
|
|
145
|
+
const metricLabel = metricLabelFormatter ?? ((m) => m);
|
|
146
|
+
const currentRun = index?.runs.find((r) => r.id === state.selectedRunId);
|
|
147
|
+
const baselineRun = index?.runs.find((r) => r.id === state.baselineRunId);
|
|
148
|
+
return (_jsxs("div", { class: ["bk-run-dashboard", className].filter(Boolean).join(" "), children: [index && (_jsx(RunSelector, { prIndex: prIndex, refIndex: refIndex, index: index, selectedRunId: state.selectedRunId ?? undefined, baselineRunId: state.baselineRunId ?? undefined, onSelectRun: onSelectRun, onSelectBaseline: onSelectBaseline })), loading && (_jsx("div", { class: "bk-run-dashboard__status", children: "Loading run data\u2026" })), error && !loading && (_jsx("div", { class: "bk-run-dashboard__status bk-run-dashboard__status--error", children: error })), !loading &&
|
|
149
|
+
!error &&
|
|
150
|
+
!state.baselineRunId &&
|
|
151
|
+
state.selectedRunId && (_jsxs("div", { class: "bk-run-dashboard__status bk-run-dashboard__status--info", children: ["No baseline run found on ", _jsx("code", { children: defaultBranch }), ". Select a baseline manually using \"set baseline\" on any run."] })), !loading && comparison && (_jsxs(_Fragment, { children: [_jsx(VerdictBanner, { result: comparison, currentLabel: runLabel(currentRun), baselineLabel: runLabel(baselineRun) }), _jsx(ComparisonSummaryTable, { entries: comparison.entries, onSelectEntry: onSelectEntry }), focusedEntry && (_jsx(FocusedMetricPanel, { entry: focusedEntry, comparison: comparison, metricLabel: metricLabel }))] })), !loading && !comparison && state.currentDetail && (_jsxs("div", { class: "bk-run-dashboard__status bk-run-dashboard__status--info", children: ["Showing run ", _jsx("strong", { children: state.selectedRunId }), " \u2014", " ", state.currentDetail.metricSnapshots.length, " metrics recorded. Select a baseline to compare."] }))] }));
|
|
152
|
+
}
|
|
153
|
+
/** Short label for a run (commit + ref). */
|
|
154
|
+
function runLabel(run) {
|
|
155
|
+
if (!run)
|
|
156
|
+
return "unknown";
|
|
157
|
+
const ref = run.ref ? formatRef(run.ref) : undefined;
|
|
158
|
+
const commit = run.commit?.slice(0, 7);
|
|
159
|
+
if (ref && ref !== "—" && commit)
|
|
160
|
+
return `${ref} (${commit})`;
|
|
161
|
+
if (ref && ref !== "—")
|
|
162
|
+
return ref;
|
|
163
|
+
if (commit)
|
|
164
|
+
return commit;
|
|
165
|
+
return run.id.slice(0, 12);
|
|
166
|
+
}
|
|
167
|
+
/** Renders a ComparisonChart for the focused metric entry. */
|
|
168
|
+
function FocusedMetricPanel({ entry, comparison, metricLabel, }) {
|
|
169
|
+
const match = comparison.entries.find((e) => e.benchmark === entry.benchmark && e.metric === entry.metric);
|
|
170
|
+
if (!match)
|
|
171
|
+
return null;
|
|
172
|
+
return (_jsxs("div", { class: "bk-run-dashboard__detail", children: [_jsxs("h3", { class: "bk-run-dashboard__detail-title", children: [entry.benchmark, " \u2014 ", metricLabel(entry.metric)] }), _jsxs("p", { class: "bk-run-dashboard__detail-summary", children: ["Baseline: ", _jsx("strong", { children: match.baseline }), " \u2192 Current:", " ", _jsx("strong", { children: match.current }), " (", match.percentChange > 0 ? "+" : "", match.percentChange.toFixed(2), "%)"] })] }));
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=RunDashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDashboard.js","sourceRoot":"","sources":["../src/RunDashboard.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDashboard.test.d.ts","sourceRoot":"","sources":["../src/RunDashboard.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { resolveBaseline, autoSelectRun } from "./RunDashboard.js";
|
|
4
|
+
describe("RunDashboard helpers", () => {
|
|
5
|
+
describe("resolveBaseline", () => {
|
|
6
|
+
const refIndex = [
|
|
7
|
+
{ ref: "refs/heads/main", latestRunId: "run-main-1", latestTimestamp: "2026-04-01T00:00:00Z", runCount: 3 },
|
|
8
|
+
{ ref: "refs/heads/dev", latestRunId: "run-dev-1", latestTimestamp: "2026-04-02T00:00:00Z", runCount: 1 },
|
|
9
|
+
];
|
|
10
|
+
it("resolves baseline from default branch", () => {
|
|
11
|
+
assert.equal(resolveBaseline(refIndex, "main"), "run-main-1");
|
|
12
|
+
});
|
|
13
|
+
it("resolves baseline from custom branch", () => {
|
|
14
|
+
assert.equal(resolveBaseline(refIndex, "dev"), "run-dev-1");
|
|
15
|
+
});
|
|
16
|
+
it("returns null when branch not found", () => {
|
|
17
|
+
assert.equal(resolveBaseline(refIndex, "release"), null);
|
|
18
|
+
});
|
|
19
|
+
it("returns null for empty refIndex", () => {
|
|
20
|
+
assert.equal(resolveBaseline([], "main"), null);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe("autoSelectRun", () => {
|
|
24
|
+
const prIndex = [
|
|
25
|
+
{ prNumber: 10, ref: "refs/pull/10/merge", latestRunId: "pr-10-old", latestTimestamp: "2026-04-01T00:00:00Z", runCount: 1 },
|
|
26
|
+
{ prNumber: 20, ref: "refs/pull/20/merge", latestRunId: "pr-20-new", latestTimestamp: "2026-04-02T00:00:00Z", runCount: 2 },
|
|
27
|
+
];
|
|
28
|
+
const refIndex = [
|
|
29
|
+
{ ref: "refs/heads/main", latestRunId: "ref-main", latestTimestamp: "2026-04-01T00:00:00Z", runCount: 5 },
|
|
30
|
+
{ ref: "refs/heads/dev", latestRunId: "ref-dev", latestTimestamp: "2026-04-03T00:00:00Z", runCount: 1 },
|
|
31
|
+
];
|
|
32
|
+
const index = {
|
|
33
|
+
runs: [
|
|
34
|
+
{ id: "run-1", timestamp: "2026-04-01T00:00:00Z" },
|
|
35
|
+
{ id: "run-2", timestamp: "2026-04-02T00:00:00Z" },
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
it("prefers latest PR when PRs exist", () => {
|
|
39
|
+
assert.equal(autoSelectRun(prIndex, refIndex, index), "pr-20-new");
|
|
40
|
+
});
|
|
41
|
+
it("falls back to latest ref when no PRs", () => {
|
|
42
|
+
assert.equal(autoSelectRun([], refIndex, index), "ref-dev");
|
|
43
|
+
});
|
|
44
|
+
it("falls back to first index run when no PRs or refs", () => {
|
|
45
|
+
assert.equal(autoSelectRun([], [], index), "run-1");
|
|
46
|
+
});
|
|
47
|
+
it("falls back to first index run when undefined PRs/refs", () => {
|
|
48
|
+
assert.equal(autoSelectRun(undefined, undefined, index), "run-1");
|
|
49
|
+
});
|
|
50
|
+
it("returns null when everything is empty", () => {
|
|
51
|
+
assert.equal(autoSelectRun([], [], { runs: [] }), null);
|
|
52
|
+
});
|
|
53
|
+
it("returns null when all undefined", () => {
|
|
54
|
+
assert.equal(autoSelectRun(undefined, undefined, undefined), null);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
//# sourceMappingURL=RunDashboard.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDashboard.test.js","sourceRoot":"","sources":["../src/RunDashboard.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { RunDetailView, RunDetailMetricSnapshot, ComparisonResult } from "@benchkit/format";
|
|
2
|
+
import { type DataSource } from "./fetch.js";
|
|
3
|
+
export interface RunDetailProps {
|
|
4
|
+
/** Preloaded run detail. If provided, no fetch is performed. */
|
|
5
|
+
detail?: RunDetailView;
|
|
6
|
+
/** Data source + run ID for on-demand fetching (ignored when `detail` is set). */
|
|
7
|
+
source?: DataSource;
|
|
8
|
+
runId?: string;
|
|
9
|
+
/** Optional comparison result to show a verdict banner + comparison table. */
|
|
10
|
+
comparison?: ComparisonResult | null;
|
|
11
|
+
/** Labels for comparison context. */
|
|
12
|
+
currentLabel?: string;
|
|
13
|
+
baselineLabel?: string;
|
|
14
|
+
/** Build a link for a commit hash. */
|
|
15
|
+
commitHref?: (commit: string) => string | undefined;
|
|
16
|
+
/** Custom metric label renderer. */
|
|
17
|
+
metricLabelFormatter?: (metric: string) => string;
|
|
18
|
+
class?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface MetricSnapshotCardProps {
|
|
21
|
+
snapshot: RunDetailMetricSnapshot;
|
|
22
|
+
formatMetric: (m: string) => string;
|
|
23
|
+
}
|
|
24
|
+
export declare function MetricSnapshotCard({ snapshot, formatMetric }: MetricSnapshotCardProps): import("preact").JSX.Element;
|
|
25
|
+
export declare function RunDetail({ detail: preloaded, source, runId, comparison, currentLabel, baselineLabel, commitHref, metricLabelFormatter, class: className, }: RunDetailProps): import("preact").JSX.Element;
|
|
26
|
+
//# sourceMappingURL=RunDetail.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunDetail.d.ts","sourceRoot":"","sources":["../src/RunDetail.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,uBAAuB,EACvB,gBAAgB,EAEjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAkB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAW7D,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,kFAAkF;IAClF,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,UAAU,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,qCAAqC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sCAAsC;IACtC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACpD,oCAAoC;IACpC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,YAAY,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AA2ED,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,uBAAuB,gCA8BrF;AAMD,wBAAgB,SAAS,CAAC,EACxB,MAAM,EAAE,SAAS,EACjB,MAAM,EACN,KAAK,EACL,UAAU,EACV,YAAY,EACZ,aAAa,EACb,UAAU,EACV,oBAAoB,EACpB,KAAK,EAAE,SAAS,GACjB,EAAE,cAAc,gCA6HhB"}
|