2025-01-06 16:14:29 +01:00
|
|
|
import { db } from "@lib/db/sqlite.ts";
|
|
|
|
import { performanceTable } from "@lib/db/schema.ts";
|
2025-01-05 18:03:59 +01:00
|
|
|
import { between } from "drizzle-orm/sql";
|
2023-08-13 00:34:03 +02:00
|
|
|
|
|
|
|
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];
|
|
|
|
}[];
|
|
|
|
};
|
|
|
|
|
2025-01-05 18:03:59 +01:00
|
|
|
export const savePerformance = async (url: string, seconds: number) => {
|
2023-08-13 00:34:03 +02:00
|
|
|
const u = new URL(url);
|
|
|
|
if (u.pathname.includes("_frsh/")) return;
|
|
|
|
u.searchParams.delete("__frsh_c");
|
|
|
|
|
2025-01-05 21:27:31 +01:00
|
|
|
await db.insert(performanceTable).values({
|
2025-01-05 18:03:59 +01:00
|
|
|
path: decodeURIComponent(u.pathname),
|
|
|
|
search: u.search,
|
|
|
|
time: Math.floor(seconds * 1000),
|
|
|
|
});
|
2023-08-13 00:34:03 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
export async function getPerformances(): Promise<PerformanceRes> {
|
2025-01-05 18:03:59 +01:00
|
|
|
const now = new Date();
|
|
|
|
const startOfDay = new Date(now.setHours(0, 0, 0, 0));
|
|
|
|
const endOfDay = new Date(now.setHours(23, 59, 59, 999));
|
2023-08-17 21:31:52 +02:00
|
|
|
|
2025-01-05 18:03:59 +01:00
|
|
|
const performances = await db.select().from(performanceTable).where(
|
|
|
|
between(performanceTable.createdAt, startOfDay, endOfDay),
|
2023-08-13 00:34:03 +02:00
|
|
|
);
|
2025-01-05 18:03:59 +01:00
|
|
|
console.log({ performances });
|
2023-08-13 00:34:03 +02:00
|
|
|
|
|
|
|
let maximum = 0;
|
|
|
|
|
|
|
|
const res = new Map<string, number[]>();
|
|
|
|
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),
|
|
|
|
};
|
|
|
|
}
|