jekyll-pwa-plugin 2.2.3 → 5.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/lib/jekyll-pwa-plugin.rb +11 -3
- data/lib/vendor/workbox-v5.1.4/workbox-background-sync.dev.js +818 -0
- data/lib/vendor/workbox-v5.1.4/workbox-background-sync.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-background-sync.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-background-sync.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.dev.js +288 -0
- data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-broadcast-update.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.dev.js +191 -0
- data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-cacheable-response.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-core.dev.js +1858 -0
- data/lib/vendor/workbox-v5.1.4/workbox-core.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-core.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-core.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-expiration.dev.js +649 -0
- data/lib/vendor/workbox-v5.1.4/workbox-expiration.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-expiration.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-expiration.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.dev.js +102 -0
- data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-navigation-preload.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.dev.js +235 -0
- data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-offline-ga.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-precaching.dev.js +1210 -0
- data/lib/vendor/workbox-v5.1.4/workbox-precaching.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-precaching.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-precaching.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-range-requests.dev.js +262 -0
- data/lib/vendor/workbox-v5.1.4/workbox-range-requests.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-range-requests.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-range-requests.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-routing.dev.js +923 -0
- data/lib/vendor/workbox-v5.1.4/workbox-routing.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-routing.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-routing.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-strategies.dev.js +923 -0
- data/lib/vendor/workbox-v5.1.4/workbox-strategies.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-strategies.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-strategies.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-streams.dev.js +318 -0
- data/lib/vendor/workbox-v5.1.4/workbox-streams.dev.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-streams.prod.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-streams.prod.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-sw.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-sw.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.es5.mjs +1125 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.es5.mjs.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.mjs +943 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.mjs.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.umd.js +1136 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.dev.umd.js.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.es5.mjs +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.es5.mjs.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.mjs +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.mjs.map +1 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.umd.js +2 -0
- data/lib/vendor/workbox-v5.1.4/workbox-window.prod.umd.js.map +1 -0
- metadata +65 -55
- data/lib/vendor/workbox-v3.6.3/workbox-background-sync.dev.js +0 -593
- data/lib/vendor/workbox-v3.6.3/workbox-background-sync.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-background-sync.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-background-sync.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.dev.js +0 -395
- data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.dev.js +0 -740
- data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.dev.js +0 -236
- data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-core.dev.js +0 -1736
- data/lib/vendor/workbox-v3.6.3/workbox-core.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-core.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-core.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.dev.js +0 -255
- data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.dev.js +0 -159
- data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-precaching.dev.js +0 -1171
- data/lib/vendor/workbox-v3.6.3/workbox-precaching.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-precaching.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-precaching.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-range-requests.dev.js +0 -299
- data/lib/vendor/workbox-v3.6.3/workbox-range-requests.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-range-requests.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-range-requests.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-routing.dev.js +0 -863
- data/lib/vendor/workbox-v3.6.3/workbox-routing.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-routing.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-routing.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-strategies.dev.js +0 -1172
- data/lib/vendor/workbox-v3.6.3/workbox-strategies.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-strategies.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-strategies.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-streams.dev.js +0 -380
- data/lib/vendor/workbox-v3.6.3/workbox-streams.dev.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-streams.prod.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-streams.prod.js.map +0 -1
- data/lib/vendor/workbox-v3.6.3/workbox-sw.js +0 -3
- data/lib/vendor/workbox-v3.6.3/workbox-sw.js.map +0 -1
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-expiration.dev.js","sources":["../_version.js","../models/CacheTimestampsModel.js","../CacheExpiration.js","../ExpirationPlugin.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:expiration:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { DBWrapper } from 'workbox-core/_private/DBWrapper.js';\nimport { deleteDatabase } from 'workbox-core/_private/deleteDatabase.js';\nimport '../_version.js';\nconst DB_NAME = 'workbox-expiration';\nconst OBJECT_STORE_NAME = 'cache-entries';\nconst normalizeURL = (unNormalizedUrl) => {\n const url = new URL(unNormalizedUrl, location.href);\n url.hash = '';\n return url.href;\n};\n/**\n * Returns the timestamp model.\n *\n * @private\n */\nclass CacheTimestampsModel {\n /**\n *\n * @param {string} cacheName\n *\n * @private\n */\n constructor(cacheName) {\n this._cacheName = cacheName;\n this._db = new DBWrapper(DB_NAME, 1, {\n onupgradeneeded: (event) => this._handleUpgrade(event),\n });\n }\n /**\n * Should perform an upgrade of indexedDB.\n *\n * @param {Event} event\n *\n * @private\n */\n _handleUpgrade(event) {\n const db = event.target.result;\n // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we\n // have to use the `id` keyPath here and create our own values (a\n // concatenation of `url + cacheName`) instead of simply using\n // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' });\n // TODO(philipwalton): once we don't have to support EdgeHTML, we can\n // create a single index with the keyPath `['cacheName', 'timestamp']`\n // instead of doing both these indexes.\n objStore.createIndex('cacheName', 'cacheName', { unique: false });\n objStore.createIndex('timestamp', 'timestamp', { unique: false });\n // Previous versions of `workbox-expiration` used `this._cacheName`\n // as the IDBDatabase name.\n deleteDatabase(this._cacheName);\n }\n /**\n * @param {string} url\n * @param {number} timestamp\n *\n * @private\n */\n async setTimestamp(url, timestamp) {\n url = normalizeURL(url);\n const entry = {\n url,\n timestamp,\n cacheName: this._cacheName,\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n id: this._getId(url),\n };\n await this._db.put(OBJECT_STORE_NAME, entry);\n }\n /**\n * Returns the timestamp stored for a given URL.\n *\n * @param {string} url\n * @return {number}\n *\n * @private\n */\n async getTimestamp(url) {\n const entry = await this._db.get(OBJECT_STORE_NAME, this._getId(url));\n return entry.timestamp;\n }\n /**\n * Iterates through all the entries in the object store (from newest to\n * oldest) and removes entries once either `maxCount` is reached or the\n * entry's timestamp is less than `minTimestamp`.\n *\n * @param {number} minTimestamp\n * @param {number} maxCount\n * @return {Array<string>}\n *\n * @private\n */\n async expireEntries(minTimestamp, maxCount) {\n const entriesToDelete = await this._db.transaction(OBJECT_STORE_NAME, 'readwrite', (txn, done) => {\n const store = txn.objectStore(OBJECT_STORE_NAME);\n const request = store.index('timestamp').openCursor(null, 'prev');\n const entriesToDelete = [];\n let entriesNotDeletedCount = 0;\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n const result = cursor.value;\n // TODO(philipwalton): once we can use a multi-key index, we\n // won't have to check `cacheName` here.\n if (result.cacheName === this._cacheName) {\n // Delete an entry if it's older than the max age or\n // if we already have the max number allowed.\n if ((minTimestamp && result.timestamp < minTimestamp) ||\n (maxCount && entriesNotDeletedCount >= maxCount)) {\n // TODO(philipwalton): we should be able to delete the\n // entry right here, but doing so causes an iteration\n // bug in Safari stable (fixed in TP). Instead we can\n // store the keys of the entries to delete, and then\n // delete the separate transactions.\n // https://github.com/GoogleChrome/workbox/issues/1978\n // cursor.delete();\n // We only need to return the URL, not the whole entry.\n entriesToDelete.push(cursor.value);\n }\n else {\n entriesNotDeletedCount++;\n }\n }\n cursor.continue();\n }\n else {\n done(entriesToDelete);\n }\n };\n });\n // TODO(philipwalton): once the Safari bug in the following issue is fixed,\n // we should be able to remove this loop and do the entry deletion in the\n // cursor loop above:\n // https://github.com/GoogleChrome/workbox/issues/1978\n const urlsDeleted = [];\n for (const entry of entriesToDelete) {\n await this._db.delete(OBJECT_STORE_NAME, entry.id);\n urlsDeleted.push(entry.url);\n }\n return urlsDeleted;\n }\n /**\n * Takes a URL and returns an ID that will be unique in the object store.\n *\n * @param {string} url\n * @return {string}\n *\n * @private\n */\n _getId(url) {\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n return this._cacheName + '|' + normalizeURL(url);\n }\n}\nexport { CacheTimestampsModel };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheTimestampsModel } from './models/CacheTimestampsModel.js';\nimport './_version.js';\n/**\n * The `CacheExpiration` class allows you define an expiration and / or\n * limit on the number of responses stored in a\n * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).\n *\n * @memberof module:workbox-expiration\n */\nclass CacheExpiration {\n /**\n * To construct a new CacheExpiration instance you must provide at least\n * one of the `config` properties.\n *\n * @param {string} cacheName Name of the cache to apply restrictions to.\n * @param {Object} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n */\n constructor(cacheName, config = {}) {\n this._isRunning = false;\n this._rerunRequested = false;\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'cacheName',\n });\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n // TODO: Assert is positive\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n // TODO: Assert is positive\n }\n }\n this._maxEntries = config.maxEntries;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._cacheName = cacheName;\n this._timestampModel = new CacheTimestampsModel(cacheName);\n }\n /**\n * Expires entries for the given cache and given criteria.\n */\n async expireEntries() {\n if (this._isRunning) {\n this._rerunRequested = true;\n return;\n }\n this._isRunning = true;\n const minTimestamp = this._maxAgeSeconds ?\n Date.now() - (this._maxAgeSeconds * 1000) : 0;\n const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);\n // Delete URLs from the cache\n const cache = await self.caches.open(this._cacheName);\n for (const url of urlsExpired) {\n await cache.delete(url);\n }\n if (process.env.NODE_ENV !== 'production') {\n if (urlsExpired.length > 0) {\n logger.groupCollapsed(`Expired ${urlsExpired.length} ` +\n `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` +\n `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` +\n `'${this._cacheName}' cache.`);\n logger.log(`Expired the following ${urlsExpired.length === 1 ?\n 'URL' : 'URLs'}:`);\n urlsExpired.forEach((url) => logger.log(` ${url}`));\n logger.groupEnd();\n }\n else {\n logger.debug(`Cache expiration ran and found no entries to remove.`);\n }\n }\n this._isRunning = false;\n if (this._rerunRequested) {\n this._rerunRequested = false;\n dontWaitFor(this.expireEntries());\n }\n }\n /**\n * Update the timestamp for the given URL. This ensures the when\n * removing entries based on maximum entries, most recently used\n * is accurate or when expiring, the timestamp is up-to-date.\n *\n * @param {string} url\n */\n async updateTimestamp(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'updateTimestamp',\n paramName: 'url',\n });\n }\n await this._timestampModel.setTimestamp(url, Date.now());\n }\n /**\n * Can be used to check if a URL has expired or not before it's used.\n *\n * This requires a look up from IndexedDB, so can be slow.\n *\n * Note: This method will not remove the cached entry, call\n * `expireEntries()` to remove indexedDB and Cache entries.\n *\n * @param {string} url\n * @return {boolean}\n */\n async isURLExpired(url) {\n if (!this._maxAgeSeconds) {\n if (process.env.NODE_ENV !== 'production') {\n throw new WorkboxError(`expired-test-without-max-age`, {\n methodName: 'isURLExpired',\n paramName: 'maxAgeSeconds',\n });\n }\n return false;\n }\n else {\n const timestamp = await this._timestampModel.getTimestamp(url);\n const expireOlderThan = Date.now() - (this._maxAgeSeconds * 1000);\n return (timestamp < expireOlderThan);\n }\n }\n /**\n * Removes the IndexedDB object store used to keep track of cache expiration\n * metadata.\n */\n async delete() {\n // Make sure we don't attempt another rerun if we're called in the middle of\n // a cache expiration.\n this._rerunRequested = false;\n await this._timestampModel.expireEntries(Infinity); // Expires all.\n }\n}\nexport { CacheExpiration };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { registerQuotaErrorCallback } from 'workbox-core/registerQuotaErrorCallback.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheExpiration } from './CacheExpiration.js';\nimport './_version.js';\n/**\n * This plugin can be used in the Workbox APIs to regularly enforce a\n * limit on the age and / or the number of cached requests.\n *\n * Whenever a cached request is used or updated, this plugin will look\n * at the used Cache and remove any old or extra requests.\n *\n * When using `maxAgeSeconds`, requests may be used *once* after expiring\n * because the expiration clean up will not have occurred until *after* the\n * cached request has been used. If the request has a \"Date\" header, then\n * a light weight expiration check is performed and the request will not be\n * used immediately.\n *\n * When using `maxEntries`, the entry least-recently requested will be removed\n * from the cache first.\n *\n * @memberof module:workbox-expiration\n */\nclass ExpirationPlugin {\n /**\n * @param {Object} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to\n * automatic deletion if the available storage quota has been exceeded.\n */\n constructor(config = {}) {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` handlers when a `Response` is about to be returned\n * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to\n * the handler. It allows the `Response` to be inspected for freshness and\n * prevents it from being used if the `Response`'s `Date` header value is\n * older than the configured `maxAgeSeconds`.\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache the response is in.\n * @param {Response} options.cachedResponse The `Response` object that's been\n * read from a cache and whose freshness should be checked.\n * @return {Response} Either the `cachedResponse`, if it's\n * fresh, or `null` if the `Response` is older than `maxAgeSeconds`.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse }) => {\n if (!cachedResponse) {\n return null;\n }\n const isFresh = this._isResponseDateFresh(cachedResponse);\n // Expire entries to ensure that even if the expiration date has\n // expired, it'll only be used once.\n const cacheExpiration = this._getCacheExpiration(cacheName);\n dontWaitFor(cacheExpiration.expireEntries());\n // Update the metadata for the request URL to the current timestamp,\n // but don't `await` it as we don't want to block the response.\n const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);\n if (event) {\n try {\n event.waitUntil(updateTimestampDone);\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n // The event may not be a fetch event; only log the URL if it is.\n if ('request' in event) {\n logger.warn(`Unable to ensure service worker stays alive when ` +\n `updating cache entry for ` +\n `'${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n }\n return isFresh ? cachedResponse : null;\n };\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` handlers when an entry is added to a cache.\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache that was updated.\n * @param {string} options.request The Request for the cached entry.\n *\n * @private\n */\n this.cacheDidUpdate = async ({ cacheName, request }) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n const cacheExpiration = this._getCacheExpiration(cacheName);\n await cacheExpiration.updateTimestamp(request.url);\n await cacheExpiration.expireEntries();\n };\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n }\n }\n this._config = config;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._cacheExpirations = new Map();\n if (config.purgeOnQuotaError) {\n registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());\n }\n }\n /**\n * A simple helper method to return a CacheExpiration instance for a given\n * cache name.\n *\n * @param {string} cacheName\n * @return {CacheExpiration}\n *\n * @private\n */\n _getCacheExpiration(cacheName) {\n if (cacheName === cacheNames.getRuntimeName()) {\n throw new WorkboxError('expire-custom-caches-only');\n }\n let cacheExpiration = this._cacheExpirations.get(cacheName);\n if (!cacheExpiration) {\n cacheExpiration = new CacheExpiration(cacheName, this._config);\n this._cacheExpirations.set(cacheName, cacheExpiration);\n }\n return cacheExpiration;\n }\n /**\n * @param {Response} cachedResponse\n * @return {boolean}\n *\n * @private\n */\n _isResponseDateFresh(cachedResponse) {\n if (!this._maxAgeSeconds) {\n // We aren't expiring by age, so return true, it's fresh\n return true;\n }\n // Check if the 'date' header will suffice a quick expiration check.\n // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for\n // discussion.\n const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);\n if (dateHeaderTimestamp === null) {\n // Unable to parse date, so assume it's fresh.\n return true;\n }\n // If we have a valid headerTime, then our response is fresh iff the\n // headerTime plus maxAgeSeconds is greater than the current time.\n const now = Date.now();\n return dateHeaderTimestamp >= now - (this._maxAgeSeconds * 1000);\n }\n /**\n * This method will extract the data header and parse it into a useful\n * value.\n *\n * @param {Response} cachedResponse\n * @return {number|null}\n *\n * @private\n */\n _getDateHeaderTimestamp(cachedResponse) {\n if (!cachedResponse.headers.has('date')) {\n return null;\n }\n const dateHeader = cachedResponse.headers.get('date');\n const parsedDate = new Date(dateHeader);\n const headerTime = parsedDate.getTime();\n // If the Date header was invalid for some reason, parsedDate.getTime()\n // will return NaN.\n if (isNaN(headerTime)) {\n return null;\n }\n return headerTime;\n }\n /**\n * This is a helper method that performs two operations:\n *\n * - Deletes *all* the underlying Cache instances associated with this plugin\n * instance, by calling caches.delete() on your behalf.\n * - Deletes the metadata from IndexedDB used to keep track of expiration\n * details for each Cache instance.\n *\n * When using cache expiration, calling this method is preferable to calling\n * `caches.delete()` directly, since this will ensure that the IndexedDB\n * metadata is also cleanly removed and open IndexedDB instances are deleted.\n *\n * Note that if you're *not* using cache expiration for a given cache, calling\n * `caches.delete()` and passing in the cache's name should be sufficient.\n * There is no Workbox-specific method needed for cleanup in that case.\n */\n async deleteCacheAndMetadata() {\n // Do this one at a time instead of all at once via `Promise.all()` to\n // reduce the chance of inconsistency if a promise rejects.\n for (const [cacheName, cacheExpiration] of this._cacheExpirations) {\n await self.caches.delete(cacheName);\n await cacheExpiration.delete();\n }\n // Reset this._cacheExpirations to its initial state.\n this._cacheExpirations = new Map();\n }\n}\nexport { ExpirationPlugin };\n"],"names":["self","_","e","DB_NAME","OBJECT_STORE_NAME","normalizeURL","unNormalizedUrl","url","URL","location","href","hash","CacheTimestampsModel","constructor","cacheName","_cacheName","_db","DBWrapper","onupgradeneeded","event","_handleUpgrade","db","target","result","objStore","createObjectStore","keyPath","createIndex","unique","deleteDatabase","setTimestamp","timestamp","entry","id","_getId","put","getTimestamp","get","expireEntries","minTimestamp","maxCount","entriesToDelete","transaction","txn","done","store","objectStore","request","index","openCursor","entriesNotDeletedCount","onsuccess","cursor","value","push","continue","urlsDeleted","delete","CacheExpiration","config","_isRunning","_rerunRequested","assert","isType","moduleName","className","funcName","paramName","maxEntries","maxAgeSeconds","WorkboxError","_maxEntries","_maxAgeSeconds","_timestampModel","Date","now","urlsExpired","cache","caches","open","length","logger","groupCollapsed","log","forEach","groupEnd","debug","dontWaitFor","updateTimestamp","isURLExpired","methodName","expireOlderThan","Infinity","ExpirationPlugin","cachedResponseWillBeUsed","cachedResponse","isFresh","_isResponseDateFresh","cacheExpiration","_getCacheExpiration","updateTimestampDone","waitUntil","error","warn","getFriendlyURL","cacheDidUpdate","isInstance","Request","_config","_cacheExpirations","Map","purgeOnQuotaError","registerQuotaErrorCallback","deleteCacheAndMetadata","cacheNames","getRuntimeName","set","dateHeaderTimestamp","_getDateHeaderTimestamp","headers","has","dateHeader","parsedDate","headerTime","getTime","isNaN"],"mappings":"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"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
this.workbox=this.workbox||{},this.workbox.expiration=function(t,e,s,i,a,n,h){"use strict";try{self["workbox:expiration:5.1.4"]&&_()}catch(t){}const r=t=>{const e=new URL(t,location.href);return e.hash="",e.href};class c{constructor(t){this.t=t,this.s=new i.DBWrapper("workbox-expiration",1,{onupgradeneeded:t=>this.i(t)})}i(t){const e=t.target.result.createObjectStore("cache-entries",{keyPath:"id"});e.createIndex("cacheName","cacheName",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),a.deleteDatabase(this.t)}async setTimestamp(t,e){const s={url:t=r(t),timestamp:e,cacheName:this.t,id:this.h(t)};await this.s.put("cache-entries",s)}async getTimestamp(t){return(await this.s.get("cache-entries",this.h(t))).timestamp}async expireEntries(t,e){const s=await this.s.transaction("cache-entries","readwrite",(s,i)=>{const a=s.objectStore("cache-entries").index("timestamp").openCursor(null,"prev"),n=[];let h=0;a.onsuccess=()=>{const s=a.result;if(s){const i=s.value;i.cacheName===this.t&&(t&&i.timestamp<t||e&&h>=e?n.push(s.value):h++),s.continue()}else i(n)}}),i=[];for(const t of s)await this.s.delete("cache-entries",t.id),i.push(t.url);return i}h(t){return this.t+"|"+r(t)}}class o{constructor(t,e={}){this.o=!1,this.u=!1,this.l=e.maxEntries,this.m=e.maxAgeSeconds,this.t=t,this.p=new c(t)}async expireEntries(){if(this.o)return void(this.u=!0);this.o=!0;const t=this.m?Date.now()-1e3*this.m:0,s=await this.p.expireEntries(t,this.l),i=await self.caches.open(this.t);for(const t of s)await i.delete(t);this.o=!1,this.u&&(this.u=!1,e.dontWaitFor(this.expireEntries()))}async updateTimestamp(t){await this.p.setTimestamp(t,Date.now())}async isURLExpired(t){if(this.m){return await this.p.getTimestamp(t)<Date.now()-1e3*this.m}return!1}async delete(){this.u=!1,await this.p.expireEntries(1/0)}}return t.CacheExpiration=o,t.ExpirationPlugin=class{constructor(t={}){this.cachedResponseWillBeUsed=async({event:t,request:s,cacheName:i,cachedResponse:a})=>{if(!a)return null;const n=this.k(a),h=this.D(i);e.dontWaitFor(h.expireEntries());const r=h.updateTimestamp(s.url);if(t)try{t.waitUntil(r)}catch(t){}return n?a:null},this.cacheDidUpdate=async({cacheName:t,request:e})=>{const s=this.D(t);await s.updateTimestamp(e.url),await s.expireEntries()},this.N=t,this.m=t.maxAgeSeconds,this.g=new Map,t.purgeOnQuotaError&&h.registerQuotaErrorCallback(()=>this.deleteCacheAndMetadata())}D(t){if(t===n.cacheNames.getRuntimeName())throw new s.WorkboxError("expire-custom-caches-only");let e=this.g.get(t);return e||(e=new o(t,this.N),this.g.set(t,e)),e}k(t){if(!this.m)return!0;const e=this._(t);if(null===e)return!0;return e>=Date.now()-1e3*this.m}_(t){if(!t.headers.has("date"))return null;const e=t.headers.get("date"),s=new Date(e).getTime();return isNaN(s)?null:s}async deleteCacheAndMetadata(){for(const[t,e]of this.g)await self.caches.delete(t),await e.delete();this.g=new Map}},t}({},workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core);
|
2
|
+
//# sourceMappingURL=workbox-expiration.prod.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-expiration.prod.js","sources":["../_version.js","../models/CacheTimestampsModel.js","../CacheExpiration.js","../ExpirationPlugin.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:expiration:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { DBWrapper } from 'workbox-core/_private/DBWrapper.js';\nimport { deleteDatabase } from 'workbox-core/_private/deleteDatabase.js';\nimport '../_version.js';\nconst DB_NAME = 'workbox-expiration';\nconst OBJECT_STORE_NAME = 'cache-entries';\nconst normalizeURL = (unNormalizedUrl) => {\n const url = new URL(unNormalizedUrl, location.href);\n url.hash = '';\n return url.href;\n};\n/**\n * Returns the timestamp model.\n *\n * @private\n */\nclass CacheTimestampsModel {\n /**\n *\n * @param {string} cacheName\n *\n * @private\n */\n constructor(cacheName) {\n this._cacheName = cacheName;\n this._db = new DBWrapper(DB_NAME, 1, {\n onupgradeneeded: (event) => this._handleUpgrade(event),\n });\n }\n /**\n * Should perform an upgrade of indexedDB.\n *\n * @param {Event} event\n *\n * @private\n */\n _handleUpgrade(event) {\n const db = event.target.result;\n // TODO(philipwalton): EdgeHTML doesn't support arrays as a keyPath, so we\n // have to use the `id` keyPath here and create our own values (a\n // concatenation of `url + cacheName`) instead of simply using\n // `keyPath: ['url', 'cacheName']`, which is supported in other browsers.\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, { keyPath: 'id' });\n // TODO(philipwalton): once we don't have to support EdgeHTML, we can\n // create a single index with the keyPath `['cacheName', 'timestamp']`\n // instead of doing both these indexes.\n objStore.createIndex('cacheName', 'cacheName', { unique: false });\n objStore.createIndex('timestamp', 'timestamp', { unique: false });\n // Previous versions of `workbox-expiration` used `this._cacheName`\n // as the IDBDatabase name.\n deleteDatabase(this._cacheName);\n }\n /**\n * @param {string} url\n * @param {number} timestamp\n *\n * @private\n */\n async setTimestamp(url, timestamp) {\n url = normalizeURL(url);\n const entry = {\n url,\n timestamp,\n cacheName: this._cacheName,\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n id: this._getId(url),\n };\n await this._db.put(OBJECT_STORE_NAME, entry);\n }\n /**\n * Returns the timestamp stored for a given URL.\n *\n * @param {string} url\n * @return {number}\n *\n * @private\n */\n async getTimestamp(url) {\n const entry = await this._db.get(OBJECT_STORE_NAME, this._getId(url));\n return entry.timestamp;\n }\n /**\n * Iterates through all the entries in the object store (from newest to\n * oldest) and removes entries once either `maxCount` is reached or the\n * entry's timestamp is less than `minTimestamp`.\n *\n * @param {number} minTimestamp\n * @param {number} maxCount\n * @return {Array<string>}\n *\n * @private\n */\n async expireEntries(minTimestamp, maxCount) {\n const entriesToDelete = await this._db.transaction(OBJECT_STORE_NAME, 'readwrite', (txn, done) => {\n const store = txn.objectStore(OBJECT_STORE_NAME);\n const request = store.index('timestamp').openCursor(null, 'prev');\n const entriesToDelete = [];\n let entriesNotDeletedCount = 0;\n request.onsuccess = () => {\n const cursor = request.result;\n if (cursor) {\n const result = cursor.value;\n // TODO(philipwalton): once we can use a multi-key index, we\n // won't have to check `cacheName` here.\n if (result.cacheName === this._cacheName) {\n // Delete an entry if it's older than the max age or\n // if we already have the max number allowed.\n if ((minTimestamp && result.timestamp < minTimestamp) ||\n (maxCount && entriesNotDeletedCount >= maxCount)) {\n // TODO(philipwalton): we should be able to delete the\n // entry right here, but doing so causes an iteration\n // bug in Safari stable (fixed in TP). Instead we can\n // store the keys of the entries to delete, and then\n // delete the separate transactions.\n // https://github.com/GoogleChrome/workbox/issues/1978\n // cursor.delete();\n // We only need to return the URL, not the whole entry.\n entriesToDelete.push(cursor.value);\n }\n else {\n entriesNotDeletedCount++;\n }\n }\n cursor.continue();\n }\n else {\n done(entriesToDelete);\n }\n };\n });\n // TODO(philipwalton): once the Safari bug in the following issue is fixed,\n // we should be able to remove this loop and do the entry deletion in the\n // cursor loop above:\n // https://github.com/GoogleChrome/workbox/issues/1978\n const urlsDeleted = [];\n for (const entry of entriesToDelete) {\n await this._db.delete(OBJECT_STORE_NAME, entry.id);\n urlsDeleted.push(entry.url);\n }\n return urlsDeleted;\n }\n /**\n * Takes a URL and returns an ID that will be unique in the object store.\n *\n * @param {string} url\n * @return {string}\n *\n * @private\n */\n _getId(url) {\n // Creating an ID from the URL and cache name won't be necessary once\n // Edge switches to Chromium and all browsers we support work with\n // array keyPaths.\n return this._cacheName + '|' + normalizeURL(url);\n }\n}\nexport { CacheTimestampsModel };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheTimestampsModel } from './models/CacheTimestampsModel.js';\nimport './_version.js';\n/**\n * The `CacheExpiration` class allows you define an expiration and / or\n * limit on the number of responses stored in a\n * [`Cache`](https://developer.mozilla.org/en-US/docs/Web/API/Cache).\n *\n * @memberof module:workbox-expiration\n */\nclass CacheExpiration {\n /**\n * To construct a new CacheExpiration instance you must provide at least\n * one of the `config` properties.\n *\n * @param {string} cacheName Name of the cache to apply restrictions to.\n * @param {Object} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n */\n constructor(cacheName, config = {}) {\n this._isRunning = false;\n this._rerunRequested = false;\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'cacheName',\n });\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n // TODO: Assert is positive\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n // TODO: Assert is positive\n }\n }\n this._maxEntries = config.maxEntries;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._cacheName = cacheName;\n this._timestampModel = new CacheTimestampsModel(cacheName);\n }\n /**\n * Expires entries for the given cache and given criteria.\n */\n async expireEntries() {\n if (this._isRunning) {\n this._rerunRequested = true;\n return;\n }\n this._isRunning = true;\n const minTimestamp = this._maxAgeSeconds ?\n Date.now() - (this._maxAgeSeconds * 1000) : 0;\n const urlsExpired = await this._timestampModel.expireEntries(minTimestamp, this._maxEntries);\n // Delete URLs from the cache\n const cache = await self.caches.open(this._cacheName);\n for (const url of urlsExpired) {\n await cache.delete(url);\n }\n if (process.env.NODE_ENV !== 'production') {\n if (urlsExpired.length > 0) {\n logger.groupCollapsed(`Expired ${urlsExpired.length} ` +\n `${urlsExpired.length === 1 ? 'entry' : 'entries'} and removed ` +\n `${urlsExpired.length === 1 ? 'it' : 'them'} from the ` +\n `'${this._cacheName}' cache.`);\n logger.log(`Expired the following ${urlsExpired.length === 1 ?\n 'URL' : 'URLs'}:`);\n urlsExpired.forEach((url) => logger.log(` ${url}`));\n logger.groupEnd();\n }\n else {\n logger.debug(`Cache expiration ran and found no entries to remove.`);\n }\n }\n this._isRunning = false;\n if (this._rerunRequested) {\n this._rerunRequested = false;\n dontWaitFor(this.expireEntries());\n }\n }\n /**\n * Update the timestamp for the given URL. This ensures the when\n * removing entries based on maximum entries, most recently used\n * is accurate or when expiring, the timestamp is up-to-date.\n *\n * @param {string} url\n */\n async updateTimestamp(url) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(url, 'string', {\n moduleName: 'workbox-expiration',\n className: 'CacheExpiration',\n funcName: 'updateTimestamp',\n paramName: 'url',\n });\n }\n await this._timestampModel.setTimestamp(url, Date.now());\n }\n /**\n * Can be used to check if a URL has expired or not before it's used.\n *\n * This requires a look up from IndexedDB, so can be slow.\n *\n * Note: This method will not remove the cached entry, call\n * `expireEntries()` to remove indexedDB and Cache entries.\n *\n * @param {string} url\n * @return {boolean}\n */\n async isURLExpired(url) {\n if (!this._maxAgeSeconds) {\n if (process.env.NODE_ENV !== 'production') {\n throw new WorkboxError(`expired-test-without-max-age`, {\n methodName: 'isURLExpired',\n paramName: 'maxAgeSeconds',\n });\n }\n return false;\n }\n else {\n const timestamp = await this._timestampModel.getTimestamp(url);\n const expireOlderThan = Date.now() - (this._maxAgeSeconds * 1000);\n return (timestamp < expireOlderThan);\n }\n }\n /**\n * Removes the IndexedDB object store used to keep track of cache expiration\n * metadata.\n */\n async delete() {\n // Make sure we don't attempt another rerun if we're called in the middle of\n // a cache expiration.\n this._rerunRequested = false;\n await this._timestampModel.expireEntries(Infinity); // Expires all.\n }\n}\nexport { CacheExpiration };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { assert } from 'workbox-core/_private/assert.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { dontWaitFor } from 'workbox-core/_private/dontWaitFor.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { registerQuotaErrorCallback } from 'workbox-core/registerQuotaErrorCallback.js';\nimport { WorkboxError } from 'workbox-core/_private/WorkboxError.js';\nimport { CacheExpiration } from './CacheExpiration.js';\nimport './_version.js';\n/**\n * This plugin can be used in the Workbox APIs to regularly enforce a\n * limit on the age and / or the number of cached requests.\n *\n * Whenever a cached request is used or updated, this plugin will look\n * at the used Cache and remove any old or extra requests.\n *\n * When using `maxAgeSeconds`, requests may be used *once* after expiring\n * because the expiration clean up will not have occurred until *after* the\n * cached request has been used. If the request has a \"Date\" header, then\n * a light weight expiration check is performed and the request will not be\n * used immediately.\n *\n * When using `maxEntries`, the entry least-recently requested will be removed\n * from the cache first.\n *\n * @memberof module:workbox-expiration\n */\nclass ExpirationPlugin {\n /**\n * @param {Object} config\n * @param {number} [config.maxEntries] The maximum number of entries to cache.\n * Entries used the least will be removed as the maximum is reached.\n * @param {number} [config.maxAgeSeconds] The maximum age of an entry before\n * it's treated as stale and removed.\n * @param {boolean} [config.purgeOnQuotaError] Whether to opt this cache in to\n * automatic deletion if the available storage quota has been exceeded.\n */\n constructor(config = {}) {\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` handlers when a `Response` is about to be returned\n * from a [Cache](https://developer.mozilla.org/en-US/docs/Web/API/Cache) to\n * the handler. It allows the `Response` to be inspected for freshness and\n * prevents it from being used if the `Response`'s `Date` header value is\n * older than the configured `maxAgeSeconds`.\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache the response is in.\n * @param {Response} options.cachedResponse The `Response` object that's been\n * read from a cache and whose freshness should be checked.\n * @return {Response} Either the `cachedResponse`, if it's\n * fresh, or `null` if the `Response` is older than `maxAgeSeconds`.\n *\n * @private\n */\n this.cachedResponseWillBeUsed = async ({ event, request, cacheName, cachedResponse }) => {\n if (!cachedResponse) {\n return null;\n }\n const isFresh = this._isResponseDateFresh(cachedResponse);\n // Expire entries to ensure that even if the expiration date has\n // expired, it'll only be used once.\n const cacheExpiration = this._getCacheExpiration(cacheName);\n dontWaitFor(cacheExpiration.expireEntries());\n // Update the metadata for the request URL to the current timestamp,\n // but don't `await` it as we don't want to block the response.\n const updateTimestampDone = cacheExpiration.updateTimestamp(request.url);\n if (event) {\n try {\n event.waitUntil(updateTimestampDone);\n }\n catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n // The event may not be a fetch event; only log the URL if it is.\n if ('request' in event) {\n logger.warn(`Unable to ensure service worker stays alive when ` +\n `updating cache entry for ` +\n `'${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n }\n return isFresh ? cachedResponse : null;\n };\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-strategies` handlers when an entry is added to a cache.\n *\n * @param {Object} options\n * @param {string} options.cacheName Name of the cache that was updated.\n * @param {string} options.request The Request for the cached entry.\n *\n * @private\n */\n this.cacheDidUpdate = async ({ cacheName, request }) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n const cacheExpiration = this._getCacheExpiration(cacheName);\n await cacheExpiration.updateTimestamp(request.url);\n await cacheExpiration.expireEntries();\n };\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.maxEntries || config.maxAgeSeconds)) {\n throw new WorkboxError('max-entries-or-age-required', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n });\n }\n if (config.maxEntries) {\n assert.isType(config.maxEntries, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxEntries',\n });\n }\n if (config.maxAgeSeconds) {\n assert.isType(config.maxAgeSeconds, 'number', {\n moduleName: 'workbox-expiration',\n className: 'Plugin',\n funcName: 'constructor',\n paramName: 'config.maxAgeSeconds',\n });\n }\n }\n this._config = config;\n this._maxAgeSeconds = config.maxAgeSeconds;\n this._cacheExpirations = new Map();\n if (config.purgeOnQuotaError) {\n registerQuotaErrorCallback(() => this.deleteCacheAndMetadata());\n }\n }\n /**\n * A simple helper method to return a CacheExpiration instance for a given\n * cache name.\n *\n * @param {string} cacheName\n * @return {CacheExpiration}\n *\n * @private\n */\n _getCacheExpiration(cacheName) {\n if (cacheName === cacheNames.getRuntimeName()) {\n throw new WorkboxError('expire-custom-caches-only');\n }\n let cacheExpiration = this._cacheExpirations.get(cacheName);\n if (!cacheExpiration) {\n cacheExpiration = new CacheExpiration(cacheName, this._config);\n this._cacheExpirations.set(cacheName, cacheExpiration);\n }\n return cacheExpiration;\n }\n /**\n * @param {Response} cachedResponse\n * @return {boolean}\n *\n * @private\n */\n _isResponseDateFresh(cachedResponse) {\n if (!this._maxAgeSeconds) {\n // We aren't expiring by age, so return true, it's fresh\n return true;\n }\n // Check if the 'date' header will suffice a quick expiration check.\n // See https://github.com/GoogleChromeLabs/sw-toolbox/issues/164 for\n // discussion.\n const dateHeaderTimestamp = this._getDateHeaderTimestamp(cachedResponse);\n if (dateHeaderTimestamp === null) {\n // Unable to parse date, so assume it's fresh.\n return true;\n }\n // If we have a valid headerTime, then our response is fresh iff the\n // headerTime plus maxAgeSeconds is greater than the current time.\n const now = Date.now();\n return dateHeaderTimestamp >= now - (this._maxAgeSeconds * 1000);\n }\n /**\n * This method will extract the data header and parse it into a useful\n * value.\n *\n * @param {Response} cachedResponse\n * @return {number|null}\n *\n * @private\n */\n _getDateHeaderTimestamp(cachedResponse) {\n if (!cachedResponse.headers.has('date')) {\n return null;\n }\n const dateHeader = cachedResponse.headers.get('date');\n const parsedDate = new Date(dateHeader);\n const headerTime = parsedDate.getTime();\n // If the Date header was invalid for some reason, parsedDate.getTime()\n // will return NaN.\n if (isNaN(headerTime)) {\n return null;\n }\n return headerTime;\n }\n /**\n * This is a helper method that performs two operations:\n *\n * - Deletes *all* the underlying Cache instances associated with this plugin\n * instance, by calling caches.delete() on your behalf.\n * - Deletes the metadata from IndexedDB used to keep track of expiration\n * details for each Cache instance.\n *\n * When using cache expiration, calling this method is preferable to calling\n * `caches.delete()` directly, since this will ensure that the IndexedDB\n * metadata is also cleanly removed and open IndexedDB instances are deleted.\n *\n * Note that if you're *not* using cache expiration for a given cache, calling\n * `caches.delete()` and passing in the cache's name should be sufficient.\n * There is no Workbox-specific method needed for cleanup in that case.\n */\n async deleteCacheAndMetadata() {\n // Do this one at a time instead of all at once via `Promise.all()` to\n // reduce the chance of inconsistency if a promise rejects.\n for (const [cacheName, cacheExpiration] of this._cacheExpirations) {\n await self.caches.delete(cacheName);\n await cacheExpiration.delete();\n }\n // Reset this._cacheExpirations to its initial state.\n this._cacheExpirations = new Map();\n }\n}\nexport { ExpirationPlugin };\n"],"names":["self","_","e","normalizeURL","unNormalizedUrl","url","URL","location","href","hash","CacheTimestampsModel","constructor","cacheName","_cacheName","_db","DBWrapper","onupgradeneeded","event","this","_handleUpgrade","objStore","target","result","createObjectStore","keyPath","createIndex","unique","deleteDatabase","timestamp","entry","id","_getId","put","get","minTimestamp","maxCount","entriesToDelete","transaction","txn","done","request","objectStore","index","openCursor","entriesNotDeletedCount","onsuccess","cursor","value","push","continue","urlsDeleted","delete","CacheExpiration","config","_isRunning","_rerunRequested","_maxEntries","maxEntries","_maxAgeSeconds","maxAgeSeconds","_timestampModel","Date","now","urlsExpired","expireEntries","cache","caches","open","dontWaitFor","setTimestamp","getTimestamp","Infinity","cachedResponseWillBeUsed","async","cachedResponse","isFresh","_isResponseDateFresh","cacheExpiration","_getCacheExpiration","updateTimestampDone","updateTimestamp","waitUntil","error","cacheDidUpdate","_config","_cacheExpirations","Map","purgeOnQuotaError","registerQuotaErrorCallback","deleteCacheAndMetadata","cacheNames","getRuntimeName","WorkboxError","set","dateHeaderTimestamp","_getDateHeaderTimestamp","headers","has","dateHeader","headerTime","getTime","isNaN"],"mappings":"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"}
|
@@ -0,0 +1,102 @@
|
|
1
|
+
this.workbox = this.workbox || {};
|
2
|
+
this.workbox.navigationPreload = (function (exports, logger_js) {
|
3
|
+
'use strict';
|
4
|
+
|
5
|
+
try {
|
6
|
+
self['workbox:navigation-preload:5.1.4'] && _();
|
7
|
+
} catch (e) {}
|
8
|
+
|
9
|
+
/*
|
10
|
+
Copyright 2018 Google LLC
|
11
|
+
|
12
|
+
Use of this source code is governed by an MIT-style
|
13
|
+
license that can be found in the LICENSE file or at
|
14
|
+
https://opensource.org/licenses/MIT.
|
15
|
+
*/
|
16
|
+
/**
|
17
|
+
* @return {boolean} Whether or not the current browser supports enabling
|
18
|
+
* navigation preload.
|
19
|
+
*
|
20
|
+
* @memberof module:workbox-navigation-preload
|
21
|
+
*/
|
22
|
+
|
23
|
+
function isSupported() {
|
24
|
+
return Boolean(self.registration && self.registration.navigationPreload);
|
25
|
+
}
|
26
|
+
|
27
|
+
/*
|
28
|
+
Copyright 2018 Google LLC
|
29
|
+
|
30
|
+
Use of this source code is governed by an MIT-style
|
31
|
+
license that can be found in the LICENSE file or at
|
32
|
+
https://opensource.org/licenses/MIT.
|
33
|
+
*/
|
34
|
+
/**
|
35
|
+
* If the browser supports Navigation Preload, then this will disable it.
|
36
|
+
*
|
37
|
+
* @memberof module:workbox-navigation-preload
|
38
|
+
*/
|
39
|
+
|
40
|
+
function disable() {
|
41
|
+
if (isSupported()) {
|
42
|
+
self.addEventListener('activate', event => {
|
43
|
+
event.waitUntil(self.registration.navigationPreload.disable().then(() => {
|
44
|
+
{
|
45
|
+
logger_js.logger.log(`Navigation preload is disabled.`);
|
46
|
+
}
|
47
|
+
}));
|
48
|
+
});
|
49
|
+
} else {
|
50
|
+
{
|
51
|
+
logger_js.logger.log(`Navigation preload is not supported in this browser.`);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
/*
|
57
|
+
Copyright 2018 Google LLC
|
58
|
+
|
59
|
+
Use of this source code is governed by an MIT-style
|
60
|
+
license that can be found in the LICENSE file or at
|
61
|
+
https://opensource.org/licenses/MIT.
|
62
|
+
*/
|
63
|
+
/**
|
64
|
+
* If the browser supports Navigation Preload, then this will enable it.
|
65
|
+
*
|
66
|
+
* @param {string} [headerValue] Optionally, allows developers to
|
67
|
+
* [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)
|
68
|
+
* the value of the `Service-Worker-Navigation-Preload` header which will be
|
69
|
+
* sent to the server when making the navigation request.
|
70
|
+
*
|
71
|
+
* @memberof module:workbox-navigation-preload
|
72
|
+
*/
|
73
|
+
|
74
|
+
function enable(headerValue) {
|
75
|
+
if (isSupported()) {
|
76
|
+
self.addEventListener('activate', event => {
|
77
|
+
event.waitUntil(self.registration.navigationPreload.enable().then(() => {
|
78
|
+
// Defaults to Service-Worker-Navigation-Preload: true if not set.
|
79
|
+
if (headerValue) {
|
80
|
+
self.registration.navigationPreload.setHeaderValue(headerValue);
|
81
|
+
}
|
82
|
+
|
83
|
+
{
|
84
|
+
logger_js.logger.log(`Navigation preload is enabled.`);
|
85
|
+
}
|
86
|
+
}));
|
87
|
+
});
|
88
|
+
} else {
|
89
|
+
{
|
90
|
+
logger_js.logger.log(`Navigation preload is not supported in this browser.`);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
exports.disable = disable;
|
96
|
+
exports.enable = enable;
|
97
|
+
exports.isSupported = isSupported;
|
98
|
+
|
99
|
+
return exports;
|
100
|
+
|
101
|
+
}({}, workbox.core._private));
|
102
|
+
//# sourceMappingURL=workbox-navigation-preload.dev.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-navigation-preload.dev.js","sources":["../_version.js","../isSupported.js","../disable.js","../enable.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:navigation-preload:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * @return {boolean} Whether or not the current browser supports enabling\n * navigation preload.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction isSupported() {\n return Boolean(self.registration && self.registration.navigationPreload);\n}\nexport { isSupported };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { isSupported } from './isSupported.js';\nimport './_version.js';\n/**\n * If the browser supports Navigation Preload, then this will disable it.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction disable() {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(self.registration.navigationPreload.disable().then(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is disabled.`);\n }\n }));\n });\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\nexport { disable };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { isSupported } from './isSupported.js';\nimport './_version.js';\n/**\n * If the browser supports Navigation Preload, then this will enable it.\n *\n * @param {string} [headerValue] Optionally, allows developers to\n * [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)\n * the value of the `Service-Worker-Navigation-Preload` header which will be\n * sent to the server when making the navigation request.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction enable(headerValue) {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(self.registration.navigationPreload.enable().then(() => {\n // Defaults to Service-Worker-Navigation-Preload: true if not set.\n if (headerValue) {\n self.registration.navigationPreload.setHeaderValue(headerValue);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is enabled.`);\n }\n }));\n });\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\nexport { enable };\n"],"names":["self","_","e","isSupported","Boolean","registration","navigationPreload","disable","addEventListener","event","waitUntil","then","logger","log","enable","headerValue","setHeaderValue"],"mappings":";;;;IAEA,IAAI;IACAA,EAAAA,IAAI,CAAC,kCAAD,CAAJ,IAA4CC,CAAC,EAA7C;IACH,CAFD,CAGA,OAAOC,CAAP,EAAU;;ICLV;;;;;;;AAOA,IACA;;;;;;;IAMA,SAASC,WAAT,GAAuB;IACnB,SAAOC,OAAO,CAACJ,IAAI,CAACK,YAAL,IAAqBL,IAAI,CAACK,YAAL,CAAkBC,iBAAxC,CAAd;IACH;;IChBD;;;;;;;AAOA,IAGA;;;;;;IAKA,SAASC,OAAT,GAAmB;IACf,MAAIJ,WAAW,EAAf,EAAmB;IACfH,IAAAA,IAAI,CAACQ,gBAAL,CAAsB,UAAtB,EAAmCC,KAAD,IAAW;IACzCA,MAAAA,KAAK,CAACC,SAAN,CAAgBV,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCC,OAApC,GAA8CI,IAA9C,CAAmD,MAAM;IACrE,QAA2C;IACvCC,UAAAA,gBAAM,CAACC,GAAP,CAAY,iCAAZ;IACH;IACJ,OAJe,CAAhB;IAKH,KAND;IAOH,GARD,MASK;IACD,IAA2C;IACvCD,MAAAA,gBAAM,CAACC,GAAP,CAAY,sDAAZ;IACH;IACJ;IACJ;;IC9BD;;;;;;;AAOA,IAGA;;;;;;;;;;;IAUA,SAASC,MAAT,CAAgBC,WAAhB,EAA6B;IACzB,MAAIZ,WAAW,EAAf,EAAmB;IACfH,IAAAA,IAAI,CAACQ,gBAAL,CAAsB,UAAtB,EAAmCC,KAAD,IAAW;IACzCA,MAAAA,KAAK,CAACC,SAAN,CAAgBV,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCQ,MAApC,GAA6CH,IAA7C,CAAkD,MAAM;IACpE;IACA,YAAII,WAAJ,EAAiB;IACbf,UAAAA,IAAI,CAACK,YAAL,CAAkBC,iBAAlB,CAAoCU,cAApC,CAAmDD,WAAnD;IACH;;IACD,QAA2C;IACvCH,UAAAA,gBAAM,CAACC,GAAP,CAAY,gCAAZ;IACH;IACJ,OARe,CAAhB;IASH,KAVD;IAWH,GAZD,MAaK;IACD,IAA2C;IACvCD,MAAAA,gBAAM,CAACC,GAAP,CAAY,sDAAZ;IACH;IACJ;IACJ;;;;;;;;;;;;"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
this.workbox=this.workbox||{},this.workbox.navigationPreload=function(t){"use strict";try{self["workbox:navigation-preload:5.1.4"]&&_()}catch(t){}function e(){return Boolean(self.registration&&self.registration.navigationPreload)}return t.disable=function(){e()&&self.addEventListener("activate",t=>{t.waitUntil(self.registration.navigationPreload.disable().then(()=>{}))})},t.enable=function(t){e()&&self.addEventListener("activate",e=>{e.waitUntil(self.registration.navigationPreload.enable().then(()=>{t&&self.registration.navigationPreload.setHeaderValue(t)}))})},t.isSupported=e,t}({});
|
2
|
+
//# sourceMappingURL=workbox-navigation-preload.prod.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-navigation-preload.prod.js","sources":["../_version.js","../isSupported.js","../disable.js","../enable.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:navigation-preload:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport './_version.js';\n/**\n * @return {boolean} Whether or not the current browser supports enabling\n * navigation preload.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction isSupported() {\n return Boolean(self.registration && self.registration.navigationPreload);\n}\nexport { isSupported };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { isSupported } from './isSupported.js';\nimport './_version.js';\n/**\n * If the browser supports Navigation Preload, then this will disable it.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction disable() {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(self.registration.navigationPreload.disable().then(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is disabled.`);\n }\n }));\n });\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\nexport { disable };\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { isSupported } from './isSupported.js';\nimport './_version.js';\n/**\n * If the browser supports Navigation Preload, then this will enable it.\n *\n * @param {string} [headerValue] Optionally, allows developers to\n * [override](https://developers.google.com/web/updates/2017/02/navigation-preload#changing_the_header)\n * the value of the `Service-Worker-Navigation-Preload` header which will be\n * sent to the server when making the navigation request.\n *\n * @memberof module:workbox-navigation-preload\n */\nfunction enable(headerValue) {\n if (isSupported()) {\n self.addEventListener('activate', (event) => {\n event.waitUntil(self.registration.navigationPreload.enable().then(() => {\n // Defaults to Service-Worker-Navigation-Preload: true if not set.\n if (headerValue) {\n self.registration.navigationPreload.setHeaderValue(headerValue);\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is enabled.`);\n }\n }));\n });\n }\n else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Navigation preload is not supported in this browser.`);\n }\n }\n}\nexport { enable };\n"],"names":["self","_","e","isSupported","Boolean","registration","navigationPreload","addEventListener","event","waitUntil","disable","then","headerValue","enable","setHeaderValue"],"mappings":"sFAEA,IACIA,KAAK,qCAAuCC,IAEhD,MAAOC,ICSP,SAASC,WACEC,QAAQJ,KAAKK,cAAgBL,KAAKK,aAAaC,oCCA1D,WACQH,KACAH,KAAKO,iBAAiB,WAAaC,IAC/BA,EAAMC,UAAUT,KAAKK,aAAaC,kBAAkBI,UAAUC,KAAK,qBCE/E,SAAgBC,GACRT,KACAH,KAAKO,iBAAiB,WAAaC,IAC/BA,EAAMC,UAAUT,KAAKK,aAAaC,kBAAkBO,SAASF,KAAK,KAE1DC,GACAZ,KAAKK,aAAaC,kBAAkBQ,eAAeF"}
|
@@ -0,0 +1,235 @@
|
|
1
|
+
this.workbox = this.workbox || {};
|
2
|
+
this.workbox.googleAnalytics = (function (exports, BackgroundSyncPlugin_js, cacheNames_js, getFriendlyURL_js, logger_js, Route_js, Router_js, NetworkFirst_js, NetworkOnly_js) {
|
3
|
+
'use strict';
|
4
|
+
|
5
|
+
try {
|
6
|
+
self['workbox:google-analytics:5.1.4'] && _();
|
7
|
+
} catch (e) {}
|
8
|
+
|
9
|
+
/*
|
10
|
+
Copyright 2018 Google LLC
|
11
|
+
|
12
|
+
Use of this source code is governed by an MIT-style
|
13
|
+
license that can be found in the LICENSE file or at
|
14
|
+
https://opensource.org/licenses/MIT.
|
15
|
+
*/
|
16
|
+
const QUEUE_NAME = 'workbox-google-analytics';
|
17
|
+
const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes
|
18
|
+
|
19
|
+
const GOOGLE_ANALYTICS_HOST = 'www.google-analytics.com';
|
20
|
+
const GTM_HOST = 'www.googletagmanager.com';
|
21
|
+
const ANALYTICS_JS_PATH = '/analytics.js';
|
22
|
+
const GTAG_JS_PATH = '/gtag/js';
|
23
|
+
const GTM_JS_PATH = '/gtm.js';
|
24
|
+
// endpoints. Most of the time the default path (/collect) is used, but
|
25
|
+
// occasionally an experimental endpoint is used when testing new features,
|
26
|
+
// (e.g. /r/collect or /j/collect)
|
27
|
+
|
28
|
+
const COLLECT_PATHS_REGEX = /^\/(\w+\/)?collect/;
|
29
|
+
|
30
|
+
/*
|
31
|
+
Copyright 2018 Google LLC
|
32
|
+
|
33
|
+
Use of this source code is governed by an MIT-style
|
34
|
+
license that can be found in the LICENSE file or at
|
35
|
+
https://opensource.org/licenses/MIT.
|
36
|
+
*/
|
37
|
+
/**
|
38
|
+
* Creates the requestWillDequeue callback to be used with the background
|
39
|
+
* sync plugin. The callback takes the failed request and adds the
|
40
|
+
* `qt` param based on the current time, as well as applies any other
|
41
|
+
* user-defined hit modifications.
|
42
|
+
*
|
43
|
+
* @param {Object} config See {@link module:workbox-google-analytics.initialize}.
|
44
|
+
* @return {Function} The requestWillDequeue callback function.
|
45
|
+
*
|
46
|
+
* @private
|
47
|
+
*/
|
48
|
+
|
49
|
+
const createOnSyncCallback = config => {
|
50
|
+
return async ({
|
51
|
+
queue
|
52
|
+
}) => {
|
53
|
+
let entry;
|
54
|
+
|
55
|
+
while (entry = await queue.shiftRequest()) {
|
56
|
+
const {
|
57
|
+
request,
|
58
|
+
timestamp
|
59
|
+
} = entry;
|
60
|
+
const url = new URL(request.url);
|
61
|
+
|
62
|
+
try {
|
63
|
+
// Measurement protocol requests can set their payload parameters in
|
64
|
+
// either the URL query string (for GET requests) or the POST body.
|
65
|
+
const params = request.method === 'POST' ? new URLSearchParams(await request.clone().text()) : url.searchParams; // Calculate the qt param, accounting for the fact that an existing
|
66
|
+
// qt param may be present and should be updated rather than replaced.
|
67
|
+
|
68
|
+
const originalHitTime = timestamp - (Number(params.get('qt')) || 0);
|
69
|
+
const queueTime = Date.now() - originalHitTime; // Set the qt param prior to applying hitFilter or parameterOverrides.
|
70
|
+
|
71
|
+
params.set('qt', String(queueTime)); // Apply `parameterOverrides`, if set.
|
72
|
+
|
73
|
+
if (config.parameterOverrides) {
|
74
|
+
for (const param of Object.keys(config.parameterOverrides)) {
|
75
|
+
const value = config.parameterOverrides[param];
|
76
|
+
params.set(param, value);
|
77
|
+
}
|
78
|
+
} // Apply `hitFilter`, if set.
|
79
|
+
|
80
|
+
|
81
|
+
if (typeof config.hitFilter === 'function') {
|
82
|
+
config.hitFilter.call(null, params);
|
83
|
+
} // Retry the fetch. Ignore URL search params from the URL as they're
|
84
|
+
// now in the post body.
|
85
|
+
|
86
|
+
|
87
|
+
await fetch(new Request(url.origin + url.pathname, {
|
88
|
+
body: params.toString(),
|
89
|
+
method: 'POST',
|
90
|
+
mode: 'cors',
|
91
|
+
credentials: 'omit',
|
92
|
+
headers: {
|
93
|
+
'Content-Type': 'text/plain'
|
94
|
+
}
|
95
|
+
}));
|
96
|
+
|
97
|
+
if ("dev" !== 'production') {
|
98
|
+
logger_js.logger.log(`Request for '${getFriendlyURL_js.getFriendlyURL(url.href)}'` + `has been replayed`);
|
99
|
+
}
|
100
|
+
} catch (err) {
|
101
|
+
await queue.unshiftRequest(entry);
|
102
|
+
|
103
|
+
{
|
104
|
+
logger_js.logger.log(`Request for '${getFriendlyURL_js.getFriendlyURL(url.href)}'` + `failed to replay, putting it back in the queue.`);
|
105
|
+
}
|
106
|
+
|
107
|
+
throw err;
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
111
|
+
{
|
112
|
+
logger_js.logger.log(`All Google Analytics request successfully replayed; ` + `the queue is now empty!`);
|
113
|
+
}
|
114
|
+
};
|
115
|
+
};
|
116
|
+
/**
|
117
|
+
* Creates GET and POST routes to catch failed Measurement Protocol hits.
|
118
|
+
*
|
119
|
+
* @param {BackgroundSyncPlugin} bgSyncPlugin
|
120
|
+
* @return {Array<Route>} The created routes.
|
121
|
+
*
|
122
|
+
* @private
|
123
|
+
*/
|
124
|
+
|
125
|
+
|
126
|
+
const createCollectRoutes = bgSyncPlugin => {
|
127
|
+
const match = ({
|
128
|
+
url
|
129
|
+
}) => url.hostname === GOOGLE_ANALYTICS_HOST && COLLECT_PATHS_REGEX.test(url.pathname);
|
130
|
+
|
131
|
+
const handler = new NetworkOnly_js.NetworkOnly({
|
132
|
+
plugins: [bgSyncPlugin]
|
133
|
+
});
|
134
|
+
return [new Route_js.Route(match, handler, 'GET'), new Route_js.Route(match, handler, 'POST')];
|
135
|
+
};
|
136
|
+
/**
|
137
|
+
* Creates a route with a network first strategy for the analytics.js script.
|
138
|
+
*
|
139
|
+
* @param {string} cacheName
|
140
|
+
* @return {Route} The created route.
|
141
|
+
*
|
142
|
+
* @private
|
143
|
+
*/
|
144
|
+
|
145
|
+
|
146
|
+
const createAnalyticsJsRoute = cacheName => {
|
147
|
+
const match = ({
|
148
|
+
url
|
149
|
+
}) => url.hostname === GOOGLE_ANALYTICS_HOST && url.pathname === ANALYTICS_JS_PATH;
|
150
|
+
|
151
|
+
const handler = new NetworkFirst_js.NetworkFirst({
|
152
|
+
cacheName
|
153
|
+
});
|
154
|
+
return new Route_js.Route(match, handler, 'GET');
|
155
|
+
};
|
156
|
+
/**
|
157
|
+
* Creates a route with a network first strategy for the gtag.js script.
|
158
|
+
*
|
159
|
+
* @param {string} cacheName
|
160
|
+
* @return {Route} The created route.
|
161
|
+
*
|
162
|
+
* @private
|
163
|
+
*/
|
164
|
+
|
165
|
+
|
166
|
+
const createGtagJsRoute = cacheName => {
|
167
|
+
const match = ({
|
168
|
+
url
|
169
|
+
}) => url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH;
|
170
|
+
|
171
|
+
const handler = new NetworkFirst_js.NetworkFirst({
|
172
|
+
cacheName
|
173
|
+
});
|
174
|
+
return new Route_js.Route(match, handler, 'GET');
|
175
|
+
};
|
176
|
+
/**
|
177
|
+
* Creates a route with a network first strategy for the gtm.js script.
|
178
|
+
*
|
179
|
+
* @param {string} cacheName
|
180
|
+
* @return {Route} The created route.
|
181
|
+
*
|
182
|
+
* @private
|
183
|
+
*/
|
184
|
+
|
185
|
+
|
186
|
+
const createGtmJsRoute = cacheName => {
|
187
|
+
const match = ({
|
188
|
+
url
|
189
|
+
}) => url.hostname === GTM_HOST && url.pathname === GTM_JS_PATH;
|
190
|
+
|
191
|
+
const handler = new NetworkFirst_js.NetworkFirst({
|
192
|
+
cacheName
|
193
|
+
});
|
194
|
+
return new Route_js.Route(match, handler, 'GET');
|
195
|
+
};
|
196
|
+
/**
|
197
|
+
* @param {Object=} [options]
|
198
|
+
* @param {Object} [options.cacheName] The cache name to store and retrieve
|
199
|
+
* analytics.js. Defaults to the cache names provided by `workbox-core`.
|
200
|
+
* @param {Object} [options.parameterOverrides]
|
201
|
+
* [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),
|
202
|
+
* expressed as key/value pairs, to be added to replayed Google Analytics
|
203
|
+
* requests. This can be used to, e.g., set a custom dimension indicating
|
204
|
+
* that the request was replayed.
|
205
|
+
* @param {Function} [options.hitFilter] A function that allows you to modify
|
206
|
+
* the hit parameters prior to replaying
|
207
|
+
* the hit. The function is invoked with the original hit's URLSearchParams
|
208
|
+
* object as its only argument.
|
209
|
+
*
|
210
|
+
* @memberof module:workbox-google-analytics
|
211
|
+
*/
|
212
|
+
|
213
|
+
|
214
|
+
const initialize = (options = {}) => {
|
215
|
+
const cacheName = cacheNames_js.cacheNames.getGoogleAnalyticsName(options.cacheName);
|
216
|
+
const bgSyncPlugin = new BackgroundSyncPlugin_js.BackgroundSyncPlugin(QUEUE_NAME, {
|
217
|
+
maxRetentionTime: MAX_RETENTION_TIME,
|
218
|
+
onSync: createOnSyncCallback(options)
|
219
|
+
});
|
220
|
+
const routes = [createGtmJsRoute(cacheName), createAnalyticsJsRoute(cacheName), createGtagJsRoute(cacheName), ...createCollectRoutes(bgSyncPlugin)];
|
221
|
+
const router = new Router_js.Router();
|
222
|
+
|
223
|
+
for (const route of routes) {
|
224
|
+
router.registerRoute(route);
|
225
|
+
}
|
226
|
+
|
227
|
+
router.addFetchListener();
|
228
|
+
};
|
229
|
+
|
230
|
+
exports.initialize = initialize;
|
231
|
+
|
232
|
+
return exports;
|
233
|
+
|
234
|
+
}({}, workbox.backgroundSync, workbox.core._private, workbox.core._private, workbox.core._private, workbox.routing, workbox.routing, workbox.strategies, workbox.strategies));
|
235
|
+
//# sourceMappingURL=workbox-offline-ga.dev.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-offline-ga.dev.js","sources":["../_version.js","../utils/constants.js","../initialize.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:google-analytics:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const QUEUE_NAME = 'workbox-google-analytics';\nexport const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes\nexport const GOOGLE_ANALYTICS_HOST = 'www.google-analytics.com';\nexport const GTM_HOST = 'www.googletagmanager.com';\nexport const ANALYTICS_JS_PATH = '/analytics.js';\nexport const GTAG_JS_PATH = '/gtag/js';\nexport const GTM_JS_PATH = '/gtm.js';\nexport const COLLECT_DEFAULT_PATH = '/collect';\n// This RegExp matches all known Measurement Protocol single-hit collect\n// endpoints. Most of the time the default path (/collect) is used, but\n// occasionally an experimental endpoint is used when testing new features,\n// (e.g. /r/collect or /j/collect)\nexport const COLLECT_PATHS_REGEX = /^\\/(\\w+\\/)?collect/;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { BackgroundSyncPlugin } from 'workbox-background-sync/BackgroundSyncPlugin.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from 'workbox-routing/Route.js';\nimport { Router } from 'workbox-routing/Router.js';\nimport { NetworkFirst } from 'workbox-strategies/NetworkFirst.js';\nimport { NetworkOnly } from 'workbox-strategies/NetworkOnly.js';\nimport { QUEUE_NAME, MAX_RETENTION_TIME, GOOGLE_ANALYTICS_HOST, GTM_HOST, ANALYTICS_JS_PATH, GTAG_JS_PATH, GTM_JS_PATH, COLLECT_PATHS_REGEX, } from './utils/constants.js';\nimport './_version.js';\n/**\n * Creates the requestWillDequeue callback to be used with the background\n * sync plugin. The callback takes the failed request and adds the\n * `qt` param based on the current time, as well as applies any other\n * user-defined hit modifications.\n *\n * @param {Object} config See {@link module:workbox-google-analytics.initialize}.\n * @return {Function} The requestWillDequeue callback function.\n *\n * @private\n */\nconst createOnSyncCallback = (config) => {\n return async ({ queue }) => {\n let entry;\n while (entry = await queue.shiftRequest()) {\n const { request, timestamp } = entry;\n const url = new URL(request.url);\n try {\n // Measurement protocol requests can set their payload parameters in\n // either the URL query string (for GET requests) or the POST body.\n const params = request.method === 'POST' ?\n new URLSearchParams(await request.clone().text()) :\n url.searchParams;\n // Calculate the qt param, accounting for the fact that an existing\n // qt param may be present and should be updated rather than replaced.\n const originalHitTime = timestamp - (Number(params.get('qt')) || 0);\n const queueTime = Date.now() - originalHitTime;\n // Set the qt param prior to applying hitFilter or parameterOverrides.\n params.set('qt', String(queueTime));\n // Apply `parameterOverrides`, if set.\n if (config.parameterOverrides) {\n for (const param of Object.keys(config.parameterOverrides)) {\n const value = config.parameterOverrides[param];\n params.set(param, value);\n }\n }\n // Apply `hitFilter`, if set.\n if (typeof config.hitFilter === 'function') {\n config.hitFilter.call(null, params);\n }\n // Retry the fetch. Ignore URL search params from the URL as they're\n // now in the post body.\n await fetch(new Request(url.origin + url.pathname, {\n body: params.toString(),\n method: 'POST',\n mode: 'cors',\n credentials: 'omit',\n headers: { 'Content-Type': 'text/plain' },\n }));\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(url.href)}'` +\n `has been replayed`);\n }\n }\n catch (err) {\n await queue.unshiftRequest(entry);\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(url.href)}'` +\n `failed to replay, putting it back in the queue.`);\n }\n throw err;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All Google Analytics request successfully replayed; ` +\n `the queue is now empty!`);\n }\n };\n};\n/**\n * Creates GET and POST routes to catch failed Measurement Protocol hits.\n *\n * @param {BackgroundSyncPlugin} bgSyncPlugin\n * @return {Array<Route>} The created routes.\n *\n * @private\n */\nconst createCollectRoutes = (bgSyncPlugin) => {\n const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&\n COLLECT_PATHS_REGEX.test(url.pathname);\n const handler = new NetworkOnly({\n plugins: [bgSyncPlugin],\n });\n return [\n new Route(match, handler, 'GET'),\n new Route(match, handler, 'POST'),\n ];\n};\n/**\n * Creates a route with a network first strategy for the analytics.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createAnalyticsJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&\n url.pathname === ANALYTICS_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * Creates a route with a network first strategy for the gtag.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createGtagJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GTM_HOST &&\n url.pathname === GTAG_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * Creates a route with a network first strategy for the gtm.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createGtmJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GTM_HOST &&\n url.pathname === GTM_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * @param {Object=} [options]\n * @param {Object} [options.cacheName] The cache name to store and retrieve\n * analytics.js. Defaults to the cache names provided by `workbox-core`.\n * @param {Object} [options.parameterOverrides]\n * [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),\n * expressed as key/value pairs, to be added to replayed Google Analytics\n * requests. This can be used to, e.g., set a custom dimension indicating\n * that the request was replayed.\n * @param {Function} [options.hitFilter] A function that allows you to modify\n * the hit parameters prior to replaying\n * the hit. The function is invoked with the original hit's URLSearchParams\n * object as its only argument.\n *\n * @memberof module:workbox-google-analytics\n */\nconst initialize = (options = {}) => {\n const cacheName = cacheNames.getGoogleAnalyticsName(options.cacheName);\n const bgSyncPlugin = new BackgroundSyncPlugin(QUEUE_NAME, {\n maxRetentionTime: MAX_RETENTION_TIME,\n onSync: createOnSyncCallback(options),\n });\n const routes = [\n createGtmJsRoute(cacheName),\n createAnalyticsJsRoute(cacheName),\n createGtagJsRoute(cacheName),\n ...createCollectRoutes(bgSyncPlugin),\n ];\n const router = new Router();\n for (const route of routes) {\n router.registerRoute(route);\n }\n router.addFetchListener();\n};\nexport { initialize, };\n"],"names":["self","_","e","QUEUE_NAME","MAX_RETENTION_TIME","GOOGLE_ANALYTICS_HOST","GTM_HOST","ANALYTICS_JS_PATH","GTAG_JS_PATH","GTM_JS_PATH","COLLECT_PATHS_REGEX","createOnSyncCallback","config","queue","entry","shiftRequest","request","timestamp","url","URL","params","method","URLSearchParams","clone","text","searchParams","originalHitTime","Number","get","queueTime","Date","now","set","String","parameterOverrides","param","Object","keys","value","hitFilter","call","fetch","Request","origin","pathname","body","toString","mode","credentials","headers","process","logger","log","getFriendlyURL","href","err","unshiftRequest","createCollectRoutes","bgSyncPlugin","match","hostname","test","handler","NetworkOnly","plugins","Route","createAnalyticsJsRoute","cacheName","NetworkFirst","createGtagJsRoute","createGtmJsRoute","initialize","options","cacheNames","getGoogleAnalyticsName","BackgroundSyncPlugin","maxRetentionTime","onSync","routes","router","Router","route","registerRoute","addFetchListener"],"mappings":"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"}
|
@@ -0,0 +1,2 @@
|
|
1
|
+
this.workbox=this.workbox||{},this.workbox.googleAnalytics=function(t,o,e,n,a,c,r,w,s){"use strict";try{self["workbox:google-analytics:5.1.4"]&&_()}catch(t){}const i=/^\/(\w+\/)?collect/,l=t=>{const o=({url:t})=>"www.google-analytics.com"===t.hostname&&i.test(t.pathname),e=new s.NetworkOnly({plugins:[t]});return[new c.Route(o,e,"GET"),new c.Route(o,e,"POST")]},g=t=>{const o=new w.NetworkFirst({cacheName:t});return new c.Route(({url:t})=>"www.google-analytics.com"===t.hostname&&"/analytics.js"===t.pathname,o,"GET")},m=t=>{const o=new w.NetworkFirst({cacheName:t});return new c.Route(({url:t})=>"www.googletagmanager.com"===t.hostname&&"/gtag/js"===t.pathname,o,"GET")},u=t=>{const o=new w.NetworkFirst({cacheName:t});return new c.Route(({url:t})=>"www.googletagmanager.com"===t.hostname&&"/gtm.js"===t.pathname,o,"GET")};return t.initialize=(t={})=>{const n=e.cacheNames.getGoogleAnalyticsName(t.cacheName),a=new o.BackgroundSyncPlugin("workbox-google-analytics",{maxRetentionTime:2880,onSync:(c=t,async({queue:t})=>{let o;for(;o=await t.shiftRequest();){const{request:e,timestamp:n}=o,a=new URL(e.url);try{const t="POST"===e.method?new URLSearchParams(await e.clone().text()):a.searchParams,o=n-(Number(t.get("qt"))||0),r=Date.now()-o;if(t.set("qt",String(r)),c.parameterOverrides)for(const o of Object.keys(c.parameterOverrides)){const e=c.parameterOverrides[o];t.set(o,e)}"function"==typeof c.hitFilter&&c.hitFilter.call(null,t),await fetch(new Request(a.origin+a.pathname,{body:t.toString(),method:"POST",mode:"cors",credentials:"omit",headers:{"Content-Type":"text/plain"}}))}catch(e){throw await t.unshiftRequest(o),e}}})});var c;const w=[u(n),g(n),m(n),...l(a)],s=new r.Router;for(const t of w)s.registerRoute(t);s.addFetchListener()},t}({},workbox.backgroundSync,workbox.core._private,workbox.core._private,workbox.core._private,workbox.routing,workbox.routing,workbox.strategies,workbox.strategies);
|
2
|
+
//# sourceMappingURL=workbox-offline-ga.prod.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"workbox-offline-ga.prod.js","sources":["../_version.js","../utils/constants.js","../initialize.js"],"sourcesContent":["\"use strict\";\n// @ts-ignore\ntry {\n self['workbox:google-analytics:5.1.4'] && _();\n}\ncatch (e) { }\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport '../_version.js';\nexport const QUEUE_NAME = 'workbox-google-analytics';\nexport const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes\nexport const GOOGLE_ANALYTICS_HOST = 'www.google-analytics.com';\nexport const GTM_HOST = 'www.googletagmanager.com';\nexport const ANALYTICS_JS_PATH = '/analytics.js';\nexport const GTAG_JS_PATH = '/gtag/js';\nexport const GTM_JS_PATH = '/gtm.js';\nexport const COLLECT_DEFAULT_PATH = '/collect';\n// This RegExp matches all known Measurement Protocol single-hit collect\n// endpoints. Most of the time the default path (/collect) is used, but\n// occasionally an experimental endpoint is used when testing new features,\n// (e.g. /r/collect or /j/collect)\nexport const COLLECT_PATHS_REGEX = /^\\/(\\w+\\/)?collect/;\n","/*\n Copyright 2018 Google LLC\n\n Use of this source code is governed by an MIT-style\n license that can be found in the LICENSE file or at\n https://opensource.org/licenses/MIT.\n*/\nimport { BackgroundSyncPlugin } from 'workbox-background-sync/BackgroundSyncPlugin.js';\nimport { cacheNames } from 'workbox-core/_private/cacheNames.js';\nimport { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';\nimport { logger } from 'workbox-core/_private/logger.js';\nimport { Route } from 'workbox-routing/Route.js';\nimport { Router } from 'workbox-routing/Router.js';\nimport { NetworkFirst } from 'workbox-strategies/NetworkFirst.js';\nimport { NetworkOnly } from 'workbox-strategies/NetworkOnly.js';\nimport { QUEUE_NAME, MAX_RETENTION_TIME, GOOGLE_ANALYTICS_HOST, GTM_HOST, ANALYTICS_JS_PATH, GTAG_JS_PATH, GTM_JS_PATH, COLLECT_PATHS_REGEX, } from './utils/constants.js';\nimport './_version.js';\n/**\n * Creates the requestWillDequeue callback to be used with the background\n * sync plugin. The callback takes the failed request and adds the\n * `qt` param based on the current time, as well as applies any other\n * user-defined hit modifications.\n *\n * @param {Object} config See {@link module:workbox-google-analytics.initialize}.\n * @return {Function} The requestWillDequeue callback function.\n *\n * @private\n */\nconst createOnSyncCallback = (config) => {\n return async ({ queue }) => {\n let entry;\n while (entry = await queue.shiftRequest()) {\n const { request, timestamp } = entry;\n const url = new URL(request.url);\n try {\n // Measurement protocol requests can set their payload parameters in\n // either the URL query string (for GET requests) or the POST body.\n const params = request.method === 'POST' ?\n new URLSearchParams(await request.clone().text()) :\n url.searchParams;\n // Calculate the qt param, accounting for the fact that an existing\n // qt param may be present and should be updated rather than replaced.\n const originalHitTime = timestamp - (Number(params.get('qt')) || 0);\n const queueTime = Date.now() - originalHitTime;\n // Set the qt param prior to applying hitFilter or parameterOverrides.\n params.set('qt', String(queueTime));\n // Apply `parameterOverrides`, if set.\n if (config.parameterOverrides) {\n for (const param of Object.keys(config.parameterOverrides)) {\n const value = config.parameterOverrides[param];\n params.set(param, value);\n }\n }\n // Apply `hitFilter`, if set.\n if (typeof config.hitFilter === 'function') {\n config.hitFilter.call(null, params);\n }\n // Retry the fetch. Ignore URL search params from the URL as they're\n // now in the post body.\n await fetch(new Request(url.origin + url.pathname, {\n body: params.toString(),\n method: 'POST',\n mode: 'cors',\n credentials: 'omit',\n headers: { 'Content-Type': 'text/plain' },\n }));\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(url.href)}'` +\n `has been replayed`);\n }\n }\n catch (err) {\n await queue.unshiftRequest(entry);\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(url.href)}'` +\n `failed to replay, putting it back in the queue.`);\n }\n throw err;\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All Google Analytics request successfully replayed; ` +\n `the queue is now empty!`);\n }\n };\n};\n/**\n * Creates GET and POST routes to catch failed Measurement Protocol hits.\n *\n * @param {BackgroundSyncPlugin} bgSyncPlugin\n * @return {Array<Route>} The created routes.\n *\n * @private\n */\nconst createCollectRoutes = (bgSyncPlugin) => {\n const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&\n COLLECT_PATHS_REGEX.test(url.pathname);\n const handler = new NetworkOnly({\n plugins: [bgSyncPlugin],\n });\n return [\n new Route(match, handler, 'GET'),\n new Route(match, handler, 'POST'),\n ];\n};\n/**\n * Creates a route with a network first strategy for the analytics.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createAnalyticsJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&\n url.pathname === ANALYTICS_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * Creates a route with a network first strategy for the gtag.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createGtagJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GTM_HOST &&\n url.pathname === GTAG_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * Creates a route with a network first strategy for the gtm.js script.\n *\n * @param {string} cacheName\n * @return {Route} The created route.\n *\n * @private\n */\nconst createGtmJsRoute = (cacheName) => {\n const match = ({ url }) => url.hostname === GTM_HOST &&\n url.pathname === GTM_JS_PATH;\n const handler = new NetworkFirst({ cacheName });\n return new Route(match, handler, 'GET');\n};\n/**\n * @param {Object=} [options]\n * @param {Object} [options.cacheName] The cache name to store and retrieve\n * analytics.js. Defaults to the cache names provided by `workbox-core`.\n * @param {Object} [options.parameterOverrides]\n * [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),\n * expressed as key/value pairs, to be added to replayed Google Analytics\n * requests. This can be used to, e.g., set a custom dimension indicating\n * that the request was replayed.\n * @param {Function} [options.hitFilter] A function that allows you to modify\n * the hit parameters prior to replaying\n * the hit. The function is invoked with the original hit's URLSearchParams\n * object as its only argument.\n *\n * @memberof module:workbox-google-analytics\n */\nconst initialize = (options = {}) => {\n const cacheName = cacheNames.getGoogleAnalyticsName(options.cacheName);\n const bgSyncPlugin = new BackgroundSyncPlugin(QUEUE_NAME, {\n maxRetentionTime: MAX_RETENTION_TIME,\n onSync: createOnSyncCallback(options),\n });\n const routes = [\n createGtmJsRoute(cacheName),\n createAnalyticsJsRoute(cacheName),\n createGtagJsRoute(cacheName),\n ...createCollectRoutes(bgSyncPlugin),\n ];\n const router = new Router();\n for (const route of routes) {\n router.registerRoute(route);\n }\n router.addFetchListener();\n};\nexport { initialize, };\n"],"names":["self","_","e","COLLECT_PATHS_REGEX","createCollectRoutes","bgSyncPlugin","match","url","hostname","test","pathname","handler","NetworkOnly","plugins","Route","createAnalyticsJsRoute","cacheName","NetworkFirst","createGtagJsRoute","createGtmJsRoute","options","cacheNames","getGoogleAnalyticsName","BackgroundSyncPlugin","maxRetentionTime","onSync","config","async","queue","entry","shiftRequest","request","timestamp","URL","params","method","URLSearchParams","clone","text","searchParams","originalHitTime","Number","get","queueTime","Date","now","set","String","parameterOverrides","param","Object","keys","value","hitFilter","call","fetch","Request","origin","body","toString","mode","credentials","headers","err","unshiftRequest","routes","router","Router","route","registerRoute","addFetchListener"],"mappings":"oGAEA,IACIA,KAAK,mCAAqCC,IAE9C,MAAOC,ICGA,MAYMC,EAAsB,qBC0E7BC,EAAuBC,UACnBC,EAAQ,EAAGC,IAAAA,KDrFgB,6BCqFNA,EAAIC,UAC3BL,EAAoBM,KAAKF,EAAIG,UAC3BC,EAAU,IAAIC,cAAY,CAC5BC,QAAS,CAACR,WAEP,CACH,IAAIS,QAAMR,EAAOK,EAAS,OAC1B,IAAIG,QAAMR,EAAOK,EAAS,UAW5BI,EAA0BC,UAGtBL,EAAU,IAAIM,eAAa,CAAED,UAAAA,WAC5B,IAAIF,QAHG,EAAGP,IAAAA,KDxGgB,6BCwGNA,EAAIC,UDtGF,kBCuGzBD,EAAIG,SAEgBC,EAAS,QAU/BO,EAAqBF,UAGjBL,EAAU,IAAIM,eAAa,CAAED,UAAAA,WAC5B,IAAIF,QAHG,EAAGP,IAAAA,KDrHG,6BCqHOA,EAAIC,UDnHP,aCoHpBD,EAAIG,SAEgBC,EAAS,QAU/BQ,EAAoBH,UAGhBL,EAAU,IAAIM,eAAa,CAAED,UAAAA,WAC5B,IAAIF,QAHG,EAAGP,IAAAA,KDnIG,6BCmIOA,EAAIC,UDhIR,YCiInBD,EAAIG,SAEgBC,EAAS,4BAkBlB,CAACS,EAAU,YACpBJ,EAAYK,aAAWC,uBAAuBF,EAAQJ,WACtDX,EAAe,IAAIkB,uBD7JH,2BC6JoC,CACtDC,iBD7J0B,KC8J1BC,QA3IsBC,EA2ION,EA1I1BO,OAASC,MAAAA,UACRC,OACGA,QAAcD,EAAME,gBAAgB,OACjCC,QAAEA,EAAFC,UAAWA,GAAcH,EACzBtB,EAAM,IAAI0B,IAAIF,EAAQxB,eAIlB2B,EAA4B,SAAnBH,EAAQI,OACnB,IAAIC,sBAAsBL,EAAQM,QAAQC,QAC1C/B,EAAIgC,aAGFC,EAAkBR,GAAaS,OAAOP,EAAOQ,IAAI,QAAU,GAC3DC,EAAYC,KAAKC,MAAQL,KAE/BN,EAAOY,IAAI,KAAMC,OAAOJ,IAEpBjB,EAAOsB,uBACF,MAAMC,KAASC,OAAOC,KAAKzB,EAAOsB,oBAAqB,OAClDI,EAAQ1B,EAAOsB,mBAAmBC,GACxCf,EAAOY,IAAIG,EAAOG,GAIM,mBAArB1B,EAAO2B,WACd3B,EAAO2B,UAAUC,KAAK,KAAMpB,SAI1BqB,MAAM,IAAIC,QAAQjD,EAAIkD,OAASlD,EAAIG,SAAU,CAC/CgD,KAAMxB,EAAOyB,WACbxB,OAAQ,OACRyB,KAAM,OACNC,YAAa,OACbC,QAAS,gBAAkB,iBAOnC,MAAOC,eACGnC,EAAMoC,eAAenC,GAKrBkC,QAjDQrC,IAAAA,QA6IpBuC,EAAS,CACX9C,EAAiBH,GACjBD,EAAuBC,GACvBE,EAAkBF,MACfZ,EAAoBC,IAErB6D,EAAS,IAAIC,aACd,MAAMC,KAASH,EAChBC,EAAOG,cAAcD,GAEzBF,EAAOI"}
|
@@ -0,0 +1,1210 @@
|
|
1
|
+
this.workbox = this.workbox || {};
|
2
|
+
this.workbox.precaching = (function (exports, cacheNames_js, getFriendlyURL_js, logger_js, assert_js, cacheWrapper_js, fetchWrapper_js, WorkboxError_js, copyResponse_js) {
|
3
|
+
'use strict';
|
4
|
+
|
5
|
+
try {
|
6
|
+
self['workbox:precaching:5.1.4'] && _();
|
7
|
+
} catch (e) {}
|
8
|
+
|
9
|
+
/*
|
10
|
+
Copyright 2019 Google LLC
|
11
|
+
|
12
|
+
Use of this source code is governed by an MIT-style
|
13
|
+
license that can be found in the LICENSE file or at
|
14
|
+
https://opensource.org/licenses/MIT.
|
15
|
+
*/
|
16
|
+
const plugins = [];
|
17
|
+
const precachePlugins = {
|
18
|
+
/*
|
19
|
+
* @return {Array}
|
20
|
+
* @private
|
21
|
+
*/
|
22
|
+
get() {
|
23
|
+
return plugins;
|
24
|
+
},
|
25
|
+
|
26
|
+
/*
|
27
|
+
* @param {Array} newPlugins
|
28
|
+
* @private
|
29
|
+
*/
|
30
|
+
add(newPlugins) {
|
31
|
+
plugins.push(...newPlugins);
|
32
|
+
}
|
33
|
+
|
34
|
+
};
|
35
|
+
|
36
|
+
/*
|
37
|
+
Copyright 2019 Google LLC
|
38
|
+
|
39
|
+
Use of this source code is governed by an MIT-style
|
40
|
+
license that can be found in the LICENSE file or at
|
41
|
+
https://opensource.org/licenses/MIT.
|
42
|
+
*/
|
43
|
+
/**
|
44
|
+
* Adds plugins to precaching.
|
45
|
+
*
|
46
|
+
* @param {Array<Object>} newPlugins
|
47
|
+
*
|
48
|
+
* @memberof module:workbox-precaching
|
49
|
+
*/
|
50
|
+
|
51
|
+
function addPlugins(newPlugins) {
|
52
|
+
precachePlugins.add(newPlugins);
|
53
|
+
}
|
54
|
+
|
55
|
+
/*
|
56
|
+
Copyright 2018 Google LLC
|
57
|
+
|
58
|
+
Use of this source code is governed by an MIT-style
|
59
|
+
license that can be found in the LICENSE file or at
|
60
|
+
https://opensource.org/licenses/MIT.
|
61
|
+
*/
|
62
|
+
|
63
|
+
const REVISION_SEARCH_PARAM = '__WB_REVISION__';
|
64
|
+
/**
|
65
|
+
* Converts a manifest entry into a versioned URL suitable for precaching.
|
66
|
+
*
|
67
|
+
* @param {Object|string} entry
|
68
|
+
* @return {string} A URL with versioning info.
|
69
|
+
*
|
70
|
+
* @private
|
71
|
+
* @memberof module:workbox-precaching
|
72
|
+
*/
|
73
|
+
|
74
|
+
function createCacheKey(entry) {
|
75
|
+
if (!entry) {
|
76
|
+
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', {
|
77
|
+
entry
|
78
|
+
});
|
79
|
+
} // If a precache manifest entry is a string, it's assumed to be a versioned
|
80
|
+
// URL, like '/app.abcd1234.js'. Return as-is.
|
81
|
+
|
82
|
+
|
83
|
+
if (typeof entry === 'string') {
|
84
|
+
const urlObject = new URL(entry, location.href);
|
85
|
+
return {
|
86
|
+
cacheKey: urlObject.href,
|
87
|
+
url: urlObject.href
|
88
|
+
};
|
89
|
+
}
|
90
|
+
|
91
|
+
const {
|
92
|
+
revision,
|
93
|
+
url
|
94
|
+
} = entry;
|
95
|
+
|
96
|
+
if (!url) {
|
97
|
+
throw new WorkboxError_js.WorkboxError('add-to-cache-list-unexpected-type', {
|
98
|
+
entry
|
99
|
+
});
|
100
|
+
} // If there's just a URL and no revision, then it's also assumed to be a
|
101
|
+
// versioned URL.
|
102
|
+
|
103
|
+
|
104
|
+
if (!revision) {
|
105
|
+
const urlObject = new URL(url, location.href);
|
106
|
+
return {
|
107
|
+
cacheKey: urlObject.href,
|
108
|
+
url: urlObject.href
|
109
|
+
};
|
110
|
+
} // Otherwise, construct a properly versioned URL using the custom Workbox
|
111
|
+
// search parameter along with the revision info.
|
112
|
+
|
113
|
+
|
114
|
+
const cacheKeyURL = new URL(url, location.href);
|
115
|
+
const originalURL = new URL(url, location.href);
|
116
|
+
cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
|
117
|
+
return {
|
118
|
+
cacheKey: cacheKeyURL.href,
|
119
|
+
url: originalURL.href
|
120
|
+
};
|
121
|
+
}
|
122
|
+
|
123
|
+
/*
|
124
|
+
Copyright 2018 Google LLC
|
125
|
+
|
126
|
+
Use of this source code is governed by an MIT-style
|
127
|
+
license that can be found in the LICENSE file or at
|
128
|
+
https://opensource.org/licenses/MIT.
|
129
|
+
*/
|
130
|
+
/**
|
131
|
+
* @param {string} groupTitle
|
132
|
+
* @param {Array<string>} deletedURLs
|
133
|
+
*
|
134
|
+
* @private
|
135
|
+
*/
|
136
|
+
|
137
|
+
const logGroup = (groupTitle, deletedURLs) => {
|
138
|
+
logger_js.logger.groupCollapsed(groupTitle);
|
139
|
+
|
140
|
+
for (const url of deletedURLs) {
|
141
|
+
logger_js.logger.log(url);
|
142
|
+
}
|
143
|
+
|
144
|
+
logger_js.logger.groupEnd();
|
145
|
+
};
|
146
|
+
/**
|
147
|
+
* @param {Array<string>} deletedURLs
|
148
|
+
*
|
149
|
+
* @private
|
150
|
+
* @memberof module:workbox-precaching
|
151
|
+
*/
|
152
|
+
|
153
|
+
|
154
|
+
function printCleanupDetails(deletedURLs) {
|
155
|
+
const deletionCount = deletedURLs.length;
|
156
|
+
|
157
|
+
if (deletionCount > 0) {
|
158
|
+
logger_js.logger.groupCollapsed(`During precaching cleanup, ` + `${deletionCount} cached ` + `request${deletionCount === 1 ? ' was' : 's were'} deleted.`);
|
159
|
+
logGroup('Deleted Cache Requests', deletedURLs);
|
160
|
+
logger_js.logger.groupEnd();
|
161
|
+
}
|
162
|
+
}
|
163
|
+
|
164
|
+
/*
|
165
|
+
Copyright 2018 Google LLC
|
166
|
+
|
167
|
+
Use of this source code is governed by an MIT-style
|
168
|
+
license that can be found in the LICENSE file or at
|
169
|
+
https://opensource.org/licenses/MIT.
|
170
|
+
*/
|
171
|
+
/**
|
172
|
+
* @param {string} groupTitle
|
173
|
+
* @param {Array<string>} urls
|
174
|
+
*
|
175
|
+
* @private
|
176
|
+
*/
|
177
|
+
|
178
|
+
function _nestedGroup(groupTitle, urls) {
|
179
|
+
if (urls.length === 0) {
|
180
|
+
return;
|
181
|
+
}
|
182
|
+
|
183
|
+
logger_js.logger.groupCollapsed(groupTitle);
|
184
|
+
|
185
|
+
for (const url of urls) {
|
186
|
+
logger_js.logger.log(url);
|
187
|
+
}
|
188
|
+
|
189
|
+
logger_js.logger.groupEnd();
|
190
|
+
}
|
191
|
+
/**
|
192
|
+
* @param {Array<string>} urlsToPrecache
|
193
|
+
* @param {Array<string>} urlsAlreadyPrecached
|
194
|
+
*
|
195
|
+
* @private
|
196
|
+
* @memberof module:workbox-precaching
|
197
|
+
*/
|
198
|
+
|
199
|
+
|
200
|
+
function printInstallDetails(urlsToPrecache, urlsAlreadyPrecached) {
|
201
|
+
const precachedCount = urlsToPrecache.length;
|
202
|
+
const alreadyPrecachedCount = urlsAlreadyPrecached.length;
|
203
|
+
|
204
|
+
if (precachedCount || alreadyPrecachedCount) {
|
205
|
+
let message = `Precaching ${precachedCount} file${precachedCount === 1 ? '' : 's'}.`;
|
206
|
+
|
207
|
+
if (alreadyPrecachedCount > 0) {
|
208
|
+
message += ` ${alreadyPrecachedCount} ` + `file${alreadyPrecachedCount === 1 ? ' is' : 's are'} already cached.`;
|
209
|
+
}
|
210
|
+
|
211
|
+
logger_js.logger.groupCollapsed(message);
|
212
|
+
|
213
|
+
_nestedGroup(`View newly precached URLs.`, urlsToPrecache);
|
214
|
+
|
215
|
+
_nestedGroup(`View previously precached URLs.`, urlsAlreadyPrecached);
|
216
|
+
|
217
|
+
logger_js.logger.groupEnd();
|
218
|
+
}
|
219
|
+
}
|
220
|
+
|
221
|
+
/*
|
222
|
+
Copyright 2019 Google LLC
|
223
|
+
|
224
|
+
Use of this source code is governed by an MIT-style
|
225
|
+
license that can be found in the LICENSE file or at
|
226
|
+
https://opensource.org/licenses/MIT.
|
227
|
+
*/
|
228
|
+
/**
|
229
|
+
* Performs efficient precaching of assets.
|
230
|
+
*
|
231
|
+
* @memberof module:workbox-precaching
|
232
|
+
*/
|
233
|
+
|
234
|
+
class PrecacheController {
|
235
|
+
/**
|
236
|
+
* Create a new PrecacheController.
|
237
|
+
*
|
238
|
+
* @param {string} [cacheName] An optional name for the cache, to override
|
239
|
+
* the default precache name.
|
240
|
+
*/
|
241
|
+
constructor(cacheName) {
|
242
|
+
this._cacheName = cacheNames_js.cacheNames.getPrecacheName(cacheName);
|
243
|
+
this._urlsToCacheKeys = new Map();
|
244
|
+
this._urlsToCacheModes = new Map();
|
245
|
+
this._cacheKeysToIntegrities = new Map();
|
246
|
+
}
|
247
|
+
/**
|
248
|
+
* This method will add items to the precache list, removing duplicates
|
249
|
+
* and ensuring the information is valid.
|
250
|
+
*
|
251
|
+
* @param {
|
252
|
+
* Array<module:workbox-precaching.PrecacheController.PrecacheEntry|string>
|
253
|
+
* } entries Array of entries to precache.
|
254
|
+
*/
|
255
|
+
|
256
|
+
|
257
|
+
addToCacheList(entries) {
|
258
|
+
{
|
259
|
+
assert_js.assert.isArray(entries, {
|
260
|
+
moduleName: 'workbox-precaching',
|
261
|
+
className: 'PrecacheController',
|
262
|
+
funcName: 'addToCacheList',
|
263
|
+
paramName: 'entries'
|
264
|
+
});
|
265
|
+
}
|
266
|
+
|
267
|
+
const urlsToWarnAbout = [];
|
268
|
+
|
269
|
+
for (const entry of entries) {
|
270
|
+
// See https://github.com/GoogleChrome/workbox/issues/2259
|
271
|
+
if (typeof entry === 'string') {
|
272
|
+
urlsToWarnAbout.push(entry);
|
273
|
+
} else if (entry && entry.revision === undefined) {
|
274
|
+
urlsToWarnAbout.push(entry.url);
|
275
|
+
}
|
276
|
+
|
277
|
+
const {
|
278
|
+
cacheKey,
|
279
|
+
url
|
280
|
+
} = createCacheKey(entry);
|
281
|
+
const cacheMode = typeof entry !== 'string' && entry.revision ? 'reload' : 'default';
|
282
|
+
|
283
|
+
if (this._urlsToCacheKeys.has(url) && this._urlsToCacheKeys.get(url) !== cacheKey) {
|
284
|
+
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-entries', {
|
285
|
+
firstEntry: this._urlsToCacheKeys.get(url),
|
286
|
+
secondEntry: cacheKey
|
287
|
+
});
|
288
|
+
}
|
289
|
+
|
290
|
+
if (typeof entry !== 'string' && entry.integrity) {
|
291
|
+
if (this._cacheKeysToIntegrities.has(cacheKey) && this._cacheKeysToIntegrities.get(cacheKey) !== entry.integrity) {
|
292
|
+
throw new WorkboxError_js.WorkboxError('add-to-cache-list-conflicting-integrities', {
|
293
|
+
url
|
294
|
+
});
|
295
|
+
}
|
296
|
+
|
297
|
+
this._cacheKeysToIntegrities.set(cacheKey, entry.integrity);
|
298
|
+
}
|
299
|
+
|
300
|
+
this._urlsToCacheKeys.set(url, cacheKey);
|
301
|
+
|
302
|
+
this._urlsToCacheModes.set(url, cacheMode);
|
303
|
+
|
304
|
+
if (urlsToWarnAbout.length > 0) {
|
305
|
+
const warningMessage = `Workbox is precaching URLs without revision ` + `info: ${urlsToWarnAbout.join(', ')}\nThis is generally NOT safe. ` + `Learn more at https://bit.ly/wb-precache`;
|
306
|
+
|
307
|
+
{
|
308
|
+
logger_js.logger.warn(warningMessage);
|
309
|
+
}
|
310
|
+
}
|
311
|
+
}
|
312
|
+
}
|
313
|
+
/**
|
314
|
+
* Precaches new and updated assets. Call this method from the service worker
|
315
|
+
* install event.
|
316
|
+
*
|
317
|
+
* @param {Object} options
|
318
|
+
* @param {Event} [options.event] The install event (if needed).
|
319
|
+
* @param {Array<Object>} [options.plugins] Plugins to be used for fetching
|
320
|
+
* and caching during install.
|
321
|
+
* @return {Promise<module:workbox-precaching.InstallResult>}
|
322
|
+
*/
|
323
|
+
|
324
|
+
|
325
|
+
async install({
|
326
|
+
event,
|
327
|
+
plugins
|
328
|
+
} = {}) {
|
329
|
+
{
|
330
|
+
if (plugins) {
|
331
|
+
assert_js.assert.isArray(plugins, {
|
332
|
+
moduleName: 'workbox-precaching',
|
333
|
+
className: 'PrecacheController',
|
334
|
+
funcName: 'install',
|
335
|
+
paramName: 'plugins'
|
336
|
+
});
|
337
|
+
}
|
338
|
+
}
|
339
|
+
|
340
|
+
const toBePrecached = [];
|
341
|
+
const alreadyPrecached = [];
|
342
|
+
const cache = await self.caches.open(this._cacheName);
|
343
|
+
const alreadyCachedRequests = await cache.keys();
|
344
|
+
const existingCacheKeys = new Set(alreadyCachedRequests.map(request => request.url));
|
345
|
+
|
346
|
+
for (const [url, cacheKey] of this._urlsToCacheKeys) {
|
347
|
+
if (existingCacheKeys.has(cacheKey)) {
|
348
|
+
alreadyPrecached.push(url);
|
349
|
+
} else {
|
350
|
+
toBePrecached.push({
|
351
|
+
cacheKey,
|
352
|
+
url
|
353
|
+
});
|
354
|
+
}
|
355
|
+
}
|
356
|
+
|
357
|
+
const precacheRequests = toBePrecached.map(({
|
358
|
+
cacheKey,
|
359
|
+
url
|
360
|
+
}) => {
|
361
|
+
const integrity = this._cacheKeysToIntegrities.get(cacheKey);
|
362
|
+
|
363
|
+
const cacheMode = this._urlsToCacheModes.get(url);
|
364
|
+
|
365
|
+
return this._addURLToCache({
|
366
|
+
cacheKey,
|
367
|
+
cacheMode,
|
368
|
+
event,
|
369
|
+
integrity,
|
370
|
+
plugins,
|
371
|
+
url
|
372
|
+
});
|
373
|
+
});
|
374
|
+
await Promise.all(precacheRequests);
|
375
|
+
const updatedURLs = toBePrecached.map(item => item.url);
|
376
|
+
|
377
|
+
{
|
378
|
+
printInstallDetails(updatedURLs, alreadyPrecached);
|
379
|
+
}
|
380
|
+
|
381
|
+
return {
|
382
|
+
updatedURLs,
|
383
|
+
notUpdatedURLs: alreadyPrecached
|
384
|
+
};
|
385
|
+
}
|
386
|
+
/**
|
387
|
+
* Deletes assets that are no longer present in the current precache manifest.
|
388
|
+
* Call this method from the service worker activate event.
|
389
|
+
*
|
390
|
+
* @return {Promise<module:workbox-precaching.CleanupResult>}
|
391
|
+
*/
|
392
|
+
|
393
|
+
|
394
|
+
async activate() {
|
395
|
+
const cache = await self.caches.open(this._cacheName);
|
396
|
+
const currentlyCachedRequests = await cache.keys();
|
397
|
+
const expectedCacheKeys = new Set(this._urlsToCacheKeys.values());
|
398
|
+
const deletedURLs = [];
|
399
|
+
|
400
|
+
for (const request of currentlyCachedRequests) {
|
401
|
+
if (!expectedCacheKeys.has(request.url)) {
|
402
|
+
await cache.delete(request);
|
403
|
+
deletedURLs.push(request.url);
|
404
|
+
}
|
405
|
+
}
|
406
|
+
|
407
|
+
{
|
408
|
+
printCleanupDetails(deletedURLs);
|
409
|
+
}
|
410
|
+
|
411
|
+
return {
|
412
|
+
deletedURLs
|
413
|
+
};
|
414
|
+
}
|
415
|
+
/**
|
416
|
+
* Requests the entry and saves it to the cache if the response is valid.
|
417
|
+
* By default, any response with a status code of less than 400 (including
|
418
|
+
* opaque responses) is considered valid.
|
419
|
+
*
|
420
|
+
* If you need to use custom criteria to determine what's valid and what
|
421
|
+
* isn't, then pass in an item in `options.plugins` that implements the
|
422
|
+
* `cacheWillUpdate()` lifecycle event.
|
423
|
+
*
|
424
|
+
* @private
|
425
|
+
* @param {Object} options
|
426
|
+
* @param {string} options.cacheKey The string to use a cache key.
|
427
|
+
* @param {string} options.url The URL to fetch and cache.
|
428
|
+
* @param {string} [options.cacheMode] The cache mode for the network request.
|
429
|
+
* @param {Event} [options.event] The install event (if passed).
|
430
|
+
* @param {Array<Object>} [options.plugins] An array of plugins to apply to
|
431
|
+
* fetch and caching.
|
432
|
+
* @param {string} [options.integrity] The value to use for the `integrity`
|
433
|
+
* field when making the request.
|
434
|
+
*/
|
435
|
+
|
436
|
+
|
437
|
+
async _addURLToCache({
|
438
|
+
cacheKey,
|
439
|
+
url,
|
440
|
+
cacheMode,
|
441
|
+
event,
|
442
|
+
plugins,
|
443
|
+
integrity
|
444
|
+
}) {
|
445
|
+
const request = new Request(url, {
|
446
|
+
integrity,
|
447
|
+
cache: cacheMode,
|
448
|
+
credentials: 'same-origin'
|
449
|
+
});
|
450
|
+
let response = await fetchWrapper_js.fetchWrapper.fetch({
|
451
|
+
event,
|
452
|
+
plugins,
|
453
|
+
request
|
454
|
+
}); // Allow developers to override the default logic about what is and isn't
|
455
|
+
// valid by passing in a plugin implementing cacheWillUpdate(), e.g.
|
456
|
+
// a `CacheableResponsePlugin` instance.
|
457
|
+
|
458
|
+
let cacheWillUpdatePlugin;
|
459
|
+
|
460
|
+
for (const plugin of plugins || []) {
|
461
|
+
if ('cacheWillUpdate' in plugin) {
|
462
|
+
cacheWillUpdatePlugin = plugin;
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
const isValidResponse = cacheWillUpdatePlugin ? // Use a callback if provided. It returns a truthy value if valid.
|
467
|
+
// NOTE: invoke the method on the plugin instance so the `this` context
|
468
|
+
// is correct.
|
469
|
+
await cacheWillUpdatePlugin.cacheWillUpdate({
|
470
|
+
event,
|
471
|
+
request,
|
472
|
+
response
|
473
|
+
}) : // Otherwise, default to considering any response status under 400 valid.
|
474
|
+
// This includes, by default, considering opaque responses valid.
|
475
|
+
response.status < 400; // Consider this a failure, leading to the `install` handler failing, if
|
476
|
+
// we get back an invalid response.
|
477
|
+
|
478
|
+
if (!isValidResponse) {
|
479
|
+
throw new WorkboxError_js.WorkboxError('bad-precaching-response', {
|
480
|
+
url,
|
481
|
+
status: response.status
|
482
|
+
});
|
483
|
+
} // Redirected responses cannot be used to satisfy a navigation request, so
|
484
|
+
// any redirected response must be "copied" rather than cloned, so the new
|
485
|
+
// response doesn't contain the `redirected` flag. See:
|
486
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=669363&desc=2#c1
|
487
|
+
|
488
|
+
|
489
|
+
if (response.redirected) {
|
490
|
+
response = await copyResponse_js.copyResponse(response);
|
491
|
+
}
|
492
|
+
|
493
|
+
await cacheWrapper_js.cacheWrapper.put({
|
494
|
+
event,
|
495
|
+
plugins,
|
496
|
+
response,
|
497
|
+
// `request` already uses `url`. We may be able to reuse it.
|
498
|
+
request: cacheKey === url ? request : new Request(cacheKey),
|
499
|
+
cacheName: this._cacheName,
|
500
|
+
matchOptions: {
|
501
|
+
ignoreSearch: true
|
502
|
+
}
|
503
|
+
});
|
504
|
+
}
|
505
|
+
/**
|
506
|
+
* Returns a mapping of a precached URL to the corresponding cache key, taking
|
507
|
+
* into account the revision information for the URL.
|
508
|
+
*
|
509
|
+
* @return {Map<string, string>} A URL to cache key mapping.
|
510
|
+
*/
|
511
|
+
|
512
|
+
|
513
|
+
getURLsToCacheKeys() {
|
514
|
+
return this._urlsToCacheKeys;
|
515
|
+
}
|
516
|
+
/**
|
517
|
+
* Returns a list of all the URLs that have been precached by the current
|
518
|
+
* service worker.
|
519
|
+
*
|
520
|
+
* @return {Array<string>} The precached URLs.
|
521
|
+
*/
|
522
|
+
|
523
|
+
|
524
|
+
getCachedURLs() {
|
525
|
+
return [...this._urlsToCacheKeys.keys()];
|
526
|
+
}
|
527
|
+
/**
|
528
|
+
* Returns the cache key used for storing a given URL. If that URL is
|
529
|
+
* unversioned, like `/index.html', then the cache key will be the original
|
530
|
+
* URL with a search parameter appended to it.
|
531
|
+
*
|
532
|
+
* @param {string} url A URL whose cache key you want to look up.
|
533
|
+
* @return {string} The versioned URL that corresponds to a cache key
|
534
|
+
* for the original URL, or undefined if that URL isn't precached.
|
535
|
+
*/
|
536
|
+
|
537
|
+
|
538
|
+
getCacheKeyForURL(url) {
|
539
|
+
const urlObject = new URL(url, location.href);
|
540
|
+
return this._urlsToCacheKeys.get(urlObject.href);
|
541
|
+
}
|
542
|
+
/**
|
543
|
+
* This acts as a drop-in replacement for [`cache.match()`](https://developer.mozilla.org/en-US/docs/Web/API/Cache/match)
|
544
|
+
* with the following differences:
|
545
|
+
*
|
546
|
+
* - It knows what the name of the precache is, and only checks in that cache.
|
547
|
+
* - It allows you to pass in an "original" URL without versioning parameters,
|
548
|
+
* and it will automatically look up the correct cache key for the currently
|
549
|
+
* active revision of that URL.
|
550
|
+
*
|
551
|
+
* E.g., `matchPrecache('index.html')` will find the correct precached
|
552
|
+
* response for the currently active service worker, even if the actual cache
|
553
|
+
* key is `'/index.html?__WB_REVISION__=1234abcd'`.
|
554
|
+
*
|
555
|
+
* @param {string|Request} request The key (without revisioning parameters)
|
556
|
+
* to look up in the precache.
|
557
|
+
* @return {Promise<Response|undefined>}
|
558
|
+
*/
|
559
|
+
|
560
|
+
|
561
|
+
async matchPrecache(request) {
|
562
|
+
const url = request instanceof Request ? request.url : request;
|
563
|
+
const cacheKey = this.getCacheKeyForURL(url);
|
564
|
+
|
565
|
+
if (cacheKey) {
|
566
|
+
const cache = await self.caches.open(this._cacheName);
|
567
|
+
return cache.match(cacheKey);
|
568
|
+
}
|
569
|
+
|
570
|
+
return undefined;
|
571
|
+
}
|
572
|
+
/**
|
573
|
+
* Returns a function that can be used within a
|
574
|
+
* {@link module:workbox-routing.Route} that will find a response for the
|
575
|
+
* incoming request against the precache.
|
576
|
+
*
|
577
|
+
* If for an unexpected reason there is a cache miss for the request,
|
578
|
+
* this will fall back to retrieving the `Response` via `fetch()` when
|
579
|
+
* `fallbackToNetwork` is `true`.
|
580
|
+
*
|
581
|
+
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the
|
582
|
+
* response from the network if there's a precache miss.
|
583
|
+
* @return {module:workbox-routing~handlerCallback}
|
584
|
+
*/
|
585
|
+
|
586
|
+
|
587
|
+
createHandler(fallbackToNetwork = true) {
|
588
|
+
return async ({
|
589
|
+
request
|
590
|
+
}) => {
|
591
|
+
try {
|
592
|
+
const response = await this.matchPrecache(request);
|
593
|
+
|
594
|
+
if (response) {
|
595
|
+
return response;
|
596
|
+
} // This shouldn't normally happen, but there are edge cases:
|
597
|
+
// https://github.com/GoogleChrome/workbox/issues/1441
|
598
|
+
|
599
|
+
|
600
|
+
throw new WorkboxError_js.WorkboxError('missing-precache-entry', {
|
601
|
+
cacheName: this._cacheName,
|
602
|
+
url: request instanceof Request ? request.url : request
|
603
|
+
});
|
604
|
+
} catch (error) {
|
605
|
+
if (fallbackToNetwork) {
|
606
|
+
{
|
607
|
+
logger_js.logger.debug(`Unable to respond with precached response. ` + `Falling back to network.`, error);
|
608
|
+
}
|
609
|
+
|
610
|
+
return fetch(request);
|
611
|
+
}
|
612
|
+
|
613
|
+
throw error;
|
614
|
+
}
|
615
|
+
};
|
616
|
+
}
|
617
|
+
/**
|
618
|
+
* Returns a function that looks up `url` in the precache (taking into
|
619
|
+
* account revision information), and returns the corresponding `Response`.
|
620
|
+
*
|
621
|
+
* If for an unexpected reason there is a cache miss when looking up `url`,
|
622
|
+
* this will fall back to retrieving the `Response` via `fetch()` when
|
623
|
+
* `fallbackToNetwork` is `true`.
|
624
|
+
*
|
625
|
+
* @param {string} url The precached URL which will be used to lookup the
|
626
|
+
* `Response`.
|
627
|
+
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the
|
628
|
+
* response from the network if there's a precache miss.
|
629
|
+
* @return {module:workbox-routing~handlerCallback}
|
630
|
+
*/
|
631
|
+
|
632
|
+
|
633
|
+
createHandlerBoundToURL(url, fallbackToNetwork = true) {
|
634
|
+
const cacheKey = this.getCacheKeyForURL(url);
|
635
|
+
|
636
|
+
if (!cacheKey) {
|
637
|
+
throw new WorkboxError_js.WorkboxError('non-precached-url', {
|
638
|
+
url
|
639
|
+
});
|
640
|
+
}
|
641
|
+
|
642
|
+
const handler = this.createHandler(fallbackToNetwork);
|
643
|
+
const request = new Request(url);
|
644
|
+
return () => handler({
|
645
|
+
request
|
646
|
+
});
|
647
|
+
}
|
648
|
+
|
649
|
+
}
|
650
|
+
|
651
|
+
/*
|
652
|
+
Copyright 2019 Google LLC
|
653
|
+
|
654
|
+
Use of this source code is governed by an MIT-style
|
655
|
+
license that can be found in the LICENSE file or at
|
656
|
+
https://opensource.org/licenses/MIT.
|
657
|
+
*/
|
658
|
+
let precacheController;
|
659
|
+
/**
|
660
|
+
* @return {PrecacheController}
|
661
|
+
* @private
|
662
|
+
*/
|
663
|
+
|
664
|
+
const getOrCreatePrecacheController = () => {
|
665
|
+
if (!precacheController) {
|
666
|
+
precacheController = new PrecacheController();
|
667
|
+
}
|
668
|
+
|
669
|
+
return precacheController;
|
670
|
+
};
|
671
|
+
|
672
|
+
/*
|
673
|
+
Copyright 2018 Google LLC
|
674
|
+
|
675
|
+
Use of this source code is governed by an MIT-style
|
676
|
+
license that can be found in the LICENSE file or at
|
677
|
+
https://opensource.org/licenses/MIT.
|
678
|
+
*/
|
679
|
+
/**
|
680
|
+
* Removes any URL search parameters that should be ignored.
|
681
|
+
*
|
682
|
+
* @param {URL} urlObject The original URL.
|
683
|
+
* @param {Array<RegExp>} ignoreURLParametersMatching RegExps to test against
|
684
|
+
* each search parameter name. Matches mean that the search parameter should be
|
685
|
+
* ignored.
|
686
|
+
* @return {URL} The URL with any ignored search parameters removed.
|
687
|
+
*
|
688
|
+
* @private
|
689
|
+
* @memberof module:workbox-precaching
|
690
|
+
*/
|
691
|
+
|
692
|
+
function removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching = []) {
|
693
|
+
// Convert the iterable into an array at the start of the loop to make sure
|
694
|
+
// deletion doesn't mess up iteration.
|
695
|
+
for (const paramName of [...urlObject.searchParams.keys()]) {
|
696
|
+
if (ignoreURLParametersMatching.some(regExp => regExp.test(paramName))) {
|
697
|
+
urlObject.searchParams.delete(paramName);
|
698
|
+
}
|
699
|
+
}
|
700
|
+
|
701
|
+
return urlObject;
|
702
|
+
}
|
703
|
+
|
704
|
+
/*
|
705
|
+
Copyright 2019 Google LLC
|
706
|
+
|
707
|
+
Use of this source code is governed by an MIT-style
|
708
|
+
license that can be found in the LICENSE file or at
|
709
|
+
https://opensource.org/licenses/MIT.
|
710
|
+
*/
|
711
|
+
/**
|
712
|
+
* Generator function that yields possible variations on the original URL to
|
713
|
+
* check, one at a time.
|
714
|
+
*
|
715
|
+
* @param {string} url
|
716
|
+
* @param {Object} options
|
717
|
+
*
|
718
|
+
* @private
|
719
|
+
* @memberof module:workbox-precaching
|
720
|
+
*/
|
721
|
+
|
722
|
+
function* generateURLVariations(url, {
|
723
|
+
ignoreURLParametersMatching,
|
724
|
+
directoryIndex,
|
725
|
+
cleanURLs,
|
726
|
+
urlManipulation
|
727
|
+
} = {}) {
|
728
|
+
const urlObject = new URL(url, location.href);
|
729
|
+
urlObject.hash = '';
|
730
|
+
yield urlObject.href;
|
731
|
+
const urlWithoutIgnoredParams = removeIgnoredSearchParams(urlObject, ignoreURLParametersMatching);
|
732
|
+
yield urlWithoutIgnoredParams.href;
|
733
|
+
|
734
|
+
if (directoryIndex && urlWithoutIgnoredParams.pathname.endsWith('/')) {
|
735
|
+
const directoryURL = new URL(urlWithoutIgnoredParams.href);
|
736
|
+
directoryURL.pathname += directoryIndex;
|
737
|
+
yield directoryURL.href;
|
738
|
+
}
|
739
|
+
|
740
|
+
if (cleanURLs) {
|
741
|
+
const cleanURL = new URL(urlWithoutIgnoredParams.href);
|
742
|
+
cleanURL.pathname += '.html';
|
743
|
+
yield cleanURL.href;
|
744
|
+
}
|
745
|
+
|
746
|
+
if (urlManipulation) {
|
747
|
+
const additionalURLs = urlManipulation({
|
748
|
+
url: urlObject
|
749
|
+
});
|
750
|
+
|
751
|
+
for (const urlToAttempt of additionalURLs) {
|
752
|
+
yield urlToAttempt.href;
|
753
|
+
}
|
754
|
+
}
|
755
|
+
}
|
756
|
+
|
757
|
+
/*
|
758
|
+
Copyright 2019 Google LLC
|
759
|
+
|
760
|
+
Use of this source code is governed by an MIT-style
|
761
|
+
license that can be found in the LICENSE file or at
|
762
|
+
https://opensource.org/licenses/MIT.
|
763
|
+
*/
|
764
|
+
/**
|
765
|
+
* This function will take the request URL and manipulate it based on the
|
766
|
+
* configuration options.
|
767
|
+
*
|
768
|
+
* @param {string} url
|
769
|
+
* @param {Object} options
|
770
|
+
* @return {string} Returns the URL in the cache that matches the request,
|
771
|
+
* if possible.
|
772
|
+
*
|
773
|
+
* @private
|
774
|
+
*/
|
775
|
+
|
776
|
+
const getCacheKeyForURL = (url, options) => {
|
777
|
+
const precacheController = getOrCreatePrecacheController();
|
778
|
+
const urlsToCacheKeys = precacheController.getURLsToCacheKeys();
|
779
|
+
|
780
|
+
for (const possibleURL of generateURLVariations(url, options)) {
|
781
|
+
const possibleCacheKey = urlsToCacheKeys.get(possibleURL);
|
782
|
+
|
783
|
+
if (possibleCacheKey) {
|
784
|
+
return possibleCacheKey;
|
785
|
+
}
|
786
|
+
}
|
787
|
+
};
|
788
|
+
|
789
|
+
/*
|
790
|
+
Copyright 2019 Google LLC
|
791
|
+
|
792
|
+
Use of this source code is governed by an MIT-style
|
793
|
+
license that can be found in the LICENSE file or at
|
794
|
+
https://opensource.org/licenses/MIT.
|
795
|
+
*/
|
796
|
+
/**
|
797
|
+
* Adds a `fetch` listener to the service worker that will
|
798
|
+
* respond to
|
799
|
+
* [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}
|
800
|
+
* with precached assets.
|
801
|
+
*
|
802
|
+
* Requests for assets that aren't precached, the `FetchEvent` will not be
|
803
|
+
* responded to, allowing the event to fall through to other `fetch` event
|
804
|
+
* listeners.
|
805
|
+
*
|
806
|
+
* NOTE: when called more than once this method will replace the previously set
|
807
|
+
* configuration options. Calling it more than once is not recommended outside
|
808
|
+
* of tests.
|
809
|
+
*
|
810
|
+
* @private
|
811
|
+
* @param {Object} [options]
|
812
|
+
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will
|
813
|
+
* check cache entries for a URLs ending with '/' to see if there is a hit when
|
814
|
+
* appending the `directoryIndex` value.
|
815
|
+
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/]] An
|
816
|
+
* array of regex's to remove search params when looking for a cache match.
|
817
|
+
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will
|
818
|
+
* check the cache for the URL with a `.html` added to the end of the end.
|
819
|
+
* @param {workbox.precaching~urlManipulation} [options.urlManipulation]
|
820
|
+
* This is a function that should take a URL and return an array of
|
821
|
+
* alternative URLs that should be checked for precache matches.
|
822
|
+
*/
|
823
|
+
|
824
|
+
const addFetchListener = ({
|
825
|
+
ignoreURLParametersMatching = [/^utm_/],
|
826
|
+
directoryIndex = 'index.html',
|
827
|
+
cleanURLs = true,
|
828
|
+
urlManipulation
|
829
|
+
} = {}) => {
|
830
|
+
const cacheName = cacheNames_js.cacheNames.getPrecacheName(); // See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
|
831
|
+
|
832
|
+
self.addEventListener('fetch', event => {
|
833
|
+
const precachedURL = getCacheKeyForURL(event.request.url, {
|
834
|
+
cleanURLs,
|
835
|
+
directoryIndex,
|
836
|
+
ignoreURLParametersMatching,
|
837
|
+
urlManipulation
|
838
|
+
});
|
839
|
+
|
840
|
+
if (!precachedURL) {
|
841
|
+
{
|
842
|
+
logger_js.logger.debug(`Precaching did not find a match for ` + getFriendlyURL_js.getFriendlyURL(event.request.url));
|
843
|
+
}
|
844
|
+
|
845
|
+
return;
|
846
|
+
}
|
847
|
+
|
848
|
+
let responsePromise = self.caches.open(cacheName).then(cache => {
|
849
|
+
return cache.match(precachedURL);
|
850
|
+
}).then(cachedResponse => {
|
851
|
+
if (cachedResponse) {
|
852
|
+
return cachedResponse;
|
853
|
+
} // Fall back to the network if we don't have a cached response
|
854
|
+
// (perhaps due to manual cache cleanup).
|
855
|
+
|
856
|
+
|
857
|
+
{
|
858
|
+
logger_js.logger.warn(`The precached response for ` + `${getFriendlyURL_js.getFriendlyURL(precachedURL)} in ${cacheName} was not found. ` + `Falling back to the network instead.`);
|
859
|
+
}
|
860
|
+
|
861
|
+
return fetch(precachedURL);
|
862
|
+
});
|
863
|
+
|
864
|
+
{
|
865
|
+
responsePromise = responsePromise.then(response => {
|
866
|
+
// Workbox is going to handle the route.
|
867
|
+
// print the routing details to the console.
|
868
|
+
logger_js.logger.groupCollapsed(`Precaching is responding to: ` + getFriendlyURL_js.getFriendlyURL(event.request.url));
|
869
|
+
logger_js.logger.log(`Serving the precached url: ${precachedURL}`);
|
870
|
+
logger_js.logger.groupCollapsed(`View request details here.`);
|
871
|
+
logger_js.logger.log(event.request);
|
872
|
+
logger_js.logger.groupEnd();
|
873
|
+
logger_js.logger.groupCollapsed(`View response details here.`);
|
874
|
+
logger_js.logger.log(response);
|
875
|
+
logger_js.logger.groupEnd();
|
876
|
+
logger_js.logger.groupEnd();
|
877
|
+
return response;
|
878
|
+
});
|
879
|
+
}
|
880
|
+
|
881
|
+
event.respondWith(responsePromise);
|
882
|
+
});
|
883
|
+
};
|
884
|
+
|
885
|
+
/*
|
886
|
+
Copyright 2019 Google LLC
|
887
|
+
Use of this source code is governed by an MIT-style
|
888
|
+
license that can be found in the LICENSE file or at
|
889
|
+
https://opensource.org/licenses/MIT.
|
890
|
+
*/
|
891
|
+
let listenerAdded = false;
|
892
|
+
/**
|
893
|
+
* Add a `fetch` listener to the service worker that will
|
894
|
+
* respond to
|
895
|
+
* [network requests]{@link https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers#Custom_responses_to_requests}
|
896
|
+
* with precached assets.
|
897
|
+
*
|
898
|
+
* Requests for assets that aren't precached, the `FetchEvent` will not be
|
899
|
+
* responded to, allowing the event to fall through to other `fetch` event
|
900
|
+
* listeners.
|
901
|
+
*
|
902
|
+
* @param {Object} [options]
|
903
|
+
* @param {string} [options.directoryIndex=index.html] The `directoryIndex` will
|
904
|
+
* check cache entries for a URLs ending with '/' to see if there is a hit when
|
905
|
+
* appending the `directoryIndex` value.
|
906
|
+
* @param {Array<RegExp>} [options.ignoreURLParametersMatching=[/^utm_/]] An
|
907
|
+
* array of regex's to remove search params when looking for a cache match.
|
908
|
+
* @param {boolean} [options.cleanURLs=true] The `cleanURLs` option will
|
909
|
+
* check the cache for the URL with a `.html` added to the end of the end.
|
910
|
+
* @param {module:workbox-precaching~urlManipulation} [options.urlManipulation]
|
911
|
+
* This is a function that should take a URL and return an array of
|
912
|
+
* alternative URLs that should be checked for precache matches.
|
913
|
+
*
|
914
|
+
* @memberof module:workbox-precaching
|
915
|
+
*/
|
916
|
+
|
917
|
+
function addRoute(options) {
|
918
|
+
if (!listenerAdded) {
|
919
|
+
addFetchListener(options);
|
920
|
+
listenerAdded = true;
|
921
|
+
}
|
922
|
+
}
|
923
|
+
|
924
|
+
/*
|
925
|
+
Copyright 2018 Google LLC
|
926
|
+
|
927
|
+
Use of this source code is governed by an MIT-style
|
928
|
+
license that can be found in the LICENSE file or at
|
929
|
+
https://opensource.org/licenses/MIT.
|
930
|
+
*/
|
931
|
+
const SUBSTRING_TO_FIND = '-precache-';
|
932
|
+
/**
|
933
|
+
* Cleans up incompatible precaches that were created by older versions of
|
934
|
+
* Workbox, by a service worker registered under the current scope.
|
935
|
+
*
|
936
|
+
* This is meant to be called as part of the `activate` event.
|
937
|
+
*
|
938
|
+
* This should be safe to use as long as you don't include `substringToFind`
|
939
|
+
* (defaulting to `-precache-`) in your non-precache cache names.
|
940
|
+
*
|
941
|
+
* @param {string} currentPrecacheName The cache name currently in use for
|
942
|
+
* precaching. This cache won't be deleted.
|
943
|
+
* @param {string} [substringToFind='-precache-'] Cache names which include this
|
944
|
+
* substring will be deleted (excluding `currentPrecacheName`).
|
945
|
+
* @return {Array<string>} A list of all the cache names that were deleted.
|
946
|
+
*
|
947
|
+
* @private
|
948
|
+
* @memberof module:workbox-precaching
|
949
|
+
*/
|
950
|
+
|
951
|
+
const deleteOutdatedCaches = async (currentPrecacheName, substringToFind = SUBSTRING_TO_FIND) => {
|
952
|
+
const cacheNames = await self.caches.keys();
|
953
|
+
const cacheNamesToDelete = cacheNames.filter(cacheName => {
|
954
|
+
return cacheName.includes(substringToFind) && cacheName.includes(self.registration.scope) && cacheName !== currentPrecacheName;
|
955
|
+
});
|
956
|
+
await Promise.all(cacheNamesToDelete.map(cacheName => self.caches.delete(cacheName)));
|
957
|
+
return cacheNamesToDelete;
|
958
|
+
};
|
959
|
+
|
960
|
+
/*
|
961
|
+
Copyright 2019 Google LLC
|
962
|
+
|
963
|
+
Use of this source code is governed by an MIT-style
|
964
|
+
license that can be found in the LICENSE file or at
|
965
|
+
https://opensource.org/licenses/MIT.
|
966
|
+
*/
|
967
|
+
/**
|
968
|
+
* Adds an `activate` event listener which will clean up incompatible
|
969
|
+
* precaches that were created by older versions of Workbox.
|
970
|
+
*
|
971
|
+
* @memberof module:workbox-precaching
|
972
|
+
*/
|
973
|
+
|
974
|
+
function cleanupOutdatedCaches() {
|
975
|
+
// See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
|
976
|
+
self.addEventListener('activate', event => {
|
977
|
+
const cacheName = cacheNames_js.cacheNames.getPrecacheName();
|
978
|
+
event.waitUntil(deleteOutdatedCaches(cacheName).then(cachesDeleted => {
|
979
|
+
{
|
980
|
+
if (cachesDeleted.length > 0) {
|
981
|
+
logger_js.logger.log(`The following out-of-date precaches were cleaned up ` + `automatically:`, cachesDeleted);
|
982
|
+
}
|
983
|
+
}
|
984
|
+
}));
|
985
|
+
});
|
986
|
+
}
|
987
|
+
|
988
|
+
/*
|
989
|
+
Copyright 2019 Google LLC
|
990
|
+
|
991
|
+
Use of this source code is governed by an MIT-style
|
992
|
+
license that can be found in the LICENSE file or at
|
993
|
+
https://opensource.org/licenses/MIT.
|
994
|
+
*/
|
995
|
+
/**
|
996
|
+
* Helper function that calls
|
997
|
+
* {@link PrecacheController#createHandler} on the default
|
998
|
+
* {@link PrecacheController} instance.
|
999
|
+
*
|
1000
|
+
* If you are creating your own {@link PrecacheController}, then call the
|
1001
|
+
* {@link PrecacheController#createHandler} on that instance,
|
1002
|
+
* instead of using this function.
|
1003
|
+
*
|
1004
|
+
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the
|
1005
|
+
* response from the network if there's a precache miss.
|
1006
|
+
* @return {module:workbox-routing~handlerCallback}
|
1007
|
+
*
|
1008
|
+
* @memberof module:workbox-precaching
|
1009
|
+
*/
|
1010
|
+
|
1011
|
+
function createHandler(fallbackToNetwork = true) {
|
1012
|
+
const precacheController = getOrCreatePrecacheController();
|
1013
|
+
return precacheController.createHandler(fallbackToNetwork);
|
1014
|
+
}
|
1015
|
+
|
1016
|
+
/*
|
1017
|
+
Copyright 2019 Google LLC
|
1018
|
+
|
1019
|
+
Use of this source code is governed by an MIT-style
|
1020
|
+
license that can be found in the LICENSE file or at
|
1021
|
+
https://opensource.org/licenses/MIT.
|
1022
|
+
*/
|
1023
|
+
/**
|
1024
|
+
* Helper function that calls
|
1025
|
+
* {@link PrecacheController#createHandlerBoundToURL} on the default
|
1026
|
+
* {@link PrecacheController} instance.
|
1027
|
+
*
|
1028
|
+
* If you are creating your own {@link PrecacheController}, then call the
|
1029
|
+
* {@link PrecacheController#createHandlerBoundToURL} on that instance,
|
1030
|
+
* instead of using this function.
|
1031
|
+
*
|
1032
|
+
* @param {string} url The precached URL which will be used to lookup the
|
1033
|
+
* `Response`.
|
1034
|
+
* @param {boolean} [fallbackToNetwork=true] Whether to attempt to get the
|
1035
|
+
* response from the network if there's a precache miss.
|
1036
|
+
* @return {module:workbox-routing~handlerCallback}
|
1037
|
+
*
|
1038
|
+
* @memberof module:workbox-precaching
|
1039
|
+
*/
|
1040
|
+
|
1041
|
+
function createHandlerBoundToURL(url) {
|
1042
|
+
const precacheController = getOrCreatePrecacheController();
|
1043
|
+
return precacheController.createHandlerBoundToURL(url);
|
1044
|
+
}
|
1045
|
+
|
1046
|
+
/*
|
1047
|
+
Copyright 2019 Google LLC
|
1048
|
+
|
1049
|
+
Use of this source code is governed by an MIT-style
|
1050
|
+
license that can be found in the LICENSE file or at
|
1051
|
+
https://opensource.org/licenses/MIT.
|
1052
|
+
*/
|
1053
|
+
/**
|
1054
|
+
* Takes in a URL, and returns the corresponding URL that could be used to
|
1055
|
+
* lookup the entry in the precache.
|
1056
|
+
*
|
1057
|
+
* If a relative URL is provided, the location of the service worker file will
|
1058
|
+
* be used as the base.
|
1059
|
+
*
|
1060
|
+
* For precached entries without revision information, the cache key will be the
|
1061
|
+
* same as the original URL.
|
1062
|
+
*
|
1063
|
+
* For precached entries with revision information, the cache key will be the
|
1064
|
+
* original URL with the addition of a query parameter used for keeping track of
|
1065
|
+
* the revision info.
|
1066
|
+
*
|
1067
|
+
* @param {string} url The URL whose cache key to look up.
|
1068
|
+
* @return {string} The cache key that corresponds to that URL.
|
1069
|
+
*
|
1070
|
+
* @memberof module:workbox-precaching
|
1071
|
+
*/
|
1072
|
+
|
1073
|
+
function getCacheKeyForURL$1(url) {
|
1074
|
+
const precacheController = getOrCreatePrecacheController();
|
1075
|
+
return precacheController.getCacheKeyForURL(url);
|
1076
|
+
}
|
1077
|
+
|
1078
|
+
/*
|
1079
|
+
Copyright 2019 Google LLC
|
1080
|
+
|
1081
|
+
Use of this source code is governed by an MIT-style
|
1082
|
+
license that can be found in the LICENSE file or at
|
1083
|
+
https://opensource.org/licenses/MIT.
|
1084
|
+
*/
|
1085
|
+
/**
|
1086
|
+
* Helper function that calls
|
1087
|
+
* {@link PrecacheController#matchPrecache} on the default
|
1088
|
+
* {@link PrecacheController} instance.
|
1089
|
+
*
|
1090
|
+
* If you are creating your own {@link PrecacheController}, then call
|
1091
|
+
* {@link PrecacheController#matchPrecache} on that instance,
|
1092
|
+
* instead of using this function.
|
1093
|
+
*
|
1094
|
+
* @param {string|Request} request The key (without revisioning parameters)
|
1095
|
+
* to look up in the precache.
|
1096
|
+
* @return {Promise<Response|undefined>}
|
1097
|
+
*
|
1098
|
+
* @memberof module:workbox-precaching
|
1099
|
+
*/
|
1100
|
+
|
1101
|
+
function matchPrecache(request) {
|
1102
|
+
const precacheController = getOrCreatePrecacheController();
|
1103
|
+
return precacheController.matchPrecache(request);
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
/*
|
1107
|
+
Copyright 2019 Google LLC
|
1108
|
+
|
1109
|
+
Use of this source code is governed by an MIT-style
|
1110
|
+
license that can be found in the LICENSE file or at
|
1111
|
+
https://opensource.org/licenses/MIT.
|
1112
|
+
*/
|
1113
|
+
|
1114
|
+
const installListener = event => {
|
1115
|
+
const precacheController = getOrCreatePrecacheController();
|
1116
|
+
const plugins = precachePlugins.get();
|
1117
|
+
event.waitUntil(precacheController.install({
|
1118
|
+
event,
|
1119
|
+
plugins
|
1120
|
+
}).catch(error => {
|
1121
|
+
{
|
1122
|
+
logger_js.logger.error(`Service worker installation failed. It will ` + `be retried automatically during the next navigation.`);
|
1123
|
+
} // Re-throw the error to ensure installation fails.
|
1124
|
+
|
1125
|
+
|
1126
|
+
throw error;
|
1127
|
+
}));
|
1128
|
+
};
|
1129
|
+
|
1130
|
+
const activateListener = event => {
|
1131
|
+
const precacheController = getOrCreatePrecacheController();
|
1132
|
+
event.waitUntil(precacheController.activate());
|
1133
|
+
};
|
1134
|
+
/**
|
1135
|
+
* Adds items to the precache list, removing any duplicates and
|
1136
|
+
* stores the files in the
|
1137
|
+
* ["precache cache"]{@link module:workbox-core.cacheNames} when the service
|
1138
|
+
* worker installs.
|
1139
|
+
*
|
1140
|
+
* This method can be called multiple times.
|
1141
|
+
*
|
1142
|
+
* Please note: This method **will not** serve any of the cached files for you.
|
1143
|
+
* It only precaches files. To respond to a network request you call
|
1144
|
+
* [addRoute()]{@link module:workbox-precaching.addRoute}.
|
1145
|
+
*
|
1146
|
+
* If you have a single array of files to precache, you can just call
|
1147
|
+
* [precacheAndRoute()]{@link module:workbox-precaching.precacheAndRoute}.
|
1148
|
+
*
|
1149
|
+
* @param {Array<Object|string>} [entries=[]] Array of entries to precache.
|
1150
|
+
*
|
1151
|
+
* @memberof module:workbox-precaching
|
1152
|
+
*/
|
1153
|
+
|
1154
|
+
|
1155
|
+
function precache(entries) {
|
1156
|
+
const precacheController = getOrCreatePrecacheController();
|
1157
|
+
precacheController.addToCacheList(entries);
|
1158
|
+
|
1159
|
+
if (entries.length > 0) {
|
1160
|
+
// NOTE: these listeners will only be added once (even if the `precache()`
|
1161
|
+
// method is called multiple times) because event listeners are implemented
|
1162
|
+
// as a set, where each listener must be unique.
|
1163
|
+
// See https://github.com/Microsoft/TypeScript/issues/28357#issuecomment-436484705
|
1164
|
+
self.addEventListener('install', installListener);
|
1165
|
+
self.addEventListener('activate', activateListener);
|
1166
|
+
}
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
/*
|
1170
|
+
Copyright 2019 Google LLC
|
1171
|
+
|
1172
|
+
Use of this source code is governed by an MIT-style
|
1173
|
+
license that can be found in the LICENSE file or at
|
1174
|
+
https://opensource.org/licenses/MIT.
|
1175
|
+
*/
|
1176
|
+
/**
|
1177
|
+
* This method will add entries to the precache list and add a route to
|
1178
|
+
* respond to fetch events.
|
1179
|
+
*
|
1180
|
+
* This is a convenience method that will call
|
1181
|
+
* [precache()]{@link module:workbox-precaching.precache} and
|
1182
|
+
* [addRoute()]{@link module:workbox-precaching.addRoute} in a single call.
|
1183
|
+
*
|
1184
|
+
* @param {Array<Object|string>} entries Array of entries to precache.
|
1185
|
+
* @param {Object} [options] See
|
1186
|
+
* [addRoute() options]{@link module:workbox-precaching.addRoute}.
|
1187
|
+
*
|
1188
|
+
* @memberof module:workbox-precaching
|
1189
|
+
*/
|
1190
|
+
|
1191
|
+
function precacheAndRoute(entries, options) {
|
1192
|
+
precache(entries);
|
1193
|
+
addRoute(options);
|
1194
|
+
}
|
1195
|
+
|
1196
|
+
exports.PrecacheController = PrecacheController;
|
1197
|
+
exports.addPlugins = addPlugins;
|
1198
|
+
exports.addRoute = addRoute;
|
1199
|
+
exports.cleanupOutdatedCaches = cleanupOutdatedCaches;
|
1200
|
+
exports.createHandler = createHandler;
|
1201
|
+
exports.createHandlerBoundToURL = createHandlerBoundToURL;
|
1202
|
+
exports.getCacheKeyForURL = getCacheKeyForURL$1;
|
1203
|
+
exports.matchPrecache = matchPrecache;
|
1204
|
+
exports.precache = precache;
|
1205
|
+
exports.precacheAndRoute = precacheAndRoute;
|
1206
|
+
|
1207
|
+
return exports;
|
1208
|
+
|
1209
|
+
}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core));
|
1210
|
+
//# sourceMappingURL=workbox-precaching.dev.js.map
|