// Time /api/v1/dashboard end-to-end via the running dev server. // First mints a PB user-token, then fires 3 cold + 3 warm GETs. import { performance } from "node:perf_hooks"; import PocketBase from "pocketbase"; async function main() { const baseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL || "http://127.0.0.1:8090"; const appUrl = process.env.WFDASH_APP_URL || "http://127.0.0.1:4001"; const email = process.env.PB_ADMIN_EMAIL; const password = process.env.PB_ADMIN_PASSWORD; if (!email || !password) { console.error("Missing PB_ADMIN_EMAIL / PB_ADMIN_PASSWORD"); process.exit(1); } const pb = new PocketBase(baseUrl); // Mint a user-token (the route asserts via /auth-refresh, which // accepts users-issued tokens). const userAuth = await pb.collection("users").authWithPassword("david.els1@outlook.com", "1234567890"); const token = userAuth.token; console.log(`App: ${appUrl}`); console.log(`PB: ${baseUrl}`); const cold: number[] = []; const warm: number[] = []; for (let i = 0; i < 3; i += 1) { const t0 = performance.now(); const res = await fetch(`${appUrl}/api/v1/dashboard`, { headers: { Authorization: token }, cache: "no-store", }); const body = await res.text(); const t1 = performance.now(); cold.push(t1 - t0); if (!res.ok) { console.error(`cold #${i + 1}: HTTP ${res.status} body=${body.slice(0, 200)}`); continue; } console.log(`cold #${i + 1}: ${(t1 - t0).toFixed(0)}ms body=${body.length}B`); } for (let i = 0; i < 3; i += 1) { const t0 = performance.now(); const res = await fetch(`${appUrl}/api/v1/dashboard`, { headers: { Authorization: token }, cache: "no-store", }); const t1 = performance.now(); warm.push(t1 - t0); console.log(`warm #${i + 1}: ${(t1 - t0).toFixed(0)}ms`); } const median = (xs: number[]) => { const sorted = [...xs].sort((a, b) => a - b); return sorted[Math.floor(sorted.length / 2)]; }; console.log("---"); console.log(`Cold median: ${median(cold).toFixed(0)}ms`); console.log(`Warm median: ${median(warm).toFixed(0)}ms`); } main().catch((e) => { console.error(e); process.exit(1); });