cache-api-local
Version:
A lib to use for caching the api res so your load to serve minimize. Plus it has revalidating feature 🔥🔥
3 lines (2 loc) • 1.99 kB
JavaScript
import*as e from"fs";import*as t from"path";class r{constructor(e,r,a){this.basePath=e;const s=function(){const e=Error.prepareStackTrace;let r;try{const e=new Error;Error.prepareStackTrace=(e,t)=>t;const t=e.stack;t?.length>2&&(r=t[2].getFileName()??void 0)}catch(e){console.error("Error determining caller directory:",e)}finally{Error.prepareStackTrace=e}if(r?.startsWith("file:///")){let e=new URL(r).pathname;return"win32"===process.platform&&e.startsWith("/")&&(e=e.slice(1)),t.dirname(e)}return r?t.dirname(r):process.cwd()}();this.actualBaseCachePath=t.resolve(s,r),this.maxAge=a}sanitizeFilename(e){return e.replace(/[\/*?:"<>|\\]/g,"_").replace(/\s+/g,"_").replace(/^_+/,"")}readJSONSafe(t){try{const r=e.readFileSync(t,"utf-8");return JSON.parse(r)}catch{return null}}writeJSON(t,r){e.writeFileSync(t,JSON.stringify(r,null,2),"utf-8")}getFilePaths(e,r){const a=this.sanitizeFilename(decodeURIComponent(e))+".json",s=t.join(this.actualBaseCachePath,r);return{dirPath:s,dataPath:t.join(s,a),metaPath:t.join(s,a.replace(".json",".meta.json"))}}async getData(e,t,r={},a=!1){const s=`${this.basePath}/${e}`,{dirPath:i,dataPath:n,metaPath:c}=this.getFilePaths(e,t);if(!a){const e=this.checkAndReadFromCache(n,c);if(null!==e)return e}try{const e=await fetch(s,r);if(!e.ok)throw new Error(`HTTP error: ${e.status}`);const t=await e.json();return this.ensureDirExists(i),this.writeJSON(n,t),this.writeJSON(c,{lastFetched:Date.now()}),t}catch(e){console.warn(`Fetch failed for ${s}, trying cache fallback...`);const t=this.readJSONSafe(n);if(t)return t;throw console.error("Cache fallback also failed:",e),e}}checkAndReadFromCache(t,r){if(!e.existsSync(t))return null;if(!this.maxAge)return this.readJSONSafe(t);const a=this.readJSONSafe(r);if(!a?.lastFetched)return this.readJSONSafe(t);return(Date.now()-a.lastFetched)/1e3<this.maxAge?this.readJSONSafe(t):null}ensureDirExists(t){e.existsSync(t)||e.mkdirSync(t,{recursive:!0})}}export{r as default};
//# sourceMappingURL=index.js.map