import M from"node:path";import{NestedMap as P}from"./utils/nested-map.js";import{touchedCacheRecordsStore as f,trackAccessStore as C,fsChangesStore as D,wasChangedCacheStore as p}from"./utils/async-storage.js";import{isLoaderCacheEnabled as T}from"./utils/is-loader-cache-enabled.js";import{sha1 as v}from"../utils/crypto.js";import{LoadError as S}from"./load-error.js";import{createLifecycleContext as A}from"../plugins/lifecycle.js";function u(l,e){return l+":"+e}class B{fs;errors=new Map;#e=new P;#t=new P;#a;#n={};#s=new Map;#o=!0;constructor(e){this.fs=e,this.#a=A(e,this),this.fs.setEmitWrapper(async r=>f.run(new Set,async()=>p.run(new Map,async()=>{await r(),this.#o||this.cleanUpCache()})))}async load(e,r,a){let t,i;typeof r=="string"?(t=r,i=this.#n[r]):(t=r.name,i=r.loader);const d=a?.join("")??"",h=a?d.length>20?v(d):d:void 0,c=this.#i(e,t,h),n=u(t,e),s=f.getStore();s?.add(n);const y=this.#e.get(t,e),g=C.getStore()??[];if(c&&y)return g.push({type:"load",loaderKey:t,cacheKey:e,hash:y.compoundHash}),h!==void 0&&g.push({type:"dependencies",hash:h}),s&&E(this.#t.get(t,e)??[],this.#t,s),y;const R=await this.#h(e,t,async()=>{let m;const K=C.getStore()||[];h!==void 0&&K.push({type:"dependencies",hash:h});const w=[],I=o=>w.push(o);try{let o;this.#s.has(n)&&c?o=this.#s.get(n):(o=i(e,this.#a,I),this.#s.set(n,o)),m=await o,w.length>0?this.errors.set(n,w):this.errors.delete(n)}catch(o){const x=this.#e.get(t,e)?.data,L=t==="redocly-config"||t==="nearest-redocly-config"?!1:(await this.load(e,"is-ignored")).data;if(!(o instanceof S)&&!L&&this.errors.set(n,[o]),!x)throw o instanceof S?o:new S(o.message,{cause:o,loaderKey:t});m=x}finally{this.#s.delete(n)}const k=v(e+K.map(o=>o.hash).join(""));return g.push({type:"load",loaderKey:t,cacheKey:e,hash:k}),{data:m,compoundHash:k}});return T(t)&&this.#e.set(t,e,R),R}cleanUpCache(){const e=f.getStore()??new Set;for(const r of this.#e.keys())for(const a of this.#e.get(r)?.keys()??[]){const t=u(r,a);e.has(t)||(this.#e.delete(r,a),this.errors.delete(t))}}setLoaders(e){this.#n={...this.#n,...e}}enableCacheCleanup(){this.#o=!1}#i(e,r,a){const t=u(r,e);return f.getStore()?.has(t)?!0:!this.#r(e,r,a)}#r(e,r,a){const t=u(r,e),i=p.getStore()?.get(t);if(i!=null)return i;const d=D.getStore()??[],h=this.#t.get(r,e)??[];if(a!==void 0&&!h.find(s=>s.type!=="dependencies"?(p.getStore()?.set(t,!1),!1):s.hash===a))return p.getStore()?.set(t,!0),!0;const c=d.some(n=>{switch(n.event){case"add":return h.some(s=>{switch(s.type){case"read":return s.path===n.path;case"readdir":return s.path===M.posix.dirname(n.path);case"exists":return s.path===n.path;case"load":return this.#r(s.cacheKey,s.loaderKey,void 0);case"scan":return!s.pattern||s.pattern.test(n.path)}});case"change":return h.some(s=>{switch(s.type){case"read":return s.path===n.path;case"readdir":return!1;case"exists":return!1;case"load":return this.#r(s.cacheKey,s.loaderKey,void 0);case"scan":return!1}});case"unlink":return h.some(s=>{switch(s.type){case"read":return s.path===n.path;case"readdir":return s.path===M.posix.dirname(n.path);case"exists":return s.path===n.path;case"load":return this.#r(s.cacheKey,s.loaderKey,void 0);case"scan":return!s.pattern||s.pattern.test(n.path)}})}});return p.getStore()?.set(t,c),c}#h(e,r,a){const t=[];return this.#t.set(r,e,t),C.run(t,a)}}const E=(l,e,r)=>{for(const a of l)if(a.type==="load"){const t=u(a.loaderKey,a.cacheKey);if(r.has(t))continue;r.add(t);const i=e.get(a.loaderKey,a.cacheKey);i&&E(i,e,r)}};export{B as Cache};
