kapcacher
Version:
A Cacher API for Kaplay.
3 lines (2 loc) • 3.22 kB
JavaScript
export const HEADER={name:"Cacher",version:"0.0.10"};const o=i=>new Promise(e=>setTimeout(e,i));export class Cacher{cacheName;_cache;set cache(e){this._cache=e,localStorage.setItem(this.cacheName,JSON.stringify(e)),this.initialized=!0}get cache(){return this._cache}initialized=!1;static nsBuilder(e,t){return`${e}~${t}`}constructor(e){this.cacheName=e}ensureIsInit(){if(!this.initialized)throw new Error("Cache not initialized, will not function without cache")}async init(){this.cache=await caches.open(this.cacheName),this.initialized=!0}createNamespace(e){return this.ensureIsInit(),new CacherNamespace(this,e)}createKaplayCacher(){return this.ensureIsInit(),new window.KaplayCacher(this)}createSpriteCacher(){return this.ensureIsInit(),new window.SpriteCacher(this)}createSoundCacher(){return this.ensureIsInit(),new window.SoundCacher(this)}}export class CacherNamespace{namespace;parent;cache;constructor(e,t){e.ensureIsInit(),this.namespace=t,this.parent=e,this.cache=()=>this.parent.cache}nsBuilder=e=>Cacher.nsBuilder(this.namespace,e);async get(e){return await this.cache().match(this.nsBuilder(e))}async put(e,t){await this.cache().put(this.nsBuilder(e),t)}makeRollout(e,t=0){return new CacheRollout(this,e,t)}}export class CacheRollout{rolloutList;rolloutInterval;parent;cache;constructor(e,t,s=0){this.rolloutList=t,this.rolloutInterval=s,this.parent=e,this.cache=()=>e.cache()}async rollout(e){return await Promise.all(this.rolloutList.map(async s=>{const a=this.parent.nsBuilder(s),r=await this.cache().match(a),c=await e(s,a,r,this);return this.rolloutInterval>0&&await o(this.rolloutInterval),c}))}async tossBrokenCaches(e){let t=await this.cache().keys(),s=[];for(let a of t){let r=a.url.split("/").pop()?.split("~")[1];e.includes(r)||s.push(r)}for(let a of s)await this.cache().delete(a)}}class n{loadEntity;fetchName=e=>`./${this.namespace}/${e}`;cache=()=>this.CNS.cache();parent;namespace;CNS;nsBuilder=e=>Cacher.nsBuilder(this.namespace,e);constructor(e,t){this.parent=e,this.namespace=t,this.CNS=new CacherNamespace(e,t)}async fetchAndCache(e){const s=await(await fetch(this.fetchName(e))).blob(),a=URL.createObjectURL(s);let r=new Response(s);return await this.CNS.put(e,r),await this.loadEntity(e,{result:a}),r}async loadCached(e,t){const s=new FileReader;return s.onload=async()=>await this.loadEntity(e,s).catch(async a=>{console.error(`Failed to load cached entity for ${e}:`,a),t=await this.fetchAndCache(e)}),s.readAsDataURL(await t.blob()),t}async rollout(e,t=0){let s=this.CNS.makeRollout(e,t),a=await s.rollout(async(r,c,h,l)=>{h?await this.loadCached(r,h):await this.fetchAndCache(r)});return await s.tossBrokenCaches(e),a}}export const staticPlugin={...HEADER,Cacher,KaplayCacher:n,CacherNamespace,CacheRollout,CacherPlugin};window.KapCacher=staticPlugin;export function CacherPlugin(i){class e extends n{static namespace="sprites";constructor(a){super(a,new.target.namespace)}loadEntity=async(a,r)=>await i.loadSprite(a,r.result)}class t extends n{static namespace="sounds";constructor(a){super(a,new.target.namespace)}loadEntity=async(a,r)=>await i.loadSound(a,r.result)}return{...staticPlugin,KaplayCacher:n,SpriteCacher:e,SoundCacher:t}}
//# sourceMappingURL=kapcache.js.map