/* ========================================================================= *\ |* === Stashing plugin using the Cache API === *| \* ========================================================================= */ // no polluting of the global namespace please (function () { /* * plugin config settings */ // sane defaults let defaultConfig = { // name of this plugin // should not be changed name: "cache" } // merge the defaults with settings from LibResilientConfig let config = {...defaultConfig, ...self.LibResilientConfig.plugins[defaultConfig.name]} /** * getting content from cache */ let getContentFromCache = (url) => { self.log(config.name, `getting from cache: ${url}`) return caches.open('v1') .then((cache) => { return cache.match(url) }) .then((response) => { if (typeof response === 'undefined') { throw new Error('Resource not found in cache'); } else { var msg = 'retrieved cached headers:' response.headers.forEach((v, k)=>{ msg += `\n+-- ${k} : ${v}` }) self.log(config.name, msg) // return the response return response } }) } /** * add resources to cache * * implements the stash() LibResilient plugin method * * accepts either a Response * or a string containing a URL * or an Array of string URLs */ let cacheContent = (resource, key) => { return caches.open('v1') .then((cache) => { if (typeof resource === 'string') { // assume URL self.log(config.name, "caching an URL") return cache.add(resource) } else if (Array.isArray(resource)) { // assume array of URLs self.log(config.name, "caching an Array of URLs") return cache.addAll(resource) } else { // assume a Response // which means we either have a Request in key, a string URL in key, // or we can use the URL in resource.url if ( (typeof key !== 'object') && ( (typeof key !== 'string') || (key === '') ) ) { if (typeof resource.url !== 'string' || resource.url === '') { throw new Error('No URL to work with!') } key = resource.url } // we need to create a new Response object // with all the headers added explicitly // otherwise the x-libresilient-* headers get ignored var init = { status: resource.status, statusText: resource.statusText, headers: {} }; resource.headers.forEach(function(val, header){ init.headers[header] = val; }); return resource .blob() .then((blob) => { self.log(config.name, "caching a Response to: " + key) return cache.put(key, new Response( blob, init )) }) } }) } /** * remove resources from cache * * implements the unstash() LibResilient plugin method * * accepts either a Response * or a string containing a URL * or an Array of string URLs */ let clearCachedContent = (resource) => { return caches.open('v1') .then((cache) => { if (typeof resource === 'string') { // assume URL self.log(config.name, "deleting a cached URL") return cache.delete(resource) } else if (Array.isArray(resource)) { // assume array of URLs self.log(config.name, "deleting an Array of cached URLs") return Promise.all( resource.map((res)=>{ return cache.delete(res) }) ) } else { // assume a Response // which means we have an URL in resource.url self.log(config.name, "removing a Response from cache: " + resource.url) return cache.delete(resource.url) } }) } // and add ourselves to it // with some additional metadata self.LibResilientPlugins.push({ name: config.name, description: 'Locally cached responses, using the Cache API.', version: 'COMMIT_UNKNOWN', fetch: getContentFromCache, stash: cacheContent, unstash: clearCachedContent }) // done with not poluting the global namespace })()