"use client";

/**
 * Shares one request between everything that asks for the same thing.
 *
 * Several components each fetched the same endpoint independently, so
 * rendering the marketplace made twelve identical requests for the listings
 * and ten for the settings. This collapses them into one.
 */
type Entry = { at: number; promise: Promise<unknown> };

const cache = new Map<string, Entry>();

/** How long a response is reused before asking again. */
const DEFAULT_TTL = 15_000;

export function fetchOnce<T>(url: string, ttl = DEFAULT_TTL): Promise<T> {
  const hit = cache.get(url);
  if (hit && Date.now() - hit.at < ttl) {
    return hit.promise as Promise<T>;
  }

  const promise = fetch(url)
    .then((r) => (r.ok ? r.json() : null))
    .catch(() => null);

  cache.set(url, { at: Date.now(), promise });
  return promise as Promise<T>;
}

/**
 * Drops a cached response, so the next read is fresh. Call this after
 * changing something the URL returns.
 */
export function forget(url?: string) {
  if (url) cache.delete(url);
  else cache.clear();
}
