A cached theme palette fetcher that still keeps contrast honest

What’s up everyone? I’m wiring up a theming panel and I’m trying to fetch a brand palette from an API without hammering it, but I also don’t want stale colors to stick around after a deploy (ETag/304 weirdness + cache invalidation races).

const mem = new Map();

export async function getThemePalette(url, { ttlMs = 5 * 60_000 } = {}) {
  const now = Date.now();
  const hit = mem.get(url);
  if (hit && hit.expiresAt > now) return hit.value;

  const res = await fetch(url, {
    cache: "no-cache", // allow revalidation, avoid stuck CDN/browser cache
    headers: hit?.etag ? { "If-None-Match": hit.etag } : {}
  });

  if (res.status === 304 && hit) return hit.value;

  const etag = res.headers.get("etag") || undefined;
  const json = await res.json();

  const value = normalizePalette(json); // expects { primaryHsl: [h,s,l], ... }
  mem.set(url, { value, etag, expiresAt: now + ttlMs });
  return value;
}

export function themeCssVars(p) {
  const [h, s, l] = p.primaryHsl;
  const bg = `hsl(${h} ${s}% ${Math.max(6, l - 42)}%)`;
  const fg = `hsl(${h} ${Math.min(22, s)}% ${Math.min(96, l + 52)}%)`;
  return {
    "--primary": `hsl(${h} ${s}% ${l}%)`,
    "--bg": bg,
    "--fg": fg,
    "--grad": `linear-gradient(135deg, ${bg}, hsl(${h} ${s}% ${l}%))`
  };
}

The neat part is it gives me a stable HSL-based palette and a quick gradient/contrast-ish set of CSS vars while still playing nice with revalidation, so the UI doesn’t flash between old/new themes when the network is flaky.