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(() => {
|
beforeEach(() => {
|
||||||
Object.assign(global, makeServiceWorkerEnv());
|
Object.assign(global, makeServiceWorkerEnv());
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
self.LibResilientPlugins = new Array()
|
global.LibResilientPluginConstructors = new Map()
|
||||||
self.LibResilientConfig = {
|
LR = {
|
||||||
plugins: {
|
log: (component, ...items)=>{
|
||||||
'cache':{}
|
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");
|
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", () => {
|
test("it should error out if resource is not found", () => {
|
||||||
require("../../plugins/cache.js");
|
require("../../plugins/cache.js");
|
||||||
|
|
||||||
expect.assertions(1)
|
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", () => {
|
test("it should stash a url successfully", () => {
|
||||||
require("../../plugins/cache.js");
|
require("../../plugins/cache.js");
|
||||||
expect.assertions(7);
|
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)
|
expect(result).toEqual(undefined)
|
||||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')
|
return cachePlugin.fetch('https://resilient.is/test.json')
|
||||||
}).then(fetchResult => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -72,21 +70,23 @@ describe("plugin: cache", () => {
|
||||||
test("it should clear a url successfully", () => {
|
test("it should clear a url successfully", () => {
|
||||||
require("../../plugins/cache.js");
|
require("../../plugins/cache.js");
|
||||||
expect.assertions(3);
|
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)
|
expect(result).toBe(undefined)
|
||||||
return self.LibResilientPlugins[0].unstash('https://resilient.is/test.json')
|
return cachePlugin.unstash('https://resilient.is/test.json')
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
expect(result).toEqual(true)
|
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", () => {
|
test("it should stash an array of urls successfully", () => {
|
||||||
require("../../plugins/cache.js");
|
require("../../plugins/cache.js");
|
||||||
expect.assertions(13);
|
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])
|
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 => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -97,7 +97,7 @@ describe("plugin: cache", () => {
|
||||||
expect(json).toEqual({ test: "success" })
|
expect(json).toEqual({ test: "success" })
|
||||||
})
|
})
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test2.json')
|
return cachePlugin.fetch('https://resilient.is/test2.json')
|
||||||
}).then(fetchResult => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -113,14 +113,15 @@ describe("plugin: cache", () => {
|
||||||
test("it should clear an array of urls successfully", () => {
|
test("it should clear an array of urls successfully", () => {
|
||||||
require("../../plugins/cache.js");
|
require("../../plugins/cache.js");
|
||||||
expect.assertions(4);
|
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])
|
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 => {
|
}).then(result => {
|
||||||
expect(result).toEqual([true, true])
|
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(()=>{
|
}).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=''
|
response.url=''
|
||||||
|
|
||||||
expect.assertions(1);
|
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", () => {
|
test("it should stash a Response successfully", () => {
|
||||||
|
@ -164,9 +165,10 @@ describe("plugin: cache", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect.assertions(7);
|
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)
|
expect(result).toEqual(undefined)
|
||||||
return self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')
|
return cachePlugin.fetch('https://resilient.is/test.json')
|
||||||
}).then(fetchResult => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -197,9 +199,10 @@ describe("plugin: cache", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect.assertions(7);
|
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)
|
expect(result).toEqual(undefined)
|
||||||
return self.LibResilientPlugins[0].fetch('special-key')
|
return cachePlugin.fetch('special-key')
|
||||||
}).then(fetchResult => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -230,9 +233,10 @@ describe("plugin: cache", () => {
|
||||||
response.url = ''
|
response.url = ''
|
||||||
|
|
||||||
expect.assertions(6);
|
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)
|
expect(result).toEqual(undefined)
|
||||||
return self.LibResilientPlugins[0].fetch('special-key')
|
return cachePlugin.fetch('special-key')
|
||||||
}).then(fetchResult => {
|
}).then(fetchResult => {
|
||||||
expect(fetchResult.status).toEqual(200)
|
expect(fetchResult.status).toEqual(200)
|
||||||
expect(fetchResult.statusText).toEqual('OK')
|
expect(fetchResult.statusText).toEqual('OK')
|
||||||
|
@ -262,12 +266,13 @@ describe("plugin: cache", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
expect.assertions(3);
|
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)
|
expect(result).toBe(undefined)
|
||||||
return self.LibResilientPlugins[0].unstash(response)
|
return cachePlugin.unstash(response)
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
expect(result).toEqual(true)
|
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
|
// no polluting of the global namespace please
|
||||||
(function () {
|
(function(LRPC){
|
||||||
|
// this never changes
|
||||||
|
const pluginName = "cache"
|
||||||
|
LRPC.set(pluginName, (LR, init={})=>{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* plugin config settings
|
* plugin config settings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// sane defaults
|
// sane defaults
|
||||||
let defaultConfig = {
|
let defaultConfig = {}
|
||||||
// name of this plugin
|
|
||||||
// should not be changed
|
// merge the defaults with settings from LibResilientConfig
|
||||||
name: "cache"
|
let config = {...defaultConfig, ...init}
|
||||||
}
|
|
||||||
|
/**
|
||||||
// merge the defaults with settings from LibResilientConfig
|
* getting content from cache
|
||||||
let config = {...defaultConfig, ...self.LibResilientConfig.plugins[defaultConfig.name]}
|
*/
|
||||||
|
let getContentFromCache = (url) => {
|
||||||
/**
|
LR.log(pluginName, `getting from cache: ${url}`)
|
||||||
* getting content from cache
|
return caches.open('v1')
|
||||||
*/
|
.then((cache) => {
|
||||||
let getContentFromCache = (url) => {
|
return cache.match(url)
|
||||||
self.log(config.name, `getting from cache: ${url}`)
|
})
|
||||||
return caches.open('v1')
|
.then((response) => {
|
||||||
.then((cache) => {
|
if ((typeof response === 'undefined') || (response === null) ) {
|
||||||
return cache.match(url)
|
throw new Error('Resource not found in cache');
|
||||||
})
|
} else {
|
||||||
.then((response) => {
|
var msg = 'retrieved cached headers:'
|
||||||
if ((typeof response === 'undefined') || (response === null) ) {
|
response.headers.forEach((v, k)=>{
|
||||||
throw new Error('Resource not found in cache');
|
msg += `\n+-- ${k} : ${v}`
|
||||||
} 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)
|
|
||||||
})
|
})
|
||||||
)
|
LR.log(pluginName, msg)
|
||||||
} else {
|
// return the response
|
||||||
// assume a Response
|
return 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)
|
}
|
||||||
}
|
|
||||||
})
|
/**
|
||||||
}
|
* 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
|
// and add ourselves to it
|
||||||
// with some additional metadata
|
// with some additional metadata
|
||||||
self.LibResilientPlugins.push({
|
return {
|
||||||
name: config.name,
|
name: pluginName,
|
||||||
description: 'Locally cached responses, using the Cache API.',
|
description: 'Locally cached responses, using the Cache API.',
|
||||||
version: 'COMMIT_UNKNOWN',
|
version: 'COMMIT_UNKNOWN',
|
||||||
fetch: getContentFromCache,
|
fetch: getContentFromCache,
|
||||||
stash: cacheContent,
|
stash: cacheContent,
|
||||||
unstash: clearCachedContent
|
unstash: clearCachedContent
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// done with not polluting the global namespace
|
// done with not polluting the global namespace
|
||||||
})()
|
})(LibResilientPluginConstructors)
|
||||||
|
|
Ładowanie…
Reference in New Issue