UNPKG

@codefast/image-loader

Version:

Flexible image loader for Next.js supporting multiple CDN providers

148 lines (147 loc) 5.29 kB
"use strict"; var __webpack_require__ = {}; (()=>{ __webpack_require__.d = (exports1, definition)=>{ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, { enumerable: true, get: definition[key] }); }; })(); (()=>{ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop); })(); (()=>{ __webpack_require__.r = (exports1)=>{ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, { value: 'Module' }); Object.defineProperty(exports1, '__esModule', { value: true }); }; })(); var __webpack_exports__ = {}; __webpack_require__.r(__webpack_exports__); __webpack_require__.d(__webpack_exports__, { ImageLoaderFactory: ()=>ImageLoaderFactory, defaultImageLoaderFactory: ()=>defaultImageLoaderFactory }); class ImageLoaderFactory { loaders = []; config; loaderCache = {}; transformCache = {}; maxCacheSize = 1000; constructor(config = {}){ this.config = { defaultQuality: 75, ...config }; } registerLoader(loader) { if (this.loaders.some((l)=>l.getName() === loader.getName())) throw new Error(`Loader with name "${loader.getName()}" is already registered`); this.loaders.push(loader); this.clearLoaderCache(); } registerLoaders(loaders) { for (const loader of loaders)this.registerLoader(loader); } unregisterLoader(name) { const index = this.loaders.findIndex((loader)=>loader.getName() === name); if (-1 !== index) { this.loaders.splice(index, 1); this.clearLoaderCache(); return true; } return false; } getLoaders() { return [ ...this.loaders ]; } findLoader(source) { const domain = this.extractDomain(source); if (domain in this.loaderCache) return this.loaderCache[domain]; let selectedLoader = null; if (this.config.domainMappings?.[domain]) { const mappedLoaderName = this.config.domainMappings[domain]; selectedLoader = this.loaders.find((loader)=>loader.getName() === mappedLoaderName) ?? null; } selectedLoader ??= this.loaders.find((loader)=>loader.canHandle(source)) ?? null; this.cacheLoader(domain, selectedLoader); return selectedLoader; } load(config) { const cacheKey = this.createTransformCacheKey(config); if (this.transformCache[cacheKey]) return this.transformCache[cacheKey]; const loader = this.findLoader(config.src); if (!loader) { console.warn(`No loader found for URL: ${config.src}. Returning original URL.`); return config.src; } const normalizedConfig = { ...config, quality: config.quality ?? this.config.defaultQuality }; const transformedUrl = loader.load(normalizedConfig); this.cacheTransform(cacheKey, transformedUrl); return transformedUrl; } createNextImageLoader() { return (params)=>this.load({ quality: params.quality, src: params.src, width: params.width }); } getStats() { return { domainMappings: this.config.domainMappings ?? {}, loaderNames: this.loaders.map((loader)=>loader.getName()), totalLoaders: this.loaders.length }; } clear() { this.loaders.length = 0; this.clearLoaderCache(); this.clearTransformCache(); } extractDomain(url) { try { const urlObject = new URL(url); return urlObject.hostname.toLowerCase(); } catch { return ""; } } cacheLoader(domain, loader) { if (Object.keys(this.loaderCache).length >= this.maxCacheSize) this.clearLoaderCache(); this.loaderCache[domain] = loader; } clearLoaderCache() { for (const key of Object.keys(this.loaderCache))delete this.loaderCache[key]; } createTransformCacheKey(config) { const quality = config.quality ?? this.config.defaultQuality ?? 75; return `${config.src}|${config.width.toString()}|${quality.toString()}`; } cacheTransform(key, transformedUrl) { if (Object.keys(this.transformCache).length >= this.maxCacheSize) this.clearTransformCache(); this.transformCache[key] = transformedUrl; } clearTransformCache() { for (const key of Object.keys(this.transformCache))delete this.transformCache[key]; } } const defaultImageLoaderFactory = new ImageLoaderFactory(); exports.ImageLoaderFactory = __webpack_exports__.ImageLoaderFactory; exports.defaultImageLoaderFactory = __webpack_exports__.defaultImageLoaderFactory; for(var __webpack_i__ in __webpack_exports__)if (-1 === [ "ImageLoaderFactory", "defaultImageLoaderFactory" ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__]; Object.defineProperty(exports, '__esModule', { value: true });