From 2192a258eb9ab09b7bbcd7f10ca195bce9bfc418 Mon Sep 17 00:00:00 2001 From: Dalton Adcock Date: Fri, 22 Nov 2024 14:04:42 -0800 Subject: [PATCH] custom sw static, maps broken --- apps/antalmanac/dev-dist/registerSW.js | 1 + apps/antalmanac/dev-dist/sw.js | 92 + apps/antalmanac/dev-dist/workbox-8027588d.js | 3391 ++++++++++++++++++ apps/antalmanac/index.html | 1 - apps/antalmanac/package.json | 8 +- apps/antalmanac/public/apple-touch-icon.png | Bin 0 -> 5604 bytes apps/antalmanac/public/fallback.png | Bin 0 -> 137496 bytes apps/antalmanac/public/index.html | 1 - apps/antalmanac/public/logo-192.png | Bin 0 -> 4769 bytes apps/antalmanac/public/logo-512.png | Bin 0 -> 25814 bytes apps/antalmanac/public/manifest.json | 15 - apps/antalmanac/src/sw.ts | 66 + apps/antalmanac/vite.config.ts | 36 +- 13 files changed, 3592 insertions(+), 19 deletions(-) create mode 100644 apps/antalmanac/dev-dist/registerSW.js create mode 100644 apps/antalmanac/dev-dist/sw.js create mode 100644 apps/antalmanac/dev-dist/workbox-8027588d.js create mode 100644 apps/antalmanac/public/apple-touch-icon.png create mode 100644 apps/antalmanac/public/fallback.png create mode 100644 apps/antalmanac/public/logo-192.png create mode 100644 apps/antalmanac/public/logo-512.png delete mode 100644 apps/antalmanac/public/manifest.json create mode 100644 apps/antalmanac/src/sw.ts diff --git a/apps/antalmanac/dev-dist/registerSW.js b/apps/antalmanac/dev-dist/registerSW.js new file mode 100644 index 000000000..1d5625f45 --- /dev/null +++ b/apps/antalmanac/dev-dist/registerSW.js @@ -0,0 +1 @@ +if('serviceWorker' in navigator) navigator.serviceWorker.register('/dev-sw.js?dev-sw', { scope: '/', type: 'classic' }) \ No newline at end of file diff --git a/apps/antalmanac/dev-dist/sw.js b/apps/antalmanac/dev-dist/sw.js new file mode 100644 index 000000000..bec60f6fc --- /dev/null +++ b/apps/antalmanac/dev-dist/sw.js @@ -0,0 +1,92 @@ +/** + * Copyright 2018 Google Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// If the loader is already loaded, just stop. +if (!self.define) { + let registry = {}; + + // Used for `eval` and `importScripts` where we can't get script URL by other means. + // In both cases, it's safe to use a global var because those functions are synchronous. + let nextDefineUri; + + const singleRequire = (uri, parentUri) => { + uri = new URL(uri + ".js", parentUri).href; + return registry[uri] || ( + + new Promise(resolve => { + if ("document" in self) { + const script = document.createElement("script"); + script.src = uri; + script.onload = resolve; + document.head.appendChild(script); + } else { + nextDefineUri = uri; + importScripts(uri); + resolve(); + } + }) + + .then(() => { + let promise = registry[uri]; + if (!promise) { + throw new Error(`Module ${uri} didn’t register its module`); + } + return promise; + }) + ); + }; + + self.define = (depsNames, factory) => { + const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href; + if (registry[uri]) { + // Module is already loading or loaded. + return; + } + let exports = {}; + const require = depUri => singleRequire(depUri, uri); + const specialDeps = { + module: { uri }, + exports, + require + }; + registry[uri] = Promise.all(depsNames.map( + depName => specialDeps[depName] || require(depName) + )).then(deps => { + factory(...deps); + return exports; + }); + }; +} +define(['./workbox-8027588d'], (function (workbox) { 'use strict'; + + self.skipWaiting(); + workbox.clientsClaim(); + + /** + * The precacheAndRoute() method efficiently caches and responds to + * requests for URLs in the manifest. + * See https://goo.gl/S9QRab + */ + workbox.precacheAndRoute([{ + "url": "registerSW.js", + "revision": "3ca0b8505b4bec776b69afdba2768812" + }, { + "url": "index.html", + "revision": "0.3bkij167fp" + }], {}); + workbox.cleanupOutdatedCaches(); + workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { + allowlist: [/^\/$/] + })); + +})); diff --git a/apps/antalmanac/dev-dist/workbox-8027588d.js b/apps/antalmanac/dev-dist/workbox-8027588d.js new file mode 100644 index 000000000..077fa26dd --- /dev/null +++ b/apps/antalmanac/dev-dist/workbox-8027588d.js @@ -0,0 +1,3391 @@ +define(['exports'], (function (exports) { 'use strict'; + + // @ts-ignore + try { + self['workbox:core:7.0.0'] && _(); + } catch (e) {} + + /* + 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. + */ + /** + * Claim any currently available clients once the service worker + * becomes active. This is normally used in conjunction with `skipWaiting()`. + * + * @memberof workbox-core + */ + function clientsClaim() { + self.addEventListener('activate', () => self.clients.claim()); + } + + /* + 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. + */ + const logger = (() => { + // Don't overwrite this value if it's already set. + // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923 + if (!('__WB_DISABLE_DEV_LOGS' in globalThis)) { + self.__WB_DISABLE_DEV_LOGS = false; + } + let inGroup = false; + const methodToColorMap = { + debug: `#7f8c8d`, + log: `#2ecc71`, + warn: `#f39c12`, + error: `#c0392b`, + groupCollapsed: `#3498db`, + groupEnd: null // No colored prefix on groupEnd + }; + const print = function (method, args) { + if (self.__WB_DISABLE_DEV_LOGS) { + return; + } + if (method === 'groupCollapsed') { + // Safari doesn't print all console.groupCollapsed() arguments: + // https://bugs.webkit.org/show_bug.cgi?id=182754 + if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { + console[method](...args); + return; + } + } + const styles = [`background: ${methodToColorMap[method]}`, `border-radius: 0.5em`, `color: white`, `font-weight: bold`, `padding: 2px 0.5em`]; + // When in a group, the workbox prefix is not displayed. + const logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')]; + console[method](...logPrefix, ...args); + if (method === 'groupCollapsed') { + inGroup = true; + } + if (method === 'groupEnd') { + inGroup = false; + } + }; + // eslint-disable-next-line @typescript-eslint/ban-types + const api = {}; + const loggerMethods = Object.keys(methodToColorMap); + for (const key of loggerMethods) { + const method = key; + api[method] = (...args) => { + print(method, args); + }; + } + return api; + })(); + + /* + 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 messages = { + 'invalid-value': ({ + paramName, + validValueDescription, + value + }) => { + if (!paramName || !validValueDescription) { + throw new Error(`Unexpected input to 'invalid-value' error.`); + } + return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`; + }, + 'not-an-array': ({ + moduleName, + className, + funcName, + paramName + }) => { + if (!moduleName || !className || !funcName || !paramName) { + throw new Error(`Unexpected input to 'not-an-array' error.`); + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`; + }, + 'incorrect-type': ({ + expectedType, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedType || !paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-type' error.`); + } + const classNameStr = className ? `${className}.` : ''; + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}` + `${funcName}()' must be of type ${expectedType}.`; + }, + 'incorrect-class': ({ + expectedClassName, + paramName, + moduleName, + className, + funcName, + isReturnValueProblem + }) => { + if (!expectedClassName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'incorrect-class' error.`); + } + const classNameStr = className ? `${className}.` : ''; + if (isReturnValueProblem) { + return `The return value from ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + } + return `The parameter '${paramName}' passed into ` + `'${moduleName}.${classNameStr}${funcName}()' ` + `must be an instance of class ${expectedClassName}.`; + }, + 'missing-a-method': ({ + expectedMethod, + paramName, + moduleName, + className, + funcName + }) => { + if (!expectedMethod || !paramName || !moduleName || !className || !funcName) { + throw new Error(`Unexpected input to 'missing-a-method' error.`); + } + return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`; + }, + 'add-to-cache-list-unexpected-type': ({ + entry + }) => { + return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`; + }, + 'add-to-cache-list-conflicting-entries': ({ + firstEntry, + secondEntry + }) => { + if (!firstEntry || !secondEntry) { + throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`); + } + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${firstEntry} but different revision details. Workbox is ` + `unable to cache and version the asset correctly. Please remove one ` + `of the entries.`; + }, + 'plugin-error-request-will-fetch': ({ + thrownErrorMessage + }) => { + if (!thrownErrorMessage) { + throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`); + } + return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownErrorMessage}'.`; + }, + 'invalid-cache-name': ({ + cacheNameId, + value + }) => { + if (!cacheNameId) { + throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`); + } + return `You must provide a name containing at least one character for ` + `setCacheDetails({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`; + }, + 'unregister-route-but-not-found-with-method': ({ + method + }) => { + if (!method) { + throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`); + } + return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`; + }, + 'unregister-route-route-not-registered': () => { + return `The route you're trying to unregister was not previously ` + `registered.`; + }, + 'queue-replay-failed': ({ + name + }) => { + return `Replaying the background sync queue '${name}' failed.`; + }, + 'duplicate-queue-name': ({ + name + }) => { + return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`; + }, + 'expired-test-without-max-age': ({ + methodName, + paramName + }) => { + return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`; + }, + 'unsupported-route-type': ({ + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`; + }, + 'not-array-of-class': ({ + value, + expectedClass, + moduleName, + className, + funcName, + paramName + }) => { + return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`; + }, + 'max-entries-or-age-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`; + }, + 'statuses-or-headers-required': ({ + moduleName, + className, + funcName + }) => { + return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`; + }, + 'invalid-string': ({ + moduleName, + funcName, + paramName + }) => { + if (!paramName || !moduleName || !funcName) { + throw new Error(`Unexpected input to 'invalid-string' error.`); + } + return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${funcName}() for ` + `more info.`; + }, + 'channel-name-required': () => { + return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`; + }, + 'invalid-responses-are-same-args': () => { + return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`; + }, + 'expire-custom-caches-only': () => { + return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`; + }, + 'unit-must-be-bytes': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`); + } + return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`; + }, + 'single-range-only': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'single-range-only' error.`); + } + return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'invalid-range-values': ({ + normalizedRangeHeader + }) => { + if (!normalizedRangeHeader) { + throw new Error(`Unexpected input to 'invalid-range-values' error.`); + } + return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`; + }, + 'no-range-header': () => { + return `No Range header was found in the Request provided.`; + }, + 'range-not-satisfiable': ({ + size, + start, + end + }) => { + return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`; + }, + 'attempt-to-cache-non-get-request': ({ + url, + method + }) => { + return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`; + }, + 'cache-put-with-no-response': ({ + url + }) => { + return `There was an attempt to cache '${url}' but the response was not ` + `defined.`; + }, + 'no-response': ({ + url, + error + }) => { + let message = `The strategy could not generate a response for '${url}'.`; + if (error) { + message += ` The underlying error is ${error}.`; + } + return message; + }, + 'bad-precaching-response': ({ + url, + status + }) => { + return `The precaching request for '${url}' failed` + (status ? ` with an HTTP status of ${status}.` : `.`); + }, + 'non-precached-url': ({ + url + }) => { + return `createHandlerBoundToURL('${url}') was called, but that URL is ` + `not precached. Please pass in a URL that is precached instead.`; + }, + 'add-to-cache-list-conflicting-integrities': ({ + url + }) => { + return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had the URL ` + `${url} with different integrity values. Please remove one of them.`; + }, + 'missing-precache-entry': ({ + cacheName, + url + }) => { + return `Unable to find a precached response in ${cacheName} for ${url}.`; + }, + 'cross-origin-copy-response': ({ + origin + }) => { + return `workbox-core.copyResponse() can only be used with same-origin ` + `responses. It was passed a response with origin ${origin}.`; + }, + 'opaque-streams-source': ({ + type + }) => { + const message = `One of the workbox-streams sources resulted in an ` + `'${type}' response.`; + if (type === 'opaqueredirect') { + return `${message} Please do not use a navigation request that results ` + `in a redirect as a source.`; + } + return `${message} Please ensure your sources are CORS-enabled.`; + } + }; + + /* + 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 generatorFunction = (code, details = {}) => { + const message = messages[code]; + if (!message) { + throw new Error(`Unable to find message for code '${code}'.`); + } + return message(details); + }; + const messageGenerator = generatorFunction; + + /* + 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. + */ + /** + * Workbox errors should be thrown with this class. + * This allows use to ensure the type easily in tests, + * helps developers identify errors from workbox + * easily and allows use to optimise error + * messages correctly. + * + * @private + */ + class WorkboxError extends Error { + /** + * + * @param {string} errorCode The error code that + * identifies this particular error. + * @param {Object=} details Any relevant arguments + * that will help developers identify issues should + * be added as a key on the context object. + */ + constructor(errorCode, details) { + const message = messageGenerator(errorCode, details); + super(message); + this.name = errorCode; + this.details = details; + } + } + + /* + 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. + */ + /* + * This method throws if the supplied value is not an array. + * The destructed values are required to produce a meaningful error for users. + * The destructed and restructured object is so it's clear what is + * needed. + */ + const isArray = (value, details) => { + if (!Array.isArray(value)) { + throw new WorkboxError('not-an-array', details); + } + }; + const hasMethod = (object, expectedMethod, details) => { + const type = typeof object[expectedMethod]; + if (type !== 'function') { + details['expectedMethod'] = expectedMethod; + throw new WorkboxError('missing-a-method', details); + } + }; + const isType = (object, expectedType, details) => { + if (typeof object !== expectedType) { + details['expectedType'] = expectedType; + throw new WorkboxError('incorrect-type', details); + } + }; + const isInstance = (object, + // Need the general type to do the check later. + // eslint-disable-next-line @typescript-eslint/ban-types + expectedClass, details) => { + if (!(object instanceof expectedClass)) { + details['expectedClassName'] = expectedClass.name; + throw new WorkboxError('incorrect-class', details); + } + }; + const isOneOf = (value, validValues, details) => { + if (!validValues.includes(value)) { + details['validValueDescription'] = `Valid values are ${JSON.stringify(validValues)}.`; + throw new WorkboxError('invalid-value', details); + } + }; + const isArrayOfClass = (value, + // Need general type to do check later. + expectedClass, + // eslint-disable-line + details) => { + const error = new WorkboxError('not-array-of-class', details); + if (!Array.isArray(value)) { + throw error; + } + for (const item of value) { + if (!(item instanceof expectedClass)) { + throw error; + } + } + }; + const finalAssertExports = { + hasMethod, + isArray, + isInstance, + isOneOf, + isType, + isArrayOfClass + }; + + // @ts-ignore + try { + self['workbox:routing:7.0.0'] && _(); + } catch (e) {} + + /* + 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. + */ + /** + * The default HTTP method, 'GET', used when there's no specific method + * configured for a route. + * + * @type {string} + * + * @private + */ + const defaultMethod = 'GET'; + /** + * The list of valid HTTP methods associated with requests that could be routed. + * + * @type {Array} + * + * @private + */ + const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT']; + + /* + 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 {function()|Object} handler Either a function, or an object with a + * 'handle' method. + * @return {Object} An object with a handle method. + * + * @private + */ + const normalizeHandler = handler => { + if (handler && typeof handler === 'object') { + { + finalAssertExports.hasMethod(handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return handler; + } else { + { + finalAssertExports.isType(handler, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'handler' + }); + } + return { + handle: handler + }; + } + }; + + /* + 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. + */ + /** + * A `Route` consists of a pair of callback functions, "match" and "handler". + * The "match" callback determine if a route should be used to "handle" a + * request by returning a non-falsy value if it can. The "handler" callback + * is called when there is a match and should return a Promise that resolves + * to a `Response`. + * + * @memberof workbox-routing + */ + class Route { + /** + * Constructor for Route class. + * + * @param {workbox-routing~matchCallback} match + * A callback function that determines whether the route matches a given + * `fetch` event by returning a non-falsy value. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resolving to a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(match, handler, method = defaultMethod) { + { + finalAssertExports.isType(match, 'function', { + moduleName: 'workbox-routing', + className: 'Route', + funcName: 'constructor', + paramName: 'match' + }); + if (method) { + finalAssertExports.isOneOf(method, validMethods, { + paramName: 'method' + }); + } + } + // These values are referenced directly by Router so cannot be + // altered by minificaton. + this.handler = normalizeHandler(handler); + this.match = match; + this.method = method; + } + /** + * + * @param {workbox-routing-handlerCallback} handler A callback + * function that returns a Promise resolving to a Response + */ + setCatchHandler(handler) { + this.catchHandler = normalizeHandler(handler); + } + } + + /* + 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. + */ + /** + * RegExpRoute makes it easy to create a regular expression based + * {@link workbox-routing.Route}. + * + * For same-origin requests the RegExp only needs to match part of the URL. For + * requests against third-party servers, you must define a RegExp that matches + * the start of the URL. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class RegExpRoute extends Route { + /** + * If the regular expression contains + * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references}, + * the captured values will be passed to the + * {@link workbox-routing~handlerCallback} `params` + * argument. + * + * @param {RegExp} regExp The regular expression to match against URLs. + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + */ + constructor(regExp, handler, method) { + { + finalAssertExports.isInstance(regExp, RegExp, { + moduleName: 'workbox-routing', + className: 'RegExpRoute', + funcName: 'constructor', + paramName: 'pattern' + }); + } + const match = ({ + url + }) => { + const result = regExp.exec(url.href); + // Return immediately if there's no match. + if (!result) { + return; + } + // Require that the match start at the first character in the URL string + // if it's a cross-origin request. + // See https://github.com/GoogleChrome/workbox/issues/281 for the context + // behind this behavior. + if (url.origin !== location.origin && result.index !== 0) { + { + logger.debug(`The regular expression '${regExp.toString()}' only partially matched ` + `against the cross-origin URL '${url.toString()}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`); + } + return; + } + // If the route matches, but there aren't any capture groups defined, then + // this will return [], which is truthy and therefore sufficient to + // indicate a match. + // If there are capture groups, then it will return their values. + return result.slice(1); + }; + super(match, handler, method); + } + } + + /* + 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 getFriendlyURL = url => { + const urlObj = new URL(String(url), location.href); + // See https://github.com/GoogleChrome/workbox/issues/2323 + // We want to include everything, except for the origin if it's same-origin. + return urlObj.href.replace(new RegExp(`^${location.origin}`), ''); + }; + + /* + 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. + */ + /** + * The Router can be used to process a `FetchEvent` using one or more + * {@link workbox-routing.Route}, responding with a `Response` if + * a matching route exists. + * + * If no route matches a given a request, the Router will use a "default" + * handler if one is defined. + * + * Should the matching Route throw an error, the Router will use a "catch" + * handler if one is defined to gracefully deal with issues and respond with a + * Request. + * + * If a request matches multiple routes, the **earliest** registered route will + * be used to respond to the request. + * + * @memberof workbox-routing + */ + class Router { + /** + * Initializes a new Router. + */ + constructor() { + this._routes = new Map(); + this._defaultHandlerMap = new Map(); + } + /** + * @return {Map>} routes A `Map` of HTTP + * method name ('GET', etc.) to an array of all the corresponding `Route` + * instances that are registered. + */ + get routes() { + return this._routes; + } + /** + * Adds a fetch event listener to respond to events when a route matches + * the event's request. + */ + addFetchListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('fetch', event => { + const { + request + } = event; + const responsePromise = this.handleRequest({ + request, + event + }); + if (responsePromise) { + event.respondWith(responsePromise); + } + }); + } + /** + * Adds a message event listener for URLs to cache from the window. + * This is useful to cache resources loaded on the page prior to when the + * service worker started controlling it. + * + * The format of the message data sent from the window should be as follows. + * Where the `urlsToCache` array may consist of URL strings or an array of + * URL string + `requestInit` object (the same as you'd pass to `fetch()`). + * + * ``` + * { + * type: 'CACHE_URLS', + * payload: { + * urlsToCache: [ + * './script1.js', + * './script2.js', + * ['./script3.js', {mode: 'no-cors'}], + * ], + * }, + * } + * ``` + */ + addCacheListener() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('message', event => { + // event.data is type 'any' + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + if (event.data && event.data.type === 'CACHE_URLS') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const { + payload + } = event.data; + { + logger.debug(`Caching URLs from the window`, payload.urlsToCache); + } + const requestPromises = Promise.all(payload.urlsToCache.map(entry => { + if (typeof entry === 'string') { + entry = [entry]; + } + const request = new Request(...entry); + return this.handleRequest({ + request, + event + }); + // TODO(philipwalton): TypeScript errors without this typecast for + // some reason (probably a bug). The real type here should work but + // doesn't: `Array | undefined>`. + })); // TypeScript + event.waitUntil(requestPromises); + // If a MessageChannel was used, reply to the message on success. + if (event.ports && event.ports[0]) { + void requestPromises.then(() => event.ports[0].postMessage(true)); + } + } + }); + } + /** + * Apply the routing rules to a FetchEvent object to get a Response from an + * appropriate Route's handler. + * + * @param {Object} options + * @param {Request} options.request The request to handle. + * @param {ExtendableEvent} options.event The event that triggered the + * request. + * @return {Promise|undefined} A promise is returned if a + * registered route can handle the request. If there is no matching + * route and there's no `defaultHandler`, `undefined` is returned. + */ + handleRequest({ + request, + event + }) { + { + finalAssertExports.isInstance(request, Request, { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'handleRequest', + paramName: 'options.request' + }); + } + const url = new URL(request.url, location.href); + if (!url.protocol.startsWith('http')) { + { + logger.debug(`Workbox Router only supports URLs that start with 'http'.`); + } + return; + } + const sameOrigin = url.origin === location.origin; + const { + params, + route + } = this.findMatchingRoute({ + event, + request, + sameOrigin, + url + }); + let handler = route && route.handler; + const debugMessages = []; + { + if (handler) { + debugMessages.push([`Found a route to handle this request:`, route]); + if (params) { + debugMessages.push([`Passing the following params to the route's handler:`, params]); + } + } + } + // If we don't have a handler because there was no matching route, then + // fall back to defaultHandler if that's defined. + const method = request.method; + if (!handler && this._defaultHandlerMap.has(method)) { + { + debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler for ${method}.`); + } + handler = this._defaultHandlerMap.get(method); + } + if (!handler) { + { + // No handler so Workbox will do nothing. If logs is set of debug + // i.e. verbose, we should print out this information. + logger.debug(`No route found for: ${getFriendlyURL(url)}`); + } + return; + } + { + // We have a handler, meaning Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Router is responding to: ${getFriendlyURL(url)}`); + debugMessages.forEach(msg => { + if (Array.isArray(msg)) { + logger.log(...msg); + } else { + logger.log(msg); + } + }); + logger.groupEnd(); + } + // Wrap in try and catch in case the handle method throws a synchronous + // error. It should still callback to the catch handler. + let responsePromise; + try { + responsePromise = handler.handle({ + url, + request, + event, + params + }); + } catch (err) { + responsePromise = Promise.reject(err); + } + // Get route's catch handler, if it exists + const catchHandler = route && route.catchHandler; + if (responsePromise instanceof Promise && (this._catchHandler || catchHandler)) { + responsePromise = responsePromise.catch(async err => { + // If there's a route catch handler, process that first + if (catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to route's Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + try { + return await catchHandler.handle({ + url, + request, + event, + params + }); + } catch (catchErr) { + if (catchErr instanceof Error) { + err = catchErr; + } + } + } + if (this._catchHandler) { + { + // Still include URL here as it will be async from the console group + // and may not make sense without the URL + logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL(url)}. Falling back to global Catch Handler.`); + logger.error(`Error thrown by:`, route); + logger.error(err); + logger.groupEnd(); + } + return this._catchHandler.handle({ + url, + request, + event + }); + } + throw err; + }); + } + return responsePromise; + } + /** + * Checks a request and URL (and optionally an event) against the list of + * registered routes, and if there's a match, returns the corresponding + * route along with any params generated by the match. + * + * @param {Object} options + * @param {URL} options.url + * @param {boolean} options.sameOrigin The result of comparing `url.origin` + * against the current origin. + * @param {Request} options.request The request to match. + * @param {Event} options.event The corresponding event. + * @return {Object} An object with `route` and `params` properties. + * They are populated if a matching route was found or `undefined` + * otherwise. + */ + findMatchingRoute({ + url, + sameOrigin, + request, + event + }) { + const routes = this._routes.get(request.method) || []; + for (const route of routes) { + let params; + // route.match returns type any, not possible to change right now. + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const matchResult = route.match({ + url, + sameOrigin, + request, + event + }); + if (matchResult) { + { + // Warn developers that using an async matchCallback is almost always + // not the right thing to do. + if (matchResult instanceof Promise) { + logger.warn(`While routing ${getFriendlyURL(url)}, an async ` + `matchCallback function was used. Please convert the ` + `following route to use a synchronous matchCallback function:`, route); + } + } + // See https://github.com/GoogleChrome/workbox/issues/2079 + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + params = matchResult; + if (Array.isArray(params) && params.length === 0) { + // Instead of passing an empty array in as params, use undefined. + params = undefined; + } else if (matchResult.constructor === Object && + // eslint-disable-line + Object.keys(matchResult).length === 0) { + // Instead of passing an empty object in as params, use undefined. + params = undefined; + } else if (typeof matchResult === 'boolean') { + // For the boolean value true (rather than just something truth-y), + // don't set params. + // See https://github.com/GoogleChrome/workbox/pull/2134#issuecomment-513924353 + params = undefined; + } + // Return early if have a match. + return { + route, + params + }; + } + } + // If no match was found above, return and empty object. + return {}; + } + /** + * Define a default `handler` that's called when no routes explicitly + * match the incoming request. + * + * Each HTTP method ('GET', 'POST', etc.) gets its own default handler. + * + * Without a default handler, unmatched requests will go against the + * network as if there were no service worker present. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {string} [method='GET'] The HTTP method to associate with this + * default handler. Each method has its own default. + */ + setDefaultHandler(handler, method = defaultMethod) { + this._defaultHandlerMap.set(method, normalizeHandler(handler)); + } + /** + * If a Route throws an error while handling a request, this `handler` + * will be called and given a chance to provide a response. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + */ + setCatchHandler(handler) { + this._catchHandler = normalizeHandler(handler); + } + /** + * Registers a route with the router. + * + * @param {workbox-routing.Route} route The route to register. + */ + registerRoute(route) { + { + finalAssertExports.isType(route, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route, 'match', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.isType(route.handler, 'object', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route' + }); + finalAssertExports.hasMethod(route.handler, 'handle', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.handler' + }); + finalAssertExports.isType(route.method, 'string', { + moduleName: 'workbox-routing', + className: 'Router', + funcName: 'registerRoute', + paramName: 'route.method' + }); + } + if (!this._routes.has(route.method)) { + this._routes.set(route.method, []); + } + // Give precedence to all of the earlier routes by adding this additional + // route to the end of the array. + this._routes.get(route.method).push(route); + } + /** + * Unregisters a route with the router. + * + * @param {workbox-routing.Route} route The route to unregister. + */ + unregisterRoute(route) { + if (!this._routes.has(route.method)) { + throw new WorkboxError('unregister-route-but-not-found-with-method', { + method: route.method + }); + } + const routeIndex = this._routes.get(route.method).indexOf(route); + if (routeIndex > -1) { + this._routes.get(route.method).splice(routeIndex, 1); + } else { + throw new WorkboxError('unregister-route-route-not-registered'); + } + } + } + + /* + 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. + */ + let defaultRouter; + /** + * Creates a new, singleton Router instance if one does not exist. If one + * does already exist, that instance is returned. + * + * @private + * @return {Router} + */ + const getOrCreateDefaultRouter = () => { + if (!defaultRouter) { + defaultRouter = new Router(); + // The helpers that use the default Router assume these listeners exist. + defaultRouter.addFetchListener(); + defaultRouter.addCacheListener(); + } + return defaultRouter; + }; + + /* + 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. + */ + /** + * Easily register a RegExp, string, or function with a caching + * strategy to a singleton Router instance. + * + * This method will generate a Route for you if needed and + * call {@link workbox-routing.Router#registerRoute}. + * + * @param {RegExp|string|workbox-routing.Route~matchCallback|workbox-routing.Route} capture + * If the capture param is a `Route`, all other arguments will be ignored. + * @param {workbox-routing~handlerCallback} [handler] A callback + * function that returns a Promise resulting in a Response. This parameter + * is required if `capture` is not a `Route` object. + * @param {string} [method='GET'] The HTTP method to match the Route + * against. + * @return {workbox-routing.Route} The generated `Route`. + * + * @memberof workbox-routing + */ + function registerRoute(capture, handler, method) { + let route; + if (typeof capture === 'string') { + const captureUrl = new URL(capture, location.href); + { + if (!(capture.startsWith('/') || capture.startsWith('http'))) { + throw new WorkboxError('invalid-string', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + // We want to check if Express-style wildcards are in the pathname only. + // TODO: Remove this log message in v4. + const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture; + // See https://github.com/pillarjs/path-to-regexp#parameters + const wildcards = '[*:?+]'; + if (new RegExp(`${wildcards}`).exec(valueToCheck)) { + logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`); + } + } + const matchCallback = ({ + url + }) => { + { + if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) { + logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url.toString()}. This route will only handle cross-origin requests ` + `if they match the entire URL.`); + } + } + return url.href === captureUrl.href; + }; + // If `capture` is a string then `handler` and `method` must be present. + route = new Route(matchCallback, handler, method); + } else if (capture instanceof RegExp) { + // If `capture` is a `RegExp` then `handler` and `method` must be present. + route = new RegExpRoute(capture, handler, method); + } else if (typeof capture === 'function') { + // If `capture` is a function then `handler` and `method` must be present. + route = new Route(capture, handler, method); + } else if (capture instanceof Route) { + route = capture; + } else { + throw new WorkboxError('unsupported-route-type', { + moduleName: 'workbox-routing', + funcName: 'registerRoute', + paramName: 'capture' + }); + } + const defaultRouter = getOrCreateDefaultRouter(); + defaultRouter.registerRoute(route); + return route; + } + + /* + 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 _cacheNameDetails = { + googleAnalytics: 'googleAnalytics', + precache: 'precache-v2', + prefix: 'workbox', + runtime: 'runtime', + suffix: typeof registration !== 'undefined' ? registration.scope : '' + }; + const _createCacheName = cacheName => { + return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value && value.length > 0).join('-'); + }; + const eachCacheNameDetail = fn => { + for (const key of Object.keys(_cacheNameDetails)) { + fn(key); + } + }; + const cacheNames = { + updateDetails: details => { + eachCacheNameDetail(key => { + if (typeof details[key] === 'string') { + _cacheNameDetails[key] = details[key]; + } + }); + }, + getGoogleAnalyticsName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics); + }, + getPrecacheName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.precache); + }, + getPrefix: () => { + return _cacheNameDetails.prefix; + }, + getRuntimeName: userCacheName => { + return userCacheName || _createCacheName(_cacheNameDetails.runtime); + }, + getSuffix: () => { + return _cacheNameDetails.suffix; + } + }; + + /* + 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. + */ + /** + * A utility method that makes it easier to use `event.waitUntil` with + * async functions and return the result. + * + * @param {ExtendableEvent} event + * @param {Function} asyncFn + * @return {Function} + * @private + */ + function waitUntil(event, asyncFn) { + const returnPromise = asyncFn(); + event.waitUntil(returnPromise); + return returnPromise; + } + + // @ts-ignore + try { + self['workbox:precaching:7.0.0'] && _(); + } catch (e) {} + + /* + 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. + */ + // Name of the search parameter used to store revision info. + 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 workbox-precaching + */ + function createCacheKey(entry) { + if (!entry) { + throw new 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 (typeof entry === 'string') { + const urlObject = new URL(entry, location.href); + return { + cacheKey: urlObject.href, + url: urlObject.href + }; + } + const { + revision, + url + } = entry; + if (!url) { + throw new 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: urlObject.href, + url: urlObject.href + }; + } + // Otherwise, construct a properly versioned URL using the custom Workbox + // search parameter along with the revision info. + 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 + }; + } + + /* + 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. + */ + /** + * A plugin, designed to be used with PrecacheController, to determine the + * of assets that were updated (or not updated) during the install event. + * + * @private + */ + class PrecacheInstallReportPlugin { + constructor() { + this.updatedURLs = []; + this.notUpdatedURLs = []; + this.handlerWillStart = async ({ + request, + state + }) => { + // TODO: `state` should never be undefined... + if (state) { + state.originalRequest = request; + } + }; + this.cachedResponseWillBeUsed = async ({ + event, + state, + cachedResponse + }) => { + if (event.type === 'install') { + if (state && state.originalRequest && state.originalRequest instanceof Request) { + // TODO: `state` should never be undefined... + const url = state.originalRequest.url; + if (cachedResponse) { + this.notUpdatedURLs.push(url); + } else { + this.updatedURLs.push(url); + } + } + } + return cachedResponse; + }; + } + } + + /* + 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. + */ + /** + * A plugin, designed to be used with PrecacheController, to translate URLs into + * the corresponding cache key, based on the current revision info. + * + * @private + */ + class PrecacheCacheKeyPlugin { + constructor({ + precacheController + }) { + this.cacheKeyWillBeUsed = async ({ + request, + params + }) => { + // Params is type any, can't change right now. + /* eslint-disable */ + const cacheKey = (params === null || params === void 0 ? void 0 : params.cacheKey) || this._precacheController.getCacheKeyForURL(request.url); + /* eslint-enable */ + return cacheKey ? new Request(cacheKey, { + headers: request.headers + }) : request; + }; + this._precacheController = precacheController; + } + } + + /* + 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} deletedURLs + * + * @private + */ + const logGroup = (groupTitle, deletedURLs) => { + logger.groupCollapsed(groupTitle); + for (const url of deletedURLs) { + logger.log(url); + } + logger.groupEnd(); + }; + /** + * @param {Array} deletedURLs + * + * @private + * @memberof workbox-precaching + */ + function printCleanupDetails(deletedURLs) { + const deletionCount = deletedURLs.length; + if (deletionCount > 0) { + logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`); + logGroup('Deleted Cache Requests', deletedURLs); + logger.groupEnd(); + } + } + + /* + 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} urls + * + * @private + */ + function _nestedGroup(groupTitle, urls) { + if (urls.length === 0) { + return; + } + logger.groupCollapsed(groupTitle); + for (const url of urls) { + logger.log(url); + } + logger.groupEnd(); + } + /** + * @param {Array} urlsToPrecache + * @param {Array} urlsAlreadyPrecached + * + * @private + * @memberof workbox-precaching + */ + 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.groupCollapsed(message); + _nestedGroup(`View newly precached URLs.`, urlsToPrecache); + _nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached); + logger.groupEnd(); + } + } + + /* + 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. + */ + let supportStatus; + /** + * A utility function that determines whether the current browser supports + * constructing a new `Response` from a `response.body` stream. + * + * @return {boolean} `true`, if the current browser can successfully + * construct a `Response` from a `response.body` stream, `false` otherwise. + * + * @private + */ + function canConstructResponseFromBodyStream() { + if (supportStatus === undefined) { + const testResponse = new Response(''); + if ('body' in testResponse) { + try { + new Response(testResponse.body); + supportStatus = true; + } catch (error) { + supportStatus = false; + } + } + supportStatus = false; + } + return supportStatus; + } + + /* + 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. + */ + /** + * Allows developers to copy a response and modify its `headers`, `status`, + * or `statusText` values (the values settable via a + * [`ResponseInit`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Response/Response#Syntax} + * object in the constructor). + * To modify these values, pass a function as the second argument. That + * function will be invoked with a single object with the response properties + * `{headers, status, statusText}`. The return value of this function will + * be used as the `ResponseInit` for the new `Response`. To change the values + * either modify the passed parameter(s) and return it, or return a totally + * new object. + * + * This method is intentionally limited to same-origin responses, regardless of + * whether CORS was used or not. + * + * @param {Response} response + * @param {Function} modifier + * @memberof workbox-core + */ + async function copyResponse(response, modifier) { + let origin = null; + // If response.url isn't set, assume it's cross-origin and keep origin null. + if (response.url) { + const responseURL = new URL(response.url); + origin = responseURL.origin; + } + if (origin !== self.location.origin) { + throw new WorkboxError('cross-origin-copy-response', { + origin + }); + } + const clonedResponse = response.clone(); + // Create a fresh `ResponseInit` object by cloning the headers. + const responseInit = { + headers: new Headers(clonedResponse.headers), + status: clonedResponse.status, + statusText: clonedResponse.statusText + }; + // Apply any user modifications. + const modifiedResponseInit = modifier ? modifier(responseInit) : responseInit; + // Create the new response from the body stream and `ResponseInit` + // modifications. Note: not all browsers support the Response.body stream, + // so fall back to reading the entire body into memory as a blob. + const body = canConstructResponseFromBodyStream() ? clonedResponse.body : await clonedResponse.blob(); + return new Response(body, modifiedResponseInit); + } + + /* + 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. + */ + function stripParams(fullURL, ignoreParams) { + const strippedURL = new URL(fullURL); + for (const param of ignoreParams) { + strippedURL.searchParams.delete(param); + } + return strippedURL.href; + } + /** + * Matches an item in the cache, ignoring specific URL params. This is similar + * to the `ignoreSearch` option, but it allows you to ignore just specific + * params (while continuing to match on the others). + * + * @private + * @param {Cache} cache + * @param {Request} request + * @param {Object} matchOptions + * @param {Array} ignoreParams + * @return {Promise} + */ + async function cacheMatchIgnoreParams(cache, request, ignoreParams, matchOptions) { + const strippedRequestURL = stripParams(request.url, ignoreParams); + // If the request doesn't include any ignored params, match as normal. + if (request.url === strippedRequestURL) { + return cache.match(request, matchOptions); + } + // Otherwise, match by comparing keys + const keysOptions = Object.assign(Object.assign({}, matchOptions), { + ignoreSearch: true + }); + const cacheKeys = await cache.keys(request, keysOptions); + for (const cacheKey of cacheKeys) { + const strippedCacheKeyURL = stripParams(cacheKey.url, ignoreParams); + if (strippedRequestURL === strippedCacheKeyURL) { + return cache.match(cacheKey, matchOptions); + } + } + return; + } + + /* + 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. + */ + /** + * The Deferred class composes Promises in a way that allows for them to be + * resolved or rejected from outside the constructor. In most cases promises + * should be used directly, but Deferreds can be necessary when the logic to + * resolve a promise must be separate. + * + * @private + */ + class Deferred { + /** + * Creates a promise and exposes its resolve and reject functions as methods. + */ + constructor() { + this.promise = new Promise((resolve, reject) => { + this.resolve = resolve; + this.reject = reject; + }); + } + } + + /* + 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. + */ + // Callbacks to be executed whenever there's a quota error. + // Can't change Function type right now. + // eslint-disable-next-line @typescript-eslint/ban-types + const quotaErrorCallbacks = new Set(); + + /* + 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. + */ + /** + * Runs all of the callback functions, one at a time sequentially, in the order + * in which they were registered. + * + * @memberof workbox-core + * @private + */ + async function executeQuotaErrorCallbacks() { + { + logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`); + } + for (const callback of quotaErrorCallbacks) { + await callback(); + { + logger.log(callback, 'is complete.'); + } + } + { + logger.log('Finished running callbacks.'); + } + } + + /* + 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. + */ + /** + * Returns a promise that resolves and the passed number of milliseconds. + * This utility is an async/await-friendly version of `setTimeout`. + * + * @param {number} ms + * @return {Promise} + * @private + */ + function timeout(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); + } + + // @ts-ignore + try { + self['workbox:strategies:7.0.0'] && _(); + } catch (e) {} + + /* + 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. + */ + function toRequest(input) { + return typeof input === 'string' ? new Request(input) : input; + } + /** + * A class created every time a Strategy instance instance calls + * {@link workbox-strategies.Strategy~handle} or + * {@link workbox-strategies.Strategy~handleAll} that wraps all fetch and + * cache actions around plugin callbacks and keeps track of when the strategy + * is "done" (i.e. all added `event.waitUntil()` promises have resolved). + * + * @memberof workbox-strategies + */ + class StrategyHandler { + /** + * Creates a new instance associated with the passed strategy and event + * that's handling the request. + * + * The constructor also initializes the state that will be passed to each of + * the plugins handling this request. + * + * @param {workbox-strategies.Strategy} strategy + * @param {Object} options + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] The return value from the + * {@link workbox-routing~matchCallback} (if applicable). + */ + constructor(strategy, options) { + this._cacheKeys = {}; + /** + * The request the strategy is performing (passed to the strategy's + * `handle()` or `handleAll()` method). + * @name request + * @instance + * @type {Request} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * The event associated with this request. + * @name event + * @instance + * @type {ExtendableEvent} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `URL` instance of `request.url` (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `url` param will be present if the strategy was invoked + * from a workbox `Route` object. + * @name url + * @instance + * @type {URL|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + /** + * A `param` value (if passed to the strategy's + * `handle()` or `handleAll()` method). + * Note: the `param` param will be present if the strategy was invoked + * from a workbox `Route` object and the + * {@link workbox-routing~matchCallback} returned + * a truthy value (it will be that value). + * @name params + * @instance + * @type {*|undefined} + * @memberof workbox-strategies.StrategyHandler + */ + { + finalAssertExports.isInstance(options.event, ExtendableEvent, { + moduleName: 'workbox-strategies', + className: 'StrategyHandler', + funcName: 'constructor', + paramName: 'options.event' + }); + } + Object.assign(this, options); + this.event = options.event; + this._strategy = strategy; + this._handlerDeferred = new Deferred(); + this._extendLifetimePromises = []; + // Copy the plugins list (since it's mutable on the strategy), + // so any mutations don't affect this handler instance. + this._plugins = [...strategy.plugins]; + this._pluginStateMap = new Map(); + for (const plugin of this._plugins) { + this._pluginStateMap.set(plugin, {}); + } + this.event.waitUntil(this._handlerDeferred.promise); + } + /** + * Fetches a given request (and invokes any applicable plugin callback + * methods) using the `fetchOptions` (for non-navigation requests) and + * `plugins` defined on the `Strategy` object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - `requestWillFetch()` + * - `fetchDidSucceed()` + * - `fetchDidFail()` + * + * @param {Request|string} input The URL or request to fetch. + * @return {Promise} + */ + async fetch(input) { + const { + event + } = this; + let request = toRequest(input); + if (request.mode === 'navigate' && event instanceof FetchEvent && event.preloadResponse) { + const possiblePreloadResponse = await event.preloadResponse; + if (possiblePreloadResponse) { + { + logger.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`); + } + return possiblePreloadResponse; + } + } + // If there is a fetchDidFail plugin, we need to save a clone of the + // original request before it's either modified by a requestWillFetch + // plugin or before the original request's body is consumed via fetch(). + const originalRequest = this.hasCallback('fetchDidFail') ? request.clone() : null; + try { + for (const cb of this.iterateCallbacks('requestWillFetch')) { + request = await cb({ + request: request.clone(), + event + }); + } + } catch (err) { + if (err instanceof Error) { + throw new WorkboxError('plugin-error-request-will-fetch', { + thrownErrorMessage: err.message + }); + } + } + // The request can be altered by plugins with `requestWillFetch` making + // the original request (most likely from a `fetch` event) different + // from the Request we make. Pass both to `fetchDidFail` to aid debugging. + const pluginFilteredRequest = request.clone(); + try { + let fetchResponse; + // See https://github.com/GoogleChrome/workbox/issues/1796 + fetchResponse = await fetch(request, request.mode === 'navigate' ? undefined : this._strategy.fetchOptions); + if ("development" !== 'production') { + logger.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`); + } + for (const callback of this.iterateCallbacks('fetchDidSucceed')) { + fetchResponse = await callback({ + event, + request: pluginFilteredRequest, + response: fetchResponse + }); + } + return fetchResponse; + } catch (error) { + { + logger.log(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error); + } + // `originalRequest` will only exist if a `fetchDidFail` callback + // is being used (see above). + if (originalRequest) { + await this.runCallbacks('fetchDidFail', { + error: error, + event, + originalRequest: originalRequest.clone(), + request: pluginFilteredRequest.clone() + }); + } + throw error; + } + } + /** + * Calls `this.fetch()` and (in the background) runs `this.cachePut()` on + * the response generated by `this.fetch()`. + * + * The call to `this.cachePut()` automatically invokes `this.waitUntil()`, + * so you do not have to manually call `waitUntil()` on the event. + * + * @param {Request|string} input The request or URL to fetch and cache. + * @return {Promise} + */ + async fetchAndCachePut(input) { + const response = await this.fetch(input); + const responseClone = response.clone(); + void this.waitUntil(this.cachePut(input, responseClone)); + return response; + } + /** + * Matches a request from the cache (and invokes any applicable plugin + * callback methods) using the `cacheName`, `matchOptions`, and `plugins` + * defined on the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillByUsed() + * - cachedResponseWillByUsed() + * + * @param {Request|string} key The Request or URL to use as the cache key. + * @return {Promise} A matching response, if found. + */ + async cacheMatch(key) { + const request = toRequest(key); + let cachedResponse; + const { + cacheName, + matchOptions + } = this._strategy; + const effectiveRequest = await this.getCacheKey(request, 'read'); + const multiMatchOptions = Object.assign(Object.assign({}, matchOptions), { + cacheName + }); + cachedResponse = await caches.match(effectiveRequest, multiMatchOptions); + { + if (cachedResponse) { + logger.debug(`Found a cached response in '${cacheName}'.`); + } else { + logger.debug(`No cached response found in '${cacheName}'.`); + } + } + for (const callback of this.iterateCallbacks('cachedResponseWillBeUsed')) { + cachedResponse = (await callback({ + cacheName, + matchOptions, + cachedResponse, + request: effectiveRequest, + event: this.event + })) || undefined; + } + return cachedResponse; + } + /** + * Puts a request/response pair in the cache (and invokes any applicable + * plugin callback methods) using the `cacheName` and `plugins` defined on + * the strategy object. + * + * The following plugin lifecycle methods are invoked when using this method: + * - cacheKeyWillByUsed() + * - cacheWillUpdate() + * - cacheDidUpdate() + * + * @param {Request|string} key The request or URL to use as the cache key. + * @param {Response} response The response to cache. + * @return {Promise} `false` if a cacheWillUpdate caused the response + * not be cached, and `true` otherwise. + */ + async cachePut(key, response) { + const request = toRequest(key); + // Run in the next task to avoid blocking other cache reads. + // https://github.com/w3c/ServiceWorker/issues/1397 + await timeout(0); + const effectiveRequest = await this.getCacheKey(request, 'write'); + { + if (effectiveRequest.method && effectiveRequest.method !== 'GET') { + throw new WorkboxError('attempt-to-cache-non-get-request', { + url: getFriendlyURL(effectiveRequest.url), + method: effectiveRequest.method + }); + } + // See https://github.com/GoogleChrome/workbox/issues/2818 + const vary = response.headers.get('Vary'); + if (vary) { + logger.debug(`The response for ${getFriendlyURL(effectiveRequest.url)} ` + `has a 'Vary: ${vary}' header. ` + `Consider setting the {ignoreVary: true} option on your strategy ` + `to ensure cache matching and deletion works as expected.`); + } + } + if (!response) { + { + logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`); + } + throw new WorkboxError('cache-put-with-no-response', { + url: getFriendlyURL(effectiveRequest.url) + }); + } + const responseToCache = await this._ensureResponseSafeToCache(response); + if (!responseToCache) { + { + logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' ` + `will not be cached.`, responseToCache); + } + return false; + } + const { + cacheName, + matchOptions + } = this._strategy; + const cache = await self.caches.open(cacheName); + const hasCacheUpdateCallback = this.hasCallback('cacheDidUpdate'); + const oldResponse = hasCacheUpdateCallback ? await cacheMatchIgnoreParams( + // TODO(philipwalton): the `__WB_REVISION__` param is a precaching + // feature. Consider into ways to only add this behavior if using + // precaching. + cache, effectiveRequest.clone(), ['__WB_REVISION__'], matchOptions) : null; + { + logger.debug(`Updating the '${cacheName}' cache with a new Response ` + `for ${getFriendlyURL(effectiveRequest.url)}.`); + } + try { + await cache.put(effectiveRequest, hasCacheUpdateCallback ? responseToCache.clone() : responseToCache); + } catch (error) { + if (error instanceof Error) { + // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError + if (error.name === 'QuotaExceededError') { + await executeQuotaErrorCallbacks(); + } + throw error; + } + } + for (const callback of this.iterateCallbacks('cacheDidUpdate')) { + await callback({ + cacheName, + oldResponse, + newResponse: responseToCache.clone(), + request: effectiveRequest, + event: this.event + }); + } + return true; + } + /** + * Checks the list of plugins for the `cacheKeyWillBeUsed` callback, and + * executes any of those callbacks found in sequence. The final `Request` + * object returned by the last plugin is treated as the cache key for cache + * reads and/or writes. If no `cacheKeyWillBeUsed` plugin callbacks have + * been registered, the passed request is returned unmodified + * + * @param {Request} request + * @param {string} mode + * @return {Promise} + */ + async getCacheKey(request, mode) { + const key = `${request.url} | ${mode}`; + if (!this._cacheKeys[key]) { + let effectiveRequest = request; + for (const callback of this.iterateCallbacks('cacheKeyWillBeUsed')) { + effectiveRequest = toRequest(await callback({ + mode, + request: effectiveRequest, + event: this.event, + // params has a type any can't change right now. + params: this.params // eslint-disable-line + })); + } + this._cacheKeys[key] = effectiveRequest; + } + return this._cacheKeys[key]; + } + /** + * Returns true if the strategy has at least one plugin with the given + * callback. + * + * @param {string} name The name of the callback to check for. + * @return {boolean} + */ + hasCallback(name) { + for (const plugin of this._strategy.plugins) { + if (name in plugin) { + return true; + } + } + return false; + } + /** + * Runs all plugin callbacks matching the given name, in order, passing the + * given param object (merged ith the current plugin state) as the only + * argument. + * + * Note: since this method runs all plugins, it's not suitable for cases + * where the return value of a callback needs to be applied prior to calling + * the next callback. See + * {@link workbox-strategies.StrategyHandler#iterateCallbacks} + * below for how to handle that case. + * + * @param {string} name The name of the callback to run within each plugin. + * @param {Object} param The object to pass as the first (and only) param + * when executing each callback. This object will be merged with the + * current plugin state prior to callback execution. + */ + async runCallbacks(name, param) { + for (const callback of this.iterateCallbacks(name)) { + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + await callback(param); + } + } + /** + * Accepts a callback and returns an iterable of matching plugin callbacks, + * where each callback is wrapped with the current handler state (i.e. when + * you call each callback, whatever object parameter you pass it will + * be merged with the plugin's current state). + * + * @param {string} name The name fo the callback to run + * @return {Array} + */ + *iterateCallbacks(name) { + for (const plugin of this._strategy.plugins) { + if (typeof plugin[name] === 'function') { + const state = this._pluginStateMap.get(plugin); + const statefulCallback = param => { + const statefulParam = Object.assign(Object.assign({}, param), { + state + }); + // TODO(philipwalton): not sure why `any` is needed. It seems like + // this should work with `as WorkboxPluginCallbackParam[C]`. + return plugin[name](statefulParam); + }; + yield statefulCallback; + } + } + } + /** + * Adds a promise to the + * [extend lifetime promises]{@link https://w3c.github.io/ServiceWorker/#extendableevent-extend-lifetime-promises} + * of the event event associated with the request being handled (usually a + * `FetchEvent`). + * + * Note: you can await + * {@link workbox-strategies.StrategyHandler~doneWaiting} + * to know when all added promises have settled. + * + * @param {Promise} promise A promise to add to the extend lifetime promises + * of the event that triggered the request. + */ + waitUntil(promise) { + this._extendLifetimePromises.push(promise); + return promise; + } + /** + * Returns a promise that resolves once all promises passed to + * {@link workbox-strategies.StrategyHandler~waitUntil} + * have settled. + * + * Note: any work done after `doneWaiting()` settles should be manually + * passed to an event's `waitUntil()` method (not this handler's + * `waitUntil()` method), otherwise the service worker thread my be killed + * prior to your work completing. + */ + async doneWaiting() { + let promise; + while (promise = this._extendLifetimePromises.shift()) { + await promise; + } + } + /** + * Stops running the strategy and immediately resolves any pending + * `waitUntil()` promises. + */ + destroy() { + this._handlerDeferred.resolve(null); + } + /** + * This method will call cacheWillUpdate on the available plugins (or use + * status === 200) to determine if the Response is safe and valid to cache. + * + * @param {Request} options.request + * @param {Response} options.response + * @return {Promise} + * + * @private + */ + async _ensureResponseSafeToCache(response) { + let responseToCache = response; + let pluginsUsed = false; + for (const callback of this.iterateCallbacks('cacheWillUpdate')) { + responseToCache = (await callback({ + request: this.request, + response: responseToCache, + event: this.event + })) || undefined; + pluginsUsed = true; + if (!responseToCache) { + break; + } + } + if (!pluginsUsed) { + if (responseToCache && responseToCache.status !== 200) { + responseToCache = undefined; + } + { + if (responseToCache) { + if (responseToCache.status !== 200) { + if (responseToCache.status === 0) { + logger.warn(`The response for '${this.request.url}' ` + `is an opaque response. The caching strategy that you're ` + `using will not cache opaque responses by default.`); + } else { + logger.debug(`The response for '${this.request.url}' ` + `returned a status code of '${response.status}' and won't ` + `be cached as a result.`); + } + } + } + } + } + return responseToCache; + } + } + + /* + 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. + */ + /** + * An abstract base class that all other strategy classes must extend from: + * + * @memberof workbox-strategies + */ + class Strategy { + /** + * Creates a new instance of the strategy and sets all documented option + * properties as public instance properties. + * + * Note: if a custom strategy class extends the base Strategy class and does + * not need more than these properties, it does not need to define its own + * constructor. + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [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`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters) + * of [non-navigation](https://github.com/GoogleChrome/workbox/issues/1796) + * `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. + */ + constructor(options = {}) { + /** + * Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * + * @type {string} + */ + this.cacheName = cacheNames.getRuntimeName(options.cacheName); + /** + * The list + * [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins} + * used by this strategy. + * + * @type {Array} + */ + this.plugins = options.plugins || []; + /** + * 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. + * + * @type {Object} + */ + this.fetchOptions = options.fetchOptions; + /** + * The + * [`CacheQueryOptions`]{@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions} + * for any `cache.match()` or `cache.put()` calls made by this strategy. + * + * @type {Object} + */ + this.matchOptions = options.matchOptions; + } + /** + * Perform a request strategy and returns a `Promise` that will resolve with + * a `Response`, invoking all relevant plugin callbacks. + * + * When a strategy instance is registered with a Workbox + * {@link workbox-routing.Route}, this method is automatically + * called when the route matches. + * + * Alternatively, this method can be used in a standalone `FetchEvent` + * listener by passing it to `event.respondWith()`. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + */ + handle(options) { + const [responseDone] = this.handleAll(options); + return responseDone; + } + /** + * Similar to {@link workbox-strategies.Strategy~handle}, but + * instead of just returning a `Promise` that resolves to a `Response` it + * it will return an tuple of `[response, done]` promises, where the former + * (`response`) is equivalent to what `handle()` returns, and the latter is a + * Promise that will resolve once any promises that were added to + * `event.waitUntil()` as part of performing the strategy have completed. + * + * You can await the `done` promise to ensure any extra work performed by + * the strategy (usually caching responses) completes successfully. + * + * @param {FetchEvent|Object} options A `FetchEvent` or an object with the + * properties listed below. + * @param {Request|string} options.request A request to run this strategy for. + * @param {ExtendableEvent} options.event The event associated with the + * request. + * @param {URL} [options.url] + * @param {*} [options.params] + * @return {Array} A tuple of [response, done] + * promises that can be used to determine when the response resolves as + * well as when the handler has completed all its work. + */ + handleAll(options) { + // Allow for flexible options to be passed. + if (options instanceof FetchEvent) { + options = { + event: options, + request: options.request + }; + } + const event = options.event; + const request = typeof options.request === 'string' ? new Request(options.request) : options.request; + const params = 'params' in options ? options.params : undefined; + const handler = new StrategyHandler(this, { + event, + request, + params + }); + const responseDone = this._getResponse(handler, request, event); + const handlerDone = this._awaitComplete(responseDone, handler, request, event); + // Return an array of promises, suitable for use with Promise.all(). + return [responseDone, handlerDone]; + } + async _getResponse(handler, request, event) { + await handler.runCallbacks('handlerWillStart', { + event, + request + }); + let response = undefined; + try { + response = await this._handle(request, handler); + // The "official" Strategy subclasses all throw this error automatically, + // but in case a third-party Strategy doesn't, ensure that we have a + // consistent failure when there's no response or an error response. + if (!response || response.type === 'error') { + throw new WorkboxError('no-response', { + url: request.url + }); + } + } catch (error) { + if (error instanceof Error) { + for (const callback of handler.iterateCallbacks('handlerDidError')) { + response = await callback({ + error, + event, + request + }); + if (response) { + break; + } + } + } + if (!response) { + throw error; + } else { + logger.log(`While responding to '${getFriendlyURL(request.url)}', ` + `an ${error instanceof Error ? error.toString() : ''} error occurred. Using a fallback response provided by ` + `a handlerDidError plugin.`); + } + } + for (const callback of handler.iterateCallbacks('handlerWillRespond')) { + response = await callback({ + event, + request, + response + }); + } + return response; + } + async _awaitComplete(responseDone, handler, request, event) { + let response; + let error; + try { + response = await responseDone; + } catch (error) { + // Ignore errors, as response errors should be caught via the `response` + // promise above. The `done` promise will only throw for errors in + // promises passed to `handler.waitUntil()`. + } + try { + await handler.runCallbacks('handlerDidRespond', { + event, + request, + response + }); + await handler.doneWaiting(); + } catch (waitUntilError) { + if (waitUntilError instanceof Error) { + error = waitUntilError; + } + } + await handler.runCallbacks('handlerDidComplete', { + event, + request, + response, + error: error + }); + handler.destroy(); + if (error) { + throw error; + } + } + } + /** + * Classes extending the `Strategy` based class should implement this method, + * and leverage the {@link workbox-strategies.StrategyHandler} + * arg to perform all fetching and cache logic, which will ensure all relevant + * cache, cache options, fetch options and plugins are used (per the current + * strategy instance). + * + * @name _handle + * @instance + * @abstract + * @function + * @param {Request} request + * @param {workbox-strategies.StrategyHandler} handler + * @return {Promise} + * + * @memberof workbox-strategies.Strategy + */ + + /* + 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. + */ + /** + * A {@link workbox-strategies.Strategy} implementation + * specifically designed to work with + * {@link 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 workbox-strategies.Strategy + * @memberof workbox-precaching + */ + class PrecacheStrategy extends Strategy { + /** + * + * @param {Object} [options] + * @param {string} [options.cacheName] Cache name to store and retrieve + * requests. Defaults to the cache names provided by + * {@link workbox-core.cacheNames}. + * @param {Array} [options.plugins] {@link https://developers.google.com/web/tools/workbox/guides/using-plugins|Plugins} + * to use in conjunction with this caching strategy. + * @param {Object} [options.fetchOptions] Values passed along to the + * {@link https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters|init} + * of all fetch() requests made by this strategy. + * @param {Object} [options.matchOptions] The + * {@link https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions|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.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(PrecacheStrategy.copyRedirectedCacheableResponsesPlugin); + } + /** + * @private + * @param {Request|string} request A request to run this strategy for. + * @param {workbox-strategies.StrategyHandler} handler The event that + * triggered the request. + * @return {Promise} + */ + async _handle(request, handler) { + const response = await handler.cacheMatch(request); + if (response) { + return response; + } + // If this is an `install` event for an entry that isn't already cached, + // then populate the cache. + if (handler.event && handler.event.type === 'install') { + return await this._handleInstall(request, handler); + } + // Getting here means something went wrong. An entry that should have been + // precached wasn't found in the cache. + return await this._handleFetch(request, handler); + } + async _handleFetch(request, handler) { + let response; + const params = handler.params || {}; + // Fall back to the network if we're configured to do so. + if (this._fallbackToNetwork) { + { + logger.warn(`The precached response for ` + `${getFriendlyURL(request.url)} in ${this.cacheName} was not ` + `found. Falling back to the network.`); + } + const integrityInManifest = params.integrity; + const integrityInRequest = request.integrity; + const noIntegrityConflict = !integrityInRequest || integrityInRequest === integrityInManifest; + // Do not add integrity if the original request is no-cors + // See https://github.com/GoogleChrome/workbox/issues/3096 + response = await handler.fetch(new Request(request, { + integrity: request.mode !== 'no-cors' ? integrityInRequest || integrityInManifest : undefined + })); + // It's only "safe" to repair the cache if we're using SRI to guarantee + // that the response matches the precache manifest's expectations, + // and there's either a) no integrity property in the incoming request + // or b) there is an integrity, and it matches the precache manifest. + // See https://github.com/GoogleChrome/workbox/issues/2858 + // Also if the original request users no-cors we don't use integrity. + // See https://github.com/GoogleChrome/workbox/issues/3096 + if (integrityInManifest && noIntegrityConflict && request.mode !== 'no-cors') { + this._useDefaultCacheabilityPluginIfNeeded(); + const wasCached = await handler.cachePut(request, response.clone()); + { + if (wasCached) { + logger.log(`A response for ${getFriendlyURL(request.url)} ` + `was used to "repair" the precache.`); + } + } + } + } else { + // This shouldn't normally happen, but there are edge cases: + // https://github.com/GoogleChrome/workbox/issues/1441 + throw new WorkboxError('missing-precache-entry', { + cacheName: this.cacheName, + url: request.url + }); + } + { + const cacheKey = params.cacheKey || (await handler.getCacheKey(request, 'read')); + // Workbox is going to handle the route. + // print the routing details to the console. + logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL(request.url)); + logger.log(`Serving the precached url: ${getFriendlyURL(cacheKey instanceof Request ? cacheKey.url : cacheKey)}`); + logger.groupCollapsed(`View request details here.`); + logger.log(request); + logger.groupEnd(); + logger.groupCollapsed(`View response details here.`); + logger.log(response); + logger.groupEnd(); + logger.groupEnd(); + } + return response; + } + async _handleInstall(request, handler) { + this._useDefaultCacheabilityPluginIfNeeded(); + const response = await handler.fetch(request); + // Make sure we defer cachePut() until after we know the response + // should be cached; see https://github.com/GoogleChrome/workbox/issues/2737 + const wasCached = await handler.cachePut(request, response.clone()); + if (!wasCached) { + // Throwing here will lead to the `install` handler failing, which + // we want to do if *any* of the responses aren't safe to cache. + throw new WorkboxError('bad-precaching-response', { + url: request.url, + status: response.status + }); + } + return response; + } + /** + * This method is complex, as there a number of things to account for: + * + * The `plugins` array can be set at construction, and/or it might be added to + * to at any time before the strategy is used. + * + * At the time the strategy is used (i.e. during an `install` event), there + * needs to be at least one plugin that implements `cacheWillUpdate` in the + * array, other than `copyRedirectedCacheableResponsesPlugin`. + * + * - If this method is called and there are no suitable `cacheWillUpdate` + * plugins, we need to add `defaultPrecacheCacheabilityPlugin`. + * + * - If this method is called and there is exactly one `cacheWillUpdate`, then + * we don't have to do anything (this might be a previously added + * `defaultPrecacheCacheabilityPlugin`, or it might be a custom plugin). + * + * - If this method is called and there is more than one `cacheWillUpdate`, + * then we need to check if one is `defaultPrecacheCacheabilityPlugin`. If so, + * we need to remove it. (This situation is unlikely, but it could happen if + * the strategy is used multiple times, the first without a `cacheWillUpdate`, + * and then later on after manually adding a custom `cacheWillUpdate`.) + * + * See https://github.com/GoogleChrome/workbox/issues/2737 for more context. + * + * @private + */ + _useDefaultCacheabilityPluginIfNeeded() { + let defaultPluginIndex = null; + let cacheWillUpdatePluginCount = 0; + for (const [index, plugin] of this.plugins.entries()) { + // Ignore the copy redirected plugin when determining what to do. + if (plugin === PrecacheStrategy.copyRedirectedCacheableResponsesPlugin) { + continue; + } + // Save the default plugin's index, in case it needs to be removed. + if (plugin === PrecacheStrategy.defaultPrecacheCacheabilityPlugin) { + defaultPluginIndex = index; + } + if (plugin.cacheWillUpdate) { + cacheWillUpdatePluginCount++; + } + } + if (cacheWillUpdatePluginCount === 0) { + this.plugins.push(PrecacheStrategy.defaultPrecacheCacheabilityPlugin); + } else if (cacheWillUpdatePluginCount > 1 && defaultPluginIndex !== null) { + // Only remove the default plugin; multiple custom plugins are allowed. + this.plugins.splice(defaultPluginIndex, 1); + } + // Nothing needs to be done if cacheWillUpdatePluginCount is 1 + } + } + PrecacheStrategy.defaultPrecacheCacheabilityPlugin = { + async cacheWillUpdate({ + response + }) { + if (!response || response.status >= 400) { + return null; + } + return response; + } + }; + PrecacheStrategy.copyRedirectedCacheableResponsesPlugin = { + async cacheWillUpdate({ + response + }) { + return response.redirected ? await copyResponse(response) : response; + } + }; + + /* + 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 workbox-precaching + */ + class PrecacheController { + /** + * Create a new PrecacheController. + * + * @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, + plugins = [], + fallbackToNetwork = true + } = {}) { + this._urlsToCacheKeys = new Map(); + this._urlsToCacheModes = new Map(); + this._cacheKeysToIntegrities = new Map(); + 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); + } + /** + * @type {workbox-precaching.PrecacheStrategy} The strategy created by this controller and + * used to cache assets and respond to fetch events. + */ + get strategy() { + return this._strategy; + } + /** + * Adds items to the precache list, removing any duplicates and + * stores the files in the + * {@link workbox-core.cacheNames|"precache cache"} when the service + * worker installs. + * + * This method can be called multiple times. + * + * @param {Array} [entries=[]] Array of entries to precache. + */ + precache(entries) { + this.addToCacheList(entries); + if (!this._installAndActiveListenersAdded) { + self.addEventListener('install', this.install); + self.addEventListener('activate', this.activate); + this._installAndActiveListenersAdded = true; + } + } + /** + * This method will add items to the precache list, removing duplicates + * and ensuring the information is valid. + * + * @param {Array} entries + * Array of entries to precache. + */ + addToCacheList(entries) { + { + finalAssertExports.isArray(entries, { + moduleName: 'workbox-precaching', + className: 'PrecacheController', + funcName: 'addToCacheList', + paramName: 'entries' + }); + } + 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('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('add-to-cache-list-conflicting-integrities', { + url + }); + } + this._cacheKeysToIntegrities.set(cacheKey, entry.integrity); + } + this._urlsToCacheKeys.set(url, cacheKey); + 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`; + { + logger.warn(warningMessage); + } + } + } + } + /** + * 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 {ExtendableEvent} event + * @return {Promise} + */ + install(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + 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 + })); + } + const { + updatedURLs, + notUpdatedURLs + } = installReportPlugin; + { + printInstallDetails(updatedURLs, notUpdatedURLs); + } + return { + updatedURLs, + notUpdatedURLs + }; + }); + } + /** + * 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} event + * @return {Promise} + */ + activate(event) { + // waitUntil returns Promise + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + 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); + } + } + { + printCleanupDetails(deletedURLs); + } + return { + deletedURLs + }; + }); + } + /** + * Returns a mapping of a precached URL to the corresponding cache key, taking + * into account the revision information for the URL. + * + * @return {Map} 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} 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. + */ + getCacheKeyForURL(url) { + const urlObject = new URL(url, location.href); + return this._urlsToCacheKeys.get(urlObject.href); + } + /** + * @param {string} url A cache key whose SRI you want to look up. + * @return {string} The subresource integrity associated with the cache key, + * or undefined if it's not set. + */ + getIntegrityForCacheKey(cacheKey) { + return this._cacheKeysToIntegrities.get(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} + */ + 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); + } + 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 {workbox-routing~handlerCallback} + */ + createHandlerBoundToURL(url) { + const cacheKey = this.getCacheKeyForURL(url); + if (!cacheKey) { + throw new WorkboxError('non-precached-url', { + url + }); + } + return options => { + options.request = new Request(url); + options.params = Object.assign({ + cacheKey + }, options.params); + return this.strategy.handle(options); + }; + } + } + + /* + 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. + */ + let precacheController; + /** + * @return {PrecacheController} + * @private + */ + const getOrCreatePrecacheController = () => { + if (!precacheController) { + precacheController = new PrecacheController(); + } + return precacheController; + }; + + /* + 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} 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 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; + } + + /* + 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. + */ + /** + * Generator function that yields possible variations on the original URL to + * check, one at a time. + * + * @param {string} url + * @param {Object} options + * + * @private + * @memberof workbox-precaching + */ + 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; + } + 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; + } + } + } + + /* + 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. + */ + /** + * A subclass of {@link workbox-routing.Route} that takes a + * {@link workbox-precaching.PrecacheController} + * instance and uses it to match incoming requests and handle fetching + * responses from the precache. + * + * @memberof workbox-precaching + * @extends workbox-routing.Route + */ + class PrecacheRoute extends Route { + /** + * @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 + * check cache entries for a URLs ending with '/' to see if there is a hit when + * appending the `directoryIndex` value. + * @param {Array} [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 {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. + */ + constructor(precacheController, options) { + const match = ({ + request + }) => { + const urlsToCacheKeys = precacheController.getURLsToCacheKeys(); + for (const possibleURL of generateURLVariations(request.url, options)) { + const cacheKey = urlsToCacheKeys.get(possibleURL); + if (cacheKey) { + const integrity = precacheController.getIntegrityForCacheKey(cacheKey); + return { + cacheKey, + integrity + }; + } + } + { + logger.debug(`Precaching did not find a match for ` + getFriendlyURL(request.url)); + } + return; + }; + super(match, precacheController.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. + */ + /** + * 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 the {@link workbox-precaching.PrecacheRoute} + * options. + * + * @memberof workbox-precaching + */ + function addRoute(options) { + const precacheController = getOrCreatePrecacheController(); + const precacheRoute = new PrecacheRoute(precacheController, options); + registerRoute(precacheRoute); + } + + /* + 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 + * {@link workbox-core.cacheNames|"precache cache"} 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 + * {@link workbox-precaching.addRoute}. + * + * If you have a single array of files to precache, you can just call + * {@link workbox-precaching.precacheAndRoute}. + * + * @param {Array} [entries=[]] Array of entries to precache. + * + * @memberof workbox-precaching + */ + function precache(entries) { + const precacheController = getOrCreatePrecacheController(); + precacheController.precache(entries); + } + + /* + 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 + * {@link workbox-precaching.precache} and + * {@link workbox-precaching.addRoute} in a single call. + * + * @param {Array} entries Array of entries to precache. + * @param {Object} [options] See the + * {@link workbox-precaching.PrecacheRoute} options. + * + * @memberof workbox-precaching + */ + function precacheAndRoute(entries, options) { + precache(entries); + addRoute(options); + } + + /* + 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} A list of all the cache names that were deleted. + * + * @private + * @memberof 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; + }; + + /* + 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 an `activate` event listener which will clean up incompatible + * precaches that were created by older versions of Workbox. + * + * @memberof workbox-precaching + */ + function cleanupOutdatedCaches() { + // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705 + self.addEventListener('activate', event => { + const cacheName = cacheNames.getPrecacheName(); + event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => { + { + if (cachesDeleted.length > 0) { + logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted); + } + } + })); + }); + } + + /* + 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. + */ + /** + * NavigationRoute makes it easy to create a + * {@link workbox-routing.Route} that matches for browser + * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}. + * + * It will only match incoming Requests whose + * {@link https://fetch.spec.whatwg.org/#concept-request-mode|mode} + * is set to `navigate`. + * + * You can optionally only apply this route to a subset of navigation requests + * by using one or both of the `denylist` and `allowlist` parameters. + * + * @memberof workbox-routing + * @extends workbox-routing.Route + */ + class NavigationRoute extends Route { + /** + * If both `denylist` and `allowlist` are provided, the `denylist` will + * take precedence and the request will not match this route. + * + * The regular expressions in `allowlist` and `denylist` + * are matched against the concatenated + * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname} + * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search} + * portions of the requested URL. + * + * *Note*: These RegExps may be evaluated against every destination URL during + * a navigation. Avoid using + * [complex RegExps](https://github.com/GoogleChrome/workbox/issues/3077), + * or else your users may see delays when navigating your site. + * + * @param {workbox-routing~handlerCallback} handler A callback + * function that returns a Promise resulting in a Response. + * @param {Object} options + * @param {Array} [options.denylist] If any of these patterns match, + * the route will not handle the request (even if a allowlist RegExp matches). + * @param {Array} [options.allowlist=[/./]] If any of these patterns + * match the URL's pathname and search parameter, the route will handle the + * request (assuming the denylist doesn't match). + */ + constructor(handler, { + allowlist = [/./], + denylist = [] + } = {}) { + { + finalAssertExports.isArrayOfClass(allowlist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.allowlist' + }); + finalAssertExports.isArrayOfClass(denylist, RegExp, { + moduleName: 'workbox-routing', + className: 'NavigationRoute', + funcName: 'constructor', + paramName: 'options.denylist' + }); + } + super(options => this._match(options), handler); + this._allowlist = allowlist; + this._denylist = denylist; + } + /** + * Routes match handler. + * + * @param {Object} options + * @param {URL} options.url + * @param {Request} options.request + * @return {boolean} + * + * @private + */ + _match({ + url, + request + }) { + if (request && request.mode !== 'navigate') { + return false; + } + const pathnameAndSearch = url.pathname + url.search; + for (const regExp of this._denylist) { + if (regExp.test(pathnameAndSearch)) { + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL matches this denylist pattern: ` + `${regExp.toString()}`); + } + return false; + } + } + if (this._allowlist.some(regExp => regExp.test(pathnameAndSearch))) { + { + logger.debug(`The navigation route ${pathnameAndSearch} ` + `is being used.`); + } + return true; + } + { + logger.log(`The navigation route ${pathnameAndSearch} is not ` + `being used, since the URL being navigated to doesn't ` + `match the allowlist.`); + } + return false; + } + } + + /* + 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 {workbox-routing~handlerCallback} + * + * @memberof workbox-precaching + */ + function createHandlerBoundToURL(url) { + const precacheController = getOrCreatePrecacheController(); + return precacheController.createHandlerBoundToURL(url); + } + + exports.NavigationRoute = NavigationRoute; + exports.cleanupOutdatedCaches = cleanupOutdatedCaches; + exports.clientsClaim = clientsClaim; + exports.createHandlerBoundToURL = createHandlerBoundToURL; + exports.precacheAndRoute = precacheAndRoute; + exports.registerRoute = registerRoute; + +})); diff --git a/apps/antalmanac/index.html b/apps/antalmanac/index.html index e3c89129b..c624ab293 100644 --- a/apps/antalmanac/index.html +++ b/apps/antalmanac/index.html @@ -46,7 +46,6 @@ /> - diff --git a/apps/antalmanac/package.json b/apps/antalmanac/package.json index 7d6a8e0c6..2228cd4e0 100644 --- a/apps/antalmanac/package.json +++ b/apps/antalmanac/package.json @@ -98,6 +98,12 @@ "prettier": "^2.8.4", "typescript": "5.6.3", "vite": "^4.4.9", - "vite-plugin-svgr": "^2.4.0" + "vite-plugin-pwa": "^0.21.0", + "vite-plugin-svgr": "^2.4.0", + "workbox-build": "^7.3.0", + "workbox-core": "^7.3.0", + "workbox-precaching": "^7.3.0", + "workbox-routing": "^7.3.0", + "workbox-strategies": "^7.3.0" } } diff --git a/apps/antalmanac/public/apple-touch-icon.png b/apps/antalmanac/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..62a3efb50d730e87c432f73021286d1842a5f2ad GIT binary patch literal 5604 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 literal 0 HcmV?d00001 diff --git a/apps/antalmanac/public/fallback.png b/apps/antalmanac/public/fallback.png new file mode 100644 index 0000000000000000000000000000000000000000..ff03934520e03b7192b5422f4dcfa7392fb32a2b GIT binary patch literal 137496 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%0AD91s*ET-q6AesbK#d=wCb%ux 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 WEgzP@0p5540x8L<$(BePef$rGKB6-K literal 0 HcmV?d00001 diff --git a/apps/antalmanac/public/manifest.json b/apps/antalmanac/public/manifest.json deleted file mode 100644 index 984de0027..000000000 --- a/apps/antalmanac/public/manifest.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "short_name": "AntAlmanac", - "name": "Antalmanac", - "icons": [ - { - "src": "logo.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "start_url": "./index.html", - "display": "standalone", - "theme_color": "#305db7", - "background_color": "#000000" -} diff --git a/apps/antalmanac/src/sw.ts b/apps/antalmanac/src/sw.ts new file mode 100644 index 000000000..31218a377 --- /dev/null +++ b/apps/antalmanac/src/sw.ts @@ -0,0 +1,66 @@ +import { clientsClaim } from 'workbox-core'; +import { registerRoute, setCatchHandler, NavigationRoute } from 'workbox-routing'; +import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching'; + +// Ensure TypeScript recognizes Service Worker globals +declare let self: ServiceWorkerGlobalScope; + +// Injected by Workbox during build +precacheAndRoute(self.__WB_MANIFEST); // Automatically precaches all assets, including fallback.png + +// Handle navigation requests by falling back to `index.html` +registerRoute(new NavigationRoute(createHandlerBoundToURL('/index.html'))); + +// Ensure the service worker takes control of the page immediately +self.skipWaiting(); +clientsClaim(); + +// Fallback for document requests (e.g., offline or missing resources) +setCatchHandler(({ event }) => { + console.log('Catch handler triggered for', event.request.url); + if (event.request.destination === 'document') { + return caches.match('/index.html'); // Serve the app shell for navigation requests + } + + return Response.error(); +}); + +// Match tile requests (e.g., https://${TILES_URL}/{z}/{x}/{y}.png) +const matchCb = ({ url }) => { + return url.origin === 'https://tile.openstreetmap.org'; +}; + +// Custom handler for tile requests +const handlerCb = async ({ request }) => { + console.log('Fetching tile:', request.url); + try { + // Attempt to fetch the tile image from the network + const response = await fetch(request); + + // Log the response status for debugging + console.log('Tile fetch status:', response ? response.status : 'No response'); + + if (!response.ok) { + throw new Error(`Failed to fetch image: ${response.status}`); + } + + // Return the network response if successful + return response; + } catch (error) { + // If the network request fails, log and serve the fallback image + console.error('Network request failed for tile, serving fallback image:', error); + return caches.match('fallback.png'); // Ensure this fallback is available in the cache + } +}; + +// Register the route for tile requests +registerRoute(matchCb, handlerCb); + +// Debugging cache state +self.addEventListener('activate', (event) => { + event.waitUntil( + caches.keys().then((cacheNames) => { + console.log('Cache names:', cacheNames); + }) + ); +}); diff --git a/apps/antalmanac/vite.config.ts b/apps/antalmanac/vite.config.ts index e2a7ae343..32dadcacf 100644 --- a/apps/antalmanac/vite.config.ts +++ b/apps/antalmanac/vite.config.ts @@ -2,9 +2,43 @@ import { resolve } from 'node:path'; import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import svgr from 'vite-plugin-svgr'; +import { VitePWA } from 'vite-plugin-pwa'; export default defineConfig({ - plugins: [react(), svgr()], + plugins: [ + react(), + svgr(), + VitePWA({ + strategies: 'injectManifest', + srcDir: 'src', + filename: 'sw.ts', + devOptions: { + enabled: true, + }, + includeAssets: ['favicon.ico', 'apple-touch-icon.png'], // may need mask-icon.svg + injectManifest: { + globPatterns: ['**/*.{html,js,css,png,svg,jpg,json}'], // Match files for pre-caching + }, + manifest: { + name: 'AntAlmanac', + short_name: 'AntAlmanac', + description: 'A course exploration and scheduling tool for UCI Anteaters', + theme_color: '#305db7', + icons: [ + { + src: 'logo-192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: 'logo-512.png', + sizes: '512x512', + type: 'image/png', + }, + ], + }, + }), + ], resolve: { alias: { $assets: resolve(__dirname, './src/assets'),