72 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { db } from "@lib/db/sqlite.ts";
 | |
| import { performanceTable } from "@lib/db/schema.ts";
 | |
| import { between } from "drizzle-orm/sql";
 | |
| 
 | |
| 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 = async (url: string, seconds: number) => {
 | |
|   const u = new URL(url);
 | |
|   if (u.pathname.includes("_frsh/")) return;
 | |
|   u.searchParams.delete("__frsh_c");
 | |
| 
 | |
|   await db.insert(performanceTable).values({
 | |
|     path: decodeURIComponent(u.pathname),
 | |
|     search: u.search,
 | |
|     time: Math.floor(seconds * 1000),
 | |
|   });
 | |
| };
 | |
| 
 | |
| export async function getPerformances(): Promise<PerformanceRes> {
 | |
|   const now = new Date();
 | |
|   const startOfDay = new Date(now.setHours(0, 0, 0, 0));
 | |
|   const endOfDay = new Date(now.setHours(23, 59, 59, 999));
 | |
| 
 | |
|   const performances = await db.select().from(performanceTable).where(
 | |
|     between(performanceTable.createdAt, startOfDay, endOfDay),
 | |
|   );
 | |
|   console.log({ performances });
 | |
| 
 | |
|   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),
 | |
|   };
 | |
| }
 |