{"version":3,"sources":["../src/sourceCache.ts"],"sourcesContent":["// A memoised raw-source reader for React `use()`. (R3-263)\n//\n// `use()` needs a STABLE promise across renders, so a component that reads a file must not\n// start a new read every time it renders. That much is obvious. The part that is not, and\n// the reason this lives in the SDK rather than being re-derived per app, is what happens\n// when a read FAILS:\n//\n//   a rejected promise left in the cache is returned to EVERY later render, so the file can\n//   never recover.\n//\n// That is not theoretical. The host↔sandbox RPC drops requests during a navigation\n// (\"Invalid RPC id\"), and a wiki entry whose read lost that race stayed **permanently blank\n// for the rest of the session** — no error, no retry, nothing short of a reload. Evicting on\n// rejection makes the next attempt a fresh read, so a transient failure costs a retry\n// instead of the page.\n//\n// Injectable reader, no `fs` import: the cache is pure and testable without a host, and the\n// same instance serves whatever mount the caller reads from.\n\nexport type SourceReader = (path: string) => Promise<string>;\n\nexport interface SourceCache {\n  /** The memoised read for `path` — the same promise identity until it settles-and-fails. */\n  read: (path: string) => Promise<string>;\n  /** Drop a memoised read (a live edit, or an explicit refresh); no argument clears all. */\n  invalidate: (path?: string) => void;\n  /** Testing/diagnostics: how many paths are memoised right now. */\n  size: () => number;\n}\n\nexport function createSourceCache(reader: SourceReader): SourceCache {\n  const cache = new Map<string, Promise<string>>();\n  return {\n    read(path) {\n      const hit = cache.get(path);\n      if (hit) return hit;\n      const p = reader(path).catch((error: unknown) => {\n        // Never let a failure become the permanent answer for this path. Guarded on\n        // identity so a newer read started after an invalidate is not evicted by an older\n        // one settling late.\n        if (cache.get(path) === p) cache.delete(path);\n        throw error;\n      });\n      cache.set(path, p);\n      return p;\n    },\n    invalidate(path) {\n      if (path === undefined) cache.clear();\n      else cache.delete(path);\n    },\n    size: () => cache.size,\n  };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8BO,SAAS,kBAAkB,QAAmC;AACnE,QAAM,QAAQ,oBAAI,IAA6B;AAC/C,SAAO;AAAA,IACL,KAAK,MAAM;AACT,YAAM,MAAM,MAAM,IAAI,IAAI;AAC1B,UAAI,IAAK,QAAO;AAChB,YAAM,IAAI,OAAO,IAAI,EAAE,MAAM,CAAC,UAAmB;AAI/C,YAAI,MAAM,IAAI,IAAI,MAAM,EAAG,OAAM,OAAO,IAAI;AAC5C,cAAM;AAAA,MACR,CAAC;AACD,YAAM,IAAI,MAAM,CAAC;AACjB,aAAO;AAAA,IACT;AAAA,IACA,WAAW,MAAM;AACf,UAAI,SAAS,OAAW,OAAM,MAAM;AAAA,UAC/B,OAAM,OAAO,IAAI;AAAA,IACxB;AAAA,IACA,MAAM,MAAM,MAAM;AAAA,EACpB;AACF;","names":[]}