Files
Checkmate/server/src/utils/dataUtils.ts
T

64 lines
2.6 KiB
TypeScript
Raw Normal View History

2026-06-09 12:34:15 -07:00
import type { GroupedCheck, HasResponseTime, NormalizedCheck, NormalizedUptimeCheck } from "@/domain/checks/check.type.js";
2026-01-21 00:01:38 +00:00
2026-02-25 20:13:07 +00:00
export const getDateForRange = (dateRange: string): Date | undefined => {
const now = Date.now();
switch (dateRange) {
case "recent":
return new Date(now - 2 * 60 * 60 * 1000); // 2 hours
case "hour":
return new Date(now - 60 * 60 * 1000); // 1 hour
case "day":
return new Date(now - 24 * 60 * 60 * 1000); // 1 day
case "week":
return new Date(now - 7 * 24 * 60 * 60 * 1000); // 7 days
case "month":
return new Date(now - 30 * 24 * 60 * 60 * 1000); // 30 days
case "all":
return undefined;
default:
return undefined;
}
};
2026-07-22 11:00:59 -07:00
const percentileBy = <T>(arr: T[], percentile: number, value: (item: T) => number): number => {
const sorted = arr.slice().sort((a, b) => value(a) - value(b));
2025-04-20 11:29:53 -07:00
const index = (percentile / 100) * (sorted.length - 1);
const lower = Math.floor(index);
const upper = lower + 1;
const weight = index % 1;
2026-07-22 11:00:59 -07:00
if (upper >= sorted.length) return value(sorted[lower]!);
return value(sorted[lower]!) * (1 - weight) + value(sorted[upper]!) * weight;
2025-04-20 11:29:53 -07:00
};
2026-07-22 11:00:59 -07:00
const rescale = (raw: number, min: number, max: number, rangeMin: number, rangeMax: number): number => {
const scaled = rangeMin + ((raw - min) * (rangeMax - rangeMin)) / (max - min);
return Math.max(rangeMin, Math.min(rangeMax, scaled));
2025-04-20 11:29:53 -07:00
};
2026-01-27 18:26:31 +00:00
export const NormalizeData = <T extends HasResponseTime>(checks: T[], rangeMin: number, rangeMax: number): NormalizedCheck<T>[] => {
2026-07-22 11:00:59 -07:00
const original = (check: T) => (typeof check.responseTime === "number" ? check.responseTime : 0);
if (checks.length <= 1) {
return checks.map((check) => ({ ...check, originalResponseTime: original(check) }));
2025-04-20 11:29:53 -07:00
}
2026-07-22 11:00:59 -07:00
const min = percentileBy(checks, 0, (c) => c.responseTime);
const max = percentileBy(checks, 95, (c) => c.responseTime);
return checks.map((check) => ({
...check,
responseTime: rescale(check.responseTime, min, max, rangeMin, rangeMax),
originalResponseTime: original(check),
}));
2025-04-20 11:29:53 -07:00
};
2026-01-21 00:01:38 +00:00
export const NormalizeDataUptimeDetails = <T extends GroupedCheck>(checks: T[], rangeMin: number, rangeMax: number): NormalizedUptimeCheck<T>[] => {
2026-07-22 11:00:59 -07:00
const original = (check: T) => (typeof check.avgResponseTime === "number" ? check.avgResponseTime : 0);
if (checks.length <= 1) {
return checks.map((check) => ({ ...check, originalAvgResponseTime: original(check) }));
2025-04-20 11:29:53 -07:00
}
2026-07-22 11:00:59 -07:00
const min = percentileBy(checks, 0, (c) => c.avgResponseTime);
const max = percentileBy(checks, 95, (c) => c.avgResponseTime);
return checks.map((check) => ({
...check,
avgResponseTime: rescale(check.avgResponseTime, min, max, rangeMin, rangeMax),
originalAvgResponseTime: original(check),
}));
2025-04-20 11:29:53 -07:00
};