/** * Site Finder multi-cad compare — localStorage-backed shortlist (issue #50). * * The compare page lets a developer pin 2–5 cadastral numbers and view their * analyze metrics side-by-side. The shortlist survives reload via localStorage * (per browser, not per server session) — mirroring `gd_recent_parcels` in * site-finder-api.ts. All access is SSR-guarded (`typeof window`). */ const STORAGE_KEY = "gd_compare_shortlist"; /** Hard cap from the issue: batch analyze runs max 5 parcels in parallel. */ export const COMPARE_MAX = 5; /** Need at least two parcels for a meaningful side-by-side. */ export const COMPARE_MIN = 2; /** * Validates cadastral number formats (same regex as CadInput): * 3-part: 66:41:0204016 (quarter) * 4-part: 66:41:0204016:10 (parcel) */ const CAD_REGEX = /^\d+:\d+:\d+(?::\d+)?$/; export function isValidCad(cad: string): boolean { return CAD_REGEX.test(cad.trim()); } export function getShortlist(): string[] { if (typeof window === "undefined") return []; try { const raw = localStorage.getItem(STORAGE_KEY); if (!raw) return []; const parsed: unknown = JSON.parse(raw); if (!Array.isArray(parsed)) return []; // Narrow to a clean, de-duplicated, capped string[] — defends against a // hand-edited / stale localStorage payload. const seen = new Set(); const out: string[] = []; for (const item of parsed) { if (typeof item !== "string") continue; const cad = item.trim(); if (!isValidCad(cad) || seen.has(cad)) continue; seen.add(cad); out.push(cad); if (out.length >= COMPARE_MAX) break; } return out; } catch { return []; } } export function saveShortlist(cads: string[]): void { if (typeof window === "undefined") return; try { localStorage.setItem(STORAGE_KEY, JSON.stringify(cads.slice(0, COMPARE_MAX))); } catch { // ignore quota / disabled-storage errors — shortlist is best-effort } }