From a931b24bd4f8906dec762d326ea4862f4d9227a6 Mon Sep 17 00:00:00 2001
From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com>
Date: Wed, 29 Jul 2026 19:53:24 +0200
Subject: [PATCH] feat(data-api): add chain sub-scores to By Provider pivot
cells
---
src/components/data-api-providers-pivot.tsx | 61 ++++++++++++++++++---
src/lib/data-api-stats.ts | 36 ++++++++++++
2 files changed, 88 insertions(+), 9 deletions(-)
diff --git a/src/components/data-api-providers-pivot.tsx b/src/components/data-api-providers-pivot.tsx
index ad75450c..8db603a6 100644
--- a/src/components/data-api-providers-pivot.tsx
+++ b/src/components/data-api-providers-pivot.tsx
@@ -9,6 +9,7 @@ import {
fmtDataValue,
type DataApiProviderPivotRow,
type DataApiRegionScore,
+ type DataApiChainScore,
type DataApiGroup,
} from "@/lib/data-api-stats";
@@ -217,6 +218,8 @@ function GroupCell({
const { bestRank, bestCell } = cell;
const accent = GROUP_META[group].accent;
const hasRegions = bestCell.regions && bestCell.regions.length > 0;
+ const hasChains = bestCell.chains && bestCell.chains.length > 0;
+ const hasSub = hasRegions || hasChains;
const bg =
bestRank === 1
@@ -250,13 +253,20 @@ function GroupCell({
{bestCell.benchShortTitle.replace("coverage", "cov.").replace("freshness", "fresh.")}
- {/* Regional sub-scores */}
- {hasRegions && (
-
+ {/* Region + chain sub-scores merged in one row */}
+ {hasSub && (
+
+ {hasRegions && (
+
+ )}
+ {hasChains && (
+
+ )}
+
)}
);
@@ -272,7 +282,7 @@ function RegionSubScores({
accent: string;
}) {
return (
-
+ <>
{regions.map((r) => (
))}
-
+ >
+ );
+}
+
+function ChainSubScores({
+ chains,
+ accent,
+}: {
+ chains: DataApiChainScore[];
+ accent: string;
+}) {
+ const MAX = 4;
+ const visible = chains.slice(0, MAX);
+ const overflow = chains.length - MAX;
+ return (
+ <>
+ {visible.map((c) => (
+
+ {c.label}
+
+ ))}
+ {overflow > 0 && (
+ +{overflow}
+ )}
+ >
);
}
diff --git a/src/lib/data-api-stats.ts b/src/lib/data-api-stats.ts
index 9f0d7b97..7283a310 100644
--- a/src/lib/data-api-stats.ts
+++ b/src/lib/data-api-stats.ts
@@ -150,6 +150,12 @@ export type DataApiRegionScore = {
p50: number;
};
+export type DataApiChainScore = {
+ chain: string;
+ label: string;
+ p50: number;
+};
+
export type DataApiProviderCell = {
benchSlug: string;
benchShortTitle: string;
@@ -160,6 +166,8 @@ export type DataApiProviderCell = {
higherIsBetter: boolean;
/** Per-region ranks for benches that have extras.regions populated. */
regions?: DataApiRegionScore[];
+ /** Chains this provider leads on in this bench (rank 1 per chain). */
+ chains?: DataApiChainScore[];
};
export type DataApiProviderPivotRow = {
@@ -321,6 +329,32 @@ function computeProviderRegionScores(
return result;
}
+/**
+ * Returns the chains where providerSlug is the winner (rank 1) in this bench.
+ */
+function computeProviderChainScores(
+ bench: Benchmark,
+ providerSlug: string,
+): DataApiChainScore[] {
+ if (!bench.bestPerChain) return [];
+ const scores: DataApiChainScore[] = [];
+ for (const [chain, r] of Object.entries(bench.bestPerChain)) {
+ if (
+ r.slug === providerSlug &&
+ r.availability !== "unavailable" &&
+ !r.unresponsive &&
+ r.ms.p50 > 0
+ ) {
+ scores.push({
+ chain,
+ label: CHAIN_LABELS[chain] ?? chain,
+ p50: r.ms.p50,
+ });
+ }
+ }
+ return scores.sort((a, b) => a.label.localeCompare(b.label));
+}
+
function toBenchRow(slug: string, bench: Benchmark): DataApiBenchRow {
const live = sortedResults(liveResults(bench), bench.higherIsBetter);
return {
@@ -420,6 +454,7 @@ async function buildSnapshot(): Promise {
providerMap.set(r.slug, { name: r.name, cells: [] });
}
const regions = regionScores.get(r.slug);
+ const chains = computeProviderChainScores(bench, r.slug);
providerMap.get(r.slug)!.cells.push({
benchSlug: slug,
benchShortTitle: BENCH_SHORT_TITLE[slug] ?? slug,
@@ -429,6 +464,7 @@ async function buildSnapshot(): Promise {
unit: bench.unit,
higherIsBetter: bench.higherIsBetter,
regions: regions && regions.length > 0 ? regions : undefined,
+ chains: chains.length > 0 ? chains : undefined,
});
}
}