Jake Vanderwerf
2 days ago 235ce5716edc2f7cbe80fdccf26eac7269587839
assets/js/min/cache.min.js
@@ -1 +1 @@
window.jvbCache=class{constructor(e,t={}){this.base=e,this.config={namespace:"jvb_cache",TTL:36e5,maxSize:100,...t},this.cacheAvailable="caches"in window,this.cacheAvailable||console.warn("Browser Cache API unavailable, reverting to LocalStorage"),this._memoryCache=new Map,this.subscribers=new Set}clearMemoryCache(){const e=this._memoryCache.size;return this._memoryCache.clear(),console.log(`Cleared ${e} items from memory cache`),e}async get(e){let t=`${this.base}_${e}`;const a=await this.getCacheItem(t);return a?this.deserializeData(a.data,a.dataType):null}async set(e,t){let a=`${this.base}_${e}`;const r=this.serializeData(t),c={data:r.data,dataType:r.type,timestamp:Date.now()};await this.setCacheItem(a,c),this.notify("cache-saved",{key:e,value:t})}remove(e){this.base}serializeData(e){if(null==e)return{data:e,type:"primitive"};if(e instanceof Map)return{data:Array.from(e.entries()),type:"Map"};if(e instanceof Set)return{data:Array.from(e),type:"Set"};if(e instanceof Date)return{data:e.toISOString(),type:"Date"};if(e instanceof RegExp)return{data:{source:e.source,flags:e.flags},type:"RegExp"};if(Array.isArray(e))return{data:e.map((e=>this.serializeData(e))),type:"Array"};if(e&&"object"==typeof e&&e.constructor===Object){const t={};for(const[a,r]of Object.entries(e))t[a]=this.serializeData(r);return{data:t,type:"Object"}}return{data:e,type:"primitive"}}deserializeData(e,t){if(!t||"primitive"===t)return e;switch(t){case"Map":return new Map(e);case"Set":return new Set(e);case"Date":return new Date(e);case"RegExp":return new RegExp(e.source,e.flags);case"Array":return e.map((e=>this.deserializeData(e.data,e.type)));case"Object":const a={};for(const[t,r]of Object.entries(e))a[t]=this.deserializeData(r.data,r.type);return a;default:return console.warn(`Unknown data type: ${t}, returning as-is`),e}}async getCacheItem(e){if(this._memoryCache.has(e))return this._memoryCache.get(e);const t=this.cacheAvailable?await this.getBrowserCacheItem(e):this.getLocalStorageItem(e);return t&&this._memoryCache.set(e,t),t}async setCacheItem(e,t){return this._memoryCache.set(e,t),this.cacheAvailable?await this.setBrowserCacheItem(e,t):this.setLocalStorageItem(e,t)}async removeCacheItem(e){return this._memoryCache.delete(e),this.cacheAvailable?await this.removeBrowserCacheItem(e):this.removeLocalStorageItem(e)}async getBrowserCacheItem(e){try{const t=await caches.open(this.config.namespace),a=await t.match(e);return a?await a.json():null}catch(e){return console.warn("Error getting from Browser Cache API:",e),null}}async setBrowserCacheItem(e,t){try{const a=await caches.open(this.config.namespace),r=new Response(JSON.stringify(t),{headers:{"Content-Type":"application/json"}});await a.put(e,r)}catch(e){console.warn("Error setting in Browser Cache API:",e)}}async removeBrowserCacheItem(e){try{const t=await caches.open(this.config.namespace);await t.delete(e)}catch(e){console.warn("Error removing from Browser Cache API:",e)}}getLocalStorageItem(e){try{const t=localStorage.getItem(e);return t?JSON.parse(t):null}catch(e){return console.warn("Error getting from localStorage:",e),null}}setLocalStorageItem(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(a){if(a instanceof DOMException&&22===a.code){this.clearOldestLocalStorageItems();try{localStorage.setItem(e,JSON.stringify(t))}catch(e){console.warn("Still failed to set localStorage item after cleanup:",e)}}else console.warn("Error setting localStorage item:",a)}}removeLocalStorageItem(e){try{localStorage.removeItem(e)}catch(e){console.warn("Error removing localStorage item:",e)}}clearOldestLocalStorageItems(){try{const e=[];for(let t=0;t<localStorage.length;t++){const a=localStorage.key(t);if(a.startsWith(this.config.namespace))try{const t=JSON.parse(localStorage.getItem(a));e.push({key:a,timestamp:t.timestamp||0})}catch(t){e.push({key:a,timestamp:0})}}e.sort(((e,t)=>e.timestamp-t.timestamp));const t=Math.max(1,Math.ceil(.2*e.length));for(let a=0;a<t;a++)e[a]&&localStorage.removeItem(e[a].key)}catch(e){console.warn("Error cleaning up localStorage:",e)}}async cleanExpired(){const e=Date.now(),t=this.config.TTL;if(this.cacheAvailable)try{const a=await caches.open(this.options.namespace),r=await a.keys();for(const c of r){const r=await a.match(c);try{e-(await r.json()).timestamp>t&&await a.delete(c)}catch(e){}}}catch(e){console.warn("Error cleaning browser cache:",e)}else try{for(let a=0;a<localStorage.length;a++){const r=localStorage.key(a);if(r&&r.startsWith(this.options.namespace))try{e-JSON.parse(localStorage.getItem(r)).timestamp>t&&localStorage.removeItem(r)}catch(e){}}}catch(e){console.warn("Error cleaning localStorage cache:",e)}for(const[a,r]of this._memoryCache.entries())e-r.timestamp>t&&this._memoryCache.delete(a)}async clear(){if(this._memoryCache.clear(),this.cacheAvailable)try{await caches.delete(this.options.namespace)}catch(e){console.warn("Error clearing browser cache:",e)}this.clearLocalStorage()}clearLocalStorage(){try{for(let e=localStorage.length-1;e>=0;e--){const t=localStorage.key(e);t&&t.startsWith(this.options.namespace)&&localStorage.removeItem(t)}}catch(e){console.warn("Error clearing localStorage cache:",e)}}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t){this.subscribers.forEach((a=>a(e,t)))}};
window.jvbCache=class{constructor(e,t={}){this.base=e,this.config={namespace:`${jvbBase.base}cache`,TTL:36e5,maxSize:100,...t},this._cache=new Map,this.subscribers=new Set}clearMemoryCache(){const e=this._cache.size;return this._cache.clear(),console.log(`Cleared ${e} items from memory cache`),e}get(e){if(this._cache.has(e))return this._cache.get(e);let t,a=`${this.base}_${e}`;try{if(t=localStorage.getItem(a),!t)return null;t=JSON.parse(t)}catch(e){return console.warn("Error getting from localStorage:",e),null}return t&&this._cache.set(e,t),t}set(e,t){this._cache.set(e,t);let a=`${this.base}_${e}`;try{localStorage.setItem(a,JSON.stringify(t))}catch(t){if(t instanceof DOMException&&22===t.code){this.clearOldestLocalStorageItems();try{localStorage.setItem(e,JSON.stringify(item))}catch(e){console.warn("Still failed to set localStorage item after cleanup:",e)}}else console.warn("Error setting localStorage item:",t)}this.notify("cache-saved",{key:e,value:t})}remove(e){let t=`${this.base}_${e}`;try{localStorage.removeItem(t)}catch(e){console.warn("Error removing localStorage item:",e)}}clearOldestLocalStorageItems(){try{const e=[];for(let t=0;t<localStorage.length;t++){const a=localStorage.key(t);if(a.startsWith(this.config.namespace))try{const t=JSON.parse(localStorage.getItem(a));e.push({key:a,timestamp:t.timestamp||0})}catch(t){e.push({key:a,timestamp:0})}}e.sort(((e,t)=>e.timestamp-t.timestamp));const t=Math.max(1,Math.ceil(.2*e.length));for(let a=0;a<t;a++)e[a]&&localStorage.removeItem(e[a].key)}catch(e){console.warn("Error cleaning up localStorage:",e)}}async loadFromCache(){for(let e=0;e<localStorage.length;e++){const t=localStorage.key(e);if(t.startsWith(`${this.base}_`)){let e=t.replace(`${this.base}_`,"");try{const a=JSON.parse(localStorage.getItem(t));this._cache.set(e,a)}catch(e){console.warn(`Failed to parse cached value for ${t}:`,e)}}}}async clear(){this._cache.clear();try{for(let e=localStorage.length-1;e>=0;e--){const t=localStorage.key(e);t&&t.startsWith(this.config.namespace)&&localStorage.removeItem(t)}}catch(e){console.warn("Error clearing localStorage cache:",e)}}subscribe(e){return this.subscribers.add(e),()=>this.subscribers.delete(e)}notify(e,t){this.subscribers.forEach((a=>a(e,t)))}};