kopia lustrzana https://gitlab.com/rysiekpl/libresilient
cache plugin ready for new plugin loading system (ref. #15)
rodzic
4e4c9b83af
commit
46b3334b25
|
@ -28,35 +28,33 @@ describe("plugin: cache", () => {
|
|||
beforeEach(() => {
|
||||
Object.assign(global, makeServiceWorkerEnv());
|
||||
jest.resetModules();
|
||||
self.LibResilientPlugins = new Array()
|
||||
self.LibResilientConfig = {
|
||||
plugins: {
|
||||
'cache':{}
|
||||
global.LibResilientPluginConstructors = new Map()
|
||||
LR = {
|
||||
log: (component, ...items)=>{
|
||||
console.debug(component + ' :: ', ...items)
|
||||
}
|
||||
}
|
||||
self.log = function(component, ...items) {
|
||||
console.debug(component + ' :: ', ...items)
|
||||
}
|
||||
})
|
||||
|
||||
test("it should register in LibResilientPlugins", () => {
|
||||
test("it should register in LibResilientPluginConstructors", () => {
|
||||
require("../../plugins/cache.js");
|
||||
expect(self.LibResilientPlugins[0].name).toEqual('cache');
|
||||
expect(LibResilientPluginConstructors.get('cache')().name).toEqual('cache');
|
||||
});
|
||||
|
||||
test("it should error out if resource is not found", () => {
|
||||
require("../../plugins/cache.js");
|
||||
|
||||
expect.assertions(1)
|
||||
return expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
return expect(LibResilientPluginConstructors.get('cache')(LR).fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
});
|
||||
|
||||
test("it should stash a url successfully", () => {
|
||||
require("../../plugins/cache.js");
|
||||
expect.assertions(7);
|
||||
return self.LibResilientPlugins[0].stash('https://resilient.is/test.json').then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash('https://resilient.is/test.json').then((result)=>{
|
||||
expect(result).toEqual(undefined)
|
||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')
|
||||
return cachePlugin.fetch('https://resilient.is/test.json')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -72,21 +70,23 @@ describe("plugin: cache", () => {
|
|||
test("it should clear a url successfully", () => {
|
||||
require("../../plugins/cache.js");
|
||||
expect.assertions(3);
|
||||
return self.LibResilientPlugins[0].stash('https://resilient.is/test.json').then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash('https://resilient.is/test.json').then((result)=>{
|
||||
expect(result).toBe(undefined)
|
||||
return self.LibResilientPlugins[0].unstash('https://resilient.is/test.json')
|
||||
return cachePlugin.unstash('https://resilient.is/test.json')
|
||||
}).then(result => {
|
||||
expect(result).toEqual(true)
|
||||
return expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
return expect(cachePlugin.fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
})
|
||||
});
|
||||
|
||||
test("it should stash an array of urls successfully", () => {
|
||||
require("../../plugins/cache.js");
|
||||
expect.assertions(13);
|
||||
return self.LibResilientPlugins[0].stash(['https://resilient.is/test.json', 'https://resilient.is/test2.json']).then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(['https://resilient.is/test.json', 'https://resilient.is/test2.json']).then((result)=>{
|
||||
expect(result).toEqual([undefined, undefined])
|
||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')
|
||||
return cachePlugin.fetch('https://resilient.is/test.json')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -97,7 +97,7 @@ describe("plugin: cache", () => {
|
|||
expect(json).toEqual({ test: "success" })
|
||||
})
|
||||
}).then(() => {
|
||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test2.json')
|
||||
return cachePlugin.fetch('https://resilient.is/test2.json')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -113,14 +113,15 @@ describe("plugin: cache", () => {
|
|||
test("it should clear an array of urls successfully", () => {
|
||||
require("../../plugins/cache.js");
|
||||
expect.assertions(4);
|
||||
return self.LibResilientPlugins[0].stash(['https://resilient.is/test.json', 'https://resilient.is/test2.json']).then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(['https://resilient.is/test.json', 'https://resilient.is/test2.json']).then((result)=>{
|
||||
expect(result).toEqual([undefined, undefined])
|
||||
return self.LibResilientPlugins[0].unstash(['https://resilient.is/test.json', 'https://resilient.is/test2.json'])
|
||||
return cachePlugin.unstash(['https://resilient.is/test.json', 'https://resilient.is/test2.json'])
|
||||
}).then(result => {
|
||||
expect(result).toEqual([true, true])
|
||||
return expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
return expect(cachePlugin.fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
}).then(()=>{
|
||||
return expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test2.json')).rejects.toThrow(Error)
|
||||
return expect(cachePlugin.fetch('https://resilient.is/test2.json')).rejects.toThrow(Error)
|
||||
})
|
||||
});
|
||||
|
||||
|
@ -143,7 +144,7 @@ describe("plugin: cache", () => {
|
|||
response.url=''
|
||||
|
||||
expect.assertions(1);
|
||||
return expect(self.LibResilientPlugins[0].stash(response)).rejects.toThrow(Error)
|
||||
return expect(LibResilientPluginConstructors.get('cache')(LR).stash(response)).rejects.toThrow(Error)
|
||||
});
|
||||
|
||||
test("it should stash a Response successfully", () => {
|
||||
|
@ -164,9 +165,10 @@ describe("plugin: cache", () => {
|
|||
});
|
||||
|
||||
expect.assertions(7);
|
||||
return self.LibResilientPlugins[0].stash(response).then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(response).then((result)=>{
|
||||
expect(result).toEqual(undefined)
|
||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')
|
||||
return cachePlugin.fetch('https://resilient.is/test.json')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -197,9 +199,10 @@ describe("plugin: cache", () => {
|
|||
});
|
||||
|
||||
expect.assertions(7);
|
||||
return self.LibResilientPlugins[0].stash(response, 'special-key').then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(response, 'special-key').then((result)=>{
|
||||
expect(result).toEqual(undefined)
|
||||
return self.LibResilientPlugins[0].fetch('special-key')
|
||||
return cachePlugin.fetch('special-key')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -230,9 +233,10 @@ describe("plugin: cache", () => {
|
|||
response.url = ''
|
||||
|
||||
expect.assertions(6);
|
||||
return self.LibResilientPlugins[0].stash(response, 'special-key').then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(response, 'special-key').then((result)=>{
|
||||
expect(result).toEqual(undefined)
|
||||
return self.LibResilientPlugins[0].fetch('special-key')
|
||||
return cachePlugin.fetch('special-key')
|
||||
}).then(fetchResult => {
|
||||
expect(fetchResult.status).toEqual(200)
|
||||
expect(fetchResult.statusText).toEqual('OK')
|
||||
|
@ -262,12 +266,13 @@ describe("plugin: cache", () => {
|
|||
});
|
||||
|
||||
expect.assertions(3);
|
||||
return self.LibResilientPlugins[0].stash(response).then((result)=>{
|
||||
var cachePlugin = LibResilientPluginConstructors.get('cache')(LR)
|
||||
return cachePlugin.stash(response).then((result)=>{
|
||||
expect(result).toBe(undefined)
|
||||
return self.LibResilientPlugins[0].unstash(response)
|
||||
return cachePlugin.unstash(response)
|
||||
}).then(result => {
|
||||
expect(result).toEqual(true)
|
||||
return expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
return expect(cachePlugin.fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
|
||||
})
|
||||
});
|
||||
|
||||
|
|
278
plugins/cache.js
278
plugins/cache.js
|
@ -3,148 +3,148 @@
|
|||
\* ========================================================================= */
|
||||
|
||||
// no polluting of the global namespace please
|
||||
(function () {
|
||||
(function(LRPC){
|
||||
// this never changes
|
||||
const pluginName = "cache"
|
||||
LRPC.set(pluginName, (LR, init={})=>{
|
||||
|
||||
/*
|
||||
* 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)
|
||||
/*
|
||||
* plugin config settings
|
||||
*/
|
||||
|
||||
// sane defaults
|
||||
let defaultConfig = {}
|
||||
|
||||
// merge the defaults with settings from LibResilientConfig
|
||||
let config = {...defaultConfig, ...init}
|
||||
|
||||
/**
|
||||
* getting content from cache
|
||||
*/
|
||||
let getContentFromCache = (url) => {
|
||||
LR.log(pluginName, `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}`
|
||||
})
|
||||
)
|
||||
} 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
LR.log(pluginName, 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
|
||||
LR.log(pluginName, "caching an URL: " + resource)
|
||||
return cache.add(resource)
|
||||
} else if (Array.isArray(resource)) {
|
||||
// assume array of URLs
|
||||
LR.log(pluginName, "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 responseInit = {
|
||||
status: resource.status,
|
||||
statusText: resource.statusText,
|
||||
headers: {}
|
||||
};
|
||||
if (typeof resource.url === 'string' && resource.url !== '') {
|
||||
responseInit.url = resource.url
|
||||
}
|
||||
resource.headers.forEach(function(val, header){
|
||||
responseInit.headers[header] = val;
|
||||
});
|
||||
return resource
|
||||
.blob()
|
||||
.then((blob) => {
|
||||
LR.log(pluginName, "caching a Response to: " + key)
|
||||
return cache.put(key, new Response(
|
||||
blob,
|
||||
responseInit
|
||||
))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
LR.log(pluginName, "deleting a cached URL")
|
||||
return cache.delete(resource)
|
||||
} else if (Array.isArray(resource)) {
|
||||
// assume array of URLs
|
||||
LR.log(pluginName, "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
|
||||
LR.log(pluginName, "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
|
||||
// and add ourselves to it
|
||||
// with some additional metadata
|
||||
return {
|
||||
name: pluginName,
|
||||
description: 'Locally cached responses, using the Cache API.',
|
||||
version: 'COMMIT_UNKNOWN',
|
||||
fetch: getContentFromCache,
|
||||
stash: cacheContent,
|
||||
unstash: clearCachedContent
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
// done with not polluting the global namespace
|
||||
})()
|
||||
})(LibResilientPluginConstructors)
|
||||
|
|
Ładowanie…
Reference in New Issue