workbox-precaching
Advanced tools
Comparing version 6.0.2 to 6.1.0
@@ -9,3 +9,3 @@ import './_version.js'; | ||
} | ||
export interface PrecacheEntry { | ||
export declare interface PrecacheEntry { | ||
integrity?: string; | ||
@@ -12,0 +12,0 @@ url: string; |
"use strict"; | ||
// @ts-ignore | ||
try { | ||
self['workbox:precaching:6.0.2'] && _(); | ||
self['workbox:precaching:6.1.0'] && _(); | ||
} | ||
catch (e) { } |
@@ -24,3 +24,3 @@ this.workbox = this.workbox || {}; | ||
try { | ||
self['workbox:precaching:6.0.2'] && _(); | ||
self['workbox:precaching:6.1.0'] && _(); | ||
} catch (e) {} | ||
@@ -284,10 +284,2 @@ | ||
*/ | ||
const copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ | ||
response | ||
}) { | ||
return response.redirected ? await copyResponse_js.copyResponse(response) : response; | ||
} | ||
}; | ||
/** | ||
@@ -332,3 +324,3 @@ * A [Strategy]{@link module:workbox-strategies.Strategy} implementation | ||
this.plugins.push(copyRedirectedCacheableResponsesPlugin); | ||
this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); | ||
} | ||
@@ -399,13 +391,10 @@ /** | ||
async _handleInstall(request, handler) { | ||
const response = await handler.fetchAndCachePut(request); // Any time there's no response, consider it a precaching error. | ||
this._useDefaultCacheabilityPluginIfNeeded(); | ||
let responseSafeToPrecache = Boolean(response); // Also consider it an error if the user didn't pass their own | ||
// cacheWillUpdate plugin, and the response is a 400+ (note: this means | ||
// that by default opaque responses can be precached). | ||
const response = await handler.fetch(request); // Make sure we defer cachePut() until after we know the response | ||
// should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 | ||
if (response && response.status >= 400 && !this._usesCustomCacheableResponseLogic()) { | ||
responseSafeToPrecache = false; | ||
} | ||
const wasCached = await handler.cachePut(request, response.clone()); | ||
if (!responseSafeToPrecache) { | ||
if (!wasCached) { | ||
// Throwing here will lead to the `install` handler failing, which | ||
@@ -422,10 +411,26 @@ // we want to do if *any* of the responses aren't safe to cache. | ||
/** | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* This method is complex, as there a number of things to account for: | ||
* | ||
* This method indicates whether the default cacheable response logic (i.e. | ||
* <400, including opaque responses) should be used. If a custom plugin | ||
* with a `cacheWillUpdate` callback is passed, then the strategy should | ||
* defer to that plugin's logic. | ||
* The `plugins` array can be set at construction, and/or it might be added to | ||
* to at any time before the strategy is used. | ||
* | ||
* At the time the strategy is used (i.e. during an `install` event), there | ||
* needs to be at least one plugin that implements `cacheWillUpdate` in the | ||
* array, other than `copyRedirectedCacheableResponsesPlugin`. | ||
* | ||
* - If this method is called and there are no suitable `cacheWillUpdate` | ||
* plugins, we need to add `defaultPrecacheCacheabilityPlugin`. | ||
* | ||
* - If this method is called and there is exactly one `cacheWillUpdate`, then | ||
* we don't have to do anything (this might be a previously added | ||
* `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). | ||
* | ||
* - If this method is called and there is more than one `cacheWillUpdate`, | ||
* then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, | ||
* we need to remove it. (This situation is unlikely, but it could happen if | ||
* the strategy is used multiple times, the first without a `cacheWillUpdate`, | ||
* and then later on after manually adding a custom `cacheWillUpdate`.) | ||
* | ||
* See https://github.com/GoogleChrome/workbox/issues/2737 for more context. | ||
* | ||
* @private | ||
@@ -435,4 +440,29 @@ */ | ||
_usesCustomCacheableResponseLogic() { | ||
return this.plugins.some(plugin => plugin.cacheWillUpdate && plugin !== copyRedirectedCacheableResponsesPlugin); | ||
_useDefaultCacheabilityPluginIfNeeded() { | ||
let defaultPluginIndex = null; | ||
let cacheWillUpdatePluginCount = 0; | ||
for (const [index, plugin] of this.plugins.entries()) { | ||
// Ignore the copy redirected plugin when determining what to do. | ||
if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { | ||
continue; | ||
} // Save the default plugin's index, in case it needs to be removed. | ||
if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { | ||
defaultPluginIndex = index; | ||
} | ||
if (plugin.cacheWillUpdate) { | ||
cacheWillUpdatePluginCount++; | ||
} | ||
} | ||
if (cacheWillUpdatePluginCount === 0) { | ||
this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); | ||
} else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { | ||
// Only remove the default plugin; multiple custom plugins are allowed. | ||
this.plugins.splice(defaultPluginIndex, 1); | ||
} // Nothing needs to be done if cacheWillUpdatePluginCount is 1 | ||
} | ||
@@ -442,2 +472,23 @@ | ||
PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { | ||
async cacheWillUpdate({ | ||
response | ||
}) { | ||
if (!response || response.status >= 400) { | ||
return null; | ||
} | ||
return response; | ||
} | ||
}; | ||
PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ | ||
response | ||
}) { | ||
return response.redirected ? await copyResponse_js.copyResponse(response) : response; | ||
} | ||
}; | ||
/** | ||
@@ -444,0 +495,0 @@ * Performs efficient precaching of assets. |
@@ -1,2 +0,2 @@ | ||
this.workbox=this.workbox||{},this.workbox.precaching=function(t,e,s,n,i,c,r,o){"use strict";function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)Object.prototype.hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t}).apply(this,arguments)}try{self["workbox:precaching:6.0.2"]&&_()}catch(t){}function h(t){if(!t)throw new s.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),c=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:c.href}}class l{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class u{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=e&&e.cacheKey||this.et.getCacheKeyForURL(t.url);return s?new Request(s):t},this.et=t}}const f={cacheWillUpdate:async({response:t})=>t.redirected?await i.copyResponse(t):t};class w extends c.Strategy{constructor(t={}){t.cacheName=e.cacheNames.getPrecacheName(t.cacheName),super(t),this.st=!1!==t.fallbackToNetwork,this.plugins.push(f)}async _handle(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.nt(t,e):await this.it(t,e))}async it(t,e){let n;if(!this.st)throw new s.WorkboxError("missing-precache-entry",{cacheName:this.cacheName,url:t.url});return n=await e.fetch(t),n}async nt(t,e){const n=await e.fetchAndCachePut(t);let i=Boolean(n);if(n&&n.status>=400&&!this.ct()&&(i=!1),!i)throw new s.WorkboxError("bad-precaching-response",{url:t.url,status:n.status});return n}ct(){return this.plugins.some((t=>t.cacheWillUpdate&&t!==f))}}class d{constructor({cacheName:t,plugins:s=[],fallbackToNetwork:n=!0}={}){this.rt=new Map,this.ot=new Map,this.at=new Map,this.ht=new w({cacheName:e.cacheNames.getPrecacheName(t),plugins:[...s,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.ht}precache(t){this.addToCacheList(t),this.lt||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.lt=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=h(n),c="string"!=typeof n&&n.revision?"reload":"default";if(this.rt.has(i)&&this.rt.get(i)!==t)throw new s.WorkboxError("add-to-cache-list-conflicting-entries",{firstEntry:this.rt.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.at.has(t)&&this.at.get(t)!==n.integrity)throw new s.WorkboxError("add-to-cache-list-conflicting-integrities",{url:i});this.at.set(t,n.integrity)}if(this.rt.set(i,t),this.ot.set(i,c),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return n.waitUntil(t,(async()=>{const e=new l;this.strategy.plugins.push(e);for(const[e,s]of this.rt){const n=this.at.get(s),i=this.ot.get(e),c=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:c,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}}))}activate(t){return n.waitUntil(t,(async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.rt.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}}))}getURLsToCacheKeys(){return this.rt}getCachedURLs(){return[...this.rt.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.rt.get(e.href)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s.WorkboxError("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=a({cacheKey:e},s.params),this.strategy.handle(s))}}let y;const p=()=>(y||(y=new d),y);class R extends o.Route{constructor(t,e){super((({request:s})=>{const n=t.getURLsToCacheKeys();for(const t of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const c=new URL(t,location.href);c.hash="",yield c.href;const r=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some((t=>t.test(s)))&&t.searchParams.delete(s);return t}(c,e);if(yield r.href,s&&r.pathname.endsWith("/")){const t=new URL(r.href);t.pathname+=s,yield t.href}if(n){const t=new URL(r.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:c});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(t);if(e)return{cacheKey:e}}}),t.strategy)}}function L(t){const e=p(),s=new R(e,t);r.registerRoute(s)}function U(t){p().precache(t)}return t.PrecacheController=d,t.PrecacheFallbackPlugin=class{constructor({fallbackURL:t,precacheController:e}){this.handlerDidError=()=>this.et.matchPrecache(this.ut),this.ut=t,this.et=e||p()}},t.PrecacheRoute=R,t.PrecacheStrategy=w,t.addPlugins=function(t){p().strategy.plugins.push(...t)},t.addRoute=L,t.cleanupOutdatedCaches=function(){self.addEventListener("activate",(t=>{const s=e.cacheNames.getPrecacheName();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter((s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t));return await Promise.all(s.map((t=>self.caches.delete(t)))),s})(s).then((t=>{})))}))},t.createHandlerBoundToURL=function(t){return p().createHandlerBoundToURL(t)},t.getCacheKeyForURL=function(t){return p().getCacheKeyForURL(t)},t.matchPrecache=function(t){return p().matchPrecache(t)},t.precache=U,t.precacheAndRoute=function(t,e){U(t),L(e)},t}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core,workbox.strategies,workbox.routing,workbox.routing); | ||
this.workbox=this.workbox||{},this.workbox.precaching=function(t,e,s,n,i,c,r,o){"use strict";function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var s=arguments[e];for(var n in s)Object.prototype.hasOwnProperty.call(s,n)&&(t[n]=s[n])}return t}).apply(this,arguments)}try{self["workbox:precaching:6.1.0"]&&_()}catch(t){}function h(t){if(!t)throw new s.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),c=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:c.href}}class l{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class u{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=e&&e.cacheKey||this.et.getCacheKeyForURL(t.url);return s?new Request(s):t},this.et=t}}class f extends c.Strategy{constructor(t={}){t.cacheName=e.cacheNames.getPrecacheName(t.cacheName),super(t),this.st=!1!==t.fallbackToNetwork,this.plugins.push(f.copyRedirectedCacheableResponsesPlugin)}async _handle(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.nt(t,e):await this.it(t,e))}async it(t,e){let n;if(!this.st)throw new s.WorkboxError("missing-precache-entry",{cacheName:this.cacheName,url:t.url});return n=await e.fetch(t),n}async nt(t,e){this.ct();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s.WorkboxError("bad-precaching-response",{url:t.url,status:n.status});return n}ct(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==f.copyRedirectedCacheableResponsesPlugin&&(n===f.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(f.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}f.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},f.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await i.copyResponse(t):t};class w{constructor({cacheName:t,plugins:s=[],fallbackToNetwork:n=!0}={}){this.rt=new Map,this.ot=new Map,this.at=new Map,this.ht=new f({cacheName:e.cacheNames.getPrecacheName(t),plugins:[...s,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.ht}precache(t){this.addToCacheList(t),this.lt||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.lt=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=h(n),c="string"!=typeof n&&n.revision?"reload":"default";if(this.rt.has(i)&&this.rt.get(i)!==t)throw new s.WorkboxError("add-to-cache-list-conflicting-entries",{firstEntry:this.rt.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.at.has(t)&&this.at.get(t)!==n.integrity)throw new s.WorkboxError("add-to-cache-list-conflicting-integrities",{url:i});this.at.set(t,n.integrity)}if(this.rt.set(i,t),this.ot.set(i,c),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return n.waitUntil(t,(async()=>{const e=new l;this.strategy.plugins.push(e);for(const[e,s]of this.rt){const n=this.at.get(s),i=this.ot.get(e),c=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:c,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}}))}activate(t){return n.waitUntil(t,(async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.rt.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}}))}getURLsToCacheKeys(){return this.rt}getCachedURLs(){return[...this.rt.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.rt.get(e.href)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s.WorkboxError("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=a({cacheKey:e},s.params),this.strategy.handle(s))}}let d;const y=()=>(d||(d=new w),d);class p extends o.Route{constructor(t,e){super((({request:s})=>{const n=t.getURLsToCacheKeys();for(const t of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const c=new URL(t,location.href);c.hash="",yield c.href;const r=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some((t=>t.test(s)))&&t.searchParams.delete(s);return t}(c,e);if(yield r.href,s&&r.pathname.endsWith("/")){const t=new URL(r.href);t.pathname+=s,yield t.href}if(n){const t=new URL(r.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:c});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(t);if(e)return{cacheKey:e}}}),t.strategy)}}function R(t){const e=y(),s=new p(e,t);r.registerRoute(s)}function U(t){y().precache(t)}return t.PrecacheController=w,t.PrecacheFallbackPlugin=class{constructor({fallbackURL:t,precacheController:e}){this.handlerDidError=()=>this.et.matchPrecache(this.ut),this.ut=t,this.et=e||y()}},t.PrecacheRoute=p,t.PrecacheStrategy=f,t.addPlugins=function(t){y().strategy.plugins.push(...t)},t.addRoute=R,t.cleanupOutdatedCaches=function(){self.addEventListener("activate",(t=>{const s=e.cacheNames.getPrecacheName();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter((s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t));return await Promise.all(s.map((t=>self.caches.delete(t)))),s})(s).then((t=>{})))}))},t.createHandlerBoundToURL=function(t){return y().createHandlerBoundToURL(t)},t.getCacheKeyForURL=function(t){return y().getCacheKeyForURL(t)},t.matchPrecache=function(t){return y().matchPrecache(t)},t.precache=U,t.precacheAndRoute=function(t,e){U(t),R(e)},t}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core,workbox.strategies,workbox.routing,workbox.routing); | ||
//# sourceMappingURL=workbox-precaching.prod.js.map |
{ | ||
"name": "workbox-precaching", | ||
"version": "6.0.2", | ||
"version": "6.1.0", | ||
"license": "MIT", | ||
@@ -24,7 +24,7 @@ "author": "Google's Web DevRel Team", | ||
"dependencies": { | ||
"workbox-core": "^6.0.2", | ||
"workbox-routing": "^6.0.2", | ||
"workbox-strategies": "^6.0.2" | ||
"workbox-core": "^6.1.0", | ||
"workbox-routing": "^6.1.0", | ||
"workbox-strategies": "^6.1.0" | ||
}, | ||
"gitHead": "025657cde5114bb301407d8e6bc546a21302c244" | ||
"gitHead": "8f1a9f2cd863ae93987a5cdfc1e3e799635c6e44" | ||
} |
@@ -6,3 +6,3 @@ import { Strategy } from 'workbox-strategies/Strategy.js'; | ||
declare global { | ||
interface WorkerGlobalScope { | ||
interface ServiceWorkerGlobalScope { | ||
__WB_MANIFEST: Array<PrecacheEntry | string>; | ||
@@ -9,0 +9,0 @@ } |
@@ -0,1 +1,2 @@ | ||
import { WorkboxPlugin } from 'workbox-core/types.js'; | ||
import { Strategy, StrategyOptions } from 'workbox-strategies/Strategy.js'; | ||
@@ -21,2 +22,4 @@ import { StrategyHandler } from 'workbox-strategies/StrategyHandler.js'; | ||
private readonly _fallbackToNetwork; | ||
static readonly defaultPrecacheCacheabilityPlugin: WorkboxPlugin; | ||
static readonly copyRedirectedCacheableResponsesPlugin: WorkboxPlugin; | ||
/** | ||
@@ -51,14 +54,30 @@ * | ||
/** | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* This method is complex, as there a number of things to account for: | ||
* | ||
* This method indicates whether the default cacheable response logic (i.e. | ||
* <400, including opaque responses) should be used. If a custom plugin | ||
* with a `cacheWillUpdate` callback is passed, then the strategy should | ||
* defer to that plugin's logic. | ||
* The `plugins` array can be set at construction, and/or it might be added to | ||
* to at any time before the strategy is used. | ||
* | ||
* At the time the strategy is used (i.e. during an `install` event), there | ||
* needs to be at least one plugin that implements `cacheWillUpdate` in the | ||
* array, other than `copyRedirectedCacheableResponsesPlugin`. | ||
* | ||
* - If this method is called and there are no suitable `cacheWillUpdate` | ||
* plugins, we need to add `defaultPrecacheCacheabilityPlugin`. | ||
* | ||
* - If this method is called and there is exactly one `cacheWillUpdate`, then | ||
* we don't have to do anything (this might be a previously added | ||
* `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). | ||
* | ||
* - If this method is called and there is more than one `cacheWillUpdate`, | ||
* then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, | ||
* we need to remove it. (This situation is unlikely, but it could happen if | ||
* the strategy is used multiple times, the first without a `cacheWillUpdate`, | ||
* and then later on after manually adding a custom `cacheWillUpdate`.) | ||
* | ||
* See https://github.com/GoogleChrome/workbox/issues/2737 for more context. | ||
* | ||
* @private | ||
*/ | ||
_usesCustomCacheableResponseLogic(): boolean; | ||
_useDefaultCacheabilityPluginIfNeeded(): void; | ||
} | ||
export { PrecacheStrategy }; |
@@ -15,7 +15,2 @@ /* | ||
import './_version.js'; | ||
const copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ response }) { | ||
return response.redirected ? await copyResponse(response) : response; | ||
} | ||
}; | ||
/** | ||
@@ -59,3 +54,3 @@ * A [Strategy]{@link module:workbox-strategies.Strategy} implementation | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 | ||
this.plugins.push(copyRedirectedCacheableResponsesPlugin); | ||
this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); | ||
} | ||
@@ -121,13 +116,8 @@ /** | ||
async _handleInstall(request, handler) { | ||
const response = await handler.fetchAndCachePut(request); | ||
// Any time there's no response, consider it a precaching error. | ||
let responseSafeToPrecache = Boolean(response); | ||
// Also consider it an error if the user didn't pass their own | ||
// cacheWillUpdate plugin, and the response is a 400+ (note: this means | ||
// that by default opaque responses can be precached). | ||
if (response && response.status >= 400 && | ||
!this._usesCustomCacheableResponseLogic()) { | ||
responseSafeToPrecache = false; | ||
} | ||
if (!responseSafeToPrecache) { | ||
this._useDefaultCacheabilityPluginIfNeeded(); | ||
const response = await handler.fetch(request); | ||
// Make sure we defer cachePut() until after we know the response | ||
// should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 | ||
const wasCached = await handler.cachePut(request, response.clone()); | ||
if (!wasCached) { | ||
// Throwing here will lead to the `install` handler failing, which | ||
@@ -143,17 +133,67 @@ // we want to do if *any* of the responses aren't safe to cache. | ||
/** | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* This method is complex, as there a number of things to account for: | ||
* | ||
* This method indicates whether the default cacheable response logic (i.e. | ||
* <400, including opaque responses) should be used. If a custom plugin | ||
* with a `cacheWillUpdate` callback is passed, then the strategy should | ||
* defer to that plugin's logic. | ||
* The `plugins` array can be set at construction, and/or it might be added to | ||
* to at any time before the strategy is used. | ||
* | ||
* At the time the strategy is used (i.e. during an `install` event), there | ||
* needs to be at least one plugin that implements `cacheWillUpdate` in the | ||
* array, other than `copyRedirectedCacheableResponsesPlugin`. | ||
* | ||
* - If this method is called and there are no suitable `cacheWillUpdate` | ||
* plugins, we need to add `defaultPrecacheCacheabilityPlugin`. | ||
* | ||
* - If this method is called and there is exactly one `cacheWillUpdate`, then | ||
* we don't have to do anything (this might be a previously added | ||
* `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). | ||
* | ||
* - If this method is called and there is more than one `cacheWillUpdate`, | ||
* then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, | ||
* we need to remove it. (This situation is unlikely, but it could happen if | ||
* the strategy is used multiple times, the first without a `cacheWillUpdate`, | ||
* and then later on after manually adding a custom `cacheWillUpdate`.) | ||
* | ||
* See https://github.com/GoogleChrome/workbox/issues/2737 for more context. | ||
* | ||
* @private | ||
*/ | ||
_usesCustomCacheableResponseLogic() { | ||
return this.plugins.some((plugin) => plugin.cacheWillUpdate && | ||
plugin !== copyRedirectedCacheableResponsesPlugin); | ||
_useDefaultCacheabilityPluginIfNeeded() { | ||
let defaultPluginIndex = null; | ||
let cacheWillUpdatePluginCount = 0; | ||
for (const [index, plugin] of this.plugins.entries()) { | ||
// Ignore the copy redirected plugin when determining what to do. | ||
if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { | ||
continue; | ||
} | ||
// Save the default plugin's index, in case it needs to be removed. | ||
if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { | ||
defaultPluginIndex = index; | ||
} | ||
if (plugin.cacheWillUpdate) { | ||
cacheWillUpdatePluginCount++; | ||
} | ||
} | ||
if (cacheWillUpdatePluginCount === 0) { | ||
this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); | ||
} | ||
else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { | ||
// Only remove the default plugin; multiple custom plugins are allowed. | ||
this.plugins.splice(defaultPluginIndex, 1); | ||
} | ||
// Nothing needs to be done if cacheWillUpdatePluginCount is 1 | ||
} | ||
} | ||
PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { | ||
async cacheWillUpdate({ response }) { | ||
if (!response || response.status >= 400) { | ||
return null; | ||
} | ||
return response; | ||
} | ||
}; | ||
PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ response }) { | ||
return response.redirected ? await copyResponse(response) : response; | ||
} | ||
}; | ||
export { PrecacheStrategy }; |
@@ -20,3 +20,3 @@ /* | ||
export interface PrecacheEntry { | ||
export declare interface PrecacheEntry { | ||
integrity?: string; | ||
@@ -23,0 +23,0 @@ url: string; |
// @ts-ignore | ||
try{self['workbox:precaching:6.0.2']&&_()}catch(e){} | ||
try{self['workbox:precaching:6.1.0']&&_()}catch(e){} |
@@ -31,3 +31,3 @@ /* | ||
declare global { | ||
interface WorkerGlobalScope { | ||
interface ServiceWorkerGlobalScope { | ||
__WB_MANIFEST: Array<PrecacheEntry|string>; | ||
@@ -34,0 +34,0 @@ } |
@@ -20,9 +20,2 @@ /* | ||
const copyRedirectedCacheableResponsesPlugin: WorkboxPlugin = { | ||
async cacheWillUpdate({response}) { | ||
return response.redirected ? await copyResponse(response) : response; | ||
} | ||
} | ||
interface PrecacheStrategyOptions extends StrategyOptions { | ||
@@ -47,2 +40,18 @@ fallbackToNetwork?: boolean; | ||
static readonly defaultPrecacheCacheabilityPlugin: WorkboxPlugin = { | ||
async cacheWillUpdate({response}) { | ||
if (!response || response.status >= 400) { | ||
return null; | ||
} | ||
return response; | ||
} | ||
}; | ||
static readonly copyRedirectedCacheableResponsesPlugin: WorkboxPlugin = { | ||
async cacheWillUpdate({response}) { | ||
return response.redirected ? await copyResponse(response) : response; | ||
} | ||
}; | ||
/** | ||
@@ -75,3 +84,3 @@ * | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 | ||
this.plugins.push(copyRedirectedCacheableResponsesPlugin); | ||
this.plugins.push(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); | ||
} | ||
@@ -146,16 +155,10 @@ | ||
async _handleInstall(request: Request, handler: StrategyHandler) { | ||
const response = await handler.fetchAndCachePut(request); | ||
this._useDefaultCacheabilityPluginIfNeeded(); | ||
// Any time there's no response, consider it a precaching error. | ||
let responseSafeToPrecache = Boolean(response); | ||
const response = await handler.fetch(request); | ||
// Also consider it an error if the user didn't pass their own | ||
// cacheWillUpdate plugin, and the response is a 400+ (note: this means | ||
// that by default opaque responses can be precached). | ||
if (response && response.status >= 400 && | ||
!this._usesCustomCacheableResponseLogic()) { | ||
responseSafeToPrecache = false; | ||
} | ||
if (!responseSafeToPrecache) { | ||
// Make sure we defer cachePut() until after we know the response | ||
// should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 | ||
const wasCached = await handler.cachePut(request, response.clone()); | ||
if (!wasCached) { | ||
// Throwing here will lead to the `install` handler failing, which | ||
@@ -173,15 +176,55 @@ // we want to do if *any* of the responses aren't safe to cache. | ||
/** | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* This method is complex, as there a number of things to account for: | ||
* | ||
* The `plugins` array can be set at construction, and/or it might be added to | ||
* to at any time before the strategy is used. | ||
* | ||
* At the time the strategy is used (i.e. during an `install` event), there | ||
* needs to be at least one plugin that implements `cacheWillUpdate` in the | ||
* array, other than `copyRedirectedCacheableResponsesPlugin`. | ||
* | ||
* - If this method is called and there are no suitable `cacheWillUpdate` | ||
* plugins, we need to add `defaultPrecacheCacheabilityPlugin`. | ||
* | ||
* - If this method is called and there is exactly one `cacheWillUpdate`, then | ||
* we don't have to do anything (this might be a previously added | ||
* `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). | ||
* | ||
* - If this method is called and there is more than one `cacheWillUpdate`, | ||
* then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, | ||
* we need to remove it. (This situation is unlikely, but it could happen if | ||
* the strategy is used multiple times, the first without a `cacheWillUpdate`, | ||
* and then later on after manually adding a custom `cacheWillUpdate`.) | ||
* | ||
* See https://github.com/GoogleChrome/workbox/issues/2737 for more context. | ||
* | ||
* This method indicates whether the default cacheable response logic (i.e. | ||
* <400, including opaque responses) should be used. If a custom plugin | ||
* with a `cacheWillUpdate` callback is passed, then the strategy should | ||
* defer to that plugin's logic. | ||
* | ||
* @private | ||
*/ | ||
_usesCustomCacheableResponseLogic(): boolean { | ||
return this.plugins.some((plugin) => plugin.cacheWillUpdate && | ||
plugin !== copyRedirectedCacheableResponsesPlugin); | ||
_useDefaultCacheabilityPluginIfNeeded(): void { | ||
let defaultPluginIndex: number | null = null; | ||
let cacheWillUpdatePluginCount = 0; | ||
for (const [index, plugin] of this.plugins.entries()) { | ||
// Ignore the copy redirected plugin when determining what to do. | ||
if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { | ||
continue; | ||
} | ||
// Save the default plugin's index, in case it needs to be removed. | ||
if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { | ||
defaultPluginIndex = index; | ||
} | ||
if (plugin.cacheWillUpdate) { | ||
cacheWillUpdatePluginCount++; | ||
} | ||
} | ||
if (cacheWillUpdatePluginCount === 0) { | ||
this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); | ||
} else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { | ||
// Only remove the default plugin; multiple custom plugins are allowed. | ||
this.plugins.splice(defaultPluginIndex, 1); | ||
} | ||
// Nothing needs to be done if cacheWillUpdatePluginCount is 1 | ||
} | ||
@@ -188,0 +231,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Unidentified License
License(Experimental) Something that seems like a license was found, but its contents could not be matched with a known license.
Found 2 instances in 1 package
387731
4417
Updatedworkbox-core@^6.1.0
Updatedworkbox-routing@^6.1.0
Updatedworkbox-strategies@^6.1.0