libresilient/plugins/cache.js

151 wiersze
5.5 KiB
JavaScript

/* ========================================================================= *\
|* === 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') || (response === null) ) {
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: " + resource)
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: {}
};
if (typeof resource.url === 'string' && resource.url !== '') {
init.url = resource.url
}
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 polluting the global namespace
})()