{
  "version": 3,
  "sources": ["prefetch.js"],
  "sourcesContent": ["// ─────────────────────────────────────────────────────────────────────────\n// Prefetch: read a crawl's payload into the cache before the reader opens it.\n//\n// The crawl hub and every viewer (report, reader, foundation, plan, questions)\n// read `/api/audit` through swr() under `audit:<id>` with AUDIT_TTL. Warming THAT\n// key with THAT request is what makes the next page paint at once; a different\n// key or body would warm a copy nobody reads. The multi-MB answers payload\n// (`qr:<id>`) is never prefetched: it is only read by the answers views, and it\n// would crowd the per-tab storage quota out for everything else.\n//\n// apiPost is passed in rather than imported, so this module stays free of the\n// auth client (and testable on its own).\n// ─────────────────────────────────────────────────────────────────────────\nimport { warm, AUDIT_TTL } from \"/account/datacache.js\";\n\nexport const auditKey = (id) => `audit:${id}`;\n\nconst WARMED = new Set();\n\n// Warm one crawl, at most once per page. Resolves true when it read the network.\nexport function warmCrawl(id, apiPost) {\n  if (!id || typeof apiPost !== \"function\" || WARMED.has(id)) return Promise.resolve(false);\n  WARMED.add(id);\n  return warm(auditKey(id), () => apiPost(\"/api/audit\", { id }), { ttl: AUDIT_TTL });\n}\n\n// Test seam only.\nexport function _resetWarmed() { WARMED.clear(); }\n\n// The newest crawls that have something delivered to open (a foundation or a\n// report), newest first, at most n. Rows are the home page's `audits` select.\nexport function prefetchTargets(audits, n = 3) {\n  const rows = (Array.isArray(audits) ? audits : [])\n    .filter((a) => a && a.id && (a.numbers_published_at || a.foundation_published_at))\n    .slice()\n    .sort((x, y) => String(y.created_at || \"\").localeCompare(String(x.created_at || \"\")));\n  const out = [];\n  for (const a of rows) {\n    if (!out.includes(a.id)) out.push(a.id);\n    if (out.length >= n) break;\n  }\n  return out;\n}\n\n// The crawl id a link opens, when it opens a page that reads `audit:<id>`.\nconst READS_AUDIT = /^\\/account\\/(crawl|report|reader|workbench|foundation|plan|query-explorer|audit)\\/?$/;\nexport function crawlIdFromHref(href) {\n  if (!href || typeof href !== \"string\") return null;\n  try {\n    const base = typeof location !== \"undefined\" && location.origin && location.origin !== \"null\" ? location.origin : \"https://resonatelabs.co\";\n    const u = new URL(href, base);\n    if (u.origin !== base || !READS_AUDIT.test(u.pathname)) return null;\n    // A preview (?demo=1) reads a fixture, not the network.\n    if (u.searchParams.get(\"demo\") === \"1\") return null;\n    return u.searchParams.get(\"id\") || null;\n  } catch { return null; }\n}\n\n// The reader asked the browser to save data: no speculative reads at all.\nexport function saveDataOn() {\n  try { return !!(typeof navigator !== \"undefined\" && navigator.connection && navigator.connection.saveData); }\n  catch { return false; }\n}\n"],
  "mappings": "AAaA,OAAS,QAAAA,EAAM,aAAAC,MAAiB,wBAEzB,aAAM,SAAYC,GAAO,SAASA,CAAE,GAE3C,MAAMC,EAAS,IAAI,IAGZ,gBAAS,UAAUD,EAAIE,EAAS,CACrC,MAAI,CAACF,GAAM,OAAOE,GAAY,YAAcD,EAAO,IAAID,CAAE,EAAU,QAAQ,QAAQ,EAAK,GACxFC,EAAO,IAAID,CAAE,EACNF,EAAK,SAASE,CAAE,EAAG,IAAME,EAAQ,aAAc,CAAE,GAAAF,CAAG,CAAC,EAAG,CAAE,IAAKD,CAAU,CAAC,EACnF,CAGO,gBAAS,cAAe,CAAEE,EAAO,MAAM,CAAG,CAI1C,gBAAS,gBAAgBE,EAAQ,EAAI,EAAG,CAC7C,MAAMC,GAAQ,MAAM,QAAQD,CAAM,EAAIA,EAAS,CAAC,GAC7C,OAAQE,GAAMA,GAAKA,EAAE,KAAOA,EAAE,sBAAwBA,EAAE,wBAAwB,EAChF,MAAM,EACN,KAAK,CAACC,EAAGC,IAAM,OAAOA,EAAE,YAAc,EAAE,EAAE,cAAc,OAAOD,EAAE,YAAc,EAAE,CAAC,CAAC,EAChFE,EAAM,CAAC,EACb,UAAWH,KAAKD,EAEd,GADKI,EAAI,SAASH,EAAE,EAAE,GAAGG,EAAI,KAAKH,EAAE,EAAE,EAClCG,EAAI,QAAU,EAAG,MAEvB,OAAOA,CACT,CAGA,MAAMC,EAAc,uFACb,gBAAS,gBAAgBC,EAAM,CACpC,GAAI,CAACA,GAAQ,OAAOA,GAAS,SAAU,OAAO,KAC9C,GAAI,CACF,MAAMC,EAAO,OAAO,SAAa,KAAe,SAAS,QAAU,SAAS,SAAW,OAAS,SAAS,OAAS,0BAC5GC,EAAI,IAAI,IAAIF,EAAMC,CAAI,EAG5B,OAFIC,EAAE,SAAWD,GAAQ,CAACF,EAAY,KAAKG,EAAE,QAAQ,GAEjDA,EAAE,aAAa,IAAI,MAAM,IAAM,IAAY,KACxCA,EAAE,aAAa,IAAI,IAAI,GAAK,IACrC,MAAQ,CAAE,OAAO,IAAM,CACzB,CAGO,gBAAS,YAAa,CAC3B,GAAI,CAAE,MAAO,CAAC,EAAE,OAAO,UAAc,KAAe,UAAU,YAAc,UAAU,WAAW,SAAW,MACtG,CAAE,MAAO,EAAO,CACxB",
  "names": ["warm", "AUDIT_TTL", "id", "WARMED", "apiPost", "audits", "rows", "a", "x", "y", "out", "READS_AUDIT", "href", "base", "u"]
}
