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

merge-requests/3/head
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(() => {
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)
})
});

Wyświetl plik

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