From 46b3334b25469da331a09874c490c7155c42d816 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=27rysiek=27=20Wo=C5=BAniak?= Date: Wed, 15 Sep 2021 21:11:17 +0000 Subject: [PATCH] cache plugin ready for new plugin loading system (ref. #15) --- __tests__/plugins/cache.test.js | 69 ++++---- plugins/cache.js | 278 ++++++++++++++++---------------- 2 files changed, 176 insertions(+), 171 deletions(-) diff --git a/__tests__/plugins/cache.test.js b/__tests__/plugins/cache.test.js index eacc11d..6b4c11d 100644 --- a/__tests__/plugins/cache.test.js +++ b/__tests__/plugins/cache.test.js @@ -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) }) }); diff --git a/plugins/cache.js b/plugins/cache.js index 209d0f8..1372942 100644 --- a/plugins/cache.js +++ b/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)