UNPKG

@codefast/image-loader

Version:

Simple, functional image loader for Next.js supporting multiple CDN providers

1 lines 2.16 kB
class e{domainRegistry=new Map;fallbackLoaders=[];fallbackLoader;urlCache=new Map;resultCache=new Map;maxCacheSize;constructor(e=[],t,r=1e3){this.fallbackLoader=t,this.maxCacheSize=r,this.initializeRegistry(e)}registerLoader(e,t,r){let a={loader:r,matcher:t,name:e},i=this.extractDomainFromMatcher(a);i?this.domainRegistry.set(i,r):this.fallbackLoaders.push(a)}transform(e){let{quality:t,src:r,width:a}=e,i=`${r}:${a}:${t??"undefined"}`;return this.getCachedResult(i,()=>{try{let t=this.extractDomainFromUrl(r);if(t){let r=this.domainRegistry.get(t);if(!r){for(let[e,a]of this.domainRegistry)if(t.endsWith(`.${e}`)||t===e){r=a;break}}if(r)return r(e)}for(let{loader:t,matcher:a}of this.fallbackLoaders)if(a(r))return t(e);if(this.fallbackLoader)return this.fallbackLoader(e);return r}catch{return r}})}getRegisteredLoaders(){return[...this.domainRegistry.keys(),...this.fallbackLoaders.map(({name:e})=>e)]}hasLoader(e){return!!this.domainRegistry.has(e)||this.fallbackLoaders.some(({name:t})=>t===e)}getCacheStats(){return{resultCacheSize:this.resultCache.size,urlCacheSize:this.urlCache.size}}clearCaches(){this.urlCache.clear(),this.resultCache.clear()}initializeRegistry(e){for(let t of e){let e=this.extractDomainFromMatcher(t);e&&!this.domainRegistry.has(e)?this.domainRegistry.set(e,t.loader):this.fallbackLoaders.push(t)}}extractDomainFromMatcher(e){if(e.domain)return e.domain;let t=e.matcher.toString(),r=/\.includes\("([^"]+)"\)/.exec(t);if(r)return r[1];let a=/\.startsWith\("https?:\/\/([^"]+)"\)/.exec(t);return a?a[1]:null}extractDomainFromUrl(e){try{return this.parseURL(e).hostname||null}catch{return null}}parseURL(e){let t=this.urlCache.get(e);if(t)return t;let r=new URL(e);if(this.urlCache.size>=this.maxCacheSize){let e=this.urlCache.keys().next().value;e&&this.urlCache.delete(e)}return this.urlCache.set(e,r),r}getCachedResult(e,t){let r=this.resultCache.get(e);if(r)return r;let a=t();if(this.resultCache.size>=this.maxCacheSize){let e=this.resultCache.keys().next().value;e&&this.resultCache.delete(e)}return this.resultCache.set(e,a),a}}function t(r=[],a,i=1e3){return new e(r,a,i)}export{e as ImageLoader,t as createImageLoader};