diff --git a/service-worker.js b/service-worker.js index 36f1716..ee9292d 100644 --- a/service-worker.js +++ b/service-worker.js @@ -518,138 +518,138 @@ let getResourceThroughLibResilient = (request, clientId, useStashed=true, doStas return LibResilientPluginsRun .slice(1) .reduce( - (prevPromise, currentPlugin)=>{ - return prevPromise.catch((error)=>{ - self.log('service-worker', "LibResilient plugin error for:", url, - '\n+-- method : ' + reqInfo.method, - '\n+-- error : ' + error.toString()) - // save info in reqInfo -- status of the previous method - reqInfo.update({ - state: "error", - fetchError: error.toString() - }) - return libresilientFetch(currentPlugin, url, init, reqInfo) - }) - }, - // this libresilientFetch() will run first - // all other promises generated by LibResilientPlugins[] will be chained on it - // using the catch() in reduce() above - // skipping this very first plugin by way of slice(1) - libresilientFetch(LibResilientPluginsRun[0], url, init, reqInfo) - ) - .then((response)=>{ - // we got a successful response - decrementActiveFetches(clientId) - - // record the success - reqInfo.update({state:"success"}) - - // get the plugin that was used to fetch content - plugin = self.LibResilientPlugins.find(p=>p.name===reqInfo.method) - - // if it's a stashing plugin... - if (typeof plugin.stash === 'function') { - // we obviously do not want to stash - self.log('service-worker', 'Not stashing, since resource is already retrieved by a stashing plugin:', url); - // since we got the data from a stashing plugin, - // let's run the rest of plugins in the background to check if we can get a fresher resource - // and stash it in cache for later use - self.log('service-worker', 'starting background no-stashed fetch for:', url); - // event.waitUntil? - // https://stackoverflow.com/questions/37902441/what-does-event-waituntil-do-in-service-worker-and-why-is-it-needed/37906330#37906330 - // TODO: perhaps don't use the `request` again? some wrapper? - getResourceThroughLibResilient(request, clientId, false, true, response.clone()).catch((e)=>{ - self.log('service-worker', 'background no-stashed fetch failed for:', url); - }) - // return the response so that stuff can keep happening - return response - - // otherwise, let's see if we want to stash - // and if we already had a stashed version that differs - } else { - - // do we have a stashed version that differs? - if (stashedResponse && stashedResponse.headers) { - // this is where we check if the response from whatever plugin we got it from - // is newer than what we've stashed - self.log('service-worker', 'checking freshness of stashed version of:', url, - '\n+-- stashed from :', stashedResponse.headers.get('X-LibResilient-Method'), - '\n+-- fetched using :', response.headers.get('X-LibResilient-Method'), - '\n+-- stashed X-LibResilient-ETag :', stashedResponse.headers.get('X-LibResilient-ETag'), - '\n+-- fetched X-LibResilient-ETag :', response.headers.get('X-LibResilient-ETag')) - // if the method does not match, or if it matches but the ETag doesn't - // we have a different response - // which means *probably* fresher content - if ( ( stashedResponse.headers.get('X-LibResilient-Method') !== response.headers.get('X-LibResilient-Method') ) - || ( stashedResponse.headers.get('X-LibResilient-ETag') !== response.headers.get('X-LibResilient-ETag') ) ) { - // inform! - self.log('service-worker', 'fetched version method or ETag differs from stashed for:', url) - self.clients.get(reqInfo.clientId).then((client)=>{ - if (client !== null) { - client.postMessage({ - url: url, - fetchedDiffers: true - }) - } + (prevPromise, currentPlugin)=>{ + return prevPromise.catch((error)=>{ + self.log('service-worker', "LibResilient plugin error for:", url, + '\n+-- method : ' + reqInfo.method, + '\n+-- error : ' + error.toString()) + // save info in reqInfo -- status of the previous method + reqInfo.update({ + state: "error", + fetchError: error.toString() }) - // TODO: this should probably modify doStash? - } - } + return libresilientFetch(currentPlugin, url, init, reqInfo) + }) + }, + // this libresilientFetch() will run first + // all other promises generated by LibResilientPlugins[] will be chained on it + // using the catch() in reduce() above + // skipping this very first plugin by way of slice(1) + libresilientFetch(LibResilientPluginsRun[0], url, init, reqInfo) + ) + .then((response)=>{ + // we got a successful response + decrementActiveFetches(clientId) - // do we want to stash? - if (doStash) { - // find the first stashing plugin - for (i=0; i{ - hdrs += `\n +-- ${k} : ${v}` + // record the success + reqInfo.update({state:"success"}) + + // get the plugin that was used to fetch content + plugin = self.LibResilientPlugins.find(p=>p.name===reqInfo.method) + + // if it's a stashing plugin... + if (typeof plugin.stash === 'function') { + // we obviously do not want to stash + self.log('service-worker', 'Not stashing, since resource is already retrieved by a stashing plugin:', url); + // since we got the data from a stashing plugin, + // let's run the rest of plugins in the background to check if we can get a fresher resource + // and stash it in cache for later use + self.log('service-worker', 'starting background no-stashed fetch for:', url); + // event.waitUntil? + // https://stackoverflow.com/questions/37902441/what-does-event-waituntil-do-in-service-worker-and-why-is-it-needed/37906330#37906330 + // TODO: perhaps don't use the `request` again? some wrapper? + getResourceThroughLibResilient(request, clientId, false, true, response.clone()).catch((e)=>{ + self.log('service-worker', 'background no-stashed fetch failed for:', url); + }) + // return the response so that stuff can keep happening + return response + + // otherwise, let's see if we want to stash + // and if we already had a stashed version that differs + } else { + + // do we have a stashed version that differs? + if (stashedResponse && stashedResponse.headers) { + // this is where we check if the response from whatever plugin we got it from + // is newer than what we've stashed + self.log('service-worker', 'checking freshness of stashed version of:', url, + '\n+-- stashed from :', stashedResponse.headers.get('X-LibResilient-Method'), + '\n+-- fetched using :', response.headers.get('X-LibResilient-Method'), + '\n+-- stashed X-LibResilient-ETag :', stashedResponse.headers.get('X-LibResilient-ETag'), + '\n+-- fetched X-LibResilient-ETag :', response.headers.get('X-LibResilient-ETag')) + // if the method does not match, or if it matches but the ETag doesn't + // we have a different response + // which means *probably* fresher content + if ( ( stashedResponse.headers.get('X-LibResilient-Method') !== response.headers.get('X-LibResilient-Method') ) + || ( stashedResponse.headers.get('X-LibResilient-ETag') !== response.headers.get('X-LibResilient-ETag') ) ) { + // inform! + self.log('service-worker', 'fetched version method or ETag differs from stashed for:', url) + self.clients.get(reqInfo.clientId).then((client)=>{ + if (client !== null) { + client.postMessage({ + url: url, + fetchedDiffers: true + }) + } }) - self.log( - 'service-worker', - `stashing a successful fetch of: ${url}`, - `\n+-- fetched using : ${response.headers.get('X-LibResilient-Method')}`, - `\n+-- stashing using : ${self.LibResilientPlugins[i].name}`, - hdrs - ) - - // working on clone()'ed response so that the original one is not touched - // TODO: should a failed stashing break the flow here? probably not! - return self.LibResilientPlugins[i].stash(response.clone(), url) - .then((res)=>{ - // original response will be needed further down - return response + // TODO: this should probably modify doStash? + } + } + + // do we want to stash? + if (doStash) { + // find the first stashing plugin + for (i=0; i{ + hdrs += `\n +-- ${k} : ${v}` }) + self.log( + 'service-worker', + `stashing a successful fetch of: ${url}`, + `\n+-- fetched using : ${response.headers.get('X-LibResilient-Method')}`, + `\n+-- stashing using : ${self.LibResilientPlugins[i].name}`, + hdrs + ) + + // working on clone()'ed response so that the original one is not touched + // TODO: should a failed stashing break the flow here? probably not! + return self.LibResilientPlugins[i].stash(response.clone(), url) + .then((res)=>{ + // original response will be needed further down + return response + }) + } } } } - } - // if we're here it means we went through the whole list of plugins - // and found not a single stashing plugin - // or we don't want to stash the resources in the first place - // that's fine, but let's make sure the response goes forth - return response - }) - // a final catch... in case all plugins fail - .catch((err)=>{ - self.log('service-worker', "LibResilient also failed completely: ", err, - '\n+-- URL : ' + url) - - // cleanup - reqInfo.update({ - state: "error", - fetchError: err.toString() + // if we're here it means we went through the whole list of plugins + // and found not a single stashing plugin + // or we don't want to stash the resources in the first place + // that's fine, but let's make sure the response goes forth + return response + }) + // a final catch... in case all plugins fail + .catch((err)=>{ + self.log('service-worker', "LibResilient also failed completely: ", err, + '\n+-- URL : ' + url) + + // cleanup + reqInfo.update({ + state: "error", + fetchError: err.toString() + }) + // this is very naïve and should in fact be handled + // inside the relevant plugin, probably + // TODO: is this even needed? + reqInfo.update({method: null}) + decrementActiveFetches(clientId) + // rethrow + throw err }) - // this is very naïve and should in fact be handled - // inside the relevant plugin, probably - // TODO: is this even needed? - reqInfo.update({method: null}) - decrementActiveFetches(clientId) - // rethrow - throw err - }) } /* ========================================================================= *\