import * as cache from "@lib/cache/cache.ts"; import { getTimeCacheKey } from "@lib/string.ts"; export type PerformancePoint = { path: string; search: string; time: number; date: Date; }; export type PerformanceRes = { max: number; res: { url: string; data: readonly [number, number, number, number]; }[]; }; export const savePerformance = (url: string, milliseconds: number) => { const cacheKey = getTimeCacheKey(); const u = new URL(url); if (u.pathname.includes("_frsh/")) return; u.searchParams.delete("__frsh_c"); cache.set( `performance:${cacheKey}`, JSON.stringify({ path: decodeURIComponent(u.pathname), search: u.search, time: Math.floor(milliseconds * 1000), }), ); }; export async function getPerformances(): Promise { const d = new Date(); const year = d.getFullYear(); const month = d.getMonth().toString(); const day = d.getDay().toString(); const keys = await cache.keys( `performance:${year}:${month}:${day}:*`, ); console.log(`performance:${year}:${month}:${day}:*`); const performances = await Promise.all( keys.map(async (key) => JSON.parse(await cache.get(key)) as PerformancePoint ), ); let maximum = 0; const res = new Map(); for (const p of performances) { const id = p.path; const timings = res.get(id) || []; if (p.time > maximum) maximum = p.time; timings.push(p.time); res.set(id, timings); } return { max: maximum, res: [...res.entries()].map(([url, timings]) => { let total = 0; let min = Infinity; let max = -Infinity; for (const t of timings) { total += t; if (t < min) min = t; if (t > max) max = t; } return { url, data: [timings.length, min, total / timings.length, max] as const, }; }).sort((a, b) => a.data[2] < b.data[2] ? 1 : -1), }; }