service-worker on the way to saner plugin loader; relevant fetch plugin changes implemented (ref. #15)

merge-requests/9/merge
Michał 'rysiek' Woźniak 2021-09-15 14:38:43 +00:00
rodzic 90696da96e
commit 295f3071cc
3 zmienionych plików z 84 dodań i 79 usunięć

Wyświetl plik

@ -24,25 +24,22 @@ describe("plugin: fetch", () => {
beforeEach(() => {
Object.assign(global, makeServiceWorkerEnv());
jest.resetModules();
self.LibResilientPlugins = new Array()
self.LibResilientConfig = {
plugins: {
'fetch':{}
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", () => {
require("../../plugins/fetch.js");
expect(self.LibResilientPlugins[0].name).toEqual('fetch');
expect(LibResilientPluginConstructors.get('fetch')().name).toEqual('fetch');
});
test("it should return data from fetch()", async () => {
require("../../plugins/fetch.js");
const response = await self.LibResilientPlugins[0].fetch('https://resilient.is/test.json');
const response = await LibResilientPluginConstructors.get('fetch')(LR).fetch('https://resilient.is/test.json');
expect(fetch).toHaveBeenCalled();
expect(await response.json()).toEqual({test: "success"})
@ -52,7 +49,7 @@ describe("plugin: fetch", () => {
test("it should set the LibResilient headers", async () => {
require("../../plugins/fetch.js");
const response = await self.LibResilientPlugins[0].fetch('https://resilient.is/test.json');
const response = await LibResilientPluginConstructors.get('fetch')(LR).fetch('https://resilient.is/test.json');
expect(fetch).toHaveBeenCalled();
expect(await response.json()).toEqual({test: "success"})
@ -82,6 +79,6 @@ describe("plugin: fetch", () => {
require("../../plugins/fetch.js");
expect.assertions(1)
expect(self.LibResilientPlugins[0].fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
expect(LibResilientPluginConstructors.get('fetch')(LR).fetch('https://resilient.is/test.json')).rejects.toThrow(Error)
});
});

Wyświetl plik

@ -6,74 +6,76 @@
* this plugin does not implement any push method
*/
// no polluting of the global namespace please
(function () {
/*
* plugin config settings
*/
// sane defaults
let defaultConfig = {
// name of this plugin
// should not be changed
name: "fetch"
}
// merge the defaults with settings from LibResilientConfig
let config = {...defaultConfig, ...self.LibResilientConfig.plugins[defaultConfig.name]}
/**
* getting content using regular HTTP(S) fetch()
*/
let fetchContent = (url) => {
self.log(config.name, `regular fetch: ${url}`)
return fetch(url, {cache: "reload"})
.then((response) => {
// 4xx? 5xx? that's a paddlin'
if (response.status >= 400) {
// throw an Error to fall back to LibResilient:
throw new Error('HTTP Error: ' + response.status + ' ' + response.statusText);
}
// all good, it seems
self.log(config.name, `fetched successfully: ${response.url}`);
// we need to create a new Response object
// with all the headers added explicitly,
// since response.headers is immutable
var init = {
status: response.status,
statusText: response.statusText,
headers: {},
url: response.url
};
response.headers.forEach(function(val, header){
init.headers[header] = val;
});
// add the X-LibResilient-* headers to the mix
init.headers['X-LibResilient-Method'] = config.name
init.headers['X-LibResilient-ETag'] = response.headers.get('ETag')
// return the new response, using the Blob from the original one
return response
.blob()
.then((blob) => {
return new Response(
blob,
init
)
})
})
}
/*
* no polluting of the global namespace please
*/
// and add ourselves to it
// with some additional metadata
self.LibResilientPlugins.push({
name: config.name,
description: 'Just a regular HTTP(S) fetch()',
version: 'COMMIT_UNKNOWN',
fetch: fetchContent
})
(function(LRPC){
// this never changes
const pluginName = "fetch"
LRPC.set(pluginName, (LR, init={})=>{
/*
* plugin config settings
*/
// sane defaults
let defaultConfig = {}
// merge the defaults with settings from init
let config = {...defaultConfig, ...init}
/**
* getting content using regular HTTP(S) fetch()
*/
let fetchContent = (url) => {
LR.log(pluginName, `regular fetch: ${url}`)
return fetch(url, {cache: "reload"})
.then((response) => {
// 4xx? 5xx? that's a paddlin'
if (response.status >= 400) {
// throw an Error to fall back to LibResilient:
throw new Error('HTTP Error: ' + response.status + ' ' + response.statusText);
}
// all good, it seems
LR.log(pluginName, `fetched successfully: ${response.url}`);
// we need to create a new Response object
// with all the headers added explicitly,
// since response.headers is immutable
var responseInit = {
status: response.status,
statusText: response.statusText,
headers: {},
url: response.url
};
response.headers.forEach(function(val, header){
responseInit.headers[header] = val;
});
// add the X-LibResilient-* headers to the mix
responseInit.headers['X-LibResilient-Method'] = pluginName
responseInit.headers['X-LibResilient-ETag'] = response.headers.get('ETag')
// return the new response, using the Blob from the original one
return response
.blob()
.then((blob) => {
return new Response(
blob,
responseInit
)
})
})
}
// return the plugin
return {
name: pluginName,
description: 'Just a regular HTTP(S) fetch()',
version: 'COMMIT_UNKNOWN',
fetch: fetchContent
}
})
// done with not polluting the global namespace
})()
})(LibResilientPluginConstructors)

Wyświetl plik

@ -107,11 +107,17 @@ try {
// get the config
self.importScripts("./config.js")
// create the LibResilientPluginConstructors map
var LibResilientPluginConstructors = new Map()
// only now load the plugins (config.js could have changed the defaults)
var plugins = Object.keys(self.LibResilientConfig.plugins)
for (var i=0; i<plugins.length; i++) {
// load a plugin
self.importScripts(`./plugins/${plugins[i]}.js`)
self.LibResilientPlugins.push(
LibResilientPluginConstructors.get(plugins[i])(self, self.LibResilientConfig.plugins[plugins[i]])
)
// check if it loaded properly
var plugin = self.LibResilientPlugins.find(p=>p.name===plugins[i])
if (plugin === undefined) {