workbox-precaching
Advanced tools
Comparing version 6.0.0-alpha.2 to 6.0.0-alpha.3
@@ -12,5 +12,5 @@ import './_version.js'; | ||
url: string; | ||
revision?: string; | ||
revision?: string | null; | ||
} | ||
export interface FetchListenerOptions { | ||
export interface PrecacheRouteOptions { | ||
directoryIndex?: string; | ||
@@ -17,0 +17,0 @@ ignoreURLParametersMatching?: RegExp[]; |
"use strict"; | ||
// @ts-ignore | ||
try { | ||
self['workbox:precaching:6.0.0-alpha.1'] && _(); | ||
self['workbox:precaching:6.0.0-alpha.2'] && _(); | ||
} | ||
catch (e) { } |
@@ -19,4 +19,4 @@ /* | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addPlugins(plugins); | ||
precacheController.strategy.plugins.push(...plugins); | ||
} | ||
export { addPlugins }; |
@@ -1,2 +0,2 @@ | ||
import { FetchListenerOptions } from './_types.js'; | ||
import { PrecacheRouteOptions } from './_types.js'; | ||
import './_version.js'; | ||
@@ -13,17 +13,8 @@ /** | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will | ||
* check cache entries for a URLs ending with '/' to see if there is a hit when | ||
* appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
* @param {Object} [options] See | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
declare function addRoute(options?: FetchListenerOptions): void; | ||
declare function addRoute(options?: PrecacheRouteOptions): void; | ||
export { addRoute }; |
@@ -7,3 +7,5 @@ /* | ||
*/ | ||
import { registerRoute } from 'workbox-routing/registerRoute.js'; | ||
import { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js'; | ||
import { PrecacheRoute } from './PrecacheRoute.js'; | ||
import './_version.js'; | ||
@@ -20,13 +22,4 @@ /** | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will | ||
* check cache entries for a URLs ending with '/' to see if there is a hit when | ||
* appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
* @param {Object} [options] See | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
@@ -37,4 +30,5 @@ * @memberof module:workbox-precaching | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addRoute(options); | ||
const precacheRoute = new PrecacheRoute(precacheController, options); | ||
registerRoute(precacheRoute); | ||
} | ||
export { addRoute }; |
this.workbox = this.workbox || {}; | ||
this.workbox.precaching = (function (exports, assert_js, cacheNames_js, getFriendlyURL_js, logger_js, WorkboxError_js, Route_js, Router_js, copyResponse_js, Strategy_js) { | ||
'use strict'; | ||
this.workbox.precaching = (function (exports, assert_js, cacheNames_js, logger_js, WorkboxError_js, waitUntil_js, copyResponse_js, getFriendlyURL_js, Strategy_js, registerRoute_js, Route_js) { | ||
'use strict'; | ||
try { | ||
self['workbox:precaching:6.0.0-alpha.1'] && _(); | ||
} catch (e) {} | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
/* | ||
Copyright 2018 Google LLC | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
return target; | ||
}; | ||
const REVISION_SEARCH_PARAM = '__WB_REVISION__'; | ||
/** | ||
* Converts a manifest entry into a versioned URL suitable for precaching. | ||
* | ||
* @param {Object|string} entry | ||
* @return {string} A URL with versioning info. | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
return _extends.apply(this, arguments); | ||
} | ||
function createCacheKey(entry) { | ||
if (!entry) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', { | ||
entry | ||
}); | ||
} // If a precache manifest entry is a string, it's assumed to be a versioned | ||
// URL, like '/app.abcd1234.js'. Return as-is. | ||
try { | ||
self['workbox:precaching:6.0.0-alpha.2'] && _(); | ||
} catch (e) {} | ||
/* | ||
Copyright 2018 Google LLC | ||
if (typeof entry === 'string') { | ||
const urlObject = new URL(entry, location.href); | ||
return { | ||
cacheKey: urlObject.href, | ||
url: urlObject.href | ||
}; | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
const { | ||
revision, | ||
url | ||
} = entry; | ||
const REVISION_SEARCH_PARAM = '__WB_REVISION__'; | ||
/** | ||
* Converts a manifest entry into a versioned URL suitable for precaching. | ||
* | ||
* @param {Object|string} entry | ||
* @return {string} A URL with versioning info. | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
if (!url) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', { | ||
entry | ||
}); | ||
} // If there's just a URL and no revision, then it's also assumed to be a | ||
// versioned URL. | ||
function createCacheKey(entry) { | ||
if (!entry) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', { | ||
entry | ||
}); | ||
} // If a precache manifest entry is a string, it's assumed to be a versioned | ||
// URL, like '/app.abcd1234.js'. Return as-is. | ||
if (!revision) { | ||
const urlObject = new URL(url, location.href); | ||
return { | ||
cacheKey: urlObject.href, | ||
url: urlObject.href | ||
}; | ||
} // Otherwise, construct a properly versioned URL using the custom Workbox | ||
// search parameter along with the revision info. | ||
if (typeof entry === 'string') { | ||
const urlObject = new URL(entry, location.href); | ||
return { | ||
cacheKey: urlObject.href, | ||
url: urlObject.href | ||
}; | ||
} | ||
const { | ||
revision, | ||
url | ||
} = entry; | ||
const cacheKeyURL = new URL(url, location.href); | ||
const originalURL = new URL(url, location.href); | ||
cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); | ||
if (!url) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', { | ||
entry | ||
}); | ||
} // If there's just a URL and no revision, then it's also assumed to be a | ||
// versioned URL. | ||
if (!revision) { | ||
const urlObject = new URL(url, location.href); | ||
return { | ||
cacheKey: cacheKeyURL.href, | ||
url: originalURL.href | ||
cacheKey: urlObject.href, | ||
url: urlObject.href | ||
}; | ||
} | ||
} // Otherwise, construct a properly versioned URL using the custom Workbox | ||
// search parameter along with the revision info. | ||
/* | ||
Copyright 2020 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
const copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ | ||
response | ||
}) { | ||
return response.redirected ? await copyResponse_js.copyResponse(response) : response; | ||
} | ||
const cacheKeyURL = new URL(url, location.href); | ||
const originalURL = new URL(url, location.href); | ||
cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision); | ||
return { | ||
cacheKey: cacheKeyURL.href, | ||
url: originalURL.href | ||
}; | ||
} | ||
class PrecacheStrategy extends Strategy_js.Strategy { | ||
constructor(options) { | ||
super(options); // Redirected responses cannot be used to satisfy a navigation request, so | ||
// any redirected response must be "copied" rather than cloned, so the new | ||
// response doesn't contain the `redirected` flag. See: | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 | ||
/* | ||
Copyright 2020 Google LLC | ||
this.plugins.push(copyRedirectedCacheableResponsesPlugin); | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* A plugin, designed to be used with PrecacheController, to determine the | ||
* of assets that were updated (or not updated) during the install event. | ||
*/ | ||
_handle(request, handler) { | ||
// If this is an `install` event then populate the cache. If this is a | ||
// `fetch` event (or any other event) then respond with the cached response. | ||
if (handler.event && handler.event.type === 'install') { | ||
return this._handleInstall(request, handler); | ||
class PrecacheInstallReportPlugin { | ||
constructor() { | ||
this.updatedURLs = []; | ||
this.notUpdatedURLs = []; | ||
this.handlerWillStart = async ({ | ||
request, | ||
state | ||
}) => { | ||
// TODO: `state` should never be undefined... | ||
if (state) { | ||
state.originalRequest = request; | ||
} | ||
}; | ||
return this._handleFetch(request, handler); | ||
} | ||
this.cachedResponseWillBeUsed = async ({ | ||
event, | ||
state, | ||
cachedResponse | ||
}) => { | ||
if (event.type === 'install') { | ||
// TODO: `state` should never be undefined... | ||
const url = state.originalRequest.url; | ||
async _handleFetch(request, handler) { | ||
let response = await handler.cacheMatch(request); | ||
if (!response) { | ||
// Fall back to the network if we don't have a cached response | ||
// (perhaps due to manual cache cleanup). | ||
if (handler.params && handler.params.fallbackToNetwork === false) { | ||
// This shouldn't normally happen, but there are edge cases: | ||
// https://github.com/GoogleChrome/workbox/issues/1441 | ||
throw new WorkboxError_js.WorkboxError('missing-precache-entry', { | ||
cacheName: this.cacheName, | ||
url: request.url | ||
}); | ||
if (cachedResponse) { | ||
this.notUpdatedURLs.push(url); | ||
} else { | ||
{ | ||
logger_js.logger.warn(`The precached response for ` + `${getFriendlyURL_js.getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network instead.`); | ||
} | ||
response = await handler.fetch(request); | ||
this.updatedURLs.push(url); | ||
} | ||
} | ||
{ | ||
// Workbox is going to handle the route. | ||
// print the routing details to the console. | ||
logger_js.logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL_js.getFriendlyURL(request.url)); | ||
logger_js.logger.log(`Serving the precached url: ` + handler.params.cacheKey); | ||
logger_js.logger.groupCollapsed(`View request details here.`); | ||
logger_js.logger.log(request); | ||
logger_js.logger.groupEnd(); | ||
logger_js.logger.groupCollapsed(`View response details here.`); | ||
logger_js.logger.log(response); | ||
logger_js.logger.groupEnd(); | ||
logger_js.logger.groupEnd(); | ||
} | ||
return cachedResponse; | ||
}; | ||
} | ||
return response; | ||
} | ||
} | ||
async _handleInstall(request, handler) { | ||
const response = await handler.fetchAndCachePut(request); // Any time there's no response, consider it a precaching error. | ||
/* | ||
Copyright 2020 Google LLC | ||
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). | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
if (response && response.status >= 400 && !this._usesCustomCacheableResponseLogic()) { | ||
responseSafeToPrecache = false; | ||
} | ||
class PrecacheCacheKeyPlugin { | ||
constructor({ | ||
precacheController | ||
}) { | ||
this.cacheKeyWillBeUsed = async ({ | ||
request, | ||
params | ||
}) => { | ||
const cacheKey = params && params.cacheKey || this._precacheController.getCacheKeyForURL(request.url); | ||
if (!responseSafeToPrecache) { | ||
// Throwing here will lead to the `install` handler failing, which | ||
// we want to do if *any* of the responses aren't safe to cache. | ||
throw new WorkboxError_js.WorkboxError('bad-precaching-response', { | ||
url: request.url, | ||
status: response.status | ||
}); | ||
} | ||
return cacheKey ? new Request(cacheKey) : request; | ||
}; | ||
return response; | ||
} | ||
/** | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* | ||
* 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 | ||
*/ | ||
this._precacheController = precacheController; | ||
} | ||
} | ||
_usesCustomCacheableResponseLogic() { | ||
return this.plugins.some(plugin => plugin.cacheWillUpdate && plugin !== copyRedirectedCacheableResponsesPlugin); | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* @param {string} groupTitle | ||
* @param {Array<string>} deletedURLs | ||
* | ||
* @private | ||
*/ | ||
const logGroup = (groupTitle, deletedURLs) => { | ||
logger_js.logger.groupCollapsed(groupTitle); | ||
for (const url of deletedURLs) { | ||
logger_js.logger.log(url); | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
logger_js.logger.groupEnd(); | ||
}; | ||
/** | ||
* @param {Array<string>} deletedURLs | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* @param {string} groupTitle | ||
* @param {Array<string>} deletedURLs | ||
* | ||
* @private | ||
*/ | ||
const logGroup = (groupTitle, deletedURLs) => { | ||
logger_js.logger.groupCollapsed(groupTitle); | ||
function printCleanupDetails(deletedURLs) { | ||
const deletionCount = deletedURLs.length; | ||
for (const url of deletedURLs) { | ||
logger_js.logger.log(url); | ||
} | ||
if (deletionCount > 0) { | ||
logger_js.logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); | ||
logGroup('Deleted Cache Requests', deletedURLs); | ||
logger_js.logger.groupEnd(); | ||
}; | ||
/** | ||
* @param {Array<string>} deletedURLs | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
} | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
function printCleanupDetails(deletedURLs) { | ||
const deletionCount = deletedURLs.length; | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* @param {string} groupTitle | ||
* @param {Array<string>} urls | ||
* | ||
* @private | ||
*/ | ||
if (deletionCount > 0) { | ||
logger_js.logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); | ||
logGroup('Deleted Cache Requests', deletedURLs); | ||
logger_js.logger.groupEnd(); | ||
} | ||
function _nestedGroup(groupTitle, urls) { | ||
if (urls.length === 0) { | ||
return; | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
logger_js.logger.groupCollapsed(groupTitle); | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* @param {string} groupTitle | ||
* @param {Array<string>} urls | ||
* | ||
* @private | ||
*/ | ||
for (const url of urls) { | ||
logger_js.logger.log(url); | ||
} | ||
function _nestedGroup(groupTitle, urls) { | ||
if (urls.length === 0) { | ||
return; | ||
} | ||
logger_js.logger.groupEnd(); | ||
} | ||
/** | ||
* @param {Array<string>} urlsToPrecache | ||
* @param {Array<string>} urlsAlreadyPrecached | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
logger_js.logger.groupCollapsed(groupTitle); | ||
for (const url of urls) { | ||
logger_js.logger.log(url); | ||
function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) { | ||
const precachedCount = urlsToPrecache.length; | ||
const alreadyPrecachedCount = urlsAlreadyPrecached.length; | ||
if (precachedCount || alreadyPrecachedCount) { | ||
let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`; | ||
if (alreadyPrecachedCount > 0) { | ||
message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`; | ||
} | ||
logger_js.logger.groupCollapsed(message); | ||
_nestedGroup(`View newly precached URLs.`, urlsToPrecache); | ||
_nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); | ||
logger_js.logger.groupEnd(); | ||
} | ||
} | ||
/* | ||
Copyright 2020 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
const copyRedirectedCacheableResponsesPlugin = { | ||
async cacheWillUpdate({ | ||
response | ||
}) { | ||
return response.redirected ? await copyResponse_js.copyResponse(response) : response; | ||
} | ||
}; | ||
/** | ||
* A [Strategy]{@link module:workbox-strategies.Strategy} implementation | ||
* specifically designed to work with | ||
* [PrecacheController]{@link module:workbox-precaching.PrecacheController} | ||
* to both cache and fetch precached assets. | ||
* | ||
* Note: an instance of this class is created automatically when creating a | ||
* `PrecacheController`; it's generally not necessary to create this yourself. | ||
* | ||
* @extends module:workbox-strategies.Strategy | ||
* @memberof module:workbox-precaching | ||
*/ | ||
class PrecacheStrategy extends Strategy_js.Strategy { | ||
/** | ||
* @param {Array<string>} urlsToPrecache | ||
* @param {Array<string>} urlsAlreadyPrecached | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.cacheName] Cache name to store and retrieve | ||
* requests. Defaults to the cache names provided by | ||
* [workbox-core]{@link module:workbox-core.cacheNames}. | ||
* @param {Array<Object>} [options.plugins] [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} | ||
* to use in conjunction with this caching strategy. | ||
* @param {Object} [options.fetchOptions] Values passed along to the | ||
* [`init`]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters} | ||
* of all fetch() requests made by this strategy. | ||
* @param {Object} [options.matchOptions] The | ||
* [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} | ||
* for any `cache.match()` or `cache.put()` calls made by this strategy. | ||
* @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to | ||
* get the response from the network if there's a precache miss. | ||
*/ | ||
constructor(options = {}) { | ||
options.cacheName = cacheNames_js.cacheNames.getPrecacheName(options.cacheName); | ||
super(options); | ||
this._fallbackToNetwork = options.fallbackToNetwork === false ? false : true; // Redirected responses cannot be used to satisfy a navigation request, so | ||
// any redirected response must be "copied" rather than cloned, so the new | ||
// response doesn't contain the `redirected` flag. See: | ||
// https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1 | ||
this.plugins.push(copyRedirectedCacheableResponsesPlugin); | ||
} | ||
/** | ||
* @private | ||
* @memberof module:workbox-precaching | ||
* @param {Request|string} request A request to run this strategy for. | ||
* @param {module:workbox-strategies.StrategyHandler} handler The event that | ||
* triggered the request. | ||
* @return {Promise<Response>} | ||
*/ | ||
function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) { | ||
const precachedCount = urlsToPrecache.length; | ||
const alreadyPrecachedCount = urlsAlreadyPrecached.length; | ||
async _handle(request, handler) { | ||
const response = await handler.cacheMatch(request); | ||
if (precachedCount || alreadyPrecachedCount) { | ||
let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`; | ||
if (!response) { | ||
// If this is an `install` event then populate the cache. If this is a | ||
// `fetch` event (or any other event) then respond with the cached | ||
// response. | ||
if (handler.event && handler.event.type === 'install') { | ||
return await this._handleInstall(request, handler); | ||
} | ||
if (alreadyPrecachedCount > 0) { | ||
message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`; | ||
return await this._handleFetch(request, handler); | ||
} | ||
return response; | ||
} | ||
async _handleFetch(request, handler) { | ||
let response; // Fall back to the network if we don't have a cached response | ||
// (perhaps due to manual cache cleanup). | ||
if (this._fallbackToNetwork) { | ||
{ | ||
logger_js.logger.warn(`The precached response for ` + `${getFriendlyURL_js.getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network instead.`); | ||
} | ||
logger_js.logger.groupCollapsed(message); | ||
response = await handler.fetch(request); | ||
} else { | ||
// This shouldn't normally happen, but there are edge cases: | ||
// https://github.com/GoogleChrome/workbox/issues/1441 | ||
throw new WorkboxError_js.WorkboxError('missing-precache-entry', { | ||
cacheName: this.cacheName, | ||
url: request.url | ||
}); | ||
} | ||
_nestedGroup(`View newly precached URLs.`, urlsToPrecache); | ||
{ | ||
const cacheKey = handler.params && handler.params.cacheKey || (await handler.getCacheKey(request, 'read')); // Workbox is going to handle the route. | ||
// print the routing details to the console. | ||
_nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); | ||
logger_js.logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL_js.getFriendlyURL(request.url)); | ||
logger_js.logger.log(`Serving the precached url: ${getFriendlyURL_js.getFriendlyURL(cacheKey.url)}`); | ||
logger_js.logger.groupCollapsed(`View request details here.`); | ||
logger_js.logger.log(request); | ||
logger_js.logger.groupEnd(); | ||
logger_js.logger.groupCollapsed(`View response details here.`); | ||
logger_js.logger.log(response); | ||
logger_js.logger.groupEnd(); | ||
logger_js.logger.groupEnd(); | ||
} | ||
return response; | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
async _handleInstall(request, handler) { | ||
const response = await handler.fetchAndCachePut(request); // Any time there's no response, consider it a precaching error. | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
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) { | ||
// Throwing here will lead to the `install` handler failing, which | ||
// we want to do if *any* of the responses aren't safe to cache. | ||
throw new WorkboxError_js.WorkboxError('bad-precaching-response', { | ||
url: request.url, | ||
status: response.status | ||
}); | ||
} | ||
return response; | ||
} | ||
/** | ||
* Removes any URL search parameters that should be ignored. | ||
* Returns true if any users plugins were added containing their own | ||
* `cacheWillUpdate` callback. | ||
* | ||
* @param {URL} urlObject The original URL. | ||
* @param {Array<RegExp>} ignoreURLParametersMatching RegExps to test against | ||
* each search parameter name. Matches mean that the search parameter should be | ||
* ignored. | ||
* @return {URL} The URL with any ignored search parameters removed. | ||
* 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 | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) { | ||
// Convert the iterable into an array at the start of the loop to make sure | ||
// deletion doesn't mess up iteration. | ||
for (const paramName of [...urlObject.searchParams.keys()]) { | ||
if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) { | ||
urlObject.searchParams.delete(paramName); | ||
} | ||
} | ||
return urlObject; | ||
_usesCustomCacheableResponseLogic() { | ||
return this.plugins.some(plugin => plugin.cacheWillUpdate && plugin !== copyRedirectedCacheableResponsesPlugin); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Performs efficient precaching of assets. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
class PrecacheController { | ||
/** | ||
* Generator function that yields possible variations on the original URL to | ||
* check, one at a time. | ||
* Create a new PrecacheController. | ||
* | ||
* @param {string} url | ||
* @param {Object} options | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
* @param {Object} [options] | ||
* @param {string} [options.cacheName] The cache to use for precaching. | ||
* @param {string} [options.plugins] Plugins to use when precaching as well | ||
* as responding to fetch events for precached assets. | ||
* @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to | ||
* get the response from the network if there's a precache miss. | ||
*/ | ||
function* generateURLVariations(url, { | ||
ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], | ||
directoryIndex = 'index.html', | ||
cleanURLs = true, | ||
urlManipulation | ||
constructor({ | ||
cacheName, | ||
plugins = [], | ||
fallbackToNetwork = true | ||
} = {}) { | ||
const urlObject = new URL(url, location.href); | ||
urlObject.hash = ''; | ||
yield urlObject.href; | ||
const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching); | ||
yield urlWithoutIgnoredParams.href; | ||
this._urlsToCacheKeys = new Map(); | ||
this._urlsToCacheModes = new Map(); | ||
this._cacheKeysToIntegrities = new Map(); | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: cacheNames_js.cacheNames.getPrecacheName(cacheName), | ||
plugins: [...plugins, new PrecacheCacheKeyPlugin({ | ||
precacheController: this | ||
})], | ||
fallbackToNetwork | ||
}); // Bind the install and activate methods to the instance. | ||
if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) { | ||
const directoryURL = new URL(urlWithoutIgnoredParams.href); | ||
directoryURL.pathname += directoryIndex; | ||
yield directoryURL.href; | ||
} | ||
this.install = this.install.bind(this); | ||
this.activate = this.activate.bind(this); | ||
} | ||
/** | ||
* @type {module:workbox-precaching.PrecacheStrategy} The strategy created by this controller and | ||
* used to cache assets and respond to fetch events. | ||
*/ | ||
if (cleanURLs) { | ||
const cleanURL = new URL(urlWithoutIgnoredParams.href); | ||
cleanURL.pathname += '.html'; | ||
yield cleanURL.href; | ||
} | ||
if (urlManipulation) { | ||
const additionalURLs = urlManipulation({ | ||
url: urlObject | ||
}); | ||
for (const urlToAttempt of additionalURLs) { | ||
yield urlToAttempt.href; | ||
} | ||
} | ||
get strategy() { | ||
return this._strategy; | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Performs efficient precaching of assets. | ||
* Adds items to the precache list, removing any duplicates and | ||
* stores the files in the | ||
* ["precache cache"]{@link module:workbox-core.cacheNames} when the service | ||
* worker installs. | ||
* | ||
* @memberof module:workbox-precaching | ||
* This method can be called multiple times. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
*/ | ||
class PrecacheController { | ||
/** | ||
* Create a new PrecacheController. | ||
* | ||
* @param {string} [cacheName] An optional name for the cache, to override | ||
* the default precache name. | ||
*/ | ||
constructor(cacheName) { | ||
this._installed = false; | ||
this._plugins = []; | ||
this._cacheName = cacheNames_js.cacheNames.getPrecacheName(cacheName); | ||
this._urlsToCacheKeys = new Map(); | ||
this._urlsToCacheModes = new Map(); | ||
this._cacheKeysToIntegrities = new Map(); | ||
this._cacheKeyPlugin = { | ||
cacheKeyWillBeUsed: async ({ | ||
request, | ||
params | ||
}) => { | ||
const cacheKey = params && params.cacheKey || this.getCacheKeyForURL(request.url); | ||
return cacheKey || request; | ||
} | ||
}; | ||
} | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
*/ | ||
precache(entries) { | ||
this.addToCacheList(entries); | ||
addPlugins(plugins) { | ||
this._plugins.push(...plugins); | ||
if (!this._installAndActiveListenersAdded) { | ||
self.addEventListener('install', this.install); | ||
self.addEventListener('activate', this.activate); | ||
this._installAndActiveListenersAdded = true; | ||
} | ||
/** | ||
* Creates a Workbox `Route` to handle requests for precached assets (based | ||
* on the passed configuration options). | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` | ||
* will check cache entries for a URLs ending with '/' to see if there is a | ||
* hit when appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
*/ | ||
} | ||
/** | ||
* This method will add items to the precache list, removing duplicates | ||
* and ensuring the information is valid. | ||
* | ||
* @param {Array<module:workbox-precaching.PrecacheController.PrecacheEntry|string>} entries | ||
* Array of entries to precache. | ||
*/ | ||
addRoute(options) { | ||
if (!this._router) { | ||
const matchCallback = this.createMatchCallback(options); | ||
const handlerCallback = this.createHandler(true); | ||
const route = new Route_js.Route(matchCallback, handlerCallback); | ||
const router = new Router_js.Router(); | ||
router.registerRoute(route); | ||
router.addFetchListener(); | ||
router.addCacheListener(); | ||
this._router = router; | ||
} | ||
addToCacheList(entries) { | ||
{ | ||
assert_js.assert.isArray(entries, { | ||
moduleName: 'workbox-precaching', | ||
className: 'PrecacheController', | ||
funcName: 'addToCacheList', | ||
paramName: 'entries' | ||
}); | ||
} | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
* stores the files in the | ||
* ["precache cache"]{@link module:workbox-core.cacheNames} when the service | ||
* worker installs. | ||
* | ||
* This method can be called multiple times. | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.PreacheController#addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
*/ | ||
const urlsToWarnAbout = []; | ||
precache(entries) { | ||
this.addToCacheList(entries); | ||
if (!this._installed) { | ||
self.addEventListener('install', event => { | ||
event.waitUntil(this.install({ | ||
event | ||
})); | ||
}); | ||
self.addEventListener('activate', event => { | ||
event.waitUntil(this.activate()); | ||
}); | ||
this._installed = true; | ||
for (const entry of entries) { | ||
// See https://github.com/GoogleChrome/workbox/issues/2259 | ||
if (typeof entry === 'string') { | ||
urlsToWarnAbout.push(entry); | ||
} else if (entry && entry.revision === undefined) { | ||
urlsToWarnAbout.push(entry.url); | ||
} | ||
} | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.PrecacheController#precache} | ||
* and | ||
* [addRoute()]{@link module:workbox-precaching.PrecacheController#addRoute} | ||
* in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
const { | ||
cacheKey, | ||
url | ||
} = createCacheKey(entry); | ||
const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default'; | ||
precacheAndRoute(entries, options) { | ||
this.precache(entries); | ||
this.addRoute(options); | ||
} | ||
/** | ||
* This method will add items to the precache list, removing duplicates | ||
* and ensuring the information is valid. | ||
* | ||
* @param {Array<module:workbox-precaching.PrecacheController.PrecacheEntry|string>} entries | ||
* Array of entries to precache. | ||
*/ | ||
addToCacheList(entries) { | ||
{ | ||
assert_js.assert.isArray(entries, { | ||
moduleName: 'workbox-precaching', | ||
className: 'PrecacheController', | ||
funcName: 'addToCacheList', | ||
paramName: 'entries' | ||
if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-entries', { | ||
firstEntry: this._urlsToCacheKeys.get(url), | ||
secondEntry: cacheKey | ||
}); | ||
} | ||
const urlsToWarnAbout = []; | ||
for (const entry of entries) { | ||
// See https://github.com/GoogleChrome/workbox/issues/2259 | ||
if (typeof entry === 'string') { | ||
urlsToWarnAbout.push(entry); | ||
} else if (entry && entry.revision === undefined) { | ||
urlsToWarnAbout.push(entry.url); | ||
} | ||
const { | ||
cacheKey, | ||
url | ||
} = createCacheKey(entry); | ||
const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default'; | ||
if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-entries', { | ||
firstEntry: this._urlsToCacheKeys.get(url), | ||
secondEntry: cacheKey | ||
if (typeof entry !== 'string' && entry.integrity) { | ||
if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-integrities', { | ||
url | ||
}); | ||
} | ||
if (typeof entry !== 'string' && entry.integrity) { | ||
if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) { | ||
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-integrities', { | ||
url | ||
}); | ||
} | ||
this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); | ||
} | ||
this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); | ||
} | ||
this._urlsToCacheKeys.set(url, cacheKey); | ||
this._urlsToCacheKeys.set(url, cacheKey); | ||
this._urlsToCacheModes.set(url, cacheMode); | ||
this._urlsToCacheModes.set(url, cacheMode); | ||
if (urlsToWarnAbout.length > 0) { | ||
const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`; | ||
if (urlsToWarnAbout.length > 0) { | ||
const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`; | ||
{ | ||
logger_js.logger.warn(warningMessage); | ||
} | ||
{ | ||
logger_js.logger.warn(warningMessage); | ||
} | ||
} | ||
} | ||
/** | ||
* Precaches new and updated assets. Call this method from the service worker | ||
* install event. | ||
* | ||
* @param {Object} options | ||
* @param {Event} options.event The install event. | ||
* @param {Array<Object>} [options.plugins] Plugins to be used for fetching | ||
* and caching during install. | ||
* @return {Promise<module:workbox-precaching.InstallResult>} | ||
*/ | ||
} | ||
/** | ||
* Precaches new and updated assets. Call this method from the service worker | ||
* install event. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {Object} options | ||
* @param {Event} options.event The install event. | ||
* @return {Promise<module:workbox-precaching.InstallResult>} | ||
*/ | ||
async install({ | ||
event, | ||
plugins | ||
}) { | ||
{ | ||
if (plugins) { | ||
assert_js.assert.isArray(plugins, { | ||
moduleName: 'workbox-precaching', | ||
className: 'PrecacheController', | ||
funcName: 'install', | ||
paramName: 'plugins' | ||
}); | ||
} | ||
} | ||
install(event) { | ||
return waitUntil_js.waitUntil(event, async () => { | ||
const installReportPlugin = new PrecacheInstallReportPlugin(); | ||
this.strategy.plugins.push(installReportPlugin); // Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
if (plugins) { | ||
this.addPlugins(plugins); | ||
} | ||
const toBePrecached = []; | ||
const alreadyPrecached = []; | ||
const cache = await self.caches.open(this._cacheName); | ||
const alreadyCachedRequests = await cache.keys(); | ||
const existingCacheKeys = new Set(alreadyCachedRequests.map(request => request.url)); | ||
for (const [url, cacheKey] of this._urlsToCacheKeys) { | ||
if (existingCacheKeys.has(cacheKey)) { | ||
alreadyPrecached.push(url); | ||
} else { | ||
toBePrecached.push({ | ||
cacheKey, | ||
url | ||
}); | ||
} | ||
} // Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
for (const { | ||
cacheKey, | ||
url | ||
} of toBePrecached) { | ||
const integrity = this._cacheKeysToIntegrities.get(cacheKey); | ||
@@ -630,15 +583,23 @@ | ||
await this._addURLToCache({ | ||
cacheKey, | ||
cacheMode, | ||
event, | ||
const request = new Request(url, { | ||
integrity, | ||
url | ||
cache: cacheMode, | ||
credentials: 'same-origin' | ||
}); | ||
await Promise.all(this.strategy.handleAll({ | ||
params: { | ||
cacheKey | ||
}, | ||
request, | ||
event | ||
})); | ||
} | ||
const updatedURLs = toBePrecached.map(item => item.url); | ||
const { | ||
updatedURLs, | ||
notUpdatedURLs | ||
} = installReportPlugin; | ||
{ | ||
printInstallDetails(updatedURLs, alreadyPrecached); | ||
printInstallDetails(updatedURLs, notUpdatedURLs); | ||
} | ||
@@ -648,15 +609,21 @@ | ||
updatedURLs, | ||
notUpdatedURLs: alreadyPrecached | ||
notUpdatedURLs | ||
}; | ||
} | ||
/** | ||
* Deletes assets that are no longer present in the current precache manifest. | ||
* Call this method from the service worker activate event. | ||
* | ||
* @return {Promise<module:workbox-precaching.CleanupResult>} | ||
*/ | ||
}); | ||
} | ||
/** | ||
* Deletes assets that are no longer present in the current precache manifest. | ||
* Call this method from the service worker activate event. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {ExtendableEvent} | ||
* @return {Promise<module:workbox-precaching.CleanupResult>} | ||
*/ | ||
async activate() { | ||
const cache = await self.caches.open(this._cacheName); | ||
activate(event) { | ||
return waitUntil_js.waitUntil(event, async () => { | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
const currentlyCachedRequests = await cache.keys(); | ||
@@ -680,285 +647,251 @@ const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); | ||
}; | ||
} | ||
/** | ||
* Requests the entry and saves it to the cache if the response is valid. | ||
* By default, any response with a status code of less than 400 (including | ||
* opaque responses) is considered valid. | ||
* | ||
* If you need to use custom criteria to determine what's valid and what | ||
* isn't, then pass in an item in `options.plugins` that implements the | ||
* `cacheWillUpdate()` lifecycle event. | ||
* | ||
* @private | ||
* @param {Object} options | ||
* @param {string} options.cacheKey The string to use a cache key. | ||
* @param {string} options.url The URL to fetch and cache. | ||
* @param {Event} options.event The install event. | ||
* @param {string} [options.cacheMode] The cache mode for the network request. | ||
* @param {string} [options.integrity] The value to use for the `integrity` | ||
* field when making the request. | ||
*/ | ||
}); | ||
} | ||
/** | ||
* Returns a mapping of a precached URL to the corresponding cache key, taking | ||
* into account the revision information for the URL. | ||
* | ||
* @return {Map<string, string>} A URL to cache key mapping. | ||
*/ | ||
async _addURLToCache({ | ||
cacheKey, | ||
url, | ||
cacheMode, | ||
event, | ||
integrity | ||
}) { | ||
const request = new Request(url, { | ||
integrity, | ||
cache: cacheMode, | ||
credentials: 'same-origin' | ||
}); | ||
await Promise.all(this._getStrategy().handleAll({ | ||
params: { | ||
cacheKey | ||
}, | ||
request, | ||
event | ||
})); | ||
} | ||
/** | ||
* Returns a mapping of a precached URL to the corresponding cache key, taking | ||
* into account the revision information for the URL. | ||
* | ||
* @return {Map<string, string>} A URL to cache key mapping. | ||
*/ | ||
getURLsToCacheKeys() { | ||
return this._urlsToCacheKeys; | ||
} | ||
/** | ||
* Returns a list of all the URLs that have been precached by the current | ||
* service worker. | ||
* | ||
* @return {Array<string>} The precached URLs. | ||
*/ | ||
getURLsToCacheKeys() { | ||
return this._urlsToCacheKeys; | ||
} | ||
/** | ||
* Returns a list of all the URLs that have been precached by the current | ||
* service worker. | ||
* | ||
* @return {Array<string>} The precached URLs. | ||
*/ | ||
getCachedURLs() { | ||
return [...this._urlsToCacheKeys.keys()]; | ||
} | ||
/** | ||
* Returns the cache key used for storing a given URL. If that URL is | ||
* unversioned, like `/index.html', then the cache key will be the original | ||
* URL with a search parameter appended to it. | ||
* | ||
* @param {string} url A URL whose cache key you want to look up. | ||
* @return {string} The versioned URL that corresponds to a cache key | ||
* for the original URL, or undefined if that URL isn't precached. | ||
*/ | ||
getCachedURLs() { | ||
return [...this._urlsToCacheKeys.keys()]; | ||
} | ||
/** | ||
* Returns the cache key used for storing a given URL. If that URL is | ||
* unversioned, like `/index.html', then the cache key will be the original | ||
* URL with a search parameter appended to it. | ||
* | ||
* @param {string} url A URL whose cache key you want to look up. | ||
* @return {string} The versioned URL that corresponds to a cache key | ||
* for the original URL, or undefined if that URL isn't precached. | ||
*/ | ||
getCacheKeyForURL(url) { | ||
const urlObject = new URL(url, location.href); | ||
return this._urlsToCacheKeys.get(urlObject.href); | ||
} | ||
/** | ||
* This acts as a drop-in replacement for | ||
* [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) | ||
* with the following differences: | ||
* | ||
* - It knows what the name of the precache is, and only checks in that cache. | ||
* - It allows you to pass in an "original" URL without versioning parameters, | ||
* and it will automatically look up the correct cache key for the currently | ||
* active revision of that URL. | ||
* | ||
* E.g., `matchPrecache('index.html')` will find the correct precached | ||
* response for the currently active service worker, even if the actual cache | ||
* key is `'/index.html?__WB_REVISION__=1234abcd'`. | ||
* | ||
* @param {string|Request} request The key (without revisioning parameters) | ||
* to look up in the precache. | ||
* @return {Promise<Response|undefined>} | ||
*/ | ||
getCacheKeyForURL(url) { | ||
const urlObject = new URL(url, location.href); | ||
return this._urlsToCacheKeys.get(urlObject.href); | ||
async matchPrecache(request) { | ||
const url = request instanceof Request ? request.url : request; | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
if (cacheKey) { | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
return cache.match(cacheKey); | ||
} | ||
/** | ||
* This acts as a drop-in replacement for | ||
* [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match) | ||
* with the following differences: | ||
* | ||
* - It knows what the name of the precache is, and only checks in that cache. | ||
* - It allows you to pass in an "original" URL without versioning parameters, | ||
* and it will automatically look up the correct cache key for the currently | ||
* active revision of that URL. | ||
* | ||
* E.g., `matchPrecache('index.html')` will find the correct precached | ||
* response for the currently active service worker, even if the actual cache | ||
* key is `'/index.html?__WB_REVISION__=1234abcd'`. | ||
* | ||
* @param {string|Request} request The key (without revisioning parameters) | ||
* to look up in the precache. | ||
* @return {Promise<Response|undefined>} | ||
*/ | ||
return undefined; | ||
} | ||
/** | ||
* Returns a function that looks up `url` in the precache (taking into | ||
* account revision information), and returns the corresponding `Response`. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
async matchPrecache(request) { | ||
const url = request instanceof Request ? request.url : request; | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
if (cacheKey) { | ||
const cache = await self.caches.open(this._cacheName); | ||
return cache.match(cacheKey); | ||
} | ||
createHandlerBoundToURL(url) { | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
return undefined; | ||
if (!cacheKey) { | ||
throw new WorkboxError_js.WorkboxError('non-precached-url', { | ||
url | ||
}); | ||
} | ||
/** | ||
* Creates a [`matchCallback`]{@link module:workbox-precaching~matchCallback} | ||
* based on the passed configuration options) that with will identify | ||
* requests in the precache and return a respective `params` object | ||
* containing the `cacheKey` of the precached asset. | ||
* | ||
* This `cacheKey` can be used by a | ||
* [`handlerCallback`]{@link module:workbox-precaching~handlerCallback} | ||
* to get the precached asset from the cache. | ||
* | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
return options => { | ||
options.request = new Request(url); | ||
options.params = _extends({ | ||
cacheKey | ||
}, options.params); | ||
return this.strategy.handle(options); | ||
}; | ||
} | ||
createMatchCallback(options) { | ||
return ({ | ||
request | ||
}) => { | ||
const urlsToCacheKeys = this.getURLsToCacheKeys(); | ||
} | ||
for (const possibleURL of generateURLVariations(request.url, options)) { | ||
const cacheKey = urlsToCacheKeys.get(possibleURL); | ||
/* | ||
Copyright 2019 Google LLC | ||
if (cacheKey) { | ||
return { | ||
cacheKey | ||
}; | ||
} | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
let precacheController; | ||
/** | ||
* @return {PrecacheController} | ||
* @private | ||
*/ | ||
{ | ||
logger_js.logger.debug(`Precaching did not find a match for ` + getFriendlyURL_js.getFriendlyURL(request.url)); | ||
} | ||
const getOrCreatePrecacheController = () => { | ||
if (!precacheController) { | ||
precacheController = new PrecacheController(); | ||
} | ||
return; | ||
}; | ||
} | ||
/** | ||
* Returns a function that can be used within a | ||
* {@link module:workbox-routing.Route} that will find a response for the | ||
* incoming request against the precache. | ||
* | ||
* If for an unexpected reason there is a cache miss for the request, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
return precacheController; | ||
}; | ||
/* | ||
Copyright 2019 Google LLC | ||
createHandler(fallbackToNetwork = true) { | ||
return options => { | ||
const request = options.request instanceof Request ? options.request : new Request(options.request); | ||
options.params = options.params || {}; | ||
options.params.fallbackToNetwork = fallbackToNetwork; | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
if (!options.params.cacheKey) { | ||
options.params.cacheKey = this.getCacheKeyForURL(request.url); | ||
} | ||
function addPlugins(plugins) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.strategy.plugins.push(...plugins); | ||
} | ||
return this._getStrategy().handle(options); | ||
}; | ||
} | ||
/** | ||
* Returns a function that looks up `url` in the precache (taking into | ||
* account revision information), and returns the corresponding `Response`. | ||
* | ||
* If for an unexpected reason there is a cache miss when looking up `url`, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
/* | ||
Copyright 2018 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Removes any URL search parameters that should be ignored. | ||
* | ||
* @param {URL} urlObject The original URL. | ||
* @param {Array<RegExp>} ignoreURLParametersMatching RegExps to test against | ||
* each search parameter name. Matches mean that the search parameter should be | ||
* ignored. | ||
* @return {URL} The URL with any ignored search parameters removed. | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
createHandlerBoundToURL(url, fallbackToNetwork = true) { | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) { | ||
// Convert the iterable into an array at the start of the loop to make sure | ||
// deletion doesn't mess up iteration. | ||
for (const paramName of [...urlObject.searchParams.keys()]) { | ||
if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) { | ||
urlObject.searchParams.delete(paramName); | ||
} | ||
} | ||
if (!cacheKey) { | ||
throw new WorkboxError_js.WorkboxError('non-precached-url', { | ||
url | ||
}); | ||
} | ||
return urlObject; | ||
} | ||
const handler = this.createHandler(fallbackToNetwork); | ||
const request = new Request(url); | ||
return options => handler(Object.assign(options, { | ||
request | ||
})); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
_getStrategy() { | ||
// NOTE: this needs to be done lazily to match v5 behavior, since the | ||
// `addPlugins()` method can be called at any time. | ||
if (!this._strategy) { | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: this._cacheName, | ||
matchOptions: { | ||
ignoreSearch: true | ||
}, | ||
plugins: [this._cacheKeyPlugin, ...this._plugins] | ||
}); | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Generator function that yields possible variations on the original URL to | ||
* check, one at a time. | ||
* | ||
* @param {string} url | ||
* @param {Object} options | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
return this._strategy; | ||
} | ||
function* generateURLVariations(url, { | ||
ignoreURLParametersMatching = [/^utm_/, /^fbclid$/], | ||
directoryIndex = 'index.html', | ||
cleanURLs = true, | ||
urlManipulation | ||
} = {}) { | ||
const urlObject = new URL(url, location.href); | ||
urlObject.hash = ''; | ||
yield urlObject.href; | ||
const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching); | ||
yield urlWithoutIgnoredParams.href; | ||
if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) { | ||
const directoryURL = new URL(urlWithoutIgnoredParams.href); | ||
directoryURL.pathname += directoryIndex; | ||
yield directoryURL.href; | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
if (cleanURLs) { | ||
const cleanURL = new URL(urlWithoutIgnoredParams.href); | ||
cleanURL.pathname += '.html'; | ||
yield cleanURL.href; | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
let precacheController; | ||
/** | ||
* @return {PrecacheController} | ||
* @private | ||
*/ | ||
if (urlManipulation) { | ||
const additionalURLs = urlManipulation({ | ||
url: urlObject | ||
}); | ||
const getOrCreatePrecacheController = () => { | ||
if (!precacheController) { | ||
precacheController = new PrecacheController(); | ||
for (const urlToAttempt of additionalURLs) { | ||
yield urlToAttempt.href; | ||
} | ||
} | ||
} | ||
return precacheController; | ||
}; | ||
/* | ||
Copyright 2020 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* A subclass of [Route]{@link module:workbox-routing.Route} that takes a | ||
* [PrecacheController]{@link module:workbox-precaching.PrecacheController} | ||
* instance and uses it to match incoming requests and handle fetching | ||
* responses from the precache. | ||
* | ||
* @memberof module:workbox-precaching | ||
* @extends module:workbox-routing.Route | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
class PrecacheRoute extends Route_js.Route { | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function addPlugins(plugins) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addPlugins(plugins); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Add a `fetch` listener to the service worker that will | ||
* respond to | ||
* [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} | ||
* with precached assets. | ||
* | ||
* Requests for assets that aren't precached, the `FetchEvent` will not be | ||
* responded to, allowing the event to fall through to other `fetch` event | ||
* listeners. | ||
* | ||
* @param {Object} [options] | ||
* @param {PrecacheController} precacheController A `PrecacheController` | ||
* instance used to both match requests and respond to fetch events. | ||
* @param {Object} [options] Options to control how requests are matched | ||
* against the list of precached URLs. | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will | ||
@@ -974,317 +907,338 @@ * check cache entries for a URLs ending with '/' to see if there is a hit when | ||
* alternative URLs that should be checked for precache matches. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
constructor(precacheController, options) { | ||
const match = ({ | ||
request | ||
}) => { | ||
const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); | ||
function addRoute(options) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addRoute(options); | ||
for (const possibleURL of generateURLVariations(request.url, options)) { | ||
const cacheKey = urlsToCacheKeys.get(possibleURL); | ||
if (cacheKey) { | ||
return { | ||
cacheKey | ||
}; | ||
} | ||
} | ||
{ | ||
logger_js.logger.debug(`Precaching did not find a match for ` + getFriendlyURL_js.getFriendlyURL(request.url)); | ||
} | ||
return; | ||
}; | ||
super(match, precacheController.strategy); | ||
} | ||
/* | ||
Copyright 2018 Google LLC | ||
} | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
const SUBSTRING_TO_FIND = '-precache-'; | ||
/** | ||
* Cleans up incompatible precaches that were created by older versions of | ||
* Workbox, by a service worker registered under the current scope. | ||
* | ||
* This is meant to be called as part of the `activate` event. | ||
* | ||
* This should be safe to use as long as you don't include `substringToFind` | ||
* (defaulting to `-precache-`) in your non-precache cache names. | ||
* | ||
* @param {string} currentPrecacheName The cache name currently in use for | ||
* precaching. This cache won't be deleted. | ||
* @param {string} [substringToFind='-precache-'] Cache names which include this | ||
* substring will be deleted (excluding `currentPrecacheName`). | ||
* @return {Array<string>} A list of all the cache names that were deleted. | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Add a `fetch` listener to the service worker that will | ||
* respond to | ||
* [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests} | ||
* with precached assets. | ||
* | ||
* Requests for assets that aren't precached, the `FetchEvent` will not be | ||
* responded to, allowing the event to fall through to other `fetch` event | ||
* listeners. | ||
* | ||
* @param {Object} [options] See | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { | ||
const cacheNames = await self.caches.keys(); | ||
const cacheNamesToDelete = cacheNames.filter(cacheName => { | ||
return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; | ||
}); | ||
await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName))); | ||
return cacheNamesToDelete; | ||
}; | ||
function addRoute(options) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
const precacheRoute = new PrecacheRoute(precacheController, options); | ||
registerRoute_js.registerRoute(precacheRoute); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2018 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Adds an `activate` event listener which will clean up incompatible | ||
* precaches that were created by older versions of Workbox. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
const SUBSTRING_TO_FIND = '-precache-'; | ||
/** | ||
* Cleans up incompatible precaches that were created by older versions of | ||
* Workbox, by a service worker registered under the current scope. | ||
* | ||
* This is meant to be called as part of the `activate` event. | ||
* | ||
* This should be safe to use as long as you don't include `substringToFind` | ||
* (defaulting to `-precache-`) in your non-precache cache names. | ||
* | ||
* @param {string} currentPrecacheName The cache name currently in use for | ||
* precaching. This cache won't be deleted. | ||
* @param {string} [substringToFind='-precache-'] Cache names which include this | ||
* substring will be deleted (excluding `currentPrecacheName`). | ||
* @return {Array<string>} A list of all the cache names that were deleted. | ||
* | ||
* @private | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function cleanupOutdatedCaches() { | ||
// See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 | ||
self.addEventListener('activate', event => { | ||
const cacheName = cacheNames_js.cacheNames.getPrecacheName(); | ||
event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { | ||
{ | ||
if (cachesDeleted.length > 0) { | ||
logger_js.logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); | ||
} | ||
} | ||
})); | ||
}); | ||
} | ||
const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => { | ||
const cacheNames = await self.caches.keys(); | ||
const cacheNamesToDelete = cacheNames.filter(cacheName => { | ||
return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName; | ||
}); | ||
await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName))); | ||
return cacheNamesToDelete; | ||
}; | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Helper function that calls | ||
* {@link PrecacheController#createHandler} on the default | ||
* {@link PrecacheController} instance. | ||
* | ||
* If you are creating your own {@link PrecacheController}, then call the | ||
* {@link PrecacheController#createHandler} on that instance, | ||
* instead of using this function. | ||
* | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Adds an `activate` event listener which will clean up incompatible | ||
* precaches that were created by older versions of Workbox. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function createHandler(fallbackToNetwork = true) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.createHandler(fallbackToNetwork); | ||
} | ||
function cleanupOutdatedCaches() { | ||
// See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 | ||
self.addEventListener('activate', event => { | ||
const cacheName = cacheNames_js.cacheNames.getPrecacheName(); | ||
event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { | ||
{ | ||
if (cachesDeleted.length > 0) { | ||
logger_js.logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); | ||
} | ||
} | ||
})); | ||
}); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Helper function that calls | ||
* {@link PrecacheController#createHandlerBoundToURL} on the default | ||
* {@link PrecacheController} instance. | ||
* | ||
* If you are creating your own {@link PrecacheController}, then call the | ||
* {@link PrecacheController#createHandlerBoundToURL} on that instance, | ||
* instead of using this function. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Helper function that calls | ||
* {@link PrecacheController#createHandlerBoundToURL} on the default | ||
* {@link PrecacheController} instance. | ||
* | ||
* If you are creating your own {@link PrecacheController}, then call the | ||
* {@link PrecacheController#createHandlerBoundToURL} on that instance, | ||
* instead of using this function. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function createHandlerBoundToURL(url) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.createHandlerBoundToURL(url); | ||
} | ||
function createHandlerBoundToURL(url) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.createHandlerBoundToURL(url); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Takes in a URL, and returns the corresponding URL that could be used to | ||
* lookup the entry in the precache. | ||
* | ||
* If a relative URL is provided, the location of the service worker file will | ||
* be used as the base. | ||
* | ||
* For precached entries without revision information, the cache key will be the | ||
* same as the original URL. | ||
* | ||
* For precached entries with revision information, the cache key will be the | ||
* original URL with the addition of a query parameter used for keeping track of | ||
* the revision info. | ||
* | ||
* @param {string} url The URL whose cache key to look up. | ||
* @return {string} The cache key that corresponds to that URL. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Takes in a URL, and returns the corresponding URL that could be used to | ||
* lookup the entry in the precache. | ||
* | ||
* If a relative URL is provided, the location of the service worker file will | ||
* be used as the base. | ||
* | ||
* For precached entries without revision information, the cache key will be the | ||
* same as the original URL. | ||
* | ||
* For precached entries with revision information, the cache key will be the | ||
* original URL with the addition of a query parameter used for keeping track of | ||
* the revision info. | ||
* | ||
* @param {string} url The URL whose cache key to look up. | ||
* @return {string} The cache key that corresponds to that URL. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function getCacheKeyForURL(url) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.getCacheKeyForURL(url); | ||
} | ||
function getCacheKeyForURL(url) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.getCacheKeyForURL(url); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Helper function that calls | ||
* {@link PrecacheController#matchPrecache} on the default | ||
* {@link PrecacheController} instance. | ||
* | ||
* If you are creating your own {@link PrecacheController}, then call | ||
* {@link PrecacheController#matchPrecache} on that instance, | ||
* instead of using this function. | ||
* | ||
* @param {string|Request} request The key (without revisioning parameters) | ||
* to look up in the precache. | ||
* @return {Promise<Response|undefined>} | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Helper function that calls | ||
* {@link PrecacheController#matchPrecache} on the default | ||
* {@link PrecacheController} instance. | ||
* | ||
* If you are creating your own {@link PrecacheController}, then call | ||
* {@link PrecacheController#matchPrecache} on that instance, | ||
* instead of using this function. | ||
* | ||
* @param {string|Request} request The key (without revisioning parameters) | ||
* to look up in the precache. | ||
* @return {Promise<Response|undefined>} | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function matchPrecache(request) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.matchPrecache(request); | ||
} | ||
function matchPrecache(request) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.matchPrecache(request); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
* stores the files in the | ||
* ["precache cache"]{@link module:workbox-core.cacheNames} when the service | ||
* worker installs. | ||
* | ||
* This method can be called multiple times. | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
* stores the files in the | ||
* ["precache cache"]{@link module:workbox-core.cacheNames} when the service | ||
* worker installs. | ||
* | ||
* This method can be called multiple times. | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function precache(entries) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.precache(entries); | ||
} | ||
function precache(entries) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.precache(entries); | ||
} | ||
/* | ||
Copyright 2019 Google LLC | ||
/* | ||
Copyright 2019 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.precache} and | ||
* [addRoute()]{@link module:workbox-precaching.addRoute} in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.addRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.precache} and | ||
* [addRoute()]{@link module:workbox-precaching.addRoute} in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function precacheAndRoute(entries, options) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.precacheAndRoute(entries, options); | ||
} | ||
function precacheAndRoute(entries, options) { | ||
precache(entries); | ||
addRoute(options); | ||
} | ||
/* | ||
Copyright 2020 Google LLC | ||
/* | ||
Copyright 2020 Google LLC | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
Use of this source code is governed by an MIT-style | ||
license that can be found in the LICENSE file or at | ||
https://opensource.org/licenses/MIT. | ||
*/ | ||
/** | ||
* `PrecacheFallbackPlugin` allows you to specify an "offline fallback" | ||
* response to be used when a given strategy is unable to generate a response. | ||
* | ||
* It does this by intercepting the `handlerDidError` plugin callback | ||
* and returning a precached response, taking the expected revision parameter | ||
* into account automatically. | ||
* | ||
* Unless you explicitly pass in a `PrecacheController` instance to the | ||
* constructor, the default instance will be used. Generally speaking, most | ||
* developers will end up using the default. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
class PrecacheFallbackPlugin { | ||
/** | ||
* `PrecacheFallbackPlugin` allows you to specify an "offline fallback" | ||
* response to be used when a given strategy is unable to generate a response. | ||
* Constructs a new PrecacheFallbackPlugin with the associated fallbackURL. | ||
* | ||
* It does this by intercepting the `handlerDidError` plugin callback | ||
* and returning a precached response, taking the expected revision parameter | ||
* into account automatically. | ||
* | ||
* Unless you explicitly pass in a `PrecacheController` instance to the | ||
* constructor, the default instance will be used. Generally speaking, most | ||
* developers will end up using the default. | ||
* | ||
* @memberof module:workbox-precaching | ||
* @param {Object} config | ||
* @param {string} config.fallbackURL A precached URL to use as the fallback | ||
* if the associated strategy can't generate a response. | ||
* @param {PrecacheController} [config.precacheController] An optional | ||
* PrecacheController instance. If not provided, the default | ||
* PrecacheController will be used. | ||
*/ | ||
class PrecacheFallbackPlugin { | ||
constructor({ | ||
fallbackURL, | ||
precacheController | ||
}) { | ||
/** | ||
* Constructs a new PrecacheFallbackPlugin with the associated fallbackURL. | ||
* @return {Promise<Response>} The precache response for the fallback URL. | ||
* | ||
* @param {Object} config | ||
* @param {string} config.fallbackURL A precached URL to use as the fallback | ||
* if the associated strategy can't generate a response. | ||
* @param {PrecacheController} [config.precacheController] An optional | ||
* PrecacheController instance. If not provided, the default | ||
* PrecacheController will be used. | ||
* @private | ||
*/ | ||
constructor({ | ||
fallbackURL, | ||
precacheController | ||
}) { | ||
/** | ||
* @return {Promise<Response>} The precache response for the fallback URL. | ||
* | ||
* @private | ||
*/ | ||
this.handlerDidError = () => this._precacheController.matchPrecache(this._fallbackURL); | ||
this.handlerDidError = () => this._precacheController.matchPrecache(this._fallbackURL); | ||
this._fallbackURL = fallbackURL; | ||
this._precacheController = precacheController || getOrCreatePrecacheController(); | ||
} | ||
this._fallbackURL = fallbackURL; | ||
this._precacheController = precacheController || getOrCreatePrecacheController(); | ||
} | ||
exports.PrecacheController = PrecacheController; | ||
exports.PrecacheFallbackPlugin = PrecacheFallbackPlugin; | ||
exports.addPlugins = addPlugins; | ||
exports.addRoute = addRoute; | ||
exports.cleanupOutdatedCaches = cleanupOutdatedCaches; | ||
exports.createHandler = createHandler; | ||
exports.createHandlerBoundToURL = createHandlerBoundToURL; | ||
exports.getCacheKeyForURL = getCacheKeyForURL; | ||
exports.matchPrecache = matchPrecache; | ||
exports.precache = precache; | ||
exports.precacheAndRoute = precacheAndRoute; | ||
} | ||
return exports; | ||
exports.PrecacheController = PrecacheController; | ||
exports.PrecacheFallbackPlugin = PrecacheFallbackPlugin; | ||
exports.PrecacheRoute = PrecacheRoute; | ||
exports.PrecacheStrategy = PrecacheStrategy; | ||
exports.addPlugins = addPlugins; | ||
exports.addRoute = addRoute; | ||
exports.cleanupOutdatedCaches = cleanupOutdatedCaches; | ||
exports.createHandlerBoundToURL = createHandlerBoundToURL; | ||
exports.getCacheKeyForURL = getCacheKeyForURL; | ||
exports.matchPrecache = matchPrecache; | ||
exports.precache = precache; | ||
exports.precacheAndRoute = precacheAndRoute; | ||
}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.routing, workbox.routing, workbox.core, workbox.strategies)); | ||
return exports; | ||
}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core, workbox.core._private, workbox.strategies, workbox.routing, workbox.routing)); | ||
//# sourceMappingURL=workbox-precaching.dev.js.map |
@@ -1,2 +0,2 @@ | ||
this.workbox=this.workbox||{},this.workbox.precaching=function(t,e,n,s,i,c,r){"use strict";try{self["workbox:precaching:6.0.0-alpha.1"]&&_()}catch(t){}function o(t){if(!t)throw new n.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:s}=t;if(!s)throw new n.WorkboxError("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(s,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(s,location.href),c=new URL(s,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:c.href}}const a={cacheWillUpdate:async({response:t})=>t.redirected?await c.copyResponse(t):t};class h extends r.Strategy{constructor(t){super(t),this.plugins.push(a)}t(t,e){return e.event&&"install"===e.event.type?this.s(t,e):this.i(t,e)}async i(t,e){let s=await e.cacheMatch(t);if(!s){if(e.params&&!1===e.params.fallbackToNetwork)throw new n.WorkboxError("missing-precache-entry",{cacheName:this.cacheName,url:t.url});s=await e.fetch(t)}return s}async s(t,e){const s=await e.fetchAndCachePut(t);let i=Boolean(s);if(s&&s.status>=400&&!this.o()&&(i=!1),!i)throw new n.WorkboxError("bad-precaching-response",{url:t.url,status:s.status});return s}o(){return this.plugins.some(t=>t.cacheWillUpdate&&t!==a)}}class l{constructor(t){this.h=!1,this.l=[],this.u=e.cacheNames.getPrecacheName(t),this.p=new Map,this.R=new Map,this.g=new Map,this.L={cacheKeyWillBeUsed:async({request:t,params:e})=>e&&e.cacheKey||this.getCacheKeyForURL(t.url)||t}}addPlugins(t){this.l.push(...t)}addRoute(t){if(!this.U){const e=this.createMatchCallback(t),n=this.createHandler(!0),c=new s.Route(e,n),r=new i.Router;r.registerRoute(c),r.addFetchListener(),r.addCacheListener(),this.U=r}}precache(t){this.addToCacheList(t),this.h||(self.addEventListener("install",t=>{t.waitUntil(this.install({event:t}))}),self.addEventListener("activate",t=>{t.waitUntil(this.activate())}),this.h=!0)}precacheAndRoute(t,e){this.precache(t),this.addRoute(e)}addToCacheList(t){const e=[];for(const s of t){"string"==typeof s?e.push(s):s&&void 0===s.revision&&e.push(s.url);const{cacheKey:t,url:i}=o(s),c="string"!=typeof s&&s.revision?"reload":"default";if(this.p.has(i)&&this.p.get(i)!==t)throw new n.WorkboxError("add-to-cache-list-conflicting-entries",{firstEntry:this.p.get(i),secondEntry:t});if("string"!=typeof s&&s.integrity){if(this.g.has(t)&&this.g.get(t)!==s.integrity)throw new n.WorkboxError("add-to-cache-list-conflicting-integrities",{url:i});this.g.set(t,s.integrity)}if(this.p.set(i,t),this.R.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)}}}async install({event:t,plugins:e}){e&&this.addPlugins(e);const n=[],s=[],i=await self.caches.open(this.u),c=await i.keys(),r=new Set(c.map(t=>t.url));for(const[t,e]of this.p)r.has(e)?s.push(t):n.push({cacheKey:e,url:t});for(const{cacheKey:e,url:s}of n){const n=this.g.get(e),i=this.R.get(s);await this.m({cacheKey:e,cacheMode:i,event:t,integrity:n,url:s})}return{updatedURLs:n.map(t=>t.url),notUpdatedURLs:s}}async activate(){const t=await self.caches.open(this.u),e=await t.keys(),n=new Set(this.p.values()),s=[];for(const i of e)n.has(i.url)||(await t.delete(i),s.push(i.url));return{deletedURLs:s}}async m({cacheKey:t,url:e,cacheMode:n,event:s,integrity:i}){const c=new Request(e,{integrity:i,cache:n,credentials:"same-origin"});await Promise.all(this.K().handleAll({params:{cacheKey:t},request:c,event:s}))}getURLsToCacheKeys(){return this.p}getCachedURLs(){return[...this.p.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.p.get(e.href)}async matchPrecache(t){const e=t instanceof Request?t.url:t,n=this.getCacheKeyForURL(e);if(n){return(await self.caches.open(this.u)).match(n)}}createMatchCallback(t){return({request:e})=>{const n=this.getURLsToCacheKeys();for(const s of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:n="index.html",cleanURLs:s=!0,urlManipulation:i}={}){const c=new URL(t,location.href);c.hash="",yield c.href;const r=function(t,e=[]){for(const n of[...t.searchParams.keys()])e.some(t=>t.test(n))&&t.searchParams.delete(n);return t}(c,e);if(yield r.href,n&&r.pathname.endsWith("/")){const t=new URL(r.href);t.pathname+=n,yield t.href}if(s){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}}(e.url,t)){const t=n.get(s);if(t)return{cacheKey:t}}}}createHandler(t=!0){return e=>{const n=e.request instanceof Request?e.request:new Request(e.request);return e.params=e.params||{},e.params.fallbackToNetwork=t,e.params.cacheKey||(e.params.cacheKey=this.getCacheKeyForURL(n.url)),this.K().handle(e)}}createHandlerBoundToURL(t,e=!0){if(!this.getCacheKeyForURL(t))throw new n.WorkboxError("non-precached-url",{url:t});const s=this.createHandler(e),i=new Request(t);return t=>s(Object.assign(t,{request:i}))}K(){return this._||(this._=new h({cacheName:this.u,matchOptions:{ignoreSearch:!0},plugins:[this.L,...this.l]})),this._}}let u;const f=()=>(u||(u=new l),u);return t.PrecacheController=l,t.PrecacheFallbackPlugin=class{constructor({fallbackURL:t,precacheController:e}){this.handlerDidError=()=>this.v.matchPrecache(this.k),this.k=t,this.v=e||f()}},t.addPlugins=function(t){return f().addPlugins(t)},t.addRoute=function(t){return f().addRoute(t)},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const n=e.cacheNames.getPrecacheName();t.waitUntil((async(t,e="-precache-")=>{const n=(await self.caches.keys()).filter(n=>n.includes(e)&&n.includes(self.registration.scope)&&n!==t);return await Promise.all(n.map(t=>self.caches.delete(t))),n})(n).then(t=>{}))})},t.createHandler=function(t=!0){return f().createHandler(t)},t.createHandlerBoundToURL=function(t){return f().createHandlerBoundToURL(t)},t.getCacheKeyForURL=function(t){return f().getCacheKeyForURL(t)},t.matchPrecache=function(t){return f().matchPrecache(t)},t.precache=function(t){f().precache(t)},t.precacheAndRoute=function(t,e){f().precacheAndRoute(t,e)},t}({},workbox.core._private,workbox.core._private,workbox.routing,workbox.routing,workbox.core,workbox.strategies); | ||
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.0-alpha.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.t.getCacheKeyForURL(t.url);return s?new Request(s):t},this.t=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.i=!1!==t.fallbackToNetwork,this.plugins.push(f)}async o(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.h(t,e):await this.l(t,e))}async l(t,e){let n;if(!this.i)throw new s.WorkboxError("missing-precache-entry",{cacheName:this.cacheName,url:t.url});return n=await e.fetch(t),n}async h(t,e){const n=await e.fetchAndCachePut(t);let i=Boolean(n);if(n&&n.status>=400&&!this.u()&&(i=!1),!i)throw new s.WorkboxError("bad-precaching-response",{url:t.url,status:n.status});return n}u(){return this.plugins.some((t=>t.cacheWillUpdate&&t!==f))}}class d{constructor({cacheName:t,plugins:s=[],fallbackToNetwork:n=!0}={}){this.p=new Map,this.R=new Map,this.L=new Map,this.U=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.U}precache(t){this.addToCacheList(t),this.g||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.g=!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.p.has(i)&&this.p.get(i)!==t)throw new s.WorkboxError("add-to-cache-list-conflicting-entries",{firstEntry:this.p.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.L.has(t)&&this.L.get(t)!==n.integrity)throw new s.WorkboxError("add-to-cache-list-conflicting-integrities",{url:i});this.L.set(t,n.integrity)}if(this.p.set(i,t),this.R.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.p){const n=this.L.get(s),i=this.R.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.p.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.p}getCachedURLs(){return[...this.p.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.p.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.t.matchPrecache(this.m),this.m=t,this.t=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); | ||
//# sourceMappingURL=workbox-precaching.prod.js.map |
import { addPlugins } from './addPlugins.js'; | ||
import { addRoute } from './addRoute.js'; | ||
import { cleanupOutdatedCaches } from './cleanupOutdatedCaches.js'; | ||
import { createHandler } from './createHandler.js'; | ||
import { createHandlerBoundToURL } from './createHandlerBoundToURL.js'; | ||
@@ -11,2 +10,4 @@ import { getCacheKeyForURL } from './getCacheKeyForURL.js'; | ||
import { PrecacheController } from './PrecacheController.js'; | ||
import { PrecacheRoute } from './PrecacheRoute.js'; | ||
import { PrecacheStrategy } from './PrecacheStrategy.js'; | ||
import { PrecacheFallbackPlugin } from './PrecacheFallbackPlugin.js'; | ||
@@ -17,11 +18,11 @@ import './_version.js'; | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute} | ||
* method to add assets to the Cache and respond to network requests with these | ||
* method to add assets to the cache and respond to network requests with these | ||
* cached assets. | ||
* | ||
* If you require finer grained control, you can use the | ||
* If you require more control over caching and routing, you can use the | ||
* [PrecacheController]{@link module:workbox-precaching.PrecacheController} | ||
* to determine when performed. | ||
* interface. | ||
* | ||
* @module workbox-precaching | ||
*/ | ||
export { addPlugins, addRoute, cleanupOutdatedCaches, createHandler, createHandlerBoundToURL, getCacheKeyForURL, matchPrecache, precache, precacheAndRoute, PrecacheController, PrecacheFallbackPlugin, }; | ||
export { addPlugins, addRoute, cleanupOutdatedCaches, createHandlerBoundToURL, getCacheKeyForURL, matchPrecache, precache, precacheAndRoute, PrecacheController, PrecacheRoute, PrecacheStrategy, PrecacheFallbackPlugin, }; |
11
index.js
@@ -11,3 +11,2 @@ /* | ||
import { cleanupOutdatedCaches } from './cleanupOutdatedCaches.js'; | ||
import { createHandler } from './createHandler.js'; | ||
import { createHandlerBoundToURL } from './createHandlerBoundToURL.js'; | ||
@@ -19,2 +18,4 @@ import { getCacheKeyForURL } from './getCacheKeyForURL.js'; | ||
import { PrecacheController } from './PrecacheController.js'; | ||
import { PrecacheRoute } from './PrecacheRoute.js'; | ||
import { PrecacheStrategy } from './PrecacheStrategy.js'; | ||
import { PrecacheFallbackPlugin } from './PrecacheFallbackPlugin.js'; | ||
@@ -25,11 +26,11 @@ import './_version.js'; | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute} | ||
* method to add assets to the Cache and respond to network requests with these | ||
* method to add assets to the cache and respond to network requests with these | ||
* cached assets. | ||
* | ||
* If you require finer grained control, you can use the | ||
* If you require more control over caching and routing, you can use the | ||
* [PrecacheController]{@link module:workbox-precaching.PrecacheController} | ||
* to determine when performed. | ||
* interface. | ||
* | ||
* @module workbox-precaching | ||
*/ | ||
export { addPlugins, addRoute, cleanupOutdatedCaches, createHandler, createHandlerBoundToURL, getCacheKeyForURL, matchPrecache, precache, precacheAndRoute, PrecacheController, PrecacheFallbackPlugin, }; | ||
export { addPlugins, addRoute, cleanupOutdatedCaches, createHandlerBoundToURL, getCacheKeyForURL, matchPrecache, precache, precacheAndRoute, PrecacheController, PrecacheRoute, PrecacheStrategy, PrecacheFallbackPlugin, }; |
{ | ||
"name": "workbox-precaching", | ||
"version": "6.0.0-alpha.2", | ||
"version": "6.0.0-alpha.3", | ||
"license": "MIT", | ||
@@ -24,7 +24,7 @@ "author": "Google's Web DevRel Team", | ||
"dependencies": { | ||
"workbox-core": "^6.0.0-alpha.2", | ||
"workbox-routing": "^6.0.0-alpha.2", | ||
"workbox-strategies": "^6.0.0-alpha.2" | ||
"workbox-core": "^6.0.0-alpha.3", | ||
"workbox-routing": "^6.0.0-alpha.3", | ||
"workbox-strategies": "^6.0.0-alpha.3" | ||
}, | ||
"gitHead": "45f41a2d2f9870c49837923bb5c5854917da3a08" | ||
"gitHead": "00ba07467b253751e874f53f424f2adb1c06e176" | ||
} |
@@ -1,2 +0,2 @@ | ||
import { FetchListenerOptions, PrecacheEntry } from './_types.js'; | ||
import { PrecacheRouteOptions, PrecacheEntry } from './_types.js'; | ||
import './_version.js'; | ||
@@ -13,7 +13,7 @@ /** | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.addRoute}. | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
declare function precacheAndRoute(entries: Array<PrecacheEntry | string>, options?: FetchListenerOptions): void; | ||
declare function precacheAndRoute(entries: Array<PrecacheEntry | string>, options?: PrecacheRouteOptions): void; | ||
export { precacheAndRoute }; |
@@ -8,3 +8,4 @@ /* | ||
*/ | ||
import { getOrCreatePrecacheController } from './utils/getOrCreatePrecacheController.js'; | ||
import { addRoute } from './addRoute.js'; | ||
import { precache } from './precache.js'; | ||
import './_version.js'; | ||
@@ -21,3 +22,3 @@ /** | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.addRoute}. | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
@@ -27,5 +28,5 @@ * @memberof module:workbox-precaching | ||
function precacheAndRoute(entries, options) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.precacheAndRoute(entries, options); | ||
precache(entries); | ||
addRoute(options); | ||
} | ||
export { precacheAndRoute }; |
@@ -1,4 +0,4 @@ | ||
import { RouteMatchCallbackOptions, RouteHandlerCallback, WorkboxPlugin } from 'workbox-core/types.js'; | ||
import { Strategy } from 'workbox-strategies/Strategy.js'; | ||
import { PrecacheEntry, FetchListenerOptions } from './_types.js'; | ||
import { RouteHandlerCallback, WorkboxPlugin } from 'workbox-core/types.js'; | ||
import { PrecacheEntry } from './_types.js'; | ||
import './_version.js'; | ||
@@ -10,2 +10,7 @@ declare global { | ||
} | ||
interface PrecacheControllerOptions { | ||
cacheName?: string; | ||
plugins?: WorkboxPlugin[]; | ||
fallbackToNetwork?: boolean; | ||
} | ||
/** | ||
@@ -17,42 +22,24 @@ * Performs efficient precaching of assets. | ||
declare class PrecacheController { | ||
private readonly _cacheName; | ||
private _installAndActiveListenersAdded?; | ||
private readonly _strategy; | ||
private readonly _urlsToCacheKeys; | ||
private readonly _urlsToCacheModes; | ||
private readonly _cacheKeysToIntegrities; | ||
private _router?; | ||
private _strategy?; | ||
private _installed?; | ||
private readonly _cacheKeyPlugin; | ||
private readonly _plugins; | ||
/** | ||
* Create a new PrecacheController. | ||
* | ||
* @param {string} [cacheName] An optional name for the cache, to override | ||
* the default precache name. | ||
* @param {Object} [options] | ||
* @param {string} [options.cacheName] The cache to use for precaching. | ||
* @param {string} [options.plugins] Plugins to use when precaching as well | ||
* as responding to fetch events for precached assets. | ||
* @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to | ||
* get the response from the network if there's a precache miss. | ||
*/ | ||
constructor(cacheName?: string); | ||
constructor({ cacheName, plugins, fallbackToNetwork }?: PrecacheControllerOptions); | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
* @type {module:workbox-precaching.PrecacheStrategy} The strategy created by this controller and | ||
* used to cache assets and respond to fetch events. | ||
*/ | ||
addPlugins(plugins: WorkboxPlugin[]): void; | ||
get strategy(): Strategy; | ||
/** | ||
* Creates a Workbox `Route` to handle requests for precached assets (based | ||
* on the passed configuration options). | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` | ||
* will check cache entries for a URLs ending with '/' to see if there is a | ||
* hit when appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
*/ | ||
addRoute(options?: FetchListenerOptions): void; | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
@@ -65,9 +52,2 @@ * stores the files in the | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.PreacheController#addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
@@ -77,17 +57,2 @@ */ | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.PrecacheController#precache} | ||
* and | ||
* [addRoute()]{@link module:workbox-precaching.PrecacheController#addRoute} | ||
* in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
precacheAndRoute(entries: Array<PrecacheEntry | string>, options?: FetchListenerOptions): void; | ||
/** | ||
* This method will add items to the precache list, removing duplicates | ||
@@ -104,15 +69,10 @@ * and ensuring the information is valid. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {Object} options | ||
* @param {Event} options.event The install event. | ||
* @param {Array<Object>} [options.plugins] Plugins to be used for fetching | ||
* and caching during install. | ||
* @return {Promise<module:workbox-precaching.InstallResult>} | ||
*/ | ||
install({ event, plugins }: { | ||
event: ExtendableEvent; | ||
plugins?: WorkboxPlugin[]; | ||
}): Promise<{ | ||
updatedURLs: string[]; | ||
notUpdatedURLs: string[]; | ||
}>; | ||
install(event: ExtendableEvent): Promise<any>; | ||
/** | ||
@@ -122,33 +82,10 @@ * Deletes assets that are no longer present in the current precache manifest. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {ExtendableEvent} | ||
* @return {Promise<module:workbox-precaching.CleanupResult>} | ||
*/ | ||
activate(): Promise<{ | ||
deletedURLs: string[]; | ||
}>; | ||
activate(event: ExtendableEvent): Promise<any>; | ||
/** | ||
* Requests the entry and saves it to the cache if the response is valid. | ||
* By default, any response with a status code of less than 400 (including | ||
* opaque responses) is considered valid. | ||
* | ||
* If you need to use custom criteria to determine what's valid and what | ||
* isn't, then pass in an item in `options.plugins` that implements the | ||
* `cacheWillUpdate()` lifecycle event. | ||
* | ||
* @private | ||
* @param {Object} options | ||
* @param {string} options.cacheKey The string to use a cache key. | ||
* @param {string} options.url The URL to fetch and cache. | ||
* @param {Event} options.event The install event. | ||
* @param {string} [options.cacheMode] The cache mode for the network request. | ||
* @param {string} [options.integrity] The value to use for the `integrity` | ||
* field when making the request. | ||
*/ | ||
_addURLToCache({ cacheKey, url, cacheMode, event, integrity }: { | ||
cacheKey: string; | ||
url: string; | ||
cacheMode: "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached" | undefined; | ||
event: ExtendableEvent; | ||
integrity?: string; | ||
}): Promise<void>; | ||
/** | ||
* Returns a mapping of a precached URL to the corresponding cache key, taking | ||
@@ -197,48 +134,11 @@ * into account the revision information for the URL. | ||
/** | ||
* Creates a [`matchCallback`]{@link module:workbox-precaching~matchCallback} | ||
* based on the passed configuration options) that with will identify | ||
* requests in the precache and return a respective `params` object | ||
* containing the `cacheKey` of the precached asset. | ||
* | ||
* This `cacheKey` can be used by a | ||
* [`handlerCallback`]{@link module:workbox-precaching~handlerCallback} | ||
* to get the precached asset from the cache. | ||
* | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
createMatchCallback(options?: FetchListenerOptions): ({ request }: RouteMatchCallbackOptions) => { | ||
cacheKey: string; | ||
} | undefined; | ||
/** | ||
* Returns a function that can be used within a | ||
* {@link module:workbox-routing.Route} that will find a response for the | ||
* incoming request against the precache. | ||
* | ||
* If for an unexpected reason there is a cache miss for the request, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandler(fallbackToNetwork?: boolean): RouteHandlerCallback; | ||
/** | ||
* Returns a function that looks up `url` in the precache (taking into | ||
* account revision information), and returns the corresponding `Response`. | ||
* | ||
* If for an unexpected reason there is a cache miss when looking up `url`, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandlerBoundToURL(url: string, fallbackToNetwork?: boolean): RouteHandlerCallback; | ||
_getStrategy(): Strategy; | ||
createHandlerBoundToURL(url: string): RouteHandlerCallback; | ||
} | ||
export { PrecacheController }; |
@@ -10,12 +10,11 @@ /* | ||
import { cacheNames } from 'workbox-core/_private/cacheNames.js'; | ||
import { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js'; | ||
import { logger } from 'workbox-core/_private/logger.js'; | ||
import { WorkboxError } from 'workbox-core/_private/WorkboxError.js'; | ||
import { Route } from 'workbox-routing/Route.js'; | ||
import { Router } from 'workbox-routing/Router.js'; | ||
import { waitUntil } from 'workbox-core/_private/waitUntil.js'; | ||
import { createCacheKey } from './utils/createCacheKey.js'; | ||
import { PrecacheStrategy } from './utils/PrecacheStrategy.js'; | ||
import { PrecacheInstallReportPlugin } from './utils/PrecacheInstallReportPlugin.js'; | ||
import { PrecacheCacheKeyPlugin } from './utils/PrecacheCacheKeyPlugin.js'; | ||
import { printCleanupDetails } from './utils/printCleanupDetails.js'; | ||
import { printInstallDetails } from './utils/printInstallDetails.js'; | ||
import { generateURLVariations } from './utils/generateURLVariations.js'; | ||
import { PrecacheStrategy } from './PrecacheStrategy.js'; | ||
import './_version.js'; | ||
@@ -31,57 +30,33 @@ /** | ||
* | ||
* @param {string} [cacheName] An optional name for the cache, to override | ||
* the default precache name. | ||
* @param {Object} [options] | ||
* @param {string} [options.cacheName] The cache to use for precaching. | ||
* @param {string} [options.plugins] Plugins to use when precaching as well | ||
* as responding to fetch events for precached assets. | ||
* @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to | ||
* get the response from the network if there's a precache miss. | ||
*/ | ||
constructor(cacheName) { | ||
this._installed = false; | ||
this._plugins = []; | ||
this._cacheName = cacheNames.getPrecacheName(cacheName); | ||
constructor({ cacheName, plugins = [], fallbackToNetwork = true } = {}) { | ||
this._urlsToCacheKeys = new Map(); | ||
this._urlsToCacheModes = new Map(); | ||
this._cacheKeysToIntegrities = new Map(); | ||
this._cacheKeyPlugin = { | ||
cacheKeyWillBeUsed: async ({ request, params }) => { | ||
const cacheKey = params && params.cacheKey || | ||
this.getCacheKeyForURL(request.url); | ||
return cacheKey || request; | ||
}, | ||
}; | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: cacheNames.getPrecacheName(cacheName), | ||
plugins: [ | ||
...plugins, | ||
new PrecacheCacheKeyPlugin({ precacheController: this }), | ||
], | ||
fallbackToNetwork, | ||
}); | ||
// Bind the install and activate methods to the instance. | ||
this.install = this.install.bind(this); | ||
this.activate = this.activate.bind(this); | ||
} | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
* @type {module:workbox-precaching.PrecacheStrategy} The strategy created by this controller and | ||
* used to cache assets and respond to fetch events. | ||
*/ | ||
addPlugins(plugins) { | ||
this._plugins.push(...plugins); | ||
get strategy() { | ||
return this._strategy; | ||
} | ||
/** | ||
* Creates a Workbox `Route` to handle requests for precached assets (based | ||
* on the passed configuration options). | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` | ||
* will check cache entries for a URLs ending with '/' to see if there is a | ||
* hit when appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
*/ | ||
addRoute(options) { | ||
if (!this._router) { | ||
const matchCallback = this.createMatchCallback(options); | ||
const handlerCallback = this.createHandler(true); | ||
const route = new Route(matchCallback, handlerCallback); | ||
const router = new Router(); | ||
router.registerRoute(route); | ||
router.addFetchListener(); | ||
router.addCacheListener(); | ||
this._router = router; | ||
} | ||
} | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
@@ -94,9 +69,2 @@ * stores the files in the | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.PreacheController#addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
@@ -106,31 +74,9 @@ */ | ||
this.addToCacheList(entries); | ||
if (!this._installed) { | ||
self.addEventListener('install', (event) => { | ||
event.waitUntil(this.install({ event })); | ||
}); | ||
self.addEventListener('activate', (event) => { | ||
event.waitUntil(this.activate()); | ||
}); | ||
this._installed = true; | ||
if (!this._installAndActiveListenersAdded) { | ||
self.addEventListener('install', this.install); | ||
self.addEventListener('activate', this.activate); | ||
this._installAndActiveListenersAdded = true; | ||
} | ||
} | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.PrecacheController#precache} | ||
* and | ||
* [addRoute()]{@link module:workbox-precaching.PrecacheController#addRoute} | ||
* in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
precacheAndRoute(entries, options) { | ||
this.precache(entries); | ||
this.addRoute(options); | ||
} | ||
/** | ||
* This method will add items to the precache list, removing duplicates | ||
@@ -200,56 +146,35 @@ * and ensuring the information is valid. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {Object} options | ||
* @param {Event} options.event The install event. | ||
* @param {Array<Object>} [options.plugins] Plugins to be used for fetching | ||
* and caching during install. | ||
* @return {Promise<module:workbox-precaching.InstallResult>} | ||
*/ | ||
async install({ event, plugins }) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (plugins) { | ||
assert.isArray(plugins, { | ||
moduleName: 'workbox-precaching', | ||
className: 'PrecacheController', | ||
funcName: 'install', | ||
paramName: 'plugins', | ||
install(event) { | ||
return waitUntil(event, async () => { | ||
const installReportPlugin = new PrecacheInstallReportPlugin(); | ||
this.strategy.plugins.push(installReportPlugin); | ||
// Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
for (const [url, cacheKey] of this._urlsToCacheKeys) { | ||
const integrity = this._cacheKeysToIntegrities.get(cacheKey); | ||
const cacheMode = this._urlsToCacheModes.get(url); | ||
const request = new Request(url, { | ||
integrity, | ||
cache: cacheMode, | ||
credentials: 'same-origin', | ||
}); | ||
await Promise.all(this.strategy.handleAll({ | ||
params: { cacheKey }, | ||
request, | ||
event, | ||
})); | ||
} | ||
} | ||
if (plugins) { | ||
this.addPlugins(plugins); | ||
} | ||
const toBePrecached = []; | ||
const alreadyPrecached = []; | ||
const cache = await self.caches.open(this._cacheName); | ||
const alreadyCachedRequests = await cache.keys(); | ||
const existingCacheKeys = new Set(alreadyCachedRequests.map((request) => request.url)); | ||
for (const [url, cacheKey] of this._urlsToCacheKeys) { | ||
if (existingCacheKeys.has(cacheKey)) { | ||
alreadyPrecached.push(url); | ||
const { updatedURLs, notUpdatedURLs } = installReportPlugin; | ||
if (process.env.NODE_ENV !== 'production') { | ||
printInstallDetails(updatedURLs, notUpdatedURLs); | ||
} | ||
else { | ||
toBePrecached.push({ cacheKey, url }); | ||
} | ||
} | ||
// Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
for (const { cacheKey, url } of toBePrecached) { | ||
const integrity = this._cacheKeysToIntegrities.get(cacheKey); | ||
const cacheMode = this._urlsToCacheModes.get(url); | ||
await this._addURLToCache({ | ||
cacheKey, | ||
cacheMode, | ||
event, | ||
integrity, | ||
url, | ||
}); | ||
} | ||
const updatedURLs = toBePrecached.map((item) => item.url); | ||
if (process.env.NODE_ENV !== 'production') { | ||
printInstallDetails(updatedURLs, alreadyPrecached); | ||
} | ||
return { | ||
updatedURLs, | ||
notUpdatedURLs: alreadyPrecached, | ||
}; | ||
return { updatedURLs, notUpdatedURLs }; | ||
}); | ||
} | ||
@@ -260,49 +185,25 @@ /** | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {ExtendableEvent} | ||
* @return {Promise<module:workbox-precaching.CleanupResult>} | ||
*/ | ||
async activate() { | ||
const cache = await self.caches.open(this._cacheName); | ||
const currentlyCachedRequests = await cache.keys(); | ||
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); | ||
const deletedURLs = []; | ||
for (const request of currentlyCachedRequests) { | ||
if (!expectedCacheKeys.has(request.url)) { | ||
await cache.delete(request); | ||
deletedURLs.push(request.url); | ||
activate(event) { | ||
return waitUntil(event, async () => { | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
const currentlyCachedRequests = await cache.keys(); | ||
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); | ||
const deletedURLs = []; | ||
for (const request of currentlyCachedRequests) { | ||
if (!expectedCacheKeys.has(request.url)) { | ||
await cache.delete(request); | ||
deletedURLs.push(request.url); | ||
} | ||
} | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
printCleanupDetails(deletedURLs); | ||
} | ||
return { deletedURLs }; | ||
} | ||
/** | ||
* Requests the entry and saves it to the cache if the response is valid. | ||
* By default, any response with a status code of less than 400 (including | ||
* opaque responses) is considered valid. | ||
* | ||
* If you need to use custom criteria to determine what's valid and what | ||
* isn't, then pass in an item in `options.plugins` that implements the | ||
* `cacheWillUpdate()` lifecycle event. | ||
* | ||
* @private | ||
* @param {Object} options | ||
* @param {string} options.cacheKey The string to use a cache key. | ||
* @param {string} options.url The URL to fetch and cache. | ||
* @param {Event} options.event The install event. | ||
* @param {string} [options.cacheMode] The cache mode for the network request. | ||
* @param {string} [options.integrity] The value to use for the `integrity` | ||
* field when making the request. | ||
*/ | ||
async _addURLToCache({ cacheKey, url, cacheMode, event, integrity }) { | ||
const request = new Request(url, { | ||
integrity, | ||
cache: cacheMode, | ||
credentials: 'same-origin', | ||
if (process.env.NODE_ENV !== 'production') { | ||
printCleanupDetails(deletedURLs); | ||
} | ||
return { deletedURLs }; | ||
}); | ||
await Promise.all(this._getStrategy().handleAll({ | ||
params: { cacheKey }, | ||
request, | ||
event, | ||
})); | ||
} | ||
@@ -362,3 +263,3 @@ /** | ||
if (cacheKey) { | ||
const cache = await self.caches.open(this._cacheName); | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
return cache.match(cacheKey); | ||
@@ -369,70 +270,10 @@ } | ||
/** | ||
* Creates a [`matchCallback`]{@link module:workbox-precaching~matchCallback} | ||
* based on the passed configuration options) that with will identify | ||
* requests in the precache and return a respective `params` object | ||
* containing the `cacheKey` of the precached asset. | ||
* | ||
* This `cacheKey` can be used by a | ||
* [`handlerCallback`]{@link module:workbox-precaching~handlerCallback} | ||
* to get the precached asset from the cache. | ||
* | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
createMatchCallback(options) { | ||
return ({ request }) => { | ||
const urlsToCacheKeys = this.getURLsToCacheKeys(); | ||
for (const possibleURL of generateURLVariations(request.url, options)) { | ||
const cacheKey = urlsToCacheKeys.get(possibleURL); | ||
if (cacheKey) { | ||
return { cacheKey }; | ||
} | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
logger.debug(`Precaching did not find a match for ` + | ||
getFriendlyURL(request.url)); | ||
} | ||
return; | ||
}; | ||
} | ||
/** | ||
* Returns a function that can be used within a | ||
* {@link module:workbox-routing.Route} that will find a response for the | ||
* incoming request against the precache. | ||
* | ||
* If for an unexpected reason there is a cache miss for the request, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandler(fallbackToNetwork = true) { | ||
return (options) => { | ||
const request = options.request instanceof Request ? | ||
options.request : new Request(options.request); | ||
options.params = options.params || {}; | ||
options.params.fallbackToNetwork = fallbackToNetwork; | ||
if (!options.params.cacheKey) { | ||
options.params.cacheKey = this.getCacheKeyForURL(request.url); | ||
} | ||
return this._getStrategy().handle(options); | ||
}; | ||
} | ||
/** | ||
* Returns a function that looks up `url` in the precache (taking into | ||
* account revision information), and returns the corresponding `Response`. | ||
* | ||
* If for an unexpected reason there is a cache miss when looking up `url`, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandlerBoundToURL(url, fallbackToNetwork = true) { | ||
createHandlerBoundToURL(url) { | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
@@ -442,24 +283,9 @@ if (!cacheKey) { | ||
} | ||
const handler = this.createHandler(fallbackToNetwork); | ||
const request = new Request(url); | ||
return (options) => handler(Object.assign(options, { request })); | ||
return (options) => { | ||
options.request = new Request(url); | ||
options.params = { cacheKey, ...options.params }; | ||
return this.strategy.handle(options); | ||
}; | ||
} | ||
_getStrategy() { | ||
// NOTE: this needs to be done lazily to match v5 behavior, since the | ||
// `addPlugins()` method can be called at any time. | ||
if (!this._strategy) { | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: this._cacheName, | ||
matchOptions: { | ||
ignoreSearch: true, | ||
}, | ||
plugins: [ | ||
this._cacheKeyPlugin, | ||
...this._plugins, | ||
], | ||
}); | ||
} | ||
return this._strategy; | ||
} | ||
} | ||
export { PrecacheController }; |
@@ -23,6 +23,5 @@ /* | ||
url: string; | ||
revision?: string; | ||
revision?: string | null; | ||
} | ||
export interface FetchListenerOptions { | ||
export interface PrecacheRouteOptions { | ||
directoryIndex?: string; | ||
@@ -29,0 +28,0 @@ ignoreURLParametersMatching?: RegExp[]; |
// @ts-ignore | ||
try{self['workbox:precaching:6.0.0-alpha.1']&&_()}catch(e){} | ||
try{self['workbox:precaching:6.0.0-alpha.2']&&_()}catch(e){} |
@@ -23,5 +23,5 @@ /* | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addPlugins(plugins); | ||
precacheController.strategy.plugins.push(...plugins); | ||
} | ||
export {addPlugins}; |
@@ -9,4 +9,8 @@ | ||
import {registerRoute} from 'workbox-routing/registerRoute.js'; | ||
import {getOrCreatePrecacheController} from './utils/getOrCreatePrecacheController.js'; | ||
import {FetchListenerOptions} from './_types.js'; | ||
import {PrecacheRoute} from './PrecacheRoute.js'; | ||
import {PrecacheRouteOptions} from './_types.js'; | ||
import './_version.js'; | ||
@@ -25,21 +29,14 @@ | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will | ||
* check cache entries for a URLs ending with '/' to see if there is a hit when | ||
* appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
* @param {Object} [options] See | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function addRoute(options?: FetchListenerOptions) { | ||
function addRoute(options?: PrecacheRouteOptions) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
return precacheController.addRoute(options); | ||
const precacheRoute = new PrecacheRoute(precacheController, options); | ||
registerRoute(precacheRoute); | ||
} | ||
export {addRoute} |
@@ -12,3 +12,2 @@ /* | ||
import {cleanupOutdatedCaches} from './cleanupOutdatedCaches.js'; | ||
import {createHandler} from './createHandler.js'; | ||
import {createHandlerBoundToURL} from './createHandlerBoundToURL.js'; | ||
@@ -20,2 +19,4 @@ import {getCacheKeyForURL} from './getCacheKeyForURL.js'; | ||
import {PrecacheController} from './PrecacheController.js'; | ||
import {PrecacheRoute} from './PrecacheRoute.js'; | ||
import {PrecacheStrategy} from './PrecacheStrategy.js'; | ||
import {PrecacheFallbackPlugin} from './PrecacheFallbackPlugin.js'; | ||
@@ -28,8 +29,8 @@ | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute} | ||
* method to add assets to the Cache and respond to network requests with these | ||
* method to add assets to the cache and respond to network requests with these | ||
* cached assets. | ||
* | ||
* If you require finer grained control, you can use the | ||
* If you require more control over caching and routing, you can use the | ||
* [PrecacheController]{@link module:workbox-precaching.PrecacheController} | ||
* to determine when performed. | ||
* interface. | ||
* | ||
@@ -43,3 +44,2 @@ * @module workbox-precaching | ||
cleanupOutdatedCaches, | ||
createHandler, | ||
createHandlerBoundToURL, | ||
@@ -51,3 +51,5 @@ getCacheKeyForURL, | ||
PrecacheController, | ||
PrecacheRoute, | ||
PrecacheStrategy, | ||
PrecacheFallbackPlugin, | ||
}; |
@@ -9,4 +9,5 @@ /* | ||
import {getOrCreatePrecacheController} from './utils/getOrCreatePrecacheController.js'; | ||
import {FetchListenerOptions, PrecacheEntry} from './_types.js'; | ||
import {addRoute} from './addRoute.js'; | ||
import {precache} from './precache.js'; | ||
import {PrecacheRouteOptions, PrecacheEntry} from './_types.js'; | ||
import './_version.js'; | ||
@@ -25,12 +26,11 @@ | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.addRoute}. | ||
* [PrecacheRoute options]{@link module:workbox-precaching.PrecacheRoute}. | ||
* | ||
* @memberof module:workbox-precaching | ||
*/ | ||
function precacheAndRoute(entries: Array<PrecacheEntry|string>, options?: FetchListenerOptions) { | ||
const precacheController = getOrCreatePrecacheController(); | ||
precacheController.precacheAndRoute(entries, options); | ||
function precacheAndRoute(entries: Array<PrecacheEntry|string>, options?: PrecacheRouteOptions) { | ||
precache(entries); | ||
addRoute(options); | ||
} | ||
export {precacheAndRoute} |
@@ -11,17 +11,15 @@ /* | ||
import {cacheNames} from 'workbox-core/_private/cacheNames.js'; | ||
import {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.js'; | ||
import {logger} from 'workbox-core/_private/logger.js'; | ||
import {WorkboxError} from 'workbox-core/_private/WorkboxError.js'; | ||
import {RouteMatchCallbackOptions, RouteHandlerCallback, RouteHandlerCallbackOptions, WorkboxPlugin} from 'workbox-core/types.js'; | ||
import {Route} from 'workbox-routing/Route.js'; | ||
import {Router} from 'workbox-routing/Router.js'; | ||
import {waitUntil} from 'workbox-core/_private/waitUntil.js'; | ||
import {Strategy} from 'workbox-strategies/Strategy.js'; | ||
import {RouteHandlerCallback, WorkboxPlugin} from 'workbox-core/types.js'; | ||
import {createCacheKey} from './utils/createCacheKey.js'; | ||
import {PrecacheStrategy} from './utils/PrecacheStrategy.js'; | ||
import {PrecacheInstallReportPlugin} from './utils/PrecacheInstallReportPlugin.js'; | ||
import {PrecacheCacheKeyPlugin} from './utils/PrecacheCacheKeyPlugin.js'; | ||
import {printCleanupDetails} from './utils/printCleanupDetails.js'; | ||
import {printInstallDetails} from './utils/printInstallDetails.js'; | ||
import {generateURLVariations} from './utils/generateURLVariations.js'; | ||
import {PrecacheEntry, FetchListenerOptions} from './_types.js'; | ||
import {PrecacheStrategy} from './PrecacheStrategy.js'; | ||
import {PrecacheEntry} from './_types.js'; | ||
import './_version.js'; | ||
@@ -39,2 +37,8 @@ | ||
interface PrecacheControllerOptions { | ||
cacheName?: string; | ||
plugins?: WorkboxPlugin[]; | ||
fallbackToNetwork?: boolean; | ||
} | ||
/** | ||
@@ -46,76 +50,42 @@ * Performs efficient precaching of assets. | ||
class PrecacheController { | ||
private readonly _cacheName: string; | ||
private readonly _urlsToCacheKeys: Map<string, string>; | ||
private readonly _urlsToCacheModes: Map<string, "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached">; | ||
private readonly _cacheKeysToIntegrities: Map<string, string>; | ||
private _installAndActiveListenersAdded?: boolean; | ||
private readonly _strategy: Strategy; | ||
private readonly _urlsToCacheKeys: Map<string, string> = new Map(); | ||
private readonly _urlsToCacheModes: Map<string, "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached"> = new Map(); | ||
private readonly _cacheKeysToIntegrities: Map<string, string> = new Map(); | ||
private _router?: Router; | ||
private _strategy?: Strategy; | ||
private _installed?: boolean = false; | ||
private readonly _cacheKeyPlugin: WorkboxPlugin; | ||
private readonly _plugins: WorkboxPlugin[] = []; | ||
/** | ||
* Create a new PrecacheController. | ||
* | ||
* @param {string} [cacheName] An optional name for the cache, to override | ||
* the default precache name. | ||
* @param {Object} [options] | ||
* @param {string} [options.cacheName] The cache to use for precaching. | ||
* @param {string} [options.plugins] Plugins to use when precaching as well | ||
* as responding to fetch events for precached assets. | ||
* @param {boolean} [options.fallbackToNetwork=true] Whether to attempt to | ||
* get the response from the network if there's a precache miss. | ||
*/ | ||
constructor(cacheName?: string) { | ||
this._cacheName = cacheNames.getPrecacheName(cacheName); | ||
this._urlsToCacheKeys = new Map(); | ||
this._urlsToCacheModes = new Map(); | ||
this._cacheKeysToIntegrities = new Map(); | ||
constructor({cacheName, plugins = [], fallbackToNetwork = true}: PrecacheControllerOptions = {}) { | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: cacheNames.getPrecacheName(cacheName), | ||
plugins: [ | ||
...plugins, | ||
new PrecacheCacheKeyPlugin({precacheController: this}), | ||
], | ||
fallbackToNetwork, | ||
}); | ||
this._cacheKeyPlugin = { | ||
cacheKeyWillBeUsed: async ({request, params}: {request: Request; params?: any}) => { | ||
const cacheKey = params && params.cacheKey || | ||
this.getCacheKeyForURL(request.url); | ||
return cacheKey || request; | ||
}, | ||
}; | ||
// Bind the install and activate methods to the instance. | ||
this.install = this.install.bind(this); | ||
this.activate = this.activate.bind(this); | ||
} | ||
/** | ||
* Adds plugins to the precaching strategy. | ||
* | ||
* @param {Array<Object>} plugins | ||
* @type {module:workbox-precaching.PrecacheStrategy} The strategy created by this controller and | ||
* used to cache assets and respond to fetch events. | ||
*/ | ||
addPlugins(plugins: WorkboxPlugin[]) { | ||
this._plugins.push(...plugins); | ||
get strategy() { | ||
return this._strategy; | ||
} | ||
/** | ||
* Creates a Workbox `Route` to handle requests for precached assets (based | ||
* on the passed configuration options). | ||
* | ||
* @param {Object} [options] | ||
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` | ||
* will check cache entries for a URLs ending with '/' to see if there is a | ||
* hit when appending the `directoryIndex` value. | ||
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/, /^fbclid$/]] An | ||
* array of regex's to remove search params when looking for a cache match. | ||
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will | ||
* check the cache for the URL with a `.html` added to the end of the end. | ||
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation] | ||
* This is a function that should take a URL and return an array of | ||
* alternative URLs that should be checked for precache matches. | ||
*/ | ||
addRoute(options?: FetchListenerOptions) { | ||
if (!this._router) { | ||
const matchCallback = this.createMatchCallback(options); | ||
const handlerCallback = this.createHandler(true); | ||
const route = new Route(matchCallback, handlerCallback); | ||
const router = new Router(); | ||
router.registerRoute(route); | ||
router.addFetchListener(); | ||
router.addCacheListener(); | ||
this._router = router; | ||
} | ||
} | ||
/** | ||
* Adds items to the precache list, removing any duplicates and | ||
@@ -128,22 +98,11 @@ * stores the files in the | ||
* | ||
* Please note: This method **will not** serve any of the cached files for you. | ||
* It only precaches files. To respond to a network request you call | ||
* [addRoute()]{@link module:workbox-precaching.PreacheController#addRoute}. | ||
* | ||
* If you have a single array of files to precache, you can just call | ||
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}. | ||
* | ||
* @param {Array<Object|string>} [entries=[]] Array of entries to precache. | ||
*/ | ||
precache(entries: Array<PrecacheEntry|string>) { | ||
precache(entries: Array<PrecacheEntry | string>) { | ||
this.addToCacheList(entries); | ||
if (!this._installed) { | ||
self.addEventListener('install', (event) => { | ||
event.waitUntil(this.install({event})); | ||
}); | ||
self.addEventListener('activate', (event) => { | ||
event.waitUntil(this.activate()); | ||
}); | ||
this._installed = true; | ||
if (!this._installAndActiveListenersAdded) { | ||
self.addEventListener('install', this.install); | ||
self.addEventListener('activate', this.activate); | ||
this._installAndActiveListenersAdded = true; | ||
} | ||
@@ -153,21 +112,2 @@ } | ||
/** | ||
* This method will add entries to the precache list and add a route to | ||
* respond to fetch events. | ||
* | ||
* This is a convenience method that will call | ||
* [precache()]{@link module:workbox-precaching.PrecacheController#precache} | ||
* and | ||
* [addRoute()]{@link module:workbox-precaching.PrecacheController#addRoute} | ||
* in a single call. | ||
* | ||
* @param {Array<Object|string>} entries Array of entries to precache. | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
precacheAndRoute(entries: Array<PrecacheEntry|string>, options?: FetchListenerOptions) { | ||
this.precache(entries); | ||
this.addRoute(options); | ||
} | ||
/** | ||
* This method will add items to the precache list, removing duplicates | ||
@@ -242,67 +182,41 @@ * and ensuring the information is valid. | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {Object} options | ||
* @param {Event} options.event The install event. | ||
* @param {Array<Object>} [options.plugins] Plugins to be used for fetching | ||
* and caching during install. | ||
* @return {Promise<module:workbox-precaching.InstallResult>} | ||
*/ | ||
async install({event, plugins}: { | ||
event: ExtendableEvent; | ||
plugins?: WorkboxPlugin[]; | ||
}) { | ||
if (process.env.NODE_ENV !== 'production') { | ||
if (plugins) { | ||
assert!.isArray(plugins, { | ||
moduleName: 'workbox-precaching', | ||
className: 'PrecacheController', | ||
funcName: 'install', | ||
paramName: 'plugins', | ||
}); | ||
} | ||
} | ||
install(event: ExtendableEvent) { | ||
return waitUntil(event, async () => { | ||
const installReportPlugin = new PrecacheInstallReportPlugin(); | ||
this.strategy.plugins.push(installReportPlugin); | ||
if (plugins) { | ||
this.addPlugins(plugins); | ||
} | ||
// Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
for (const [url, cacheKey] of this._urlsToCacheKeys) { | ||
const integrity = this._cacheKeysToIntegrities.get(cacheKey); | ||
const cacheMode = this._urlsToCacheModes.get(url); | ||
const toBePrecached: {cacheKey: string; url: string}[] = []; | ||
const alreadyPrecached: string[] = []; | ||
const request = new Request(url, { | ||
integrity, | ||
cache: cacheMode, | ||
credentials: 'same-origin', | ||
}); | ||
const cache = await self.caches.open(this._cacheName); | ||
const alreadyCachedRequests = await cache.keys(); | ||
const existingCacheKeys = new Set(alreadyCachedRequests.map( | ||
(request) => request.url)); | ||
for (const [url, cacheKey] of this._urlsToCacheKeys) { | ||
if (existingCacheKeys.has(cacheKey)) { | ||
alreadyPrecached.push(url); | ||
} else { | ||
toBePrecached.push({cacheKey, url}); | ||
await Promise.all(this.strategy.handleAll({ | ||
params: {cacheKey}, | ||
request, | ||
event, | ||
})); | ||
} | ||
} | ||
// Cache entries one at a time. | ||
// See https://github.com/GoogleChrome/workbox/issues/2528 | ||
for (const {cacheKey, url} of toBePrecached) { | ||
const integrity = this._cacheKeysToIntegrities.get(cacheKey); | ||
const cacheMode = this._urlsToCacheModes.get(url); | ||
await this._addURLToCache({ | ||
cacheKey, | ||
cacheMode, | ||
event, | ||
integrity, | ||
url, | ||
}); | ||
} | ||
const {updatedURLs, notUpdatedURLs} = installReportPlugin; | ||
const updatedURLs = toBePrecached.map((item) => item.url); | ||
if (process.env.NODE_ENV !== 'production') { | ||
printInstallDetails(updatedURLs, notUpdatedURLs); | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
printInstallDetails(updatedURLs, alreadyPrecached); | ||
} | ||
return { | ||
updatedURLs, | ||
notUpdatedURLs: alreadyPrecached, | ||
}; | ||
return {updatedURLs, notUpdatedURLs}; | ||
}); | ||
} | ||
@@ -314,60 +228,28 @@ | ||
* | ||
* Note: this method calls `event.waitUntil()` for you, so you do not need | ||
* to call it yourself in your event handlers. | ||
* | ||
* @param {ExtendableEvent} | ||
* @return {Promise<module:workbox-precaching.CleanupResult>} | ||
*/ | ||
async activate() { | ||
const cache = await self.caches.open(this._cacheName); | ||
const currentlyCachedRequests = await cache.keys(); | ||
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); | ||
activate(event: ExtendableEvent) { | ||
return waitUntil(event, async () => { | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
const currentlyCachedRequests = await cache.keys(); | ||
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values()); | ||
const deletedURLs = []; | ||
for (const request of currentlyCachedRequests) { | ||
if (!expectedCacheKeys.has(request.url)) { | ||
await cache.delete(request); | ||
deletedURLs.push(request.url); | ||
const deletedURLs = []; | ||
for (const request of currentlyCachedRequests) { | ||
if (!expectedCacheKeys.has(request.url)) { | ||
await cache.delete(request); | ||
deletedURLs.push(request.url); | ||
} | ||
} | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
printCleanupDetails(deletedURLs); | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
printCleanupDetails(deletedURLs); | ||
} | ||
return {deletedURLs}; | ||
} | ||
/** | ||
* Requests the entry and saves it to the cache if the response is valid. | ||
* By default, any response with a status code of less than 400 (including | ||
* opaque responses) is considered valid. | ||
* | ||
* If you need to use custom criteria to determine what's valid and what | ||
* isn't, then pass in an item in `options.plugins` that implements the | ||
* `cacheWillUpdate()` lifecycle event. | ||
* | ||
* @private | ||
* @param {Object} options | ||
* @param {string} options.cacheKey The string to use a cache key. | ||
* @param {string} options.url The URL to fetch and cache. | ||
* @param {Event} options.event The install event. | ||
* @param {string} [options.cacheMode] The cache mode for the network request. | ||
* @param {string} [options.integrity] The value to use for the `integrity` | ||
* field when making the request. | ||
*/ | ||
async _addURLToCache({cacheKey, url, cacheMode, event, integrity}: { | ||
cacheKey: string; | ||
url: string; | ||
cacheMode: "reload" | "default" | "no-store" | "no-cache" | "force-cache" | "only-if-cached" | undefined; | ||
event: ExtendableEvent; | ||
integrity?: string; | ||
}) { | ||
const request = new Request(url, { | ||
integrity, | ||
cache: cacheMode, | ||
credentials: 'same-origin', | ||
return {deletedURLs}; | ||
}); | ||
await Promise.all(this._getStrategy().handleAll({ | ||
params: {cacheKey}, | ||
request, | ||
event, | ||
})); | ||
} | ||
@@ -431,3 +313,3 @@ | ||
if (cacheKey) { | ||
const cache = await self.caches.open(this._cacheName); | ||
const cache = await self.caches.open(this.strategy.cacheName); | ||
return cache.match(cacheKey); | ||
@@ -439,75 +321,10 @@ } | ||
/** | ||
* Creates a [`matchCallback`]{@link module:workbox-precaching~matchCallback} | ||
* based on the passed configuration options) that with will identify | ||
* requests in the precache and return a respective `params` object | ||
* containing the `cacheKey` of the precached asset. | ||
* | ||
* This `cacheKey` can be used by a | ||
* [`handlerCallback`]{@link module:workbox-precaching~handlerCallback} | ||
* to get the precached asset from the cache. | ||
* | ||
* @param {Object} [options] See | ||
* [addRoute() options]{@link module:workbox-precaching.PrecacheController#addRoute}. | ||
*/ | ||
createMatchCallback(options?: FetchListenerOptions) { | ||
return ({request}: RouteMatchCallbackOptions) => { | ||
const urlsToCacheKeys = this.getURLsToCacheKeys(); | ||
for (const possibleURL of generateURLVariations(request.url, options)) { | ||
const cacheKey = urlsToCacheKeys.get(possibleURL); | ||
if (cacheKey) { | ||
return {cacheKey}; | ||
} | ||
} | ||
if (process.env.NODE_ENV !== 'production') { | ||
logger.debug(`Precaching did not find a match for ` + | ||
getFriendlyURL(request.url)); | ||
} | ||
return; | ||
} | ||
} | ||
/** | ||
* Returns a function that can be used within a | ||
* {@link module:workbox-routing.Route} that will find a response for the | ||
* incoming request against the precache. | ||
* | ||
* If for an unexpected reason there is a cache miss for the request, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandler(fallbackToNetwork = true): RouteHandlerCallback { | ||
return (options: RouteHandlerCallbackOptions) => { | ||
const request = options.request instanceof Request ? | ||
options.request : new Request(options.request); | ||
options.params = options.params || {}; | ||
options.params.fallbackToNetwork = fallbackToNetwork; | ||
if (!options.params.cacheKey) { | ||
options.params.cacheKey = this.getCacheKeyForURL(request.url); | ||
} | ||
return this._getStrategy().handle(options); | ||
}; | ||
} | ||
/** | ||
* Returns a function that looks up `url` in the precache (taking into | ||
* account revision information), and returns the corresponding `Response`. | ||
* | ||
* If for an unexpected reason there is a cache miss when looking up `url`, | ||
* this will fall back to retrieving the `Response` via `fetch()` when | ||
* `fallbackToNetwork` is `true`. | ||
* | ||
* @param {string} url The precached URL which will be used to lookup the | ||
* `Response`. | ||
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the | ||
* response from the network if there's a precache miss. | ||
* @return {module:workbox-routing~handlerCallback} | ||
*/ | ||
createHandlerBoundToURL(url: string, fallbackToNetwork = true): RouteHandlerCallback { | ||
createHandlerBoundToURL(url: string): RouteHandlerCallback { | ||
const cacheKey = this.getCacheKeyForURL(url); | ||
@@ -517,28 +334,11 @@ if (!cacheKey) { | ||
} | ||
return (options) => { | ||
options.request = new Request(url); | ||
options.params = {cacheKey, ...options.params}; | ||
const handler = this.createHandler(fallbackToNetwork); | ||
const request = new Request(url); | ||
return (options) => handler(Object.assign(options, {request})); | ||
return this.strategy.handle(options); | ||
}; | ||
} | ||
_getStrategy(): Strategy { | ||
// NOTE: this needs to be done lazily to match v5 behavior, since the | ||
// `addPlugins()` method can be called at any time. | ||
if (!this._strategy) { | ||
this._strategy = new PrecacheStrategy({ | ||
cacheName: this._cacheName, | ||
matchOptions: { | ||
ignoreSearch: true, | ||
}, | ||
plugins: [ | ||
this._cacheKeyPlugin, | ||
...this._plugins, | ||
], | ||
}); | ||
} | ||
return this._strategy; | ||
} | ||
} | ||
export {PrecacheController}; |
@@ -10,3 +10,3 @@ /* | ||
import {removeIgnoredSearchParams} from './removeIgnoredSearchParams.js'; | ||
import {FetchListenerOptions} from '../_types.js'; | ||
import {PrecacheRouteOptions} from '../_types.js'; | ||
import '../_version.js'; | ||
@@ -30,3 +30,3 @@ | ||
urlManipulation, | ||
}: FetchListenerOptions = {}) { | ||
}: PrecacheRouteOptions = {}) { | ||
const urlObject = new URL(url, location.href); | ||
@@ -33,0 +33,0 @@ urlObject.hash = ''; |
@@ -11,3 +11,3 @@ /* | ||
import {generateURLVariations} from './generateURLVariations.js'; | ||
import {FetchListenerOptions} from '../_types.js'; | ||
import {PrecacheRouteOptions} from '../_types.js'; | ||
import '../_version.js'; | ||
@@ -28,3 +28,3 @@ | ||
export const getCacheKeyForURL = | ||
(url: string, options: FetchListenerOptions): string | void => { | ||
(url: string, options: PrecacheRouteOptions): string | void => { | ||
const precacheController = getOrCreatePrecacheController(); | ||
@@ -31,0 +31,0 @@ |
@@ -1,2 +0,2 @@ | ||
import { FetchListenerOptions } from '../_types.js'; | ||
import { PrecacheRouteOptions } from '../_types.js'; | ||
import '../_version.js'; | ||
@@ -13,2 +13,2 @@ /** | ||
*/ | ||
export declare function generateURLVariations(url: string, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, }?: FetchListenerOptions): Generator<string, void, unknown>; | ||
export declare function generateURLVariations(url: string, { ignoreURLParametersMatching, directoryIndex, cleanURLs, urlManipulation, }?: PrecacheRouteOptions): Generator<string, void, unknown>; |
@@ -1,2 +0,2 @@ | ||
import { FetchListenerOptions } from '../_types.js'; | ||
import { PrecacheRouteOptions } from '../_types.js'; | ||
import '../_version.js'; | ||
@@ -14,2 +14,2 @@ /** | ||
*/ | ||
export declare const getCacheKeyForURL: (url: string, options: FetchListenerOptions) => string | void; | ||
export declare const getCacheKeyForURL: (url: string, options: PrecacheRouteOptions) => string | void; |
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 3 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
Network access
Supply chain riskThis module accesses the network.
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 4 instances in 1 package
10
9
0
371670
4244