cache plugin ready for new plugin loading system (ref. #15)

merge-requests/9/merge
Michał 'rysiek' Woźniak 2021-09-15 21:11:17 +00:00
rodzic 4e4c9b83af
commit 46b3334b25
2 zmienionych plików z 176 dodań i 171 usunięć

Wyświetl plik

@ -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)
}) })
}); });

Wyświetl plik

@ -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)