kopia lustrzana https://gitlab.com/rysiekpl/libresilient
important hotfix: config.json now properly cached, SW init performed reliably after SW re-start (ref. #31)
rodzic
387009782e
commit
6fe4e94199
|
@ -92,11 +92,11 @@ self.log = function(component, ...items) {
|
|||
|
||||
|
||||
/**
|
||||
* verifying a config JSON
|
||||
* verifying and loading a config JSON
|
||||
*
|
||||
* cdata - config data to verify
|
||||
*/
|
||||
let verifyConfigData = (cdata) => {
|
||||
let loadConfigData = (cdata) => {
|
||||
// basic check for the plugins field
|
||||
if ( !("plugins" in cdata) || ! Array.isArray(cdata.plugins) ) {
|
||||
self.log('service-worker', 'fetched config does not contain a valid "plugins" field')
|
||||
|
@ -107,23 +107,34 @@ let verifyConfigData = (cdata) => {
|
|||
self.log('service-worker', 'fetched config does not contain a valid "loggedComponents" field')
|
||||
return false;
|
||||
}
|
||||
// defaultPluginTimeout optional
|
||||
// defaultPluginTimeout is optional
|
||||
if ("defaultPluginTimeout" in cdata) {
|
||||
if (!Number.isInteger(cdata.defaultPluginTimeout)) {
|
||||
self.log('service-worker', 'fetched config contains invalid "defaultPluginTimeout" data (integer expected)')
|
||||
return false;
|
||||
}
|
||||
// safe to apply defaultPluginTimeout
|
||||
self.LibResilientConfig.defaultPluginTimeout = cdata.defaultPluginTimeout
|
||||
}
|
||||
// safe to apply main config data
|
||||
self.LibResilientConfig.plugins = cdata.plugins
|
||||
self.LibResilientConfig.loggedComponents = cdata.loggedComponents
|
||||
// we're good
|
||||
return true;
|
||||
}
|
||||
|
||||
// flag signifying the SW has been initialized already
|
||||
var initDone = false
|
||||
|
||||
// load the plugins
|
||||
//
|
||||
let initServiceWorker = async () => {
|
||||
// if init has already been done, skip!
|
||||
if (initDone) {
|
||||
self.log('service-worker', 'skipping service-worker init, already done')
|
||||
return false;
|
||||
}
|
||||
// everything in a try-catch block
|
||||
// so that we get an informative message if there's an error
|
||||
let initServiceWorker = async () => {
|
||||
try {
|
||||
|
||||
// get the config
|
||||
|
@ -134,19 +145,37 @@ let initServiceWorker = async () => {
|
|||
// TODO: providing config directly from browser-side control script via postMessage?
|
||||
// TODO: `updateViaCache=imports` allows at least config.json to be updated using the cache plugin?
|
||||
try {
|
||||
//self.importScripts(self.registration.scope + "config.json")
|
||||
var cdata = await fetch(self.registration.scope + "config.json")
|
||||
if (cdata.status != 200) {
|
||||
// config.json URL
|
||||
var configURL = self.registration.scope + "config.json"
|
||||
// we need to know if the config was already cached
|
||||
var wasCached = true
|
||||
// get the config file, cached or otherwise
|
||||
var cresponse = await caches.match(configURL)
|
||||
if (cresponse != undefined) {
|
||||
self.log('service-worker', `config file retrieved from cache.`)
|
||||
} else {
|
||||
self.log('service-worker', `config file not found in cache, fetching.`)
|
||||
wasCached = false
|
||||
cresponse = await fetch(configURL)
|
||||
}
|
||||
// check for sanity
|
||||
if (cresponse.status != 200) {
|
||||
self.log('service-worker', `failed to fetch config (${cdata.status} ${cdata.statusText}).`)
|
||||
} else {
|
||||
cdata = await cdata.json()
|
||||
if (verifyConfigData(cdata)) {
|
||||
self.LibResilientConfig.plugins = cdata.plugins
|
||||
self.LibResilientConfig.loggedComponents = cdata.loggedComponents
|
||||
if ("defaultPluginTimeout" in cdata) {
|
||||
self.LibResilientConfig.defaultPluginTimeout = cdata.defaultPluginTimeout
|
||||
}
|
||||
// process the data
|
||||
cdata = await cresponse.clone().json()
|
||||
if (loadConfigData(cdata)) {
|
||||
self.log('service-worker', 'config loaded.')
|
||||
// cache the valid config.json
|
||||
if (!wasCached) {
|
||||
try {
|
||||
var cache = await caches.open('v1')
|
||||
await cache.put(configURL, cresponse)
|
||||
self.log('service-worker', 'config cached.')
|
||||
} catch(e) {
|
||||
self.log('service-worker', `failed to cache config: ${e}`)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.log('service-worker', 'ignoring invalid config, using defaults.')
|
||||
}
|
||||
|
@ -251,6 +280,7 @@ let initServiceWorker = async () => {
|
|||
|
||||
// inform
|
||||
self.log('service-worker', `DEBUG: Strategy in use: ${self.LibResilientPlugins.map(p=>p.name).join(', ')}`)
|
||||
initDone = true;
|
||||
|
||||
} catch(e) {
|
||||
// we only get a cryptic "Error while registering a service worker"
|
||||
|
@ -258,6 +288,7 @@ let initServiceWorker = async () => {
|
|||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -718,17 +749,19 @@ let getResourceThroughLibResilient = (url, init, clientId, useStashed=true, doSt
|
|||
\* ========================================================================= */
|
||||
self.addEventListener('install', async (event) => {
|
||||
event.waitUntil(initServiceWorker())
|
||||
// TODO: Might we want to have a local cache?
|
||||
// "COMMIT_UNKNOWN" will be replaced with commit ID
|
||||
self.log('service-worker', "0. Installed LibResilient Service Worker (commit: COMMIT_UNKNOWN).");
|
||||
});
|
||||
|
||||
self.addEventListener('activate', event => {
|
||||
self.addEventListener('activate', async event => {
|
||||
self.log('service-worker', "1. Activated LibResilient Service Worker (commit: COMMIT_UNKNOWN).");
|
||||
// TODO: should we do some plugin initialization here?
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
self.addEventListener('fetch', async event => {
|
||||
return void event.respondWith(async function () {
|
||||
// initialize the SW
|
||||
await initServiceWorker()
|
||||
// if event.resultingClientId is available, we need to use this
|
||||
// otherwise event.clientId is what we want
|
||||
// ref. https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent/resultingClientId
|
||||
|
@ -791,7 +824,8 @@ self.addEventListener('fetch', event => {
|
|||
|
||||
// GET requests to our own domain that are *not* #libresilient-info requests
|
||||
// get handled by plugins in case of an error
|
||||
return void event.respondWith(getResourceThroughLibResilient(url, init, clientId))
|
||||
return getResourceThroughLibResilient(url, init, clientId)
|
||||
}())
|
||||
});
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue