Files
homarr/packages/widgets/src/speedtest-tracker/helpers.ts
T
2026-04-10 19:04:42 +02:00

54 lines
2.1 KiB
TypeScript

import { formatNumber } from "@homarr/common";
import type {
SpeedtestTrackerDashboardData,
SpeedtestTrackerResult,
SpeedtestTrackerStats,
} from "@homarr/integrations/types";
export const mergeStats = (
statsA: SpeedtestTrackerDashboardData["stats"],
statsB: SpeedtestTrackerDashboardData["stats"],
): SpeedtestTrackerDashboardData["stats"] => {
if (!statsB) return statsA;
if (!statsA) return statsB;
return {
ping: {
avg: (statsA.ping.avg + statsB.ping.avg) / 2,
min: Math.min(statsA.ping.min, statsB.ping.min),
max: Math.max(statsA.ping.max, statsB.ping.max),
},
download: {
avg: (statsA.download.avg + statsB.download.avg) / 2,
avg_bits:
statsA.download.avg_bits !== undefined && statsB.download.avg_bits !== undefined
? (statsA.download.avg_bits + statsB.download.avg_bits) / 2
: (statsA.download.avg_bits ?? statsB.download.avg_bits),
min: Math.min(statsA.download.min, statsB.download.min),
max: Math.max(statsA.download.max, statsB.download.max),
},
upload: {
avg: (statsA.upload.avg + statsB.upload.avg) / 2,
avg_bits:
statsA.upload.avg_bits !== undefined && statsB.upload.avg_bits !== undefined
? (statsA.upload.avg_bits + statsB.upload.avg_bits) / 2
: (statsA.upload.avg_bits ?? statsB.upload.avg_bits),
min: Math.min(statsA.upload.min, statsB.upload.min),
max: Math.max(statsA.upload.max, statsB.upload.max),
},
total_results: statsA.total_results + statsB.total_results,
};
};
export const formatBitsPerSec = (bps: number): string => `${formatNumber(bps, 2)}bps`;
export const formatResultSpeed = (result: SpeedtestTrackerResult, dir: "download" | "upload"): string => {
const bits = dir === "download" ? result.download_bits : result.upload_bits;
if (bits != null) return formatBitsPerSec(bits);
return "—";
};
export const formatStatsSpeed = (band: SpeedtestTrackerStats["download"]): string => {
if (band.avg_bits != null) return formatBitsPerSec(band.avg_bits);
return formatBitsPerSec(band.avg * 8);
};