workbox-expiration.dev.js.map
35.5 KB
{"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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"}