import { isSegment, readSong } from "@/lib/browse"; import { DEFAULT_TOLERANCE, diffPlans, summariseDiff } from "@/lib/plandiff"; export const dynamic = "force-dynamic"; // `?song=&a=&b=` — two plans of one song, aligned and compared. // // A 880-note plan produces a lot of deltas, so `?deltas=` caps what comes back; // the counts are always complete and the cap is reported, because a truncation // you cannot see reads as "that is all of them". export async function GET(request: Request) { const url = new URL(request.url); const id = url.searchParams.get("song") ?? ""; const a = url.searchParams.get("a") ?? ""; const b = url.searchParams.get("b") ?? ""; const limit = Math.min(2000, Math.max(0, Number(url.searchParams.get("deltas")) || 400)); const tol = Number(url.searchParams.get("tolerance")); if (!isSegment(id)) return Response.json({ error: "bad song" }, { status: 400 }); if (!(await readSong(id))) return Response.json({ error: "no such song" }, { status: 404 }); if (a === b) return Response.json({ error: "pick two different plans" }, { status: 400 }); const diff = await diffPlans(id, a, b, Number.isFinite(tol) && tol > 0 ? tol : DEFAULT_TOLERANCE); if (!diff) { return Response.json({ error: "both names must be files in plan/" }, { status: 404 }); } const shown = diff.deltas.slice(0, limit); return Response.json( { ...diff, deltas: shown, deltaCount: diff.deltas.length, truncated: diff.deltas.length - shown.length, summary: summariseDiff(diff), }, { headers: { "cache-control": "no-store" } }, ); }