diff --git a/viz/app/store_page.js b/viz/app/store_page.js index 4cb6456..481217c 100644 --- a/viz/app/store_page.js +++ b/viz/app/store_page.js @@ -1,4 +1,4 @@ -import { esc, renderThumbHtml, prettyTs } from "./dom.js"; +import { esc, renderThumbHtml } from "./dom.js"; import { tokenizeQuery, matchesAllTokens, @@ -6,464 +6,536 @@ import { keySkuForRow, parsePriceToNumber, } from "./sku.js"; -import { loadIndex, loadRecent, saveQuery, loadSavedQuery } from "./state.js"; +import { loadIndex } from "./state.js"; import { aggregateBySku } from "./catalog.js"; import { loadSkuRules } from "./mapping.js"; -export function renderStore($app, storeLabelParam) { +function normStoreLabel(s) { + return String(s || "").trim().toLowerCase(); +} + +function abbrevStoreLabel(s) { + const t = String(s || "").trim(); + if (!t) return ""; + return t.split(/\s+/)[0] || t; +} + +function readLinkHrefForSkuInStore(listingsLive, canonSku, storeLabelNorm) { + // Prefer the most recent-ish url if multiple exist; stable enough for viz. + let bestUrl = ""; + let bestScore = -1; + + function scoreUrl(u) { + if (!u) return -1; + let s = u.length; + if (/\bproduct\/\d+\//.test(u)) s += 50; + if (/[a-z0-9-]{8,}/i.test(u)) s += 10; + return s; + } + + for (const r of listingsLive) { + if (!r || r.removed) continue; + const store = normStoreLabel(r.storeLabel || r.store || ""); + if (store !== storeLabelNorm) continue; + + const skuKey = String( + rulesCache?.canonicalSku(keySkuForRow(r)) || keySkuForRow(r) + ); + if (skuKey !== canonSku) continue; + + const u = String(r.url || "").trim(); + const sc = scoreUrl(u); + if (sc > bestScore) { + bestScore = sc; + bestUrl = u; + } else if (sc === bestScore && u && bestUrl && u < bestUrl) { + bestUrl = u; + } + } + return bestUrl; +} + +// small module-level cache so we can reuse in readLinkHrefForSkuInStore +let rulesCache = null; + +export async function renderStore($app, storeLabelRaw) { + const storeLabel = String(storeLabelRaw || "").trim(); + const storeLabelShort = + abbrevStoreLabel(storeLabel) || (storeLabel ? storeLabel : "Store"); + $app.innerHTML = `