jekyll-pwa-workbox 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/jekyll-pwa-workbox.rb +13 -13
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-background-sync.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-background-sync.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-background-sync.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-background-sync.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-broadcast-update.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-broadcast-update.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-broadcast-update.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-broadcast-update.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-cacheable-response.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-cacheable-response.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-cacheable-response.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-cacheable-response.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-core.dev.js +658 -619
- data/lib/vendor/workbox-v4.3.1/workbox-core.dev.js.map +1 -0
- data/lib/vendor/workbox-v4.3.1/workbox-core.prod.js +2 -0
- data/lib/vendor/workbox-v4.3.1/workbox-core.prod.js.map +1 -0
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-expiration.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-expiration.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-expiration.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-expiration.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-navigation-preload.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-navigation-preload.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-navigation-preload.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-navigation-preload.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-offline-ga.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-offline-ga.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-offline-ga.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-offline-ga.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-precaching.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-precaching.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-precaching.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-precaching.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-range-requests.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-range-requests.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-range-requests.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-range-requests.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-routing.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-routing.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-routing.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-routing.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-strategies.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-strategies.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-strategies.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-strategies.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-streams.dev.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-streams.dev.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-streams.prod.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-streams.prod.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-sw.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-sw.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.es5.mjs +2 -2
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.es5.mjs.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.mjs +2 -2
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.mjs.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.umd.js +2 -2
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.dev.umd.js.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.es5.mjs +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.es5.mjs.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.mjs +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.mjs.map +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.umd.js +1 -1
- data/lib/vendor/{workbox-v4.3.0 → workbox-v4.3.1}/workbox-window.prod.umd.js.map +1 -1
- metadata +65 -65
- data/lib/vendor/workbox-v4.3.0/workbox-core.dev.js.map +0 -1
- data/lib/vendor/workbox-v4.3.0/workbox-core.prod.js +0 -2
- data/lib/vendor/workbox-v4.3.0/workbox-core.prod.js.map +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cca62e49b0c77764563ace8d9ba25e47ddff893f8367e97722d1dff22db96455
|
4
|
+
data.tar.gz: 57b4d18801373e3fafb277ce33acbd81752f34aa6ac23ae7eb3fc18a28bc4a40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1046adda5ab8efb14a8daea92f838f76fb474557ec6f3a3cfc7e80c2522f0b822887a011bcee8a311ff4442324beb84f895ff150848c1ff31b86aee1b63c2e87
|
7
|
+
data.tar.gz: 7cd61cbf7b095fd5ca6972f8e4649e33bfe3bb7d5727fbfec855be0367fc1c6dd9af3d333e825a436dab23fc4a90d8bd32516a40fe51355eb561dd67f841305f
|
data/lib/jekyll-pwa-workbox.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class SWHelper
|
2
|
-
WORKBOX_VERSION = 'v4.3.
|
2
|
+
WORKBOX_VERSION = 'v4.3.1'
|
3
3
|
def initialize(site, config)
|
4
4
|
@site = site
|
5
5
|
@config = config
|
@@ -13,7 +13,7 @@ class SWHelper
|
|
13
13
|
# add build version in url params
|
14
14
|
sw_register_file.puts(
|
15
15
|
<<-SCRIPT
|
16
|
-
|
16
|
+
"serviceWorker"in navigator&&navigator.serviceWorker.register("#{@site.baseurl.to_s}/#{@sw_filename}?v=#{@site.time.to_i.to_s}").then(function(e){e.onupdatefound=function(){var t=e.installing;t.onstatechange=function(){switch(t.state){case"installed":if(navigator.serviceWorker.controller){var e=document.createEvent("Event");e.initEvent("sw.update",!0,!0),window.dispatchEvent(e)}}}}}).catch(function(e){console.error("Error during service worker registration:",e)});
|
17
17
|
SCRIPT
|
18
18
|
)
|
19
19
|
sw_register_file.close
|
@@ -94,18 +94,18 @@ class SWHelper
|
|
94
94
|
sw_src_file_str = File.read(@site.in_source_dir(@sw_src_filepath))
|
95
95
|
workbox_dir = File.join(@site.baseurl.to_s, dest_js_directory, "workbox-#{SWHelper::WORKBOX_VERSION}")
|
96
96
|
import_scripts_str =
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
97
|
+
<<-SCRIPT
|
98
|
+
importScripts("#{workbox_dir}/workbox-sw.js");
|
99
|
+
workbox.setConfig({modulePathPrefix: "#{workbox_dir}"});
|
100
|
+
SCRIPT
|
102
101
|
sw_dest_file = File.new(@site.in_dest_dir(@sw_filename), 'w')
|
103
102
|
sw_dest_file.puts(
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
103
|
+
<<-SCRIPT
|
104
|
+
#{import_scripts_str}
|
105
|
+
self.__precacheManifest = [#{precache_list_str}];
|
106
|
+
|
107
|
+
#{sw_src_file_str}
|
108
|
+
SCRIPT
|
109
109
|
)
|
110
110
|
sw_dest_file.close
|
111
111
|
end
|
@@ -122,4 +122,4 @@ module Jekyll
|
|
122
122
|
sw_helper.write_sw()
|
123
123
|
end
|
124
124
|
|
125
|
-
end
|
125
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-background-sync.dev.js","sources":["../_version.mjs","../lib/QueueStore.mjs","../lib/StorableRequest.mjs","../Queue.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:background-sync:4.3.0']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs';\nimport '../_version.mjs';\n\n\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst OBJECT_STORE_NAME = 'requests';\nconst INDEXED_PROP = 'queueName';\n\n/**\n * A class to manage storing requests from a Queue in IndexedbDB,\n * indexed by their queue name for easier access.\n *\n * @private\n */\nexport class QueueStore {\n /**\n * Associates this instance with a Queue instance, so entries added can be\n * identified by their queue name.\n *\n * @param {string} queueName\n * @private\n */\n constructor(queueName) {\n this._queueName = queueName;\n this._db = new DBWrapper(DB_NAME, DB_VERSION, {\n onupgradeneeded: this._upgradeDb,\n });\n }\n\n /**\n * Append an entry last in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async pushEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry.requestData',\n });\n }\n\n // Don't specify an ID since one is automatically generated.\n delete entry.id;\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Preppend an entry first in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async unshiftEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry.requestData',\n });\n }\n\n const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n count: 1,\n });\n\n if (firstEntry) {\n // Pick an ID one less than the lowest ID in the object store.\n entry.id = firstEntry.id - 1;\n } else {\n // Otherwise let the auto-incrementor assign the ID.\n delete entry.id;\n }\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Removes and returns the last entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async popEntry() {\n return this._removeEntry({direction: 'prev'});\n }\n\n /**\n * Removes and returns the first entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async shiftEntry() {\n return this._removeEntry({direction: 'next'});\n }\n\n /**\n * Returns all entries in the store matching the `queueName`.\n *\n * @param {Object} options See workbox.backgroundSync.Queue~getAll}\n * @return {Promise<Array<Object>>}\n * @private\n */\n async getAll() {\n return await this._db.getAllMatching(OBJECT_STORE_NAME, {\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n });\n }\n\n /**\n * Deletes the entry for the given ID.\n *\n * WARNING: this method does not ensure the deleted enry belongs to this\n * queue (i.e. matches the `queueName`). But this limitation is acceptable\n * as this class is not publicly exposed. An additional check would make\n * this method slower than it needs to be.\n *\n * @private\n * @param {number} id\n */\n async deleteEntry(id) {\n await this._db.delete(OBJECT_STORE_NAME, id);\n }\n\n /**\n * Removes and returns the first or last entry in the queue (based on the\n * `direction` argument) matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async _removeEntry({direction}) {\n const [entry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n direction,\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n count: 1,\n });\n\n if (entry) {\n await this.deleteEntry(entry.id);\n return entry;\n }\n }\n\n /**\n * Upgrades the database given an `upgradeneeded` event.\n *\n * @param {Event} event\n * @private\n */\n _upgradeDb(event) {\n const db = event.target.result;\n\n if (event.oldVersion > 0 && event.oldVersion < DB_VERSION) {\n if (db.objectStoreNames.contains(OBJECT_STORE_NAME)) {\n db.deleteObjectStore(OBJECT_STORE_NAME);\n }\n }\n\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, {\n autoIncrement: true,\n keyPath: 'id',\n });\n objStore.createIndex(INDEXED_PROP, INDEXED_PROP, {unique: false});\n }\n}\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport '../_version.mjs';\n\n\nconst serializableProperties = [\n 'method',\n 'referrer',\n 'referrerPolicy',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'integrity',\n 'keepalive',\n];\n\n\n/**\n * A class to make it easier to serialize and de-serialize requests so they\n * can be stored in IndexedDB.\n *\n * @private\n */\nclass StorableRequest {\n /**\n * Converts a Request object to a plain object that can be structured\n * cloned or JSON-stringified.\n *\n * @param {Request} request\n * @return {Promise<StorableRequest>}\n *\n * @private\n */\n static async fromRequest(request) {\n const requestData = {\n url: request.url,\n headers: {},\n };\n\n // Set the body if present.\n if (request.method !== 'GET') {\n // Use ArrayBuffer to support non-text request bodies.\n // NOTE: we can't use Blobs becuse Safari doesn't support storing\n // Blobs in IndexedDB in some cases:\n // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457\n requestData.body = await request.clone().arrayBuffer();\n }\n\n // Convert the headers from an iterable to an object.\n for (const [key, value] of request.headers.entries()) {\n requestData.headers[key] = value;\n }\n\n // Add all other serializable request properties\n for (const prop of serializableProperties) {\n if (request[prop] !== undefined) {\n requestData[prop] = request[prop];\n }\n }\n\n return new StorableRequest(requestData);\n }\n\n /**\n * Accepts an object of request data that can be used to construct a\n * `Request` but can also be stored in IndexedDB.\n *\n * @param {Object} requestData An object of request data that includes the\n * `url` plus any relevant properties of\n * [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}.\n * @private\n */\n constructor(requestData) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData',\n });\n assert.isType(requestData.url, 'string', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData.url',\n });\n }\n\n // If the request's mode is `navigate`, convert it to `same-origin` since\n // navigation requests can't be constructed via script.\n if (requestData.mode === 'navigate') {\n requestData.mode = 'same-origin';\n }\n\n this._requestData = requestData;\n }\n\n /**\n * Returns a deep clone of the instances `_requestData` object.\n *\n * @return {Object}\n *\n * @private\n */\n toObject() {\n const requestData = Object.assign({}, this._requestData);\n requestData.headers = Object.assign({}, this._requestData.headers);\n if (requestData.body) {\n requestData.body = requestData.body.slice(0);\n }\n\n return requestData;\n }\n\n /**\n * Converts this instance to a Request.\n *\n * @return {Request}\n *\n * @private\n */\n toRequest() {\n return new Request(this._requestData.url, this._requestData);\n }\n\n /**\n * Creates and returns a deep clone of the instance.\n *\n * @return {StorableRequest}\n *\n * @private\n */\n clone() {\n return new StorableRequest(this.toObject());\n }\n}\n\nexport {StorableRequest};\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {QueueStore} from './lib/QueueStore.mjs';\nimport {StorableRequest} from './lib/StorableRequest.mjs';\nimport './_version.mjs';\n\n\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\n\nconst queueNames = new Set();\n\n/**\n * A class to manage storing failed requests in IndexedDB and retrying them\n * later. All parts of the storing and replaying process are observable via\n * callbacks.\n *\n * @memberof workbox.backgroundSync\n */\nclass Queue {\n /**\n * Creates an instance of Queue with the given options\n *\n * @param {string} name The unique name for this queue. This name must be\n * unique as it's used to register sync events and store requests\n * in IndexedDB specific to this instance. An error will be thrown if\n * a duplicate name is detected.\n * @param {Object} [options]\n * @param {Function} [options.onSync] A function that gets invoked whenever\n * the 'sync' event fires. The function is invoked with an object\n * containing the `queue` property (referencing this instance), and you\n * can use the callback to customize the replay behavior of the queue.\n * When not set the `replayRequests()` method is called.\n * Note: if the replay fails after a sync event, make sure you throw an\n * error, so the browser knows to retry the sync event later.\n * @param {number} [options.maxRetentionTime=7 days] The amount of time (in\n * minutes) a request may be retried. After this amount of time has\n * passed, the request will be deleted from the queue.\n */\n constructor(name, {onSync, maxRetentionTime} = {}) {\n // Ensure the store name is not already being used\n if (queueNames.has(name)) {\n throw new WorkboxError('duplicate-queue-name', {name});\n } else {\n queueNames.add(name);\n }\n\n this._name = name;\n this._onSync = onSync || this.replayRequests;\n this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n this._queueStore = new QueueStore(this._name);\n\n this._addSyncListener();\n }\n\n /**\n * @return {string}\n */\n get name() {\n return this._name;\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the end of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async pushRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'push');\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the beginning of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async unshiftRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'unshift');\n }\n\n /**\n * Removes and returns the last request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async popRequest() {\n return this._removeRequest('pop');\n }\n\n /**\n * Removes and returns the first request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async shiftRequest() {\n return this._removeRequest('shift');\n }\n\n /**\n * Returns all the entries that have not expired (per `maxRetentionTime`).\n * Any expired entries are removed from the queue.\n *\n * @return {Promise<Array<Object>>}\n */\n async getAll() {\n const allEntries = await this._queueStore.getAll();\n const now = Date.now();\n\n const unexpiredEntries = [];\n for (const entry of allEntries) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n await this._queueStore.deleteEntry(entry.id);\n } else {\n unexpiredEntries.push(convertEntry(entry));\n }\n }\n\n return unexpiredEntries;\n }\n\n\n /**\n * Adds the entry to the QueueStore and registers for a sync event.\n *\n * @param {Object} entry\n * @param {Request} entry.request\n * @param {Object} [entry.metadata]\n * @param {number} [entry.timestamp=Date.now()]\n * @param {string} operation ('push' or 'unshift')\n * @private\n */\n async _addRequest(\n {request, metadata, timestamp = Date.now()}, operation) {\n const storableRequest = await StorableRequest.fromRequest(request.clone());\n const entry = {\n requestData: storableRequest.toObject(),\n timestamp,\n };\n\n // Only include metadata if it's present.\n if (metadata) {\n entry.metadata = metadata;\n }\n\n await this._queueStore[`${operation}Entry`](entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(request.url)}' has ` +\n `been added to background sync queue '${this._name}'.`);\n }\n\n // Don't register for a sync if we're in the middle of a sync. Instead,\n // we wait until the sync is complete and call register if\n // `this._requestsAddedDuringSync` is true.\n if (this._syncInProgress) {\n this._requestsAddedDuringSync = true;\n } else {\n await this.registerSync();\n }\n }\n\n /**\n * Removes and returns the first or last (depending on `operation`) entry\n * from the QueueStore that's not older than the `maxRetentionTime`.\n *\n * @param {string} operation ('pop' or 'shift')\n * @return {Object|undefined}\n * @private\n */\n async _removeRequest(operation) {\n const now = Date.now();\n const entry = await this._queueStore[`${operation}Entry`]();\n\n if (entry) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n return this._removeRequest(operation);\n }\n\n return convertEntry(entry);\n }\n }\n\n /**\n * Loops through each request in the queue and attempts to re-fetch it.\n * If any request fails to re-fetch, it's put back in the same position in\n * the queue (which registers a retry for the next sync event).\n */\n async replayRequests() {\n let entry;\n while (entry = await this.shiftRequest()) {\n try {\n await fetch(entry.request.clone());\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `has been replayed in queue '${this._name}'`);\n }\n } catch (error) {\n await this.unshiftRequest(entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `failed to replay, putting it back in queue '${this._name}'`);\n }\n throw new WorkboxError('queue-replay-failed', {name: this._name});\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All requests in queue '${this.name}' have successfully ` +\n `replayed; the queue is now empty!`);\n }\n }\n\n /**\n * Registers a sync event with a tag unique to this instance.\n */\n async registerSync() {\n if ('sync' in registration) {\n try {\n await registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n } catch (err) {\n // This means the registration failed for some reason, possibly due to\n // the user disabling it.\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(\n `Unable to register sync event for '${this._name}'.`, err);\n }\n }\n }\n }\n\n /**\n * In sync-supporting browsers, this adds a listener for the sync event.\n * In non-sync-supporting browsers, this will retry the queue on service\n * worker startup.\n *\n * @private\n */\n _addSyncListener() {\n if ('sync' in registration) {\n self.addEventListener('sync', (event) => {\n if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync for tag '${event.tag}'` +\n `has been received`);\n }\n\n const syncComplete = async () => {\n this._syncInProgress = true;\n\n let syncError;\n try {\n await this._onSync({queue: this});\n } catch (error) {\n syncError = error;\n\n // Rethrow the error. Note: the logic in the finally clause\n // will run before this gets rethrown.\n throw syncError;\n } finally {\n // New items may have been added to the queue during the sync,\n // so we need to register for a new sync if that's happened...\n // Unless there was an error during the sync, in which\n // case the browser will automatically retry later, as long\n // as `event.lastChance` is not true.\n if (this._requestsAddedDuringSync &&\n !(syncError && !event.lastChance)) {\n await this.registerSync();\n }\n\n this._syncInProgress = false;\n this._requestsAddedDuringSync = false;\n }\n };\n event.waitUntil(syncComplete());\n }\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync replaying without background sync event`);\n }\n // If the browser doesn't support background sync, retry\n // every time the service worker starts up as a fallback.\n this._onSync({queue: this});\n }\n }\n\n /**\n * Returns the set of queue names. This is primarily used to reset the list\n * of queue names in tests.\n *\n * @return {Set}\n *\n * @private\n */\n static get _queueNames() {\n return queueNames;\n }\n}\n\n\n/**\n * Converts a QueueStore entry into the format exposed by Queue. This entails\n * converting the request data into a real request and omitting the `id` and\n * `queueName` properties.\n *\n * @param {Object} queueStoreEntry\n * @return {Object}\n * @private\n */\nconst convertEntry = (queueStoreEntry) => {\n const queueEntry = {\n request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n timestamp: queueStoreEntry.timestamp,\n };\n if (queueStoreEntry.metadata) {\n queueEntry.metadata = queueStoreEntry.metadata;\n }\n return queueEntry;\n};\n\nexport {Queue};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `fetchDidFail` lifecycle callback. This makes it\n * easier to add failed requests to a background sync Queue.\n *\n * @memberof workbox.backgroundSync\n */\nclass Plugin {\n /**\n * @param {...*} queueArgs Args to forward to the composed Queue instance.\n * See the [Queue]{@link workbox.backgroundSync.Queue} documentation for\n * parameter details.\n */\n constructor(...queueArgs) {\n this._queue = new Queue(...queueArgs);\n this.fetchDidFail = this.fetchDidFail.bind(this);\n }\n\n /**\n * @param {Object} options\n * @param {Request} options.request\n * @private\n */\n async fetchDidFail({request}) {\n await this._queue.pushRequest({request});\n }\n}\n\nexport {Plugin};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.backgroundSync\n */\n\nexport {\n Queue,\n Plugin,\n};\n"],"names":["self","_","e","DB_VERSION","DB_NAME","OBJECT_STORE_NAME","INDEXED_PROP","QueueStore","constructor","queueName","_queueName","_db","DBWrapper","onupgradeneeded","_upgradeDb","pushEntry","entry","assert","isType","moduleName","className","funcName","paramName","requestData","id","add","unshiftEntry","firstEntry","getAllMatching","count","popEntry","_removeEntry","direction","shiftEntry","getAll","index","query","IDBKeyRange","only","deleteEntry","delete","event","db","target","result","oldVersion","objectStoreNames","contains","deleteObjectStore","objStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","serializableProperties","StorableRequest","fromRequest","request","url","headers","method","body","clone","arrayBuffer","key","value","entries","prop","undefined","mode","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","MAX_RETENTION_TIME","queueNames","Set","Queue","name","onSync","maxRetentionTime","has","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_queueStore","_addSyncListener","pushRequest","isInstance","_addRequest","unshiftRequest","popRequest","_removeRequest","shiftRequest","allEntries","now","Date","unexpiredEntries","maxRetentionTimeInMs","timestamp","push","convertEntry","metadata","operation","storableRequest","logger","log","getFriendlyURL","_syncInProgress","_requestsAddedDuringSync","registerSync","fetch","error","registration","sync","register","err","warn","addEventListener","tag","syncComplete","syncError","queue","lastChance","waitUntil","_queueNames","queueStoreEntry","queueEntry","Plugin","queueArgs","_queue","fetchDidFail","bind"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"workbox-background-sync.dev.js","sources":["../_version.mjs","../lib/QueueStore.mjs","../lib/StorableRequest.mjs","../Queue.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:background-sync:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs';\nimport '../_version.mjs';\n\n\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst OBJECT_STORE_NAME = 'requests';\nconst INDEXED_PROP = 'queueName';\n\n/**\n * A class to manage storing requests from a Queue in IndexedbDB,\n * indexed by their queue name for easier access.\n *\n * @private\n */\nexport class QueueStore {\n /**\n * Associates this instance with a Queue instance, so entries added can be\n * identified by their queue name.\n *\n * @param {string} queueName\n * @private\n */\n constructor(queueName) {\n this._queueName = queueName;\n this._db = new DBWrapper(DB_NAME, DB_VERSION, {\n onupgradeneeded: this._upgradeDb,\n });\n }\n\n /**\n * Append an entry last in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async pushEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry.requestData',\n });\n }\n\n // Don't specify an ID since one is automatically generated.\n delete entry.id;\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Preppend an entry first in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async unshiftEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry.requestData',\n });\n }\n\n const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n count: 1,\n });\n\n if (firstEntry) {\n // Pick an ID one less than the lowest ID in the object store.\n entry.id = firstEntry.id - 1;\n } else {\n // Otherwise let the auto-incrementor assign the ID.\n delete entry.id;\n }\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Removes and returns the last entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async popEntry() {\n return this._removeEntry({direction: 'prev'});\n }\n\n /**\n * Removes and returns the first entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async shiftEntry() {\n return this._removeEntry({direction: 'next'});\n }\n\n /**\n * Returns all entries in the store matching the `queueName`.\n *\n * @param {Object} options See workbox.backgroundSync.Queue~getAll}\n * @return {Promise<Array<Object>>}\n * @private\n */\n async getAll() {\n return await this._db.getAllMatching(OBJECT_STORE_NAME, {\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n });\n }\n\n /**\n * Deletes the entry for the given ID.\n *\n * WARNING: this method does not ensure the deleted enry belongs to this\n * queue (i.e. matches the `queueName`). But this limitation is acceptable\n * as this class is not publicly exposed. An additional check would make\n * this method slower than it needs to be.\n *\n * @private\n * @param {number} id\n */\n async deleteEntry(id) {\n await this._db.delete(OBJECT_STORE_NAME, id);\n }\n\n /**\n * Removes and returns the first or last entry in the queue (based on the\n * `direction` argument) matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async _removeEntry({direction}) {\n const [entry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n direction,\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n count: 1,\n });\n\n if (entry) {\n await this.deleteEntry(entry.id);\n return entry;\n }\n }\n\n /**\n * Upgrades the database given an `upgradeneeded` event.\n *\n * @param {Event} event\n * @private\n */\n _upgradeDb(event) {\n const db = event.target.result;\n\n if (event.oldVersion > 0 && event.oldVersion < DB_VERSION) {\n if (db.objectStoreNames.contains(OBJECT_STORE_NAME)) {\n db.deleteObjectStore(OBJECT_STORE_NAME);\n }\n }\n\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, {\n autoIncrement: true,\n keyPath: 'id',\n });\n objStore.createIndex(INDEXED_PROP, INDEXED_PROP, {unique: false});\n }\n}\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport '../_version.mjs';\n\n\nconst serializableProperties = [\n 'method',\n 'referrer',\n 'referrerPolicy',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'integrity',\n 'keepalive',\n];\n\n\n/**\n * A class to make it easier to serialize and de-serialize requests so they\n * can be stored in IndexedDB.\n *\n * @private\n */\nclass StorableRequest {\n /**\n * Converts a Request object to a plain object that can be structured\n * cloned or JSON-stringified.\n *\n * @param {Request} request\n * @return {Promise<StorableRequest>}\n *\n * @private\n */\n static async fromRequest(request) {\n const requestData = {\n url: request.url,\n headers: {},\n };\n\n // Set the body if present.\n if (request.method !== 'GET') {\n // Use ArrayBuffer to support non-text request bodies.\n // NOTE: we can't use Blobs becuse Safari doesn't support storing\n // Blobs in IndexedDB in some cases:\n // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457\n requestData.body = await request.clone().arrayBuffer();\n }\n\n // Convert the headers from an iterable to an object.\n for (const [key, value] of request.headers.entries()) {\n requestData.headers[key] = value;\n }\n\n // Add all other serializable request properties\n for (const prop of serializableProperties) {\n if (request[prop] !== undefined) {\n requestData[prop] = request[prop];\n }\n }\n\n return new StorableRequest(requestData);\n }\n\n /**\n * Accepts an object of request data that can be used to construct a\n * `Request` but can also be stored in IndexedDB.\n *\n * @param {Object} requestData An object of request data that includes the\n * `url` plus any relevant properties of\n * [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}.\n * @private\n */\n constructor(requestData) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData',\n });\n assert.isType(requestData.url, 'string', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData.url',\n });\n }\n\n // If the request's mode is `navigate`, convert it to `same-origin` since\n // navigation requests can't be constructed via script.\n if (requestData.mode === 'navigate') {\n requestData.mode = 'same-origin';\n }\n\n this._requestData = requestData;\n }\n\n /**\n * Returns a deep clone of the instances `_requestData` object.\n *\n * @return {Object}\n *\n * @private\n */\n toObject() {\n const requestData = Object.assign({}, this._requestData);\n requestData.headers = Object.assign({}, this._requestData.headers);\n if (requestData.body) {\n requestData.body = requestData.body.slice(0);\n }\n\n return requestData;\n }\n\n /**\n * Converts this instance to a Request.\n *\n * @return {Request}\n *\n * @private\n */\n toRequest() {\n return new Request(this._requestData.url, this._requestData);\n }\n\n /**\n * Creates and returns a deep clone of the instance.\n *\n * @return {StorableRequest}\n *\n * @private\n */\n clone() {\n return new StorableRequest(this.toObject());\n }\n}\n\nexport {StorableRequest};\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {QueueStore} from './lib/QueueStore.mjs';\nimport {StorableRequest} from './lib/StorableRequest.mjs';\nimport './_version.mjs';\n\n\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\n\nconst queueNames = new Set();\n\n/**\n * A class to manage storing failed requests in IndexedDB and retrying them\n * later. All parts of the storing and replaying process are observable via\n * callbacks.\n *\n * @memberof workbox.backgroundSync\n */\nclass Queue {\n /**\n * Creates an instance of Queue with the given options\n *\n * @param {string} name The unique name for this queue. This name must be\n * unique as it's used to register sync events and store requests\n * in IndexedDB specific to this instance. An error will be thrown if\n * a duplicate name is detected.\n * @param {Object} [options]\n * @param {Function} [options.onSync] A function that gets invoked whenever\n * the 'sync' event fires. The function is invoked with an object\n * containing the `queue` property (referencing this instance), and you\n * can use the callback to customize the replay behavior of the queue.\n * When not set the `replayRequests()` method is called.\n * Note: if the replay fails after a sync event, make sure you throw an\n * error, so the browser knows to retry the sync event later.\n * @param {number} [options.maxRetentionTime=7 days] The amount of time (in\n * minutes) a request may be retried. After this amount of time has\n * passed, the request will be deleted from the queue.\n */\n constructor(name, {onSync, maxRetentionTime} = {}) {\n // Ensure the store name is not already being used\n if (queueNames.has(name)) {\n throw new WorkboxError('duplicate-queue-name', {name});\n } else {\n queueNames.add(name);\n }\n\n this._name = name;\n this._onSync = onSync || this.replayRequests;\n this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n this._queueStore = new QueueStore(this._name);\n\n this._addSyncListener();\n }\n\n /**\n * @return {string}\n */\n get name() {\n return this._name;\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the end of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async pushRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'push');\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the beginning of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async unshiftRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'unshift');\n }\n\n /**\n * Removes and returns the last request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async popRequest() {\n return this._removeRequest('pop');\n }\n\n /**\n * Removes and returns the first request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async shiftRequest() {\n return this._removeRequest('shift');\n }\n\n /**\n * Returns all the entries that have not expired (per `maxRetentionTime`).\n * Any expired entries are removed from the queue.\n *\n * @return {Promise<Array<Object>>}\n */\n async getAll() {\n const allEntries = await this._queueStore.getAll();\n const now = Date.now();\n\n const unexpiredEntries = [];\n for (const entry of allEntries) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n await this._queueStore.deleteEntry(entry.id);\n } else {\n unexpiredEntries.push(convertEntry(entry));\n }\n }\n\n return unexpiredEntries;\n }\n\n\n /**\n * Adds the entry to the QueueStore and registers for a sync event.\n *\n * @param {Object} entry\n * @param {Request} entry.request\n * @param {Object} [entry.metadata]\n * @param {number} [entry.timestamp=Date.now()]\n * @param {string} operation ('push' or 'unshift')\n * @private\n */\n async _addRequest(\n {request, metadata, timestamp = Date.now()}, operation) {\n const storableRequest = await StorableRequest.fromRequest(request.clone());\n const entry = {\n requestData: storableRequest.toObject(),\n timestamp,\n };\n\n // Only include metadata if it's present.\n if (metadata) {\n entry.metadata = metadata;\n }\n\n await this._queueStore[`${operation}Entry`](entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(request.url)}' has ` +\n `been added to background sync queue '${this._name}'.`);\n }\n\n // Don't register for a sync if we're in the middle of a sync. Instead,\n // we wait until the sync is complete and call register if\n // `this._requestsAddedDuringSync` is true.\n if (this._syncInProgress) {\n this._requestsAddedDuringSync = true;\n } else {\n await this.registerSync();\n }\n }\n\n /**\n * Removes and returns the first or last (depending on `operation`) entry\n * from the QueueStore that's not older than the `maxRetentionTime`.\n *\n * @param {string} operation ('pop' or 'shift')\n * @return {Object|undefined}\n * @private\n */\n async _removeRequest(operation) {\n const now = Date.now();\n const entry = await this._queueStore[`${operation}Entry`]();\n\n if (entry) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n return this._removeRequest(operation);\n }\n\n return convertEntry(entry);\n }\n }\n\n /**\n * Loops through each request in the queue and attempts to re-fetch it.\n * If any request fails to re-fetch, it's put back in the same position in\n * the queue (which registers a retry for the next sync event).\n */\n async replayRequests() {\n let entry;\n while (entry = await this.shiftRequest()) {\n try {\n await fetch(entry.request.clone());\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `has been replayed in queue '${this._name}'`);\n }\n } catch (error) {\n await this.unshiftRequest(entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `failed to replay, putting it back in queue '${this._name}'`);\n }\n throw new WorkboxError('queue-replay-failed', {name: this._name});\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All requests in queue '${this.name}' have successfully ` +\n `replayed; the queue is now empty!`);\n }\n }\n\n /**\n * Registers a sync event with a tag unique to this instance.\n */\n async registerSync() {\n if ('sync' in registration) {\n try {\n await registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n } catch (err) {\n // This means the registration failed for some reason, possibly due to\n // the user disabling it.\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(\n `Unable to register sync event for '${this._name}'.`, err);\n }\n }\n }\n }\n\n /**\n * In sync-supporting browsers, this adds a listener for the sync event.\n * In non-sync-supporting browsers, this will retry the queue on service\n * worker startup.\n *\n * @private\n */\n _addSyncListener() {\n if ('sync' in registration) {\n self.addEventListener('sync', (event) => {\n if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync for tag '${event.tag}'` +\n `has been received`);\n }\n\n const syncComplete = async () => {\n this._syncInProgress = true;\n\n let syncError;\n try {\n await this._onSync({queue: this});\n } catch (error) {\n syncError = error;\n\n // Rethrow the error. Note: the logic in the finally clause\n // will run before this gets rethrown.\n throw syncError;\n } finally {\n // New items may have been added to the queue during the sync,\n // so we need to register for a new sync if that's happened...\n // Unless there was an error during the sync, in which\n // case the browser will automatically retry later, as long\n // as `event.lastChance` is not true.\n if (this._requestsAddedDuringSync &&\n !(syncError && !event.lastChance)) {\n await this.registerSync();\n }\n\n this._syncInProgress = false;\n this._requestsAddedDuringSync = false;\n }\n };\n event.waitUntil(syncComplete());\n }\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync replaying without background sync event`);\n }\n // If the browser doesn't support background sync, retry\n // every time the service worker starts up as a fallback.\n this._onSync({queue: this});\n }\n }\n\n /**\n * Returns the set of queue names. This is primarily used to reset the list\n * of queue names in tests.\n *\n * @return {Set}\n *\n * @private\n */\n static get _queueNames() {\n return queueNames;\n }\n}\n\n\n/**\n * Converts a QueueStore entry into the format exposed by Queue. This entails\n * converting the request data into a real request and omitting the `id` and\n * `queueName` properties.\n *\n * @param {Object} queueStoreEntry\n * @return {Object}\n * @private\n */\nconst convertEntry = (queueStoreEntry) => {\n const queueEntry = {\n request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n timestamp: queueStoreEntry.timestamp,\n };\n if (queueStoreEntry.metadata) {\n queueEntry.metadata = queueStoreEntry.metadata;\n }\n return queueEntry;\n};\n\nexport {Queue};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `fetchDidFail` lifecycle callback. This makes it\n * easier to add failed requests to a background sync Queue.\n *\n * @memberof workbox.backgroundSync\n */\nclass Plugin {\n /**\n * @param {...*} queueArgs Args to forward to the composed Queue instance.\n * See the [Queue]{@link workbox.backgroundSync.Queue} documentation for\n * parameter details.\n */\n constructor(...queueArgs) {\n this._queue = new Queue(...queueArgs);\n this.fetchDidFail = this.fetchDidFail.bind(this);\n }\n\n /**\n * @param {Object} options\n * @param {Request} options.request\n * @private\n */\n async fetchDidFail({request}) {\n await this._queue.pushRequest({request});\n }\n}\n\nexport {Plugin};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.backgroundSync\n */\n\nexport {\n Queue,\n Plugin,\n};\n"],"names":["self","_","e","DB_VERSION","DB_NAME","OBJECT_STORE_NAME","INDEXED_PROP","QueueStore","constructor","queueName","_queueName","_db","DBWrapper","onupgradeneeded","_upgradeDb","pushEntry","entry","assert","isType","moduleName","className","funcName","paramName","requestData","id","add","unshiftEntry","firstEntry","getAllMatching","count","popEntry","_removeEntry","direction","shiftEntry","getAll","index","query","IDBKeyRange","only","deleteEntry","delete","event","db","target","result","oldVersion","objectStoreNames","contains","deleteObjectStore","objStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","serializableProperties","StorableRequest","fromRequest","request","url","headers","method","body","clone","arrayBuffer","key","value","entries","prop","undefined","mode","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","MAX_RETENTION_TIME","queueNames","Set","Queue","name","onSync","maxRetentionTime","has","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_queueStore","_addSyncListener","pushRequest","isInstance","_addRequest","unshiftRequest","popRequest","_removeRequest","shiftRequest","allEntries","now","Date","unexpiredEntries","maxRetentionTimeInMs","timestamp","push","convertEntry","metadata","operation","storableRequest","logger","log","getFriendlyURL","_syncInProgress","_requestsAddedDuringSync","registerSync","fetch","error","registration","sync","register","err","warn","addEventListener","tag","syncComplete","syncError","queue","lastChance","waitUntil","_queueNames","queueStoreEntry","queueEntry","Plugin","queueArgs","_queue","fetchDidFail","bind"],"mappings":"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"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
this.workbox=this.workbox||{},this.workbox.backgroundSync=function(t,e,s){"use strict";try{self["workbox:background-sync:4.3.
|
1
|
+
this.workbox=this.workbox||{},this.workbox.backgroundSync=function(t,e,s){"use strict";try{self["workbox:background-sync:4.3.1"]&&_()}catch(t){}const i=3,n="workbox-background-sync",a="requests",r="queueName";class c{constructor(t){this.t=t,this.s=new s.DBWrapper(n,i,{onupgradeneeded:this.i})}async pushEntry(t){delete t.id,t.queueName=this.t,await this.s.add(a,t)}async unshiftEntry(t){const[e]=await this.s.getAllMatching(a,{count:1});e?t.id=e.id-1:delete t.id,t.queueName=this.t,await this.s.add(a,t)}async popEntry(){return this.h({direction:"prev"})}async shiftEntry(){return this.h({direction:"next"})}async getAll(){return await this.s.getAllMatching(a,{index:r,query:IDBKeyRange.only(this.t)})}async deleteEntry(t){await this.s.delete(a,t)}async h({direction:t}){const[e]=await this.s.getAllMatching(a,{direction:t,index:r,query:IDBKeyRange.only(this.t),count:1});if(e)return await this.deleteEntry(e.id),e}i(t){const e=t.target.result;t.oldVersion>0&&t.oldVersion<i&&e.objectStoreNames.contains(a)&&e.deleteObjectStore(a),e.createObjectStore(a,{autoIncrement:!0,keyPath:"id"}).createIndex(r,r,{unique:!1})}}const h=["method","referrer","referrerPolicy","mode","credentials","cache","redirect","integrity","keepalive"];class o{static async fromRequest(t){const e={url:t.url,headers:{}};"GET"!==t.method&&(e.body=await t.clone().arrayBuffer());for(const[s,i]of t.headers.entries())e.headers[s]=i;for(const s of h)void 0!==t[s]&&(e[s]=t[s]);return new o(e)}constructor(t){"navigate"===t.mode&&(t.mode="same-origin"),this.o=t}toObject(){const t=Object.assign({},this.o);return t.headers=Object.assign({},this.o.headers),t.body&&(t.body=t.body.slice(0)),t}toRequest(){return new Request(this.o.url,this.o)}clone(){return new o(this.toObject())}}const u="workbox-background-sync",y=10080,w=new Set;class d{constructor(t,{onSync:s,maxRetentionTime:i}={}){if(w.has(t))throw new e.WorkboxError("duplicate-queue-name",{name:t});w.add(t),this.u=t,this.l=s||this.replayRequests,this.q=i||y,this.m=new c(this.u),this.p()}get name(){return this.u}async pushRequest(t){await this.g(t,"push")}async unshiftRequest(t){await this.g(t,"unshift")}async popRequest(){return this.R("pop")}async shiftRequest(){return this.R("shift")}async getAll(){const t=await this.m.getAll(),e=Date.now(),s=[];for(const i of t){const t=60*this.q*1e3;e-i.timestamp>t?await this.m.deleteEntry(i.id):s.push(f(i))}return s}async g({request:t,metadata:e,timestamp:s=Date.now()},i){const n={requestData:(await o.fromRequest(t.clone())).toObject(),timestamp:s};e&&(n.metadata=e),await this.m[`${i}Entry`](n),this.k?this.D=!0:await this.registerSync()}async R(t){const e=Date.now(),s=await this.m[`${t}Entry`]();if(s){const i=60*this.q*1e3;return e-s.timestamp>i?this.R(t):f(s)}}async replayRequests(){let t;for(;t=await this.shiftRequest();)try{await fetch(t.request.clone())}catch(s){throw await this.unshiftRequest(t),new e.WorkboxError("queue-replay-failed",{name:this.u})}}async registerSync(){if("sync"in registration)try{await registration.sync.register(`${u}:${this.u}`)}catch(t){}}p(){"sync"in registration?self.addEventListener("sync",t=>{if(t.tag===`${u}:${this.u}`){const e=async()=>{let e;this.k=!0;try{await this.l({queue:this})}catch(t){throw e=t}finally{!this.D||e&&!t.lastChance||await this.registerSync(),this.k=!1,this.D=!1}};t.waitUntil(e())}}):this.l({queue:this})}static get _(){return w}}const f=t=>{const e={request:new o(t.requestData).toRequest(),timestamp:t.timestamp};return t.metadata&&(e.metadata=t.metadata),e};return t.Queue=d,t.Plugin=class{constructor(...t){this.v=new d(...t),this.fetchDidFail=this.fetchDidFail.bind(this)}async fetchDidFail({request:t}){await this.v.pushRequest({request:t})}},t}({},workbox.core._private,workbox.core._private);
|
2
2
|
//# sourceMappingURL=workbox-background-sync.prod.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-background-sync.prod.js","sources":["../_version.mjs","../lib/QueueStore.mjs","../lib/StorableRequest.mjs","../Queue.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:background-sync:4.3.0']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs';\nimport '../_version.mjs';\n\n\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst OBJECT_STORE_NAME = 'requests';\nconst INDEXED_PROP = 'queueName';\n\n/**\n * A class to manage storing requests from a Queue in IndexedbDB,\n * indexed by their queue name for easier access.\n *\n * @private\n */\nexport class QueueStore {\n /**\n * Associates this instance with a Queue instance, so entries added can be\n * identified by their queue name.\n *\n * @param {string} queueName\n * @private\n */\n constructor(queueName) {\n this._queueName = queueName;\n this._db = new DBWrapper(DB_NAME, DB_VERSION, {\n onupgradeneeded: this._upgradeDb,\n });\n }\n\n /**\n * Append an entry last in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async pushEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry.requestData',\n });\n }\n\n // Don't specify an ID since one is automatically generated.\n delete entry.id;\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Preppend an entry first in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async unshiftEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry.requestData',\n });\n }\n\n const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n count: 1,\n });\n\n if (firstEntry) {\n // Pick an ID one less than the lowest ID in the object store.\n entry.id = firstEntry.id - 1;\n } else {\n // Otherwise let the auto-incrementor assign the ID.\n delete entry.id;\n }\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Removes and returns the last entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async popEntry() {\n return this._removeEntry({direction: 'prev'});\n }\n\n /**\n * Removes and returns the first entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async shiftEntry() {\n return this._removeEntry({direction: 'next'});\n }\n\n /**\n * Returns all entries in the store matching the `queueName`.\n *\n * @param {Object} options See workbox.backgroundSync.Queue~getAll}\n * @return {Promise<Array<Object>>}\n * @private\n */\n async getAll() {\n return await this._db.getAllMatching(OBJECT_STORE_NAME, {\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n });\n }\n\n /**\n * Deletes the entry for the given ID.\n *\n * WARNING: this method does not ensure the deleted enry belongs to this\n * queue (i.e. matches the `queueName`). But this limitation is acceptable\n * as this class is not publicly exposed. An additional check would make\n * this method slower than it needs to be.\n *\n * @private\n * @param {number} id\n */\n async deleteEntry(id) {\n await this._db.delete(OBJECT_STORE_NAME, id);\n }\n\n /**\n * Removes and returns the first or last entry in the queue (based on the\n * `direction` argument) matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async _removeEntry({direction}) {\n const [entry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n direction,\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n count: 1,\n });\n\n if (entry) {\n await this.deleteEntry(entry.id);\n return entry;\n }\n }\n\n /**\n * Upgrades the database given an `upgradeneeded` event.\n *\n * @param {Event} event\n * @private\n */\n _upgradeDb(event) {\n const db = event.target.result;\n\n if (event.oldVersion > 0 && event.oldVersion < DB_VERSION) {\n if (db.objectStoreNames.contains(OBJECT_STORE_NAME)) {\n db.deleteObjectStore(OBJECT_STORE_NAME);\n }\n }\n\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, {\n autoIncrement: true,\n keyPath: 'id',\n });\n objStore.createIndex(INDEXED_PROP, INDEXED_PROP, {unique: false});\n }\n}\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport '../_version.mjs';\n\n\nconst serializableProperties = [\n 'method',\n 'referrer',\n 'referrerPolicy',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'integrity',\n 'keepalive',\n];\n\n\n/**\n * A class to make it easier to serialize and de-serialize requests so they\n * can be stored in IndexedDB.\n *\n * @private\n */\nclass StorableRequest {\n /**\n * Converts a Request object to a plain object that can be structured\n * cloned or JSON-stringified.\n *\n * @param {Request} request\n * @return {Promise<StorableRequest>}\n *\n * @private\n */\n static async fromRequest(request) {\n const requestData = {\n url: request.url,\n headers: {},\n };\n\n // Set the body if present.\n if (request.method !== 'GET') {\n // Use ArrayBuffer to support non-text request bodies.\n // NOTE: we can't use Blobs becuse Safari doesn't support storing\n // Blobs in IndexedDB in some cases:\n // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457\n requestData.body = await request.clone().arrayBuffer();\n }\n\n // Convert the headers from an iterable to an object.\n for (const [key, value] of request.headers.entries()) {\n requestData.headers[key] = value;\n }\n\n // Add all other serializable request properties\n for (const prop of serializableProperties) {\n if (request[prop] !== undefined) {\n requestData[prop] = request[prop];\n }\n }\n\n return new StorableRequest(requestData);\n }\n\n /**\n * Accepts an object of request data that can be used to construct a\n * `Request` but can also be stored in IndexedDB.\n *\n * @param {Object} requestData An object of request data that includes the\n * `url` plus any relevant properties of\n * [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}.\n * @private\n */\n constructor(requestData) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData',\n });\n assert.isType(requestData.url, 'string', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData.url',\n });\n }\n\n // If the request's mode is `navigate`, convert it to `same-origin` since\n // navigation requests can't be constructed via script.\n if (requestData.mode === 'navigate') {\n requestData.mode = 'same-origin';\n }\n\n this._requestData = requestData;\n }\n\n /**\n * Returns a deep clone of the instances `_requestData` object.\n *\n * @return {Object}\n *\n * @private\n */\n toObject() {\n const requestData = Object.assign({}, this._requestData);\n requestData.headers = Object.assign({}, this._requestData.headers);\n if (requestData.body) {\n requestData.body = requestData.body.slice(0);\n }\n\n return requestData;\n }\n\n /**\n * Converts this instance to a Request.\n *\n * @return {Request}\n *\n * @private\n */\n toRequest() {\n return new Request(this._requestData.url, this._requestData);\n }\n\n /**\n * Creates and returns a deep clone of the instance.\n *\n * @return {StorableRequest}\n *\n * @private\n */\n clone() {\n return new StorableRequest(this.toObject());\n }\n}\n\nexport {StorableRequest};\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {QueueStore} from './lib/QueueStore.mjs';\nimport {StorableRequest} from './lib/StorableRequest.mjs';\nimport './_version.mjs';\n\n\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\n\nconst queueNames = new Set();\n\n/**\n * A class to manage storing failed requests in IndexedDB and retrying them\n * later. All parts of the storing and replaying process are observable via\n * callbacks.\n *\n * @memberof workbox.backgroundSync\n */\nclass Queue {\n /**\n * Creates an instance of Queue with the given options\n *\n * @param {string} name The unique name for this queue. This name must be\n * unique as it's used to register sync events and store requests\n * in IndexedDB specific to this instance. An error will be thrown if\n * a duplicate name is detected.\n * @param {Object} [options]\n * @param {Function} [options.onSync] A function that gets invoked whenever\n * the 'sync' event fires. The function is invoked with an object\n * containing the `queue` property (referencing this instance), and you\n * can use the callback to customize the replay behavior of the queue.\n * When not set the `replayRequests()` method is called.\n * Note: if the replay fails after a sync event, make sure you throw an\n * error, so the browser knows to retry the sync event later.\n * @param {number} [options.maxRetentionTime=7 days] The amount of time (in\n * minutes) a request may be retried. After this amount of time has\n * passed, the request will be deleted from the queue.\n */\n constructor(name, {onSync, maxRetentionTime} = {}) {\n // Ensure the store name is not already being used\n if (queueNames.has(name)) {\n throw new WorkboxError('duplicate-queue-name', {name});\n } else {\n queueNames.add(name);\n }\n\n this._name = name;\n this._onSync = onSync || this.replayRequests;\n this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n this._queueStore = new QueueStore(this._name);\n\n this._addSyncListener();\n }\n\n /**\n * @return {string}\n */\n get name() {\n return this._name;\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the end of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async pushRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'push');\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the beginning of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async unshiftRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'unshift');\n }\n\n /**\n * Removes and returns the last request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async popRequest() {\n return this._removeRequest('pop');\n }\n\n /**\n * Removes and returns the first request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async shiftRequest() {\n return this._removeRequest('shift');\n }\n\n /**\n * Returns all the entries that have not expired (per `maxRetentionTime`).\n * Any expired entries are removed from the queue.\n *\n * @return {Promise<Array<Object>>}\n */\n async getAll() {\n const allEntries = await this._queueStore.getAll();\n const now = Date.now();\n\n const unexpiredEntries = [];\n for (const entry of allEntries) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n await this._queueStore.deleteEntry(entry.id);\n } else {\n unexpiredEntries.push(convertEntry(entry));\n }\n }\n\n return unexpiredEntries;\n }\n\n\n /**\n * Adds the entry to the QueueStore and registers for a sync event.\n *\n * @param {Object} entry\n * @param {Request} entry.request\n * @param {Object} [entry.metadata]\n * @param {number} [entry.timestamp=Date.now()]\n * @param {string} operation ('push' or 'unshift')\n * @private\n */\n async _addRequest(\n {request, metadata, timestamp = Date.now()}, operation) {\n const storableRequest = await StorableRequest.fromRequest(request.clone());\n const entry = {\n requestData: storableRequest.toObject(),\n timestamp,\n };\n\n // Only include metadata if it's present.\n if (metadata) {\n entry.metadata = metadata;\n }\n\n await this._queueStore[`${operation}Entry`](entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(request.url)}' has ` +\n `been added to background sync queue '${this._name}'.`);\n }\n\n // Don't register for a sync if we're in the middle of a sync. Instead,\n // we wait until the sync is complete and call register if\n // `this._requestsAddedDuringSync` is true.\n if (this._syncInProgress) {\n this._requestsAddedDuringSync = true;\n } else {\n await this.registerSync();\n }\n }\n\n /**\n * Removes and returns the first or last (depending on `operation`) entry\n * from the QueueStore that's not older than the `maxRetentionTime`.\n *\n * @param {string} operation ('pop' or 'shift')\n * @return {Object|undefined}\n * @private\n */\n async _removeRequest(operation) {\n const now = Date.now();\n const entry = await this._queueStore[`${operation}Entry`]();\n\n if (entry) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n return this._removeRequest(operation);\n }\n\n return convertEntry(entry);\n }\n }\n\n /**\n * Loops through each request in the queue and attempts to re-fetch it.\n * If any request fails to re-fetch, it's put back in the same position in\n * the queue (which registers a retry for the next sync event).\n */\n async replayRequests() {\n let entry;\n while (entry = await this.shiftRequest()) {\n try {\n await fetch(entry.request.clone());\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `has been replayed in queue '${this._name}'`);\n }\n } catch (error) {\n await this.unshiftRequest(entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `failed to replay, putting it back in queue '${this._name}'`);\n }\n throw new WorkboxError('queue-replay-failed', {name: this._name});\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All requests in queue '${this.name}' have successfully ` +\n `replayed; the queue is now empty!`);\n }\n }\n\n /**\n * Registers a sync event with a tag unique to this instance.\n */\n async registerSync() {\n if ('sync' in registration) {\n try {\n await registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n } catch (err) {\n // This means the registration failed for some reason, possibly due to\n // the user disabling it.\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(\n `Unable to register sync event for '${this._name}'.`, err);\n }\n }\n }\n }\n\n /**\n * In sync-supporting browsers, this adds a listener for the sync event.\n * In non-sync-supporting browsers, this will retry the queue on service\n * worker startup.\n *\n * @private\n */\n _addSyncListener() {\n if ('sync' in registration) {\n self.addEventListener('sync', (event) => {\n if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync for tag '${event.tag}'` +\n `has been received`);\n }\n\n const syncComplete = async () => {\n this._syncInProgress = true;\n\n let syncError;\n try {\n await this._onSync({queue: this});\n } catch (error) {\n syncError = error;\n\n // Rethrow the error. Note: the logic in the finally clause\n // will run before this gets rethrown.\n throw syncError;\n } finally {\n // New items may have been added to the queue during the sync,\n // so we need to register for a new sync if that's happened...\n // Unless there was an error during the sync, in which\n // case the browser will automatically retry later, as long\n // as `event.lastChance` is not true.\n if (this._requestsAddedDuringSync &&\n !(syncError && !event.lastChance)) {\n await this.registerSync();\n }\n\n this._syncInProgress = false;\n this._requestsAddedDuringSync = false;\n }\n };\n event.waitUntil(syncComplete());\n }\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync replaying without background sync event`);\n }\n // If the browser doesn't support background sync, retry\n // every time the service worker starts up as a fallback.\n this._onSync({queue: this});\n }\n }\n\n /**\n * Returns the set of queue names. This is primarily used to reset the list\n * of queue names in tests.\n *\n * @return {Set}\n *\n * @private\n */\n static get _queueNames() {\n return queueNames;\n }\n}\n\n\n/**\n * Converts a QueueStore entry into the format exposed by Queue. This entails\n * converting the request data into a real request and omitting the `id` and\n * `queueName` properties.\n *\n * @param {Object} queueStoreEntry\n * @return {Object}\n * @private\n */\nconst convertEntry = (queueStoreEntry) => {\n const queueEntry = {\n request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n timestamp: queueStoreEntry.timestamp,\n };\n if (queueStoreEntry.metadata) {\n queueEntry.metadata = queueStoreEntry.metadata;\n }\n return queueEntry;\n};\n\nexport {Queue};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `fetchDidFail` lifecycle callback. This makes it\n * easier to add failed requests to a background sync Queue.\n *\n * @memberof workbox.backgroundSync\n */\nclass Plugin {\n /**\n * @param {...*} queueArgs Args to forward to the composed Queue instance.\n * See the [Queue]{@link workbox.backgroundSync.Queue} documentation for\n * parameter details.\n */\n constructor(...queueArgs) {\n this._queue = new Queue(...queueArgs);\n this.fetchDidFail = this.fetchDidFail.bind(this);\n }\n\n /**\n * @param {Object} options\n * @param {Request} options.request\n * @private\n */\n async fetchDidFail({request}) {\n await this._queue.pushRequest({request});\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","DB_VERSION","DB_NAME","OBJECT_STORE_NAME","INDEXED_PROP","QueueStore","constructor","queueName","_queueName","_db","DBWrapper","onupgradeneeded","this","_upgradeDb","entry","id","add","firstEntry","getAllMatching","count","_removeEntry","direction","index","query","IDBKeyRange","only","delete","deleteEntry","event","db","target","result","oldVersion","objectStoreNames","contains","deleteObjectStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","serializableProperties","StorableRequest","request","requestData","url","headers","method","body","clone","arrayBuffer","key","value","entries","prop","undefined","mode","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","MAX_RETENTION_TIME","queueNames","Set","Queue","name","onSync","maxRetentionTime","has","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_queueStore","_addSyncListener","_addRequest","_removeRequest","allEntries","getAll","now","Date","unexpiredEntries","maxRetentionTimeInMs","timestamp","push","convertEntry","metadata","operation","fromRequest","_syncInProgress","_requestsAddedDuringSync","registerSync","shiftRequest","fetch","error","unshiftRequest","registration","sync","register","err","addEventListener","tag","syncComplete","async","syncError","queue","lastChance","waitUntil","queueStoreEntry","queueEntry","queueArgs","_queue","fetchDidFail","bind","pushRequest"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"workbox-background-sync.prod.js","sources":["../_version.mjs","../lib/QueueStore.mjs","../lib/StorableRequest.mjs","../Queue.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:background-sync:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {DBWrapper} from 'workbox-core/_private/DBWrapper.mjs';\nimport '../_version.mjs';\n\n\nconst DB_VERSION = 3;\nconst DB_NAME = 'workbox-background-sync';\nconst OBJECT_STORE_NAME = 'requests';\nconst INDEXED_PROP = 'queueName';\n\n/**\n * A class to manage storing requests from a Queue in IndexedbDB,\n * indexed by their queue name for easier access.\n *\n * @private\n */\nexport class QueueStore {\n /**\n * Associates this instance with a Queue instance, so entries added can be\n * identified by their queue name.\n *\n * @param {string} queueName\n * @private\n */\n constructor(queueName) {\n this._queueName = queueName;\n this._db = new DBWrapper(DB_NAME, DB_VERSION, {\n onupgradeneeded: this._upgradeDb,\n });\n }\n\n /**\n * Append an entry last in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async pushEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'pushEntry',\n paramName: 'entry.requestData',\n });\n }\n\n // Don't specify an ID since one is automatically generated.\n delete entry.id;\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Preppend an entry first in the queue.\n *\n * @param {Object} entry\n * @param {Object} entry.requestData\n * @param {number} [entry.timestamp]\n * @param {Object} [entry.metadata]\n * @private\n */\n async unshiftEntry(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry',\n });\n assert.isType(entry.requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'QueueStore',\n funcName: 'unshiftEntry',\n paramName: 'entry.requestData',\n });\n }\n\n const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n count: 1,\n });\n\n if (firstEntry) {\n // Pick an ID one less than the lowest ID in the object store.\n entry.id = firstEntry.id - 1;\n } else {\n // Otherwise let the auto-incrementor assign the ID.\n delete entry.id;\n }\n entry.queueName = this._queueName;\n\n await this._db.add(OBJECT_STORE_NAME, entry);\n }\n\n /**\n * Removes and returns the last entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async popEntry() {\n return this._removeEntry({direction: 'prev'});\n }\n\n /**\n * Removes and returns the first entry in the queue matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async shiftEntry() {\n return this._removeEntry({direction: 'next'});\n }\n\n /**\n * Returns all entries in the store matching the `queueName`.\n *\n * @param {Object} options See workbox.backgroundSync.Queue~getAll}\n * @return {Promise<Array<Object>>}\n * @private\n */\n async getAll() {\n return await this._db.getAllMatching(OBJECT_STORE_NAME, {\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n });\n }\n\n /**\n * Deletes the entry for the given ID.\n *\n * WARNING: this method does not ensure the deleted enry belongs to this\n * queue (i.e. matches the `queueName`). But this limitation is acceptable\n * as this class is not publicly exposed. An additional check would make\n * this method slower than it needs to be.\n *\n * @private\n * @param {number} id\n */\n async deleteEntry(id) {\n await this._db.delete(OBJECT_STORE_NAME, id);\n }\n\n /**\n * Removes and returns the first or last entry in the queue (based on the\n * `direction` argument) matching the `queueName`.\n *\n * @return {Promise<Object>}\n * @private\n */\n async _removeEntry({direction}) {\n const [entry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {\n direction,\n index: INDEXED_PROP,\n query: IDBKeyRange.only(this._queueName),\n count: 1,\n });\n\n if (entry) {\n await this.deleteEntry(entry.id);\n return entry;\n }\n }\n\n /**\n * Upgrades the database given an `upgradeneeded` event.\n *\n * @param {Event} event\n * @private\n */\n _upgradeDb(event) {\n const db = event.target.result;\n\n if (event.oldVersion > 0 && event.oldVersion < DB_VERSION) {\n if (db.objectStoreNames.contains(OBJECT_STORE_NAME)) {\n db.deleteObjectStore(OBJECT_STORE_NAME);\n }\n }\n\n const objStore = db.createObjectStore(OBJECT_STORE_NAME, {\n autoIncrement: true,\n keyPath: 'id',\n });\n objStore.createIndex(INDEXED_PROP, INDEXED_PROP, {unique: false});\n }\n}\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport '../_version.mjs';\n\n\nconst serializableProperties = [\n 'method',\n 'referrer',\n 'referrerPolicy',\n 'mode',\n 'credentials',\n 'cache',\n 'redirect',\n 'integrity',\n 'keepalive',\n];\n\n\n/**\n * A class to make it easier to serialize and de-serialize requests so they\n * can be stored in IndexedDB.\n *\n * @private\n */\nclass StorableRequest {\n /**\n * Converts a Request object to a plain object that can be structured\n * cloned or JSON-stringified.\n *\n * @param {Request} request\n * @return {Promise<StorableRequest>}\n *\n * @private\n */\n static async fromRequest(request) {\n const requestData = {\n url: request.url,\n headers: {},\n };\n\n // Set the body if present.\n if (request.method !== 'GET') {\n // Use ArrayBuffer to support non-text request bodies.\n // NOTE: we can't use Blobs becuse Safari doesn't support storing\n // Blobs in IndexedDB in some cases:\n // https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457\n requestData.body = await request.clone().arrayBuffer();\n }\n\n // Convert the headers from an iterable to an object.\n for (const [key, value] of request.headers.entries()) {\n requestData.headers[key] = value;\n }\n\n // Add all other serializable request properties\n for (const prop of serializableProperties) {\n if (request[prop] !== undefined) {\n requestData[prop] = request[prop];\n }\n }\n\n return new StorableRequest(requestData);\n }\n\n /**\n * Accepts an object of request data that can be used to construct a\n * `Request` but can also be stored in IndexedDB.\n *\n * @param {Object} requestData An object of request data that includes the\n * `url` plus any relevant properties of\n * [requestInit]{@link https://fetch.spec.whatwg.org/#requestinit}.\n * @private\n */\n constructor(requestData) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(requestData, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData',\n });\n assert.isType(requestData.url, 'string', {\n moduleName: 'workbox-background-sync',\n className: 'StorableRequest',\n funcName: 'constructor',\n paramName: 'requestData.url',\n });\n }\n\n // If the request's mode is `navigate`, convert it to `same-origin` since\n // navigation requests can't be constructed via script.\n if (requestData.mode === 'navigate') {\n requestData.mode = 'same-origin';\n }\n\n this._requestData = requestData;\n }\n\n /**\n * Returns a deep clone of the instances `_requestData` object.\n *\n * @return {Object}\n *\n * @private\n */\n toObject() {\n const requestData = Object.assign({}, this._requestData);\n requestData.headers = Object.assign({}, this._requestData.headers);\n if (requestData.body) {\n requestData.body = requestData.body.slice(0);\n }\n\n return requestData;\n }\n\n /**\n * Converts this instance to a Request.\n *\n * @return {Request}\n *\n * @private\n */\n toRequest() {\n return new Request(this._requestData.url, this._requestData);\n }\n\n /**\n * Creates and returns a deep clone of the instance.\n *\n * @return {StorableRequest}\n *\n * @private\n */\n clone() {\n return new StorableRequest(this.toObject());\n }\n}\n\nexport {StorableRequest};\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {QueueStore} from './lib/QueueStore.mjs';\nimport {StorableRequest} from './lib/StorableRequest.mjs';\nimport './_version.mjs';\n\n\nconst TAG_PREFIX = 'workbox-background-sync';\nconst MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes\n\nconst queueNames = new Set();\n\n/**\n * A class to manage storing failed requests in IndexedDB and retrying them\n * later. All parts of the storing and replaying process are observable via\n * callbacks.\n *\n * @memberof workbox.backgroundSync\n */\nclass Queue {\n /**\n * Creates an instance of Queue with the given options\n *\n * @param {string} name The unique name for this queue. This name must be\n * unique as it's used to register sync events and store requests\n * in IndexedDB specific to this instance. An error will be thrown if\n * a duplicate name is detected.\n * @param {Object} [options]\n * @param {Function} [options.onSync] A function that gets invoked whenever\n * the 'sync' event fires. The function is invoked with an object\n * containing the `queue` property (referencing this instance), and you\n * can use the callback to customize the replay behavior of the queue.\n * When not set the `replayRequests()` method is called.\n * Note: if the replay fails after a sync event, make sure you throw an\n * error, so the browser knows to retry the sync event later.\n * @param {number} [options.maxRetentionTime=7 days] The amount of time (in\n * minutes) a request may be retried. After this amount of time has\n * passed, the request will be deleted from the queue.\n */\n constructor(name, {onSync, maxRetentionTime} = {}) {\n // Ensure the store name is not already being used\n if (queueNames.has(name)) {\n throw new WorkboxError('duplicate-queue-name', {name});\n } else {\n queueNames.add(name);\n }\n\n this._name = name;\n this._onSync = onSync || this.replayRequests;\n this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;\n this._queueStore = new QueueStore(this._name);\n\n this._addSyncListener();\n }\n\n /**\n * @return {string}\n */\n get name() {\n return this._name;\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the end of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async pushRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'pushRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'push');\n }\n\n /**\n * Stores the passed request in IndexedDB (with its timestamp and any\n * metadata) at the beginning of the queue.\n *\n * @param {Object} entry\n * @param {Request} entry.request The request to store in the queue.\n * @param {Object} [entry.metadata] Any metadata you want associated with the\n * stored request. When requests are replayed you'll have access to this\n * metadata object in case you need to modify the request beforehand.\n * @param {number} [entry.timestamp] The timestamp (Epoch time in\n * milliseconds) when the request was first added to the queue. This is\n * used along with `maxRetentionTime` to remove outdated requests. In\n * general you don't need to set this value, as it's automatically set\n * for you (defaulting to `Date.now()`), but you can update it if you\n * don't want particular requests to expire.\n */\n async unshiftRequest(entry) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(entry, 'object', {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry',\n });\n assert.isInstance(entry.request, Request, {\n moduleName: 'workbox-background-sync',\n className: 'Queue',\n funcName: 'unshiftRequest',\n paramName: 'entry.request',\n });\n }\n\n await this._addRequest(entry, 'unshift');\n }\n\n /**\n * Removes and returns the last request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async popRequest() {\n return this._removeRequest('pop');\n }\n\n /**\n * Removes and returns the first request in the queue (along with its\n * timestamp and any metadata). The returned object takes the form:\n * `{request, timestamp, metadata}`.\n *\n * @return {Promise<Object>}\n */\n async shiftRequest() {\n return this._removeRequest('shift');\n }\n\n /**\n * Returns all the entries that have not expired (per `maxRetentionTime`).\n * Any expired entries are removed from the queue.\n *\n * @return {Promise<Array<Object>>}\n */\n async getAll() {\n const allEntries = await this._queueStore.getAll();\n const now = Date.now();\n\n const unexpiredEntries = [];\n for (const entry of allEntries) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n await this._queueStore.deleteEntry(entry.id);\n } else {\n unexpiredEntries.push(convertEntry(entry));\n }\n }\n\n return unexpiredEntries;\n }\n\n\n /**\n * Adds the entry to the QueueStore and registers for a sync event.\n *\n * @param {Object} entry\n * @param {Request} entry.request\n * @param {Object} [entry.metadata]\n * @param {number} [entry.timestamp=Date.now()]\n * @param {string} operation ('push' or 'unshift')\n * @private\n */\n async _addRequest(\n {request, metadata, timestamp = Date.now()}, operation) {\n const storableRequest = await StorableRequest.fromRequest(request.clone());\n const entry = {\n requestData: storableRequest.toObject(),\n timestamp,\n };\n\n // Only include metadata if it's present.\n if (metadata) {\n entry.metadata = metadata;\n }\n\n await this._queueStore[`${operation}Entry`](entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(request.url)}' has ` +\n `been added to background sync queue '${this._name}'.`);\n }\n\n // Don't register for a sync if we're in the middle of a sync. Instead,\n // we wait until the sync is complete and call register if\n // `this._requestsAddedDuringSync` is true.\n if (this._syncInProgress) {\n this._requestsAddedDuringSync = true;\n } else {\n await this.registerSync();\n }\n }\n\n /**\n * Removes and returns the first or last (depending on `operation`) entry\n * from the QueueStore that's not older than the `maxRetentionTime`.\n *\n * @param {string} operation ('pop' or 'shift')\n * @return {Object|undefined}\n * @private\n */\n async _removeRequest(operation) {\n const now = Date.now();\n const entry = await this._queueStore[`${operation}Entry`]();\n\n if (entry) {\n // Ignore requests older than maxRetentionTime. Call this function\n // recursively until an unexpired request is found.\n const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;\n if (now - entry.timestamp > maxRetentionTimeInMs) {\n return this._removeRequest(operation);\n }\n\n return convertEntry(entry);\n }\n }\n\n /**\n * Loops through each request in the queue and attempts to re-fetch it.\n * If any request fails to re-fetch, it's put back in the same position in\n * the queue (which registers a retry for the next sync event).\n */\n async replayRequests() {\n let entry;\n while (entry = await this.shiftRequest()) {\n try {\n await fetch(entry.request.clone());\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `has been replayed in queue '${this._name}'`);\n }\n } catch (error) {\n await this.unshiftRequest(entry);\n\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Request for '${getFriendlyURL(entry.request.url)}'` +\n `failed to replay, putting it back in queue '${this._name}'`);\n }\n throw new WorkboxError('queue-replay-failed', {name: this._name});\n }\n }\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`All requests in queue '${this.name}' have successfully ` +\n `replayed; the queue is now empty!`);\n }\n }\n\n /**\n * Registers a sync event with a tag unique to this instance.\n */\n async registerSync() {\n if ('sync' in registration) {\n try {\n await registration.sync.register(`${TAG_PREFIX}:${this._name}`);\n } catch (err) {\n // This means the registration failed for some reason, possibly due to\n // the user disabling it.\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(\n `Unable to register sync event for '${this._name}'.`, err);\n }\n }\n }\n }\n\n /**\n * In sync-supporting browsers, this adds a listener for the sync event.\n * In non-sync-supporting browsers, this will retry the queue on service\n * worker startup.\n *\n * @private\n */\n _addSyncListener() {\n if ('sync' in registration) {\n self.addEventListener('sync', (event) => {\n if (event.tag === `${TAG_PREFIX}:${this._name}`) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync for tag '${event.tag}'` +\n `has been received`);\n }\n\n const syncComplete = async () => {\n this._syncInProgress = true;\n\n let syncError;\n try {\n await this._onSync({queue: this});\n } catch (error) {\n syncError = error;\n\n // Rethrow the error. Note: the logic in the finally clause\n // will run before this gets rethrown.\n throw syncError;\n } finally {\n // New items may have been added to the queue during the sync,\n // so we need to register for a new sync if that's happened...\n // Unless there was an error during the sync, in which\n // case the browser will automatically retry later, as long\n // as `event.lastChance` is not true.\n if (this._requestsAddedDuringSync &&\n !(syncError && !event.lastChance)) {\n await this.registerSync();\n }\n\n this._syncInProgress = false;\n this._requestsAddedDuringSync = false;\n }\n };\n event.waitUntil(syncComplete());\n }\n });\n } else {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Background sync replaying without background sync event`);\n }\n // If the browser doesn't support background sync, retry\n // every time the service worker starts up as a fallback.\n this._onSync({queue: this});\n }\n }\n\n /**\n * Returns the set of queue names. This is primarily used to reset the list\n * of queue names in tests.\n *\n * @return {Set}\n *\n * @private\n */\n static get _queueNames() {\n return queueNames;\n }\n}\n\n\n/**\n * Converts a QueueStore entry into the format exposed by Queue. This entails\n * converting the request data into a real request and omitting the `id` and\n * `queueName` properties.\n *\n * @param {Object} queueStoreEntry\n * @return {Object}\n * @private\n */\nconst convertEntry = (queueStoreEntry) => {\n const queueEntry = {\n request: new StorableRequest(queueStoreEntry.requestData).toRequest(),\n timestamp: queueStoreEntry.timestamp,\n };\n if (queueStoreEntry.metadata) {\n queueEntry.metadata = queueStoreEntry.metadata;\n }\n return queueEntry;\n};\n\nexport {Queue};\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*/\n\nimport {Queue} from './Queue.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `fetchDidFail` lifecycle callback. This makes it\n * easier to add failed requests to a background sync Queue.\n *\n * @memberof workbox.backgroundSync\n */\nclass Plugin {\n /**\n * @param {...*} queueArgs Args to forward to the composed Queue instance.\n * See the [Queue]{@link workbox.backgroundSync.Queue} documentation for\n * parameter details.\n */\n constructor(...queueArgs) {\n this._queue = new Queue(...queueArgs);\n this.fetchDidFail = this.fetchDidFail.bind(this);\n }\n\n /**\n * @param {Object} options\n * @param {Request} options.request\n * @private\n */\n async fetchDidFail({request}) {\n await this._queue.pushRequest({request});\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","DB_VERSION","DB_NAME","OBJECT_STORE_NAME","INDEXED_PROP","QueueStore","constructor","queueName","_queueName","_db","DBWrapper","onupgradeneeded","this","_upgradeDb","entry","id","add","firstEntry","getAllMatching","count","_removeEntry","direction","index","query","IDBKeyRange","only","delete","deleteEntry","event","db","target","result","oldVersion","objectStoreNames","contains","deleteObjectStore","createObjectStore","autoIncrement","keyPath","createIndex","unique","serializableProperties","StorableRequest","request","requestData","url","headers","method","body","clone","arrayBuffer","key","value","entries","prop","undefined","mode","_requestData","toObject","Object","assign","slice","toRequest","Request","TAG_PREFIX","MAX_RETENTION_TIME","queueNames","Set","Queue","name","onSync","maxRetentionTime","has","WorkboxError","_name","_onSync","replayRequests","_maxRetentionTime","_queueStore","_addSyncListener","_addRequest","_removeRequest","allEntries","getAll","now","Date","unexpiredEntries","maxRetentionTimeInMs","timestamp","push","convertEntry","metadata","operation","fromRequest","_syncInProgress","_requestsAddedDuringSync","registerSync","shiftRequest","fetch","error","unshiftRequest","registration","sync","register","err","addEventListener","tag","syncComplete","async","syncError","queue","lastChance","waitUntil","queueStoreEntry","queueEntry","queueArgs","_queue","fetchDidFail","bind","pushRequest"],"mappings":"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"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-broadcast-update.dev.js","sources":["../_version.mjs","../responsesAreSame.mjs","../utils/constants.mjs","../broadcastUpdate.mjs","../BroadcastCacheUpdate.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:broadcast-update:4.3.0']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @param {Response} firstResponse\n * @param {Response} secondResponse\n * @param {Array<string>} headersToCheck\n * @return {boolean}\n *\n * @memberof workbox.broadcastUpdate\n * @private\n */\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {\n if (process.env.NODE_ENV !== 'production') {\n if (!(firstResponse instanceof Response &&\n secondResponse instanceof Response)) {\n throw new WorkboxError('invalid-responses-are-same-args');\n }\n }\n\n const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n return firstResponse.headers.has(header) &&\n secondResponse.headers.has(header);\n });\n\n if (!atLeastOneHeaderAvailable) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to determine where the response has been updated ` +\n `because none of the headers that would be checked are present.`);\n logger.debug(`Attempting to compare the following: `,\n firstResponse, secondResponse, headersToCheck);\n }\n\n // Just return true, indicating the that responses are the same, since we\n // can't determine otherwise.\n return true;\n }\n\n return headersToCheck.every((header) => {\n const headerStateComparison = firstResponse.headers.has(header) ===\n secondResponse.headers.has(header);\n const headerValueComparison = firstResponse.headers.get(header) ===\n secondResponse.headers.get(header);\n\n return headerStateComparison && headerValueComparison;\n });\n};\n\nexport {responsesAreSame};\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*/\n\nimport '../_version.mjs';\n\nexport const CACHE_UPDATED_MESSAGE_TYPE = 'CACHE_UPDATED';\nexport const CACHE_UPDATED_MESSAGE_META = 'workbox-broadcast-update';\nexport const DEFAULT_BROADCAST_CHANNEL_NAME = 'workbox';\nexport const DEFAULT_DEFER_NOTIFICATION_TIMEOUT = 10000;\nexport const DEFAULT_HEADERS_TO_CHECK = [\n 'content-length',\n 'etag',\n 'last-modified',\n];\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {CACHE_UPDATED_MESSAGE_TYPE, CACHE_UPDATED_MESSAGE_META}\n from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n * type: 'CACHE_UPDATED',\n * meta: 'workbox-broadcast-update',\n * payload: {\n * cacheName: 'the-cache-name',\n * updatedURL: 'https://example.com/'\n * }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @param {Object} options\n * @param {string} options.cacheName The name of the cache in which the updated\n * `Response` was stored.\n * @param {string} options.url The URL associated with the updated `Response`.\n * @param {BroadcastChannel} [options.channel] The `BroadcastChannel` to use.\n * If no channel is set or the browser doesn't support the BroadcastChannel\n * api, then an attempt will be made to `postMessage` each window client.\n *\n * @memberof workbox.broadcastUpdate\n */\nconst broadcastUpdate = async ({channel, cacheName, url}) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'cacheName',\n });\n assert.isType(url, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'url',\n });\n }\n\n const data = {\n type: CACHE_UPDATED_MESSAGE_TYPE,\n meta: CACHE_UPDATED_MESSAGE_META,\n payload: {\n cacheName: cacheName,\n updatedURL: url,\n },\n };\n\n if (channel) {\n channel.postMessage(data);\n } else {\n const windows = await clients.matchAll({type: 'window'});\n for (const win of windows) {\n win.postMessage(data);\n }\n }\n};\n\nexport {broadcastUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {Deferred} from 'workbox-core/_private/Deferred.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\n\nimport {DEFAULT_HEADERS_TO_CHECK, DEFAULT_BROADCAST_CHANNEL_NAME,\n DEFAULT_DEFER_NOTIFICATION_TIMEOUT} from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}\n * to notify interested parties when a cached response has been updated.\n * In browsers that do not support the Broadcast Channel API, the instance\n * falls back to sending the update via `postMessage()` to all window clients.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass BroadcastCacheUpdate {\n /**\n * Construct a BroadcastCacheUpdate instance with a specific `channelName` to\n * broadcast messages on\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor({headersToCheck, channelName, deferNoticationTimeout} = {}) {\n this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK;\n this._channelName = channelName || DEFAULT_BROADCAST_CHANNEL_NAME;\n this._deferNoticationTimeout =\n deferNoticationTimeout || DEFAULT_DEFER_NOTIFICATION_TIMEOUT;\n\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(this._channelName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'channelName',\n });\n assert.isArray(this._headersToCheck, {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'headersToCheck',\n });\n }\n\n this._initWindowReadyDeferreds();\n }\n\n /**\n * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and send a message via the\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * if they differ.\n *\n * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.\n *\n * @param {Object} options\n * @param {Response} options.oldResponse Cached response to compare.\n * @param {Response} options.newResponse Possibly updated response to compare.\n * @param {string} options.url The URL of the request.\n * @param {string} options.cacheName Name of the cache the responses belong\n * to. This is included in the broadcast message.\n * @param {Event} [options.event] event An optional event that triggered\n * this possible cache update.\n * @return {Promise} Resolves once the update is sent.\n */\n notifyIfUpdated({oldResponse, newResponse, url, cacheName, event}) {\n if (!responsesAreSame(oldResponse, newResponse, this._headersToCheck)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Newer response found (and cached) for:`, url);\n }\n\n const sendUpdate = async () => {\n // In the case of a navigation request, the requesting page will likely\n // not have loaded its JavaScript in time to recevied the update\n // notification, so we defer it until ready (or we timeout waiting).\n if (event && event.request && event.request.mode === 'navigate') {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Original request was a navigation request, ` +\n `waiting for a ready message from the window`, event.request);\n }\n await this._windowReadyOrTimeout(event);\n }\n await this._broadcastUpdate({\n channel: this._getChannel(),\n cacheName,\n url,\n });\n };\n\n // Send the update and ensure the SW stays alive until it's sent.\n const done = sendUpdate();\n\n if (event) {\n try {\n event.waitUntil(done);\n } catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to ensure service worker stays alive ` +\n `when broadcasting cache update for ` +\n `${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n return done;\n }\n }\n\n /**\n * NOTE: this is exposed on the instance primarily so it can be spied on\n * in tests.\n *\n * @param {Object} opts\n * @private\n */\n async _broadcastUpdate(opts) {\n await broadcastUpdate(opts);\n }\n\n /**\n * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for\n * broadcasting updates, or undefined if the browser doesn't support the\n * Broadcast Channel API.\n *\n * @private\n */\n _getChannel() {\n if (('BroadcastChannel' in self) && !this._channel) {\n this._channel = new BroadcastChannel(this._channelName);\n }\n return this._channel;\n }\n\n /**\n * Waits for a message from the window indicating that it's capable of\n * receiving broadcasts. By default, this will only wait for the amount of\n * time specified via the `deferNoticationTimeout` option.\n *\n * @param {Event} event The navigation fetch event.\n * @return {Promise}\n * @private\n */\n _windowReadyOrTimeout(event) {\n if (!this._navigationEventsDeferreds.has(event)) {\n const deferred = new Deferred();\n\n // Set the deferred on the `_navigationEventsDeferreds` map so it will\n // be resolved when the next ready message event comes.\n this._navigationEventsDeferreds.set(event, deferred);\n\n // But don't wait too long for the message since it may never come.\n const timeout = setTimeout(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Timed out after ${this._deferNoticationTimeout}` +\n `ms waiting for message from window`);\n }\n deferred.resolve();\n }, this._deferNoticationTimeout);\n\n // Ensure the timeout is cleared if the deferred promise is resolved.\n deferred.promise.then(() => clearTimeout(timeout));\n }\n return this._navigationEventsDeferreds.get(event).promise;\n }\n\n /**\n * Creates a mapping between navigation fetch events and deferreds, and adds\n * a listener for message events from the window. When message events arrive,\n * all deferreds in the mapping are resolved.\n *\n * Note: it would be easier if we could only resolve the deferred of\n * navigation fetch event whose client ID matched the source ID of the\n * message event, but currently client IDs are not exposed on navigation\n * fetch events: https://www.chromestatus.com/feature/4846038800138240\n *\n * @private\n */\n _initWindowReadyDeferreds() {\n // A mapping between navigation events and their deferreds.\n this._navigationEventsDeferreds = new Map();\n\n // The message listener needs to be added in the initial run of the\n // service worker, but since we don't actually need to be listening for\n // messages until the cache updates, we only invoke the callback if set.\n self.addEventListener('message', (event) => {\n if (event.data.type === 'WINDOW_READY' &&\n event.data.meta === 'workbox-window' &&\n this._navigationEventsDeferreds.size > 0) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Received WINDOW_READY event: `, event);\n }\n // Resolve any pending deferreds.\n for (const deferred of this._navigationEventsDeferreds.values()) {\n deferred.resolve();\n }\n this._navigationEventsDeferreds.clear();\n }\n });\n }\n}\n\nexport {BroadcastCacheUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport './_version.mjs';\n\n/**\n * This plugin will automatically broadcast a message whenever a cached response\n * is updated.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass Plugin {\n /**\n * Construct a BroadcastCacheUpdate instance with the passed options and\n * calls its `notifyIfUpdated()` method whenever the plugin's\n * `cacheDidUpdate` callback is invoked.\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor(options) {\n this._broadcastUpdate = new BroadcastCacheUpdate(options);\n }\n\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n * added to a cache.\n *\n * @private\n * @param {Object} options The input object to this function.\n * @param {string} options.cacheName Name of the cache being updated.\n * @param {Response} [options.oldResponse] The previous cached value, if any.\n * @param {Response} options.newResponse The new value in the cache.\n * @param {Request} options.request The request that triggered the udpate.\n * @param {Request} [options.event] The event that triggered the update.\n */\n cacheDidUpdate({cacheName, oldResponse, newResponse, request, event}) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(newResponse, Response, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'newResponse',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n\n if (!oldResponse) {\n // Without a two responses there is nothing to compare.\n return;\n }\n this._broadcastUpdate.notifyIfUpdated({\n cacheName,\n oldResponse,\n newResponse,\n event,\n url: request.url,\n });\n }\n}\n\nexport {Plugin};\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*/\n\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.broadcastUpdate\n */\n\nexport {\n BroadcastCacheUpdate,\n Plugin,\n broadcastUpdate,\n responsesAreSame,\n};\n"],"names":["self","_","e","responsesAreSame","firstResponse","secondResponse","headersToCheck","Response","WorkboxError","atLeastOneHeaderAvailable","some","header","headers","has","logger","warn","debug","every","headerStateComparison","headerValueComparison","get","CACHE_UPDATED_MESSAGE_TYPE","CACHE_UPDATED_MESSAGE_META","DEFAULT_BROADCAST_CHANNEL_NAME","DEFAULT_DEFER_NOTIFICATION_TIMEOUT","DEFAULT_HEADERS_TO_CHECK","broadcastUpdate","channel","cacheName","url","assert","isType","moduleName","className","funcName","paramName","data","type","meta","payload","updatedURL","postMessage","windows","clients","matchAll","win","BroadcastCacheUpdate","constructor","channelName","deferNoticationTimeout","_headersToCheck","_channelName","_deferNoticationTimeout","isArray","_initWindowReadyDeferreds","notifyIfUpdated","oldResponse","newResponse","event","log","sendUpdate","request","mode","_windowReadyOrTimeout","_broadcastUpdate","_getChannel","done","waitUntil","error","getFriendlyURL","opts","_channel","BroadcastChannel","_navigationEventsDeferreds","deferred","Deferred","set","timeout","setTimeout","resolve","promise","then","clearTimeout","Map","addEventListener","size","values","clear","Plugin","options","cacheDidUpdate","isInstance","Request"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"workbox-broadcast-update.dev.js","sources":["../_version.mjs","../responsesAreSame.mjs","../utils/constants.mjs","../broadcastUpdate.mjs","../BroadcastCacheUpdate.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:broadcast-update:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @param {Response} firstResponse\n * @param {Response} secondResponse\n * @param {Array<string>} headersToCheck\n * @return {boolean}\n *\n * @memberof workbox.broadcastUpdate\n * @private\n */\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {\n if (process.env.NODE_ENV !== 'production') {\n if (!(firstResponse instanceof Response &&\n secondResponse instanceof Response)) {\n throw new WorkboxError('invalid-responses-are-same-args');\n }\n }\n\n const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n return firstResponse.headers.has(header) &&\n secondResponse.headers.has(header);\n });\n\n if (!atLeastOneHeaderAvailable) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to determine where the response has been updated ` +\n `because none of the headers that would be checked are present.`);\n logger.debug(`Attempting to compare the following: `,\n firstResponse, secondResponse, headersToCheck);\n }\n\n // Just return true, indicating the that responses are the same, since we\n // can't determine otherwise.\n return true;\n }\n\n return headersToCheck.every((header) => {\n const headerStateComparison = firstResponse.headers.has(header) ===\n secondResponse.headers.has(header);\n const headerValueComparison = firstResponse.headers.get(header) ===\n secondResponse.headers.get(header);\n\n return headerStateComparison && headerValueComparison;\n });\n};\n\nexport {responsesAreSame};\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*/\n\nimport '../_version.mjs';\n\nexport const CACHE_UPDATED_MESSAGE_TYPE = 'CACHE_UPDATED';\nexport const CACHE_UPDATED_MESSAGE_META = 'workbox-broadcast-update';\nexport const DEFAULT_BROADCAST_CHANNEL_NAME = 'workbox';\nexport const DEFAULT_DEFER_NOTIFICATION_TIMEOUT = 10000;\nexport const DEFAULT_HEADERS_TO_CHECK = [\n 'content-length',\n 'etag',\n 'last-modified',\n];\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {CACHE_UPDATED_MESSAGE_TYPE, CACHE_UPDATED_MESSAGE_META}\n from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n * type: 'CACHE_UPDATED',\n * meta: 'workbox-broadcast-update',\n * payload: {\n * cacheName: 'the-cache-name',\n * updatedURL: 'https://example.com/'\n * }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @param {Object} options\n * @param {string} options.cacheName The name of the cache in which the updated\n * `Response` was stored.\n * @param {string} options.url The URL associated with the updated `Response`.\n * @param {BroadcastChannel} [options.channel] The `BroadcastChannel` to use.\n * If no channel is set or the browser doesn't support the BroadcastChannel\n * api, then an attempt will be made to `postMessage` each window client.\n *\n * @memberof workbox.broadcastUpdate\n */\nconst broadcastUpdate = async ({channel, cacheName, url}) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'cacheName',\n });\n assert.isType(url, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'url',\n });\n }\n\n const data = {\n type: CACHE_UPDATED_MESSAGE_TYPE,\n meta: CACHE_UPDATED_MESSAGE_META,\n payload: {\n cacheName: cacheName,\n updatedURL: url,\n },\n };\n\n if (channel) {\n channel.postMessage(data);\n } else {\n const windows = await clients.matchAll({type: 'window'});\n for (const win of windows) {\n win.postMessage(data);\n }\n }\n};\n\nexport {broadcastUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {Deferred} from 'workbox-core/_private/Deferred.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\n\nimport {DEFAULT_HEADERS_TO_CHECK, DEFAULT_BROADCAST_CHANNEL_NAME,\n DEFAULT_DEFER_NOTIFICATION_TIMEOUT} from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}\n * to notify interested parties when a cached response has been updated.\n * In browsers that do not support the Broadcast Channel API, the instance\n * falls back to sending the update via `postMessage()` to all window clients.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass BroadcastCacheUpdate {\n /**\n * Construct a BroadcastCacheUpdate instance with a specific `channelName` to\n * broadcast messages on\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor({headersToCheck, channelName, deferNoticationTimeout} = {}) {\n this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK;\n this._channelName = channelName || DEFAULT_BROADCAST_CHANNEL_NAME;\n this._deferNoticationTimeout =\n deferNoticationTimeout || DEFAULT_DEFER_NOTIFICATION_TIMEOUT;\n\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(this._channelName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'channelName',\n });\n assert.isArray(this._headersToCheck, {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'headersToCheck',\n });\n }\n\n this._initWindowReadyDeferreds();\n }\n\n /**\n * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and send a message via the\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * if they differ.\n *\n * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.\n *\n * @param {Object} options\n * @param {Response} options.oldResponse Cached response to compare.\n * @param {Response} options.newResponse Possibly updated response to compare.\n * @param {string} options.url The URL of the request.\n * @param {string} options.cacheName Name of the cache the responses belong\n * to. This is included in the broadcast message.\n * @param {Event} [options.event] event An optional event that triggered\n * this possible cache update.\n * @return {Promise} Resolves once the update is sent.\n */\n notifyIfUpdated({oldResponse, newResponse, url, cacheName, event}) {\n if (!responsesAreSame(oldResponse, newResponse, this._headersToCheck)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Newer response found (and cached) for:`, url);\n }\n\n const sendUpdate = async () => {\n // In the case of a navigation request, the requesting page will likely\n // not have loaded its JavaScript in time to recevied the update\n // notification, so we defer it until ready (or we timeout waiting).\n if (event && event.request && event.request.mode === 'navigate') {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Original request was a navigation request, ` +\n `waiting for a ready message from the window`, event.request);\n }\n await this._windowReadyOrTimeout(event);\n }\n await this._broadcastUpdate({\n channel: this._getChannel(),\n cacheName,\n url,\n });\n };\n\n // Send the update and ensure the SW stays alive until it's sent.\n const done = sendUpdate();\n\n if (event) {\n try {\n event.waitUntil(done);\n } catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to ensure service worker stays alive ` +\n `when broadcasting cache update for ` +\n `${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n return done;\n }\n }\n\n /**\n * NOTE: this is exposed on the instance primarily so it can be spied on\n * in tests.\n *\n * @param {Object} opts\n * @private\n */\n async _broadcastUpdate(opts) {\n await broadcastUpdate(opts);\n }\n\n /**\n * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for\n * broadcasting updates, or undefined if the browser doesn't support the\n * Broadcast Channel API.\n *\n * @private\n */\n _getChannel() {\n if (('BroadcastChannel' in self) && !this._channel) {\n this._channel = new BroadcastChannel(this._channelName);\n }\n return this._channel;\n }\n\n /**\n * Waits for a message from the window indicating that it's capable of\n * receiving broadcasts. By default, this will only wait for the amount of\n * time specified via the `deferNoticationTimeout` option.\n *\n * @param {Event} event The navigation fetch event.\n * @return {Promise}\n * @private\n */\n _windowReadyOrTimeout(event) {\n if (!this._navigationEventsDeferreds.has(event)) {\n const deferred = new Deferred();\n\n // Set the deferred on the `_navigationEventsDeferreds` map so it will\n // be resolved when the next ready message event comes.\n this._navigationEventsDeferreds.set(event, deferred);\n\n // But don't wait too long for the message since it may never come.\n const timeout = setTimeout(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Timed out after ${this._deferNoticationTimeout}` +\n `ms waiting for message from window`);\n }\n deferred.resolve();\n }, this._deferNoticationTimeout);\n\n // Ensure the timeout is cleared if the deferred promise is resolved.\n deferred.promise.then(() => clearTimeout(timeout));\n }\n return this._navigationEventsDeferreds.get(event).promise;\n }\n\n /**\n * Creates a mapping between navigation fetch events and deferreds, and adds\n * a listener for message events from the window. When message events arrive,\n * all deferreds in the mapping are resolved.\n *\n * Note: it would be easier if we could only resolve the deferred of\n * navigation fetch event whose client ID matched the source ID of the\n * message event, but currently client IDs are not exposed on navigation\n * fetch events: https://www.chromestatus.com/feature/4846038800138240\n *\n * @private\n */\n _initWindowReadyDeferreds() {\n // A mapping between navigation events and their deferreds.\n this._navigationEventsDeferreds = new Map();\n\n // The message listener needs to be added in the initial run of the\n // service worker, but since we don't actually need to be listening for\n // messages until the cache updates, we only invoke the callback if set.\n self.addEventListener('message', (event) => {\n if (event.data.type === 'WINDOW_READY' &&\n event.data.meta === 'workbox-window' &&\n this._navigationEventsDeferreds.size > 0) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Received WINDOW_READY event: `, event);\n }\n // Resolve any pending deferreds.\n for (const deferred of this._navigationEventsDeferreds.values()) {\n deferred.resolve();\n }\n this._navigationEventsDeferreds.clear();\n }\n });\n }\n}\n\nexport {BroadcastCacheUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport './_version.mjs';\n\n/**\n * This plugin will automatically broadcast a message whenever a cached response\n * is updated.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass Plugin {\n /**\n * Construct a BroadcastCacheUpdate instance with the passed options and\n * calls its `notifyIfUpdated()` method whenever the plugin's\n * `cacheDidUpdate` callback is invoked.\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor(options) {\n this._broadcastUpdate = new BroadcastCacheUpdate(options);\n }\n\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n * added to a cache.\n *\n * @private\n * @param {Object} options The input object to this function.\n * @param {string} options.cacheName Name of the cache being updated.\n * @param {Response} [options.oldResponse] The previous cached value, if any.\n * @param {Response} options.newResponse The new value in the cache.\n * @param {Request} options.request The request that triggered the udpate.\n * @param {Request} [options.event] The event that triggered the update.\n */\n cacheDidUpdate({cacheName, oldResponse, newResponse, request, event}) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(newResponse, Response, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'newResponse',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n\n if (!oldResponse) {\n // Without a two responses there is nothing to compare.\n return;\n }\n this._broadcastUpdate.notifyIfUpdated({\n cacheName,\n oldResponse,\n newResponse,\n event,\n url: request.url,\n });\n }\n}\n\nexport {Plugin};\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*/\n\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.broadcastUpdate\n */\n\nexport {\n BroadcastCacheUpdate,\n Plugin,\n broadcastUpdate,\n responsesAreSame,\n};\n"],"names":["self","_","e","responsesAreSame","firstResponse","secondResponse","headersToCheck","Response","WorkboxError","atLeastOneHeaderAvailable","some","header","headers","has","logger","warn","debug","every","headerStateComparison","headerValueComparison","get","CACHE_UPDATED_MESSAGE_TYPE","CACHE_UPDATED_MESSAGE_META","DEFAULT_BROADCAST_CHANNEL_NAME","DEFAULT_DEFER_NOTIFICATION_TIMEOUT","DEFAULT_HEADERS_TO_CHECK","broadcastUpdate","channel","cacheName","url","assert","isType","moduleName","className","funcName","paramName","data","type","meta","payload","updatedURL","postMessage","windows","clients","matchAll","win","BroadcastCacheUpdate","constructor","channelName","deferNoticationTimeout","_headersToCheck","_channelName","_deferNoticationTimeout","isArray","_initWindowReadyDeferreds","notifyIfUpdated","oldResponse","newResponse","event","log","sendUpdate","request","mode","_windowReadyOrTimeout","_broadcastUpdate","_getChannel","done","waitUntil","error","getFriendlyURL","opts","_channel","BroadcastChannel","_navigationEventsDeferreds","deferred","Deferred","set","timeout","setTimeout","resolve","promise","then","clearTimeout","Map","addEventListener","size","values","clear","Plugin","options","cacheDidUpdate","isInstance","Request"],"mappings":"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"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
this.workbox=this.workbox||{},this.workbox.broadcastUpdate=function(e,t){"use strict";try{self["workbox:broadcast-update:4.3.
|
1
|
+
this.workbox=this.workbox||{},this.workbox.broadcastUpdate=function(e,t){"use strict";try{self["workbox:broadcast-update:4.3.1"]&&_()}catch(e){}const s=(e,t,s)=>{return!s.some(s=>e.headers.has(s)&&t.headers.has(s))||s.every(s=>{const n=e.headers.has(s)===t.headers.has(s),a=e.headers.get(s)===t.headers.get(s);return n&&a})},n="workbox",a=1e4,i=["content-length","etag","last-modified"],o=async({channel:e,cacheName:t,url:s})=>{const n={type:"CACHE_UPDATED",meta:"workbox-broadcast-update",payload:{cacheName:t,updatedURL:s}};if(e)e.postMessage(n);else{const e=await clients.matchAll({type:"window"});for(const t of e)t.postMessage(n)}};class c{constructor({headersToCheck:e,channelName:t,deferNoticationTimeout:s}={}){this.t=e||i,this.s=t||n,this.i=s||a,this.o()}notifyIfUpdated({oldResponse:e,newResponse:t,url:n,cacheName:a,event:i}){if(!s(e,t,this.t)){const e=(async()=>{i&&i.request&&"navigate"===i.request.mode&&await this.h(i),await this.l({channel:this.u(),cacheName:a,url:n})})();if(i)try{i.waitUntil(e)}catch(e){}return e}}async l(e){await o(e)}u(){return"BroadcastChannel"in self&&!this.p&&(this.p=new BroadcastChannel(this.s)),this.p}h(e){if(!this.m.has(e)){const s=new t.Deferred;this.m.set(e,s);const n=setTimeout(()=>{s.resolve()},this.i);s.promise.then(()=>clearTimeout(n))}return this.m.get(e).promise}o(){this.m=new Map,self.addEventListener("message",e=>{if("WINDOW_READY"===e.data.type&&"workbox-window"===e.data.meta&&this.m.size>0){for(const e of this.m.values())e.resolve();this.m.clear()}})}}return e.BroadcastCacheUpdate=c,e.Plugin=class{constructor(e){this.l=new c(e)}cacheDidUpdate({cacheName:e,oldResponse:t,newResponse:s,request:n,event:a}){t&&this.l.notifyIfUpdated({cacheName:e,oldResponse:t,newResponse:s,event:a,url:n.url})}},e.broadcastUpdate=o,e.responsesAreSame=s,e}({},workbox.core._private);
|
2
2
|
//# sourceMappingURL=workbox-broadcast-update.prod.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-broadcast-update.prod.js","sources":["../_version.mjs","../responsesAreSame.mjs","../utils/constants.mjs","../broadcastUpdate.mjs","../BroadcastCacheUpdate.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:broadcast-update:4.3.0']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @param {Response} firstResponse\n * @param {Response} secondResponse\n * @param {Array<string>} headersToCheck\n * @return {boolean}\n *\n * @memberof workbox.broadcastUpdate\n * @private\n */\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {\n if (process.env.NODE_ENV !== 'production') {\n if (!(firstResponse instanceof Response &&\n secondResponse instanceof Response)) {\n throw new WorkboxError('invalid-responses-are-same-args');\n }\n }\n\n const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n return firstResponse.headers.has(header) &&\n secondResponse.headers.has(header);\n });\n\n if (!atLeastOneHeaderAvailable) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to determine where the response has been updated ` +\n `because none of the headers that would be checked are present.`);\n logger.debug(`Attempting to compare the following: `,\n firstResponse, secondResponse, headersToCheck);\n }\n\n // Just return true, indicating the that responses are the same, since we\n // can't determine otherwise.\n return true;\n }\n\n return headersToCheck.every((header) => {\n const headerStateComparison = firstResponse.headers.has(header) ===\n secondResponse.headers.has(header);\n const headerValueComparison = firstResponse.headers.get(header) ===\n secondResponse.headers.get(header);\n\n return headerStateComparison && headerValueComparison;\n });\n};\n\nexport {responsesAreSame};\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*/\n\nimport '../_version.mjs';\n\nexport const CACHE_UPDATED_MESSAGE_TYPE = 'CACHE_UPDATED';\nexport const CACHE_UPDATED_MESSAGE_META = 'workbox-broadcast-update';\nexport const DEFAULT_BROADCAST_CHANNEL_NAME = 'workbox';\nexport const DEFAULT_DEFER_NOTIFICATION_TIMEOUT = 10000;\nexport const DEFAULT_HEADERS_TO_CHECK = [\n 'content-length',\n 'etag',\n 'last-modified',\n];\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {CACHE_UPDATED_MESSAGE_TYPE, CACHE_UPDATED_MESSAGE_META}\n from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n * type: 'CACHE_UPDATED',\n * meta: 'workbox-broadcast-update',\n * payload: {\n * cacheName: 'the-cache-name',\n * updatedURL: 'https://example.com/'\n * }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @param {Object} options\n * @param {string} options.cacheName The name of the cache in which the updated\n * `Response` was stored.\n * @param {string} options.url The URL associated with the updated `Response`.\n * @param {BroadcastChannel} [options.channel] The `BroadcastChannel` to use.\n * If no channel is set or the browser doesn't support the BroadcastChannel\n * api, then an attempt will be made to `postMessage` each window client.\n *\n * @memberof workbox.broadcastUpdate\n */\nconst broadcastUpdate = async ({channel, cacheName, url}) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'cacheName',\n });\n assert.isType(url, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'url',\n });\n }\n\n const data = {\n type: CACHE_UPDATED_MESSAGE_TYPE,\n meta: CACHE_UPDATED_MESSAGE_META,\n payload: {\n cacheName: cacheName,\n updatedURL: url,\n },\n };\n\n if (channel) {\n channel.postMessage(data);\n } else {\n const windows = await clients.matchAll({type: 'window'});\n for (const win of windows) {\n win.postMessage(data);\n }\n }\n};\n\nexport {broadcastUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {Deferred} from 'workbox-core/_private/Deferred.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\n\nimport {DEFAULT_HEADERS_TO_CHECK, DEFAULT_BROADCAST_CHANNEL_NAME,\n DEFAULT_DEFER_NOTIFICATION_TIMEOUT} from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}\n * to notify interested parties when a cached response has been updated.\n * In browsers that do not support the Broadcast Channel API, the instance\n * falls back to sending the update via `postMessage()` to all window clients.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass BroadcastCacheUpdate {\n /**\n * Construct a BroadcastCacheUpdate instance with a specific `channelName` to\n * broadcast messages on\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor({headersToCheck, channelName, deferNoticationTimeout} = {}) {\n this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK;\n this._channelName = channelName || DEFAULT_BROADCAST_CHANNEL_NAME;\n this._deferNoticationTimeout =\n deferNoticationTimeout || DEFAULT_DEFER_NOTIFICATION_TIMEOUT;\n\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(this._channelName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'channelName',\n });\n assert.isArray(this._headersToCheck, {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'headersToCheck',\n });\n }\n\n this._initWindowReadyDeferreds();\n }\n\n /**\n * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and send a message via the\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * if they differ.\n *\n * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.\n *\n * @param {Object} options\n * @param {Response} options.oldResponse Cached response to compare.\n * @param {Response} options.newResponse Possibly updated response to compare.\n * @param {string} options.url The URL of the request.\n * @param {string} options.cacheName Name of the cache the responses belong\n * to. This is included in the broadcast message.\n * @param {Event} [options.event] event An optional event that triggered\n * this possible cache update.\n * @return {Promise} Resolves once the update is sent.\n */\n notifyIfUpdated({oldResponse, newResponse, url, cacheName, event}) {\n if (!responsesAreSame(oldResponse, newResponse, this._headersToCheck)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Newer response found (and cached) for:`, url);\n }\n\n const sendUpdate = async () => {\n // In the case of a navigation request, the requesting page will likely\n // not have loaded its JavaScript in time to recevied the update\n // notification, so we defer it until ready (or we timeout waiting).\n if (event && event.request && event.request.mode === 'navigate') {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Original request was a navigation request, ` +\n `waiting for a ready message from the window`, event.request);\n }\n await this._windowReadyOrTimeout(event);\n }\n await this._broadcastUpdate({\n channel: this._getChannel(),\n cacheName,\n url,\n });\n };\n\n // Send the update and ensure the SW stays alive until it's sent.\n const done = sendUpdate();\n\n if (event) {\n try {\n event.waitUntil(done);\n } catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to ensure service worker stays alive ` +\n `when broadcasting cache update for ` +\n `${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n return done;\n }\n }\n\n /**\n * NOTE: this is exposed on the instance primarily so it can be spied on\n * in tests.\n *\n * @param {Object} opts\n * @private\n */\n async _broadcastUpdate(opts) {\n await broadcastUpdate(opts);\n }\n\n /**\n * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for\n * broadcasting updates, or undefined if the browser doesn't support the\n * Broadcast Channel API.\n *\n * @private\n */\n _getChannel() {\n if (('BroadcastChannel' in self) && !this._channel) {\n this._channel = new BroadcastChannel(this._channelName);\n }\n return this._channel;\n }\n\n /**\n * Waits for a message from the window indicating that it's capable of\n * receiving broadcasts. By default, this will only wait for the amount of\n * time specified via the `deferNoticationTimeout` option.\n *\n * @param {Event} event The navigation fetch event.\n * @return {Promise}\n * @private\n */\n _windowReadyOrTimeout(event) {\n if (!this._navigationEventsDeferreds.has(event)) {\n const deferred = new Deferred();\n\n // Set the deferred on the `_navigationEventsDeferreds` map so it will\n // be resolved when the next ready message event comes.\n this._navigationEventsDeferreds.set(event, deferred);\n\n // But don't wait too long for the message since it may never come.\n const timeout = setTimeout(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Timed out after ${this._deferNoticationTimeout}` +\n `ms waiting for message from window`);\n }\n deferred.resolve();\n }, this._deferNoticationTimeout);\n\n // Ensure the timeout is cleared if the deferred promise is resolved.\n deferred.promise.then(() => clearTimeout(timeout));\n }\n return this._navigationEventsDeferreds.get(event).promise;\n }\n\n /**\n * Creates a mapping between navigation fetch events and deferreds, and adds\n * a listener for message events from the window. When message events arrive,\n * all deferreds in the mapping are resolved.\n *\n * Note: it would be easier if we could only resolve the deferred of\n * navigation fetch event whose client ID matched the source ID of the\n * message event, but currently client IDs are not exposed on navigation\n * fetch events: https://www.chromestatus.com/feature/4846038800138240\n *\n * @private\n */\n _initWindowReadyDeferreds() {\n // A mapping between navigation events and their deferreds.\n this._navigationEventsDeferreds = new Map();\n\n // The message listener needs to be added in the initial run of the\n // service worker, but since we don't actually need to be listening for\n // messages until the cache updates, we only invoke the callback if set.\n self.addEventListener('message', (event) => {\n if (event.data.type === 'WINDOW_READY' &&\n event.data.meta === 'workbox-window' &&\n this._navigationEventsDeferreds.size > 0) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Received WINDOW_READY event: `, event);\n }\n // Resolve any pending deferreds.\n for (const deferred of this._navigationEventsDeferreds.values()) {\n deferred.resolve();\n }\n this._navigationEventsDeferreds.clear();\n }\n });\n }\n}\n\nexport {BroadcastCacheUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport './_version.mjs';\n\n/**\n * This plugin will automatically broadcast a message whenever a cached response\n * is updated.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass Plugin {\n /**\n * Construct a BroadcastCacheUpdate instance with the passed options and\n * calls its `notifyIfUpdated()` method whenever the plugin's\n * `cacheDidUpdate` callback is invoked.\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor(options) {\n this._broadcastUpdate = new BroadcastCacheUpdate(options);\n }\n\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n * added to a cache.\n *\n * @private\n * @param {Object} options The input object to this function.\n * @param {string} options.cacheName Name of the cache being updated.\n * @param {Response} [options.oldResponse] The previous cached value, if any.\n * @param {Response} options.newResponse The new value in the cache.\n * @param {Request} options.request The request that triggered the udpate.\n * @param {Request} [options.event] The event that triggered the update.\n */\n cacheDidUpdate({cacheName, oldResponse, newResponse, request, event}) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(newResponse, Response, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'newResponse',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n\n if (!oldResponse) {\n // Without a two responses there is nothing to compare.\n return;\n }\n this._broadcastUpdate.notifyIfUpdated({\n cacheName,\n oldResponse,\n newResponse,\n event,\n url: request.url,\n });\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","responsesAreSame","firstResponse","secondResponse","headersToCheck","some","header","headers","has","every","headerStateComparison","headerValueComparison","get","DEFAULT_BROADCAST_CHANNEL_NAME","DEFAULT_DEFER_NOTIFICATION_TIMEOUT","DEFAULT_HEADERS_TO_CHECK","broadcastUpdate","async","channel","cacheName","url","data","type","meta","payload","updatedURL","postMessage","windows","clients","matchAll","win","BroadcastCacheUpdate","constructor","channelName","deferNoticationTimeout","_headersToCheck","_channelName","_deferNoticationTimeout","_initWindowReadyDeferreds","notifyIfUpdated","oldResponse","newResponse","event","this","done","request","mode","_windowReadyOrTimeout","_broadcastUpdate","_getChannel","sendUpdate","waitUntil","error","opts","_channel","BroadcastChannel","_navigationEventsDeferreds","deferred","Deferred","set","timeout","setTimeout","resolve","promise","then","clearTimeout","Map","addEventListener","size","values","clear","options","cacheDidUpdate"],"mappings":"sFAAA,IAAIA,KAAK,mCAAmCC,IAAI,MAAMC,UCwBhDC,EAAmB,CAACC,EAAeC,EAAgBC,YAQrBA,EAAeC,KAAMC,GAC9CJ,EAAcK,QAAQC,IAAIF,IAC/BH,EAAeI,QAAQC,IAAIF,KAgBxBF,EAAeK,MAAOH,UACrBI,EAAwBR,EAAcK,QAAQC,IAAIF,KACtDH,EAAeI,QAAQC,IAAIF,GACvBK,EAAwBT,EAAcK,QAAQK,IAAIN,KACtDH,EAAeI,QAAQK,IAAIN,UAEtBI,GAAyBC,KC5CvBE,EAAiC,UACjCC,EAAqC,IACrCC,EAA2B,CACtC,iBACA,OACA,iBCmCIC,EAAkBC,OAAQC,QAAAA,EAASC,UAAAA,EAAWC,IAAAA,YAgB5CC,EAAO,CACXC,KD3DsC,gBC4DtCC,KD3DsC,2BC4DtCC,QAAS,CACPL,UAAWA,EACXM,WAAYL,OAIZF,EACFA,EAAQQ,YAAYL,OACf,OACCM,QAAgBC,QAAQC,SAAS,CAACP,KAAM,eACzC,MAAMQ,KAAOH,EAChBG,EAAIJ,YAAYL,KCnDtB,MAAMU,EAiBJC,aAAY5B,eAACA,EAAD6B,YAAiBA,EAAjBC,uBAA8BA,GAA0B,SAC7DC,EAAkB/B,GAAkBW,OACpCqB,EAAeH,GAAepB,OAC9BwB,EACDH,GAA0BpB,OAiBzBwB,IAqBPC,iBAAgBC,YAACA,EAADC,YAAcA,EAAdrB,IAA2BA,EAA3BD,UAAgCA,EAAhCuB,MAA2CA,QACpDzC,EAAiBuC,EAAaC,EAAaE,KAAKR,GAAkB,OAwB/DS,EAnBa3B,WAIbyB,GAASA,EAAMG,SAAkC,aAAvBH,EAAMG,QAAQC,YAKpCH,KAAKI,EAAsBL,SAE7BC,KAAKK,EAAiB,CAC1B9B,QAASyB,KAAKM,IACd9B,UAAAA,EACAC,IAAAA,KAKS8B,MAETR,MAEAA,EAAMS,UAAUP,GAChB,MAAOQ,WAQJR,WAWYS,SACfrC,EAAgBqC,GAUxBJ,UACO,qBAAsBnD,OAAU6C,KAAKW,SACnCA,EAAW,IAAIC,iBAAiBZ,KAAKP,IAErCO,KAAKW,EAYdP,EAAsBL,OACfC,KAAKa,EAA2BhD,IAAIkC,GAAQ,OACzCe,EAAW,IAAIC,gBAIhBF,EAA2BG,IAAIjB,EAAOe,SAGrCG,EAAUC,WAAW,KAKzBJ,EAASK,WACRnB,KAAKN,GAGRoB,EAASM,QAAQC,KAAK,IAAMC,aAAaL,WAEpCjB,KAAKa,EAA2B5C,IAAI8B,GAAOqB,QAepDzB,SAEOkB,EAA6B,IAAIU,IAKtCpE,KAAKqE,iBAAiB,UAAYzB,OACR,iBAApBA,EAAMrB,KAAKC,MACS,mBAApBoB,EAAMrB,KAAKE,MACXoB,KAAKa,EAA2BY,KAAO,EAAG,KAKvC,MAAMX,KAAYd,KAAKa,EAA2Ba,SACrDZ,EAASK,eAENN,EAA2Bc,qDCzMxC,MAkBEtC,YAAYuC,QACLvB,EAAmB,IAAIjB,EAAqBwC,GAgBnDC,gBAAerD,UAACA,EAADqB,YAAYA,EAAZC,YAAyBA,EAAzBI,QAAsCA,EAAtCH,MAA+CA,IAsBvDF,QAIAQ,EAAiBT,gBAAgB,CACpCpB,UAAAA,EACAqB,YAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAtB,IAAKyB,EAAQzB"}
|
1
|
+
{"version":3,"file":"workbox-broadcast-update.prod.js","sources":["../_version.mjs","../responsesAreSame.mjs","../utils/constants.mjs","../broadcastUpdate.mjs","../BroadcastCacheUpdate.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:broadcast-update:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * Given two `Response's`, compares several header values to see if they are\n * the same or not.\n *\n * @param {Response} firstResponse\n * @param {Response} secondResponse\n * @param {Array<string>} headersToCheck\n * @return {boolean}\n *\n * @memberof workbox.broadcastUpdate\n * @private\n */\nconst responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {\n if (process.env.NODE_ENV !== 'production') {\n if (!(firstResponse instanceof Response &&\n secondResponse instanceof Response)) {\n throw new WorkboxError('invalid-responses-are-same-args');\n }\n }\n\n const atLeastOneHeaderAvailable = headersToCheck.some((header) => {\n return firstResponse.headers.has(header) &&\n secondResponse.headers.has(header);\n });\n\n if (!atLeastOneHeaderAvailable) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to determine where the response has been updated ` +\n `because none of the headers that would be checked are present.`);\n logger.debug(`Attempting to compare the following: `,\n firstResponse, secondResponse, headersToCheck);\n }\n\n // Just return true, indicating the that responses are the same, since we\n // can't determine otherwise.\n return true;\n }\n\n return headersToCheck.every((header) => {\n const headerStateComparison = firstResponse.headers.has(header) ===\n secondResponse.headers.has(header);\n const headerValueComparison = firstResponse.headers.get(header) ===\n secondResponse.headers.get(header);\n\n return headerStateComparison && headerValueComparison;\n });\n};\n\nexport {responsesAreSame};\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*/\n\nimport '../_version.mjs';\n\nexport const CACHE_UPDATED_MESSAGE_TYPE = 'CACHE_UPDATED';\nexport const CACHE_UPDATED_MESSAGE_META = 'workbox-broadcast-update';\nexport const DEFAULT_BROADCAST_CHANNEL_NAME = 'workbox';\nexport const DEFAULT_DEFER_NOTIFICATION_TIMEOUT = 10000;\nexport const DEFAULT_HEADERS_TO_CHECK = [\n 'content-length',\n 'etag',\n 'last-modified',\n];\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {CACHE_UPDATED_MESSAGE_TYPE, CACHE_UPDATED_MESSAGE_META}\n from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * You would not normally call this method directly; it's called automatically\n * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here\n * for the benefit of developers who would rather not use the full\n * `BroadcastCacheUpdate` implementation.\n *\n * Calling this will dispatch a message on the provided\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}\n * to notify interested subscribers about a change to a cached resource.\n *\n * The message that's posted has a formation inspired by the\n * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)\n * format like so:\n *\n * ```\n * {\n * type: 'CACHE_UPDATED',\n * meta: 'workbox-broadcast-update',\n * payload: {\n * cacheName: 'the-cache-name',\n * updatedURL: 'https://example.com/'\n * }\n * }\n * ```\n *\n * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at\n * all required.)\n *\n * @param {Object} options\n * @param {string} options.cacheName The name of the cache in which the updated\n * `Response` was stored.\n * @param {string} options.url The URL associated with the updated `Response`.\n * @param {BroadcastChannel} [options.channel] The `BroadcastChannel` to use.\n * If no channel is set or the browser doesn't support the BroadcastChannel\n * api, then an attempt will be made to `postMessage` each window client.\n *\n * @memberof workbox.broadcastUpdate\n */\nconst broadcastUpdate = async ({channel, cacheName, url}) => {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'cacheName',\n });\n assert.isType(url, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: '~',\n funcName: 'broadcastUpdate',\n paramName: 'url',\n });\n }\n\n const data = {\n type: CACHE_UPDATED_MESSAGE_TYPE,\n meta: CACHE_UPDATED_MESSAGE_META,\n payload: {\n cacheName: cacheName,\n updatedURL: url,\n },\n };\n\n if (channel) {\n channel.postMessage(data);\n } else {\n const windows = await clients.matchAll({type: 'window'});\n for (const win of windows) {\n win.postMessage(data);\n }\n }\n};\n\nexport {broadcastUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport {Deferred} from 'workbox-core/_private/Deferred.mjs';\nimport {responsesAreSame} from './responsesAreSame.mjs';\nimport {broadcastUpdate} from './broadcastUpdate.mjs';\n\nimport {DEFAULT_HEADERS_TO_CHECK, DEFAULT_BROADCAST_CHANNEL_NAME,\n DEFAULT_DEFER_NOTIFICATION_TIMEOUT} from './utils/constants.mjs';\n\nimport './_version.mjs';\n\n/**\n * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}\n * to notify interested parties when a cached response has been updated.\n * In browsers that do not support the Broadcast Channel API, the instance\n * falls back to sending the update via `postMessage()` to all window clients.\n *\n * For efficiency's sake, the underlying response bodies are not compared;\n * only specific response headers are checked.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass BroadcastCacheUpdate {\n /**\n * Construct a BroadcastCacheUpdate instance with a specific `channelName` to\n * broadcast messages on\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor({headersToCheck, channelName, deferNoticationTimeout} = {}) {\n this._headersToCheck = headersToCheck || DEFAULT_HEADERS_TO_CHECK;\n this._channelName = channelName || DEFAULT_BROADCAST_CHANNEL_NAME;\n this._deferNoticationTimeout =\n deferNoticationTimeout || DEFAULT_DEFER_NOTIFICATION_TIMEOUT;\n\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(this._channelName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'channelName',\n });\n assert.isArray(this._headersToCheck, {\n moduleName: 'workbox-broadcast-update',\n className: 'BroadcastCacheUpdate',\n funcName: 'constructor',\n paramName: 'headersToCheck',\n });\n }\n\n this._initWindowReadyDeferreds();\n }\n\n /**\n * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * and send a message via the\n * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}\n * if they differ.\n *\n * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.\n *\n * @param {Object} options\n * @param {Response} options.oldResponse Cached response to compare.\n * @param {Response} options.newResponse Possibly updated response to compare.\n * @param {string} options.url The URL of the request.\n * @param {string} options.cacheName Name of the cache the responses belong\n * to. This is included in the broadcast message.\n * @param {Event} [options.event] event An optional event that triggered\n * this possible cache update.\n * @return {Promise} Resolves once the update is sent.\n */\n notifyIfUpdated({oldResponse, newResponse, url, cacheName, event}) {\n if (!responsesAreSame(oldResponse, newResponse, this._headersToCheck)) {\n if (process.env.NODE_ENV !== 'production') {\n logger.log(`Newer response found (and cached) for:`, url);\n }\n\n const sendUpdate = async () => {\n // In the case of a navigation request, the requesting page will likely\n // not have loaded its JavaScript in time to recevied the update\n // notification, so we defer it until ready (or we timeout waiting).\n if (event && event.request && event.request.mode === 'navigate') {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Original request was a navigation request, ` +\n `waiting for a ready message from the window`, event.request);\n }\n await this._windowReadyOrTimeout(event);\n }\n await this._broadcastUpdate({\n channel: this._getChannel(),\n cacheName,\n url,\n });\n };\n\n // Send the update and ensure the SW stays alive until it's sent.\n const done = sendUpdate();\n\n if (event) {\n try {\n event.waitUntil(done);\n } catch (error) {\n if (process.env.NODE_ENV !== 'production') {\n logger.warn(`Unable to ensure service worker stays alive ` +\n `when broadcasting cache update for ` +\n `${getFriendlyURL(event.request.url)}'.`);\n }\n }\n }\n return done;\n }\n }\n\n /**\n * NOTE: this is exposed on the instance primarily so it can be spied on\n * in tests.\n *\n * @param {Object} opts\n * @private\n */\n async _broadcastUpdate(opts) {\n await broadcastUpdate(opts);\n }\n\n /**\n * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for\n * broadcasting updates, or undefined if the browser doesn't support the\n * Broadcast Channel API.\n *\n * @private\n */\n _getChannel() {\n if (('BroadcastChannel' in self) && !this._channel) {\n this._channel = new BroadcastChannel(this._channelName);\n }\n return this._channel;\n }\n\n /**\n * Waits for a message from the window indicating that it's capable of\n * receiving broadcasts. By default, this will only wait for the amount of\n * time specified via the `deferNoticationTimeout` option.\n *\n * @param {Event} event The navigation fetch event.\n * @return {Promise}\n * @private\n */\n _windowReadyOrTimeout(event) {\n if (!this._navigationEventsDeferreds.has(event)) {\n const deferred = new Deferred();\n\n // Set the deferred on the `_navigationEventsDeferreds` map so it will\n // be resolved when the next ready message event comes.\n this._navigationEventsDeferreds.set(event, deferred);\n\n // But don't wait too long for the message since it may never come.\n const timeout = setTimeout(() => {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Timed out after ${this._deferNoticationTimeout}` +\n `ms waiting for message from window`);\n }\n deferred.resolve();\n }, this._deferNoticationTimeout);\n\n // Ensure the timeout is cleared if the deferred promise is resolved.\n deferred.promise.then(() => clearTimeout(timeout));\n }\n return this._navigationEventsDeferreds.get(event).promise;\n }\n\n /**\n * Creates a mapping between navigation fetch events and deferreds, and adds\n * a listener for message events from the window. When message events arrive,\n * all deferreds in the mapping are resolved.\n *\n * Note: it would be easier if we could only resolve the deferred of\n * navigation fetch event whose client ID matched the source ID of the\n * message event, but currently client IDs are not exposed on navigation\n * fetch events: https://www.chromestatus.com/feature/4846038800138240\n *\n * @private\n */\n _initWindowReadyDeferreds() {\n // A mapping between navigation events and their deferreds.\n this._navigationEventsDeferreds = new Map();\n\n // The message listener needs to be added in the initial run of the\n // service worker, but since we don't actually need to be listening for\n // messages until the cache updates, we only invoke the callback if set.\n self.addEventListener('message', (event) => {\n if (event.data.type === 'WINDOW_READY' &&\n event.data.meta === 'workbox-window' &&\n this._navigationEventsDeferreds.size > 0) {\n if (process.env.NODE_ENV !== 'production') {\n logger.debug(`Received WINDOW_READY event: `, event);\n }\n // Resolve any pending deferreds.\n for (const deferred of this._navigationEventsDeferreds.values()) {\n deferred.resolve();\n }\n this._navigationEventsDeferreds.clear();\n }\n });\n }\n}\n\nexport {BroadcastCacheUpdate};\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*/\n\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {BroadcastCacheUpdate} from './BroadcastCacheUpdate.mjs';\nimport './_version.mjs';\n\n/**\n * This plugin will automatically broadcast a message whenever a cached response\n * is updated.\n *\n * @memberof workbox.broadcastUpdate\n */\nclass Plugin {\n /**\n * Construct a BroadcastCacheUpdate instance with the passed options and\n * calls its `notifyIfUpdated()` method whenever the plugin's\n * `cacheDidUpdate` callback is invoked.\n *\n * @param {Object} options\n * @param {Array<string>}\n * [options.headersToCheck=['content-length', 'etag', 'last-modified']]\n * A list of headers that will be used to determine whether the responses\n * differ.\n * @param {string} [options.channelName='workbox'] The name that will be used\n *. when creating the `BroadcastChannel`, which defaults to 'workbox' (the\n * channel name used by the `workbox-window` package).\n * @param {string} [options.deferNoticationTimeout=10000] The amount of time\n * to wait for a ready message from the window on navigation requests\n * before sending the update.\n */\n constructor(options) {\n this._broadcastUpdate = new BroadcastCacheUpdate(options);\n }\n\n /**\n * A \"lifecycle\" callback that will be triggered automatically by the\n * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is\n * added to a cache.\n *\n * @private\n * @param {Object} options The input object to this function.\n * @param {string} options.cacheName Name of the cache being updated.\n * @param {Response} [options.oldResponse] The previous cached value, if any.\n * @param {Response} options.newResponse The new value in the cache.\n * @param {Request} options.request The request that triggered the udpate.\n * @param {Request} [options.event] The event that triggered the update.\n */\n cacheDidUpdate({cacheName, oldResponse, newResponse, request, event}) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isType(cacheName, 'string', {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'cacheName',\n });\n assert.isInstance(newResponse, Response, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'newResponse',\n });\n assert.isInstance(request, Request, {\n moduleName: 'workbox-broadcast-update',\n className: 'Plugin',\n funcName: 'cacheDidUpdate',\n paramName: 'request',\n });\n }\n\n if (!oldResponse) {\n // Without a two responses there is nothing to compare.\n return;\n }\n this._broadcastUpdate.notifyIfUpdated({\n cacheName,\n oldResponse,\n newResponse,\n event,\n url: request.url,\n });\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","responsesAreSame","firstResponse","secondResponse","headersToCheck","some","header","headers","has","every","headerStateComparison","headerValueComparison","get","DEFAULT_BROADCAST_CHANNEL_NAME","DEFAULT_DEFER_NOTIFICATION_TIMEOUT","DEFAULT_HEADERS_TO_CHECK","broadcastUpdate","async","channel","cacheName","url","data","type","meta","payload","updatedURL","postMessage","windows","clients","matchAll","win","BroadcastCacheUpdate","constructor","channelName","deferNoticationTimeout","_headersToCheck","_channelName","_deferNoticationTimeout","_initWindowReadyDeferreds","notifyIfUpdated","oldResponse","newResponse","event","this","done","request","mode","_windowReadyOrTimeout","_broadcastUpdate","_getChannel","sendUpdate","waitUntil","error","opts","_channel","BroadcastChannel","_navigationEventsDeferreds","deferred","Deferred","set","timeout","setTimeout","resolve","promise","then","clearTimeout","Map","addEventListener","size","values","clear","options","cacheDidUpdate"],"mappings":"sFAAA,IAAIA,KAAK,mCAAmCC,IAAI,MAAMC,UCwBhDC,EAAmB,CAACC,EAAeC,EAAgBC,YAQrBA,EAAeC,KAAMC,GAC9CJ,EAAcK,QAAQC,IAAIF,IAC/BH,EAAeI,QAAQC,IAAIF,KAgBxBF,EAAeK,MAAOH,UACrBI,EAAwBR,EAAcK,QAAQC,IAAIF,KACtDH,EAAeI,QAAQC,IAAIF,GACvBK,EAAwBT,EAAcK,QAAQK,IAAIN,KACtDH,EAAeI,QAAQK,IAAIN,UAEtBI,GAAyBC,KC5CvBE,EAAiC,UACjCC,EAAqC,IACrCC,EAA2B,CACtC,iBACA,OACA,iBCmCIC,EAAkBC,OAAQC,QAAAA,EAASC,UAAAA,EAAWC,IAAAA,YAgB5CC,EAAO,CACXC,KD3DsC,gBC4DtCC,KD3DsC,2BC4DtCC,QAAS,CACPL,UAAWA,EACXM,WAAYL,OAIZF,EACFA,EAAQQ,YAAYL,OACf,OACCM,QAAgBC,QAAQC,SAAS,CAACP,KAAM,eACzC,MAAMQ,KAAOH,EAChBG,EAAIJ,YAAYL,KCnDtB,MAAMU,EAiBJC,aAAY5B,eAACA,EAAD6B,YAAiBA,EAAjBC,uBAA8BA,GAA0B,SAC7DC,EAAkB/B,GAAkBW,OACpCqB,EAAeH,GAAepB,OAC9BwB,EACDH,GAA0BpB,OAiBzBwB,IAqBPC,iBAAgBC,YAACA,EAADC,YAAcA,EAAdrB,IAA2BA,EAA3BD,UAAgCA,EAAhCuB,MAA2CA,QACpDzC,EAAiBuC,EAAaC,EAAaE,KAAKR,GAAkB,OAwB/DS,EAnBa3B,WAIbyB,GAASA,EAAMG,SAAkC,aAAvBH,EAAMG,QAAQC,YAKpCH,KAAKI,EAAsBL,SAE7BC,KAAKK,EAAiB,CAC1B9B,QAASyB,KAAKM,IACd9B,UAAAA,EACAC,IAAAA,KAKS8B,MAETR,MAEAA,EAAMS,UAAUP,GAChB,MAAOQ,WAQJR,WAWYS,SACfrC,EAAgBqC,GAUxBJ,UACO,qBAAsBnD,OAAU6C,KAAKW,SACnCA,EAAW,IAAIC,iBAAiBZ,KAAKP,IAErCO,KAAKW,EAYdP,EAAsBL,OACfC,KAAKa,EAA2BhD,IAAIkC,GAAQ,OACzCe,EAAW,IAAIC,gBAIhBF,EAA2BG,IAAIjB,EAAOe,SAGrCG,EAAUC,WAAW,KAKzBJ,EAASK,WACRnB,KAAKN,GAGRoB,EAASM,QAAQC,KAAK,IAAMC,aAAaL,WAEpCjB,KAAKa,EAA2B5C,IAAI8B,GAAOqB,QAepDzB,SAEOkB,EAA6B,IAAIU,IAKtCpE,KAAKqE,iBAAiB,UAAYzB,OACR,iBAApBA,EAAMrB,KAAKC,MACS,mBAApBoB,EAAMrB,KAAKE,MACXoB,KAAKa,EAA2BY,KAAO,EAAG,KAKvC,MAAMX,KAAYd,KAAKa,EAA2Ba,SACrDZ,EAASK,eAENN,EAA2Bc,qDCzMxC,MAkBEtC,YAAYuC,QACLvB,EAAmB,IAAIjB,EAAqBwC,GAgBnDC,gBAAerD,UAACA,EAADqB,YAAYA,EAAZC,YAAyBA,EAAzBI,QAAsCA,EAAtCH,MAA+CA,IAsBvDF,QAIAQ,EAAiBT,gBAAgB,CACpCpB,UAAAA,EACAqB,YAAAA,EACAC,YAAAA,EACAC,MAAAA,EACAtB,IAAKyB,EAAQzB"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-cacheable-response.dev.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.0']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\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*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\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*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.cacheableResponse\n */\n\nexport {\n CacheableResponse,\n Plugin,\n};\n"],"names":["self","_","e","CacheableResponse","constructor","config","statuses","headers","WorkboxError","moduleName","className","funcName","assert","isArray","paramName","isType","_statuses","_headers","isResponseCacheable","response","isInstance","Response","cacheable","includes","status","Object","keys","some","headerName","get","logger","groupCollapsed","getFriendlyURL","url","log","JSON","stringify","groupEnd","logFriendlyHeaders","forEach","value","key","Plugin","_cacheableResponse","cacheWillUpdate"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"workbox-cacheable-response.dev.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs","../index.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\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*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\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*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport {Plugin} from './Plugin.mjs';\nimport './_version.mjs';\n\n\n/**\n * @namespace workbox.cacheableResponse\n */\n\nexport {\n CacheableResponse,\n Plugin,\n};\n"],"names":["self","_","e","CacheableResponse","constructor","config","statuses","headers","WorkboxError","moduleName","className","funcName","assert","isArray","paramName","isType","_statuses","_headers","isResponseCacheable","response","isInstance","Response","cacheable","includes","status","Object","keys","some","headerName","get","logger","groupCollapsed","getFriendlyURL","url","log","JSON","stringify","groupEnd","logFriendlyHeaders","forEach","value","key","Plugin","_cacheableResponse","cacheWillUpdate"],"mappings":";;;;EAAA,IAAG;EAACA,EAAAA,IAAI,CAAC,kCAAD,CAAJ,IAA0CC,CAAC,EAA3C;EAA8C,CAAlD,CAAkD,OAAMC,CAAN,EAAQ;;ECA1D;;;;;;;AAQA,EAMA;;;;;;;;;EAQA,MAAMC,iBAAN,CAAwB;EACtB;;;;;;;;;;;;;;EAcAC,EAAAA,WAAW,CAACC,MAAM,GAAG,EAAV,EAAc;EACvB,IAA2C;EACzC,UAAI,EAAEA,MAAM,CAACC,QAAP,IAAmBD,MAAM,CAACE,OAA5B,CAAJ,EAA0C;EACxC,cAAM,IAAIC,6BAAJ,CAAiB,8BAAjB,EAAiD;EACrDC,UAAAA,UAAU,EAAE,4BADyC;EAErDC,UAAAA,SAAS,EAAE,mBAF0C;EAGrDC,UAAAA,QAAQ,EAAE;EAH2C,SAAjD,CAAN;EAKD;;EAED,UAAIN,MAAM,CAACC,QAAX,EAAqB;EACnBM,QAAAA,iBAAM,CAACC,OAAP,CAAeR,MAAM,CAACC,QAAtB,EAAgC;EAC9BG,UAAAA,UAAU,EAAE,4BADkB;EAE9BC,UAAAA,SAAS,EAAE,mBAFmB;EAG9BC,UAAAA,QAAQ,EAAE,aAHoB;EAI9BG,UAAAA,SAAS,EAAE;EAJmB,SAAhC;EAMD;;EAED,UAAIT,MAAM,CAACE,OAAX,EAAoB;EAClBK,QAAAA,iBAAM,CAACG,MAAP,CAAcV,MAAM,CAACE,OAArB,EAA8B,QAA9B,EAAwC;EACtCE,UAAAA,UAAU,EAAE,4BAD0B;EAEtCC,UAAAA,SAAS,EAAE,mBAF2B;EAGtCC,UAAAA,QAAQ,EAAE,aAH4B;EAItCG,UAAAA,SAAS,EAAE;EAJ2B,SAAxC;EAMD;EACF;;EAED,SAAKE,SAAL,GAAiBX,MAAM,CAACC,QAAxB;EACA,SAAKW,QAAL,GAAgBZ,MAAM,CAACE,OAAvB;EACD;EAED;;;;;;;;;;;EASAW,EAAAA,mBAAmB,CAACC,QAAD,EAAW;EAC5B,IAA2C;EACzCP,MAAAA,iBAAM,CAACQ,UAAP,CAAkBD,QAAlB,EAA4BE,QAA5B,EAAsC;EACpCZ,QAAAA,UAAU,EAAE,4BADwB;EAEpCC,QAAAA,SAAS,EAAE,mBAFyB;EAGpCC,QAAAA,QAAQ,EAAE,qBAH0B;EAIpCG,QAAAA,SAAS,EAAE;EAJyB,OAAtC;EAMD;;EAED,QAAIQ,SAAS,GAAG,IAAhB;;EAEA,QAAI,KAAKN,SAAT,EAAoB;EAClBM,MAAAA,SAAS,GAAG,KAAKN,SAAL,CAAeO,QAAf,CAAwBJ,QAAQ,CAACK,MAAjC,CAAZ;EACD;;EAED,QAAI,KAAKP,QAAL,IAAiBK,SAArB,EAAgC;EAC9BA,MAAAA,SAAS,GAAGG,MAAM,CAACC,IAAP,CAAY,KAAKT,QAAjB,EAA2BU,IAA3B,CAAiCC,UAAD,IAAgB;EAC1D,eAAOT,QAAQ,CAACZ,OAAT,CAAiBsB,GAAjB,CAAqBD,UAArB,MAAqC,KAAKX,QAAL,CAAcW,UAAd,CAA5C;EACD,OAFW,CAAZ;EAGD;;EAED,IAA2C;EACzC,UAAI,CAACN,SAAL,EAAgB;EACdQ,QAAAA,iBAAM,CAACC,cAAP,CAAuB,kBAAD,GACnB,IAAGC,iCAAc,CAACb,QAAQ,CAACc,GAAV,CAAe,kCADb,GAEnB,yCAFH;EAIAH,QAAAA,iBAAM,CAACC,cAAP,CAAuB,kCAAvB;EACAD,QAAAA,iBAAM,CAACI,GAAP,CAAY,sBAAD,GACTC,IAAI,CAACC,SAAL,CAAe,KAAKpB,SAApB,CADF;EAEAc,QAAAA,iBAAM,CAACI,GAAP,CAAY,qBAAD,GACTC,IAAI,CAACC,SAAL,CAAe,KAAKnB,QAApB,EAA8B,IAA9B,EAAoC,CAApC,CADF;EAEAa,QAAAA,iBAAM,CAACO,QAAP;EAEA,cAAMC,kBAAkB,GAAG,EAA3B;EACAnB,QAAAA,QAAQ,CAACZ,OAAT,CAAiBgC,OAAjB,CAAyB,CAACC,KAAD,EAAQC,GAAR,KAAgB;EACvCH,UAAAA,kBAAkB,CAACG,GAAD,CAAlB,GAA0BD,KAA1B;EACD,SAFD;EAIAV,QAAAA,iBAAM,CAACC,cAAP,CAAuB,wCAAvB;EACAD,QAAAA,iBAAM,CAACI,GAAP,CAAY,mBAAD,GAAsBf,QAAQ,CAACK,MAA1C;EACAM,QAAAA,iBAAM,CAACI,GAAP,CAAY,oBAAD,GACTC,IAAI,CAACC,SAAL,CAAeE,kBAAf,EAAmC,IAAnC,EAAyC,CAAzC,CADF;EAEAR,QAAAA,iBAAM,CAACO,QAAP;EAEAP,QAAAA,iBAAM,CAACC,cAAP,CAAuB,kCAAvB;EACAD,QAAAA,iBAAM,CAACI,GAAP,CAAWf,QAAQ,CAACZ,OAApB;EACAuB,QAAAA,iBAAM,CAACI,GAAP,CAAWf,QAAX;EACAW,QAAAA,iBAAM,CAACO,QAAP;EAEAP,QAAAA,iBAAM,CAACO,QAAP;EACD;EACF;;EAED,WAAOf,SAAP;EACD;;EAjHqB;;ECtBxB;;;;;;;AAQA,EAGA;;;;;;;;EAOA,MAAMoB,MAAN,CAAa;EACX;;;;;;;;;;;;;;EAcAtC,EAAAA,WAAW,CAACC,MAAD,EAAS;EAClB,SAAKsC,kBAAL,GAA0B,IAAIxC,iBAAJ,CAAsBE,MAAtB,CAA1B;EACD;EAED;;;;;;;;EAMAuC,EAAAA,eAAe,CAAC;EAACzB,IAAAA;EAAD,GAAD,EAAa;EAC1B,QAAI,KAAKwB,kBAAL,CAAwBzB,mBAAxB,CAA4CC,QAA5C,CAAJ,EAA2D;EACzD,aAAOA,QAAP;EACD;;EACD,WAAO,IAAP;EACD;;EA9BU;;EClBb;;;;;;;;;;;;;;;;;"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
this.workbox=this.workbox||{},this.workbox.cacheableResponse=function(t){"use strict";try{self["workbox:cacheable-response:4.3.
|
1
|
+
this.workbox=this.workbox||{},this.workbox.cacheableResponse=function(t){"use strict";try{self["workbox:cacheable-response:4.3.1"]&&_()}catch(t){}class s{constructor(t={}){this.t=t.statuses,this.s=t.headers}isResponseCacheable(t){let s=!0;return this.t&&(s=this.t.includes(t.status)),this.s&&s&&(s=Object.keys(this.s).some(s=>t.headers.get(s)===this.s[s])),s}}return t.CacheableResponse=s,t.Plugin=class{constructor(t){this.i=new s(t)}cacheWillUpdate({response:t}){return this.i.isResponseCacheable(t)?t:null}},t}({});
|
2
2
|
//# sourceMappingURL=workbox-cacheable-response.prod.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"workbox-cacheable-response.prod.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.
|
1
|
+
{"version":3,"file":"workbox-cacheable-response.prod.js","sources":["../_version.mjs","../CacheableResponse.mjs","../Plugin.mjs"],"sourcesContent":["try{self['workbox:cacheable-response:4.3.1']&&_()}catch(e){}// eslint-disable-line","/*\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*/\n\nimport {WorkboxError} from 'workbox-core/_private/WorkboxError.mjs';\nimport {assert} from 'workbox-core/_private/assert.mjs';\nimport {getFriendlyURL} from 'workbox-core/_private/getFriendlyURL.mjs';\nimport {logger} from 'workbox-core/_private/logger.mjs';\nimport './_version.mjs';\n\n/**\n * This class allows you to set up rules determining what\n * status codes and/or headers need to be present in order for a\n * [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response)\n * to be considered cacheable.\n *\n * @memberof workbox.cacheableResponse\n */\nclass CacheableResponse {\n /**\n * To construct a new CacheableResponse instance you must provide at least\n * one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config = {}) {\n if (process.env.NODE_ENV !== 'production') {\n if (!(config.statuses || config.headers)) {\n throw new WorkboxError('statuses-or-headers-required', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n });\n }\n\n if (config.statuses) {\n assert.isArray(config.statuses, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.statuses',\n });\n }\n\n if (config.headers) {\n assert.isType(config.headers, 'object', {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'constructor',\n paramName: 'config.headers',\n });\n }\n }\n\n this._statuses = config.statuses;\n this._headers = config.headers;\n }\n\n /**\n * Checks a response to see whether it's cacheable or not, based on this\n * object's configuration.\n *\n * @param {Response} response The response whose cacheability is being\n * checked.\n * @return {boolean} `true` if the `Response` is cacheable, and `false`\n * otherwise.\n */\n isResponseCacheable(response) {\n if (process.env.NODE_ENV !== 'production') {\n assert.isInstance(response, Response, {\n moduleName: 'workbox-cacheable-response',\n className: 'CacheableResponse',\n funcName: 'isResponseCacheable',\n paramName: 'response',\n });\n }\n\n let cacheable = true;\n\n if (this._statuses) {\n cacheable = this._statuses.includes(response.status);\n }\n\n if (this._headers && cacheable) {\n cacheable = Object.keys(this._headers).some((headerName) => {\n return response.headers.get(headerName) === this._headers[headerName];\n });\n }\n\n if (process.env.NODE_ENV !== 'production') {\n if (!cacheable) {\n logger.groupCollapsed(`The request for ` +\n `'${getFriendlyURL(response.url)}' returned a response that does ` +\n `not meet the criteria for being cached.`);\n\n logger.groupCollapsed(`View cacheability criteria here.`);\n logger.log(`Cacheable statuses: ` +\n JSON.stringify(this._statuses));\n logger.log(`Cacheable headers: ` +\n JSON.stringify(this._headers, null, 2));\n logger.groupEnd();\n\n const logFriendlyHeaders = {};\n response.headers.forEach((value, key) => {\n logFriendlyHeaders[key] = value;\n });\n\n logger.groupCollapsed(`View response status and headers here.`);\n logger.log(`Response status: ` + response.status);\n logger.log(`Response headers: ` +\n JSON.stringify(logFriendlyHeaders, null, 2));\n logger.groupEnd();\n\n logger.groupCollapsed(`View full response details here.`);\n logger.log(response.headers);\n logger.log(response);\n logger.groupEnd();\n\n logger.groupEnd();\n }\n }\n\n return cacheable;\n }\n}\n\nexport {CacheableResponse};\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*/\n\nimport {CacheableResponse} from './CacheableResponse.mjs';\nimport './_version.mjs';\n\n/**\n * A class implementing the `cacheWillUpdate` lifecycle callback. This makes it\n * easier to add in cacheability checks to requests made via Workbox's built-in\n * strategies.\n *\n * @memberof workbox.cacheableResponse\n */\nclass Plugin {\n /**\n * To construct a new cacheable response Plugin instance you must provide at\n * least one of the `config` properties.\n *\n * If both `statuses` and `headers` are specified, then both conditions must\n * be met for the `Response` to be considered cacheable.\n *\n * @param {Object} config\n * @param {Array<number>} [config.statuses] One or more status codes that a\n * `Response` can have and be considered cacheable.\n * @param {Object<string,string>} [config.headers] A mapping of header names\n * and expected values that a `Response` can have and be considered cacheable.\n * If multiple headers are provided, only one needs to be present.\n */\n constructor(config) {\n this._cacheableResponse = new CacheableResponse(config);\n }\n\n /**\n * @param {Object} options\n * @param {Response} options.response\n * @return {boolean}\n * @private\n */\n cacheWillUpdate({response}) {\n if (this._cacheableResponse.isResponseCacheable(response)) {\n return response;\n }\n return null;\n }\n}\n\nexport {Plugin};\n"],"names":["self","_","e","CacheableResponse","constructor","config","_statuses","statuses","_headers","headers","isResponseCacheable","response","cacheable","this","includes","status","Object","keys","some","headerName","get","_cacheableResponse","cacheWillUpdate"],"mappings":"sFAAA,IAAIA,KAAK,qCAAqCC,IAAI,MAAMC,ICsBxD,MAAMC,EAeJC,YAAYC,EAAS,SA6BdC,EAAYD,EAAOE,cACnBC,EAAWH,EAAOI,QAYzBC,oBAAoBC,OAUdC,GAAY,SAEZC,KAAKP,IACPM,EAAYC,KAAKP,EAAUQ,SAASH,EAASI,SAG3CF,KAAKL,GAAYI,IACnBA,EAAYI,OAAOC,KAAKJ,KAAKL,GAAUU,KAAMC,GACpCR,EAASF,QAAQW,IAAID,KAAgBN,KAAKL,EAASW,KAqCvDP,yCCpHX,MAeER,YAAYC,QACLgB,EAAqB,IAAIlB,EAAkBE,GASlDiB,iBAAgBX,SAACA,WACXE,KAAKQ,EAAmBX,oBAAoBC,GACvCA,EAEF"}
|
@@ -3,7 +3,7 @@ this.workbox.core = (function (exports) {
|
|
3
3
|
'use strict';
|
4
4
|
|
5
5
|
try {
|
6
|
-
self['workbox:core:4.3.
|
6
|
+
self['workbox:core:4.3.1'] && _();
|
7
7
|
} catch (e) {} // eslint-disable-line
|
8
8
|
|
9
9
|
/*
|
@@ -538,10 +538,19 @@ this.workbox.core = (function (exports) {
|
|
538
538
|
license that can be found in the LICENSE file or at
|
539
539
|
https://opensource.org/licenses/MIT.
|
540
540
|
*/
|
541
|
-
|
541
|
+
|
542
|
+
const quotaErrorCallbacks = new Set();
|
543
|
+
|
544
|
+
/*
|
545
|
+
Copyright 2019 Google LLC
|
546
|
+
|
547
|
+
Use of this source code is governed by an MIT-style
|
548
|
+
license that can be found in the LICENSE file or at
|
549
|
+
https://opensource.org/licenses/MIT.
|
550
|
+
*/
|
542
551
|
/**
|
543
|
-
* Adds a function to the set of
|
544
|
-
* a quota error.
|
552
|
+
* Adds a function to the set of quotaErrorCallbacks that will be executed if
|
553
|
+
* there's a quota error.
|
545
554
|
*
|
546
555
|
* @param {Function} callback
|
547
556
|
* @memberof workbox.core
|
@@ -556,12 +565,82 @@ this.workbox.core = (function (exports) {
|
|
556
565
|
});
|
557
566
|
}
|
558
567
|
|
559
|
-
|
568
|
+
quotaErrorCallbacks.add(callback);
|
560
569
|
|
561
570
|
{
|
562
571
|
logger.log('Registered a callback to respond to quota errors.', callback);
|
563
572
|
}
|
564
573
|
}
|
574
|
+
|
575
|
+
/*
|
576
|
+
Copyright 2018 Google LLC
|
577
|
+
|
578
|
+
Use of this source code is governed by an MIT-style
|
579
|
+
license that can be found in the LICENSE file or at
|
580
|
+
https://opensource.org/licenses/MIT.
|
581
|
+
*/
|
582
|
+
const _cacheNameDetails = {
|
583
|
+
googleAnalytics: 'googleAnalytics',
|
584
|
+
precache: 'precache-v2',
|
585
|
+
prefix: 'workbox',
|
586
|
+
runtime: 'runtime',
|
587
|
+
suffix: self.registration.scope
|
588
|
+
};
|
589
|
+
|
590
|
+
const _createCacheName = cacheName => {
|
591
|
+
return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value.length > 0).join('-');
|
592
|
+
};
|
593
|
+
|
594
|
+
const cacheNames = {
|
595
|
+
updateDetails: details => {
|
596
|
+
Object.keys(_cacheNameDetails).forEach(key => {
|
597
|
+
if (typeof details[key] !== 'undefined') {
|
598
|
+
_cacheNameDetails[key] = details[key];
|
599
|
+
}
|
600
|
+
});
|
601
|
+
},
|
602
|
+
getGoogleAnalyticsName: userCacheName => {
|
603
|
+
return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);
|
604
|
+
},
|
605
|
+
getPrecacheName: userCacheName => {
|
606
|
+
return userCacheName || _createCacheName(_cacheNameDetails.precache);
|
607
|
+
},
|
608
|
+
getPrefix: () => {
|
609
|
+
return _cacheNameDetails.prefix;
|
610
|
+
},
|
611
|
+
getRuntimeName: userCacheName => {
|
612
|
+
return userCacheName || _createCacheName(_cacheNameDetails.runtime);
|
613
|
+
},
|
614
|
+
getSuffix: () => {
|
615
|
+
return _cacheNameDetails.suffix;
|
616
|
+
}
|
617
|
+
};
|
618
|
+
|
619
|
+
/*
|
620
|
+
Copyright 2018 Google LLC
|
621
|
+
|
622
|
+
Use of this source code is governed by an MIT-style
|
623
|
+
license that can be found in the LICENSE file or at
|
624
|
+
https://opensource.org/licenses/MIT.
|
625
|
+
*/
|
626
|
+
|
627
|
+
const getFriendlyURL = url => {
|
628
|
+
const urlObj = new URL(url, location);
|
629
|
+
|
630
|
+
if (urlObj.origin === location.origin) {
|
631
|
+
return urlObj.pathname;
|
632
|
+
}
|
633
|
+
|
634
|
+
return urlObj.href;
|
635
|
+
};
|
636
|
+
|
637
|
+
/*
|
638
|
+
Copyright 2018 Google LLC
|
639
|
+
|
640
|
+
Use of this source code is governed by an MIT-style
|
641
|
+
license that can be found in the LICENSE file or at
|
642
|
+
https://opensource.org/licenses/MIT.
|
643
|
+
*/
|
565
644
|
/**
|
566
645
|
* Runs all of the callback functions, one at a time sequentially, in the order
|
567
646
|
* in which they were registered.
|
@@ -570,13 +649,12 @@ this.workbox.core = (function (exports) {
|
|
570
649
|
* @private
|
571
650
|
*/
|
572
651
|
|
573
|
-
|
574
652
|
async function executeQuotaErrorCallbacks() {
|
575
653
|
{
|
576
|
-
logger.log(`About to run ${
|
654
|
+
logger.log(`About to run ${quotaErrorCallbacks.size} ` + `callbacks to clean up caches.`);
|
577
655
|
}
|
578
656
|
|
579
|
-
for (const callback of
|
657
|
+
for (const callback of quotaErrorCallbacks) {
|
580
658
|
await callback();
|
581
659
|
|
582
660
|
{
|
@@ -590,12 +668,34 @@ this.workbox.core = (function (exports) {
|
|
590
668
|
}
|
591
669
|
|
592
670
|
/*
|
593
|
-
Copyright
|
671
|
+
Copyright 2018 Google LLC
|
672
|
+
|
673
|
+
Use of this source code is governed by an MIT-style
|
674
|
+
license that can be found in the LICENSE file or at
|
675
|
+
https://opensource.org/licenses/MIT.
|
676
|
+
*/
|
677
|
+
const pluginEvents = {
|
678
|
+
CACHE_DID_UPDATE: 'cacheDidUpdate',
|
679
|
+
CACHE_KEY_WILL_BE_USED: 'cacheKeyWillBeUsed',
|
680
|
+
CACHE_WILL_UPDATE: 'cacheWillUpdate',
|
681
|
+
CACHED_RESPONSE_WILL_BE_USED: 'cachedResponseWillBeUsed',
|
682
|
+
FETCH_DID_FAIL: 'fetchDidFail',
|
683
|
+
FETCH_DID_SUCCEED: 'fetchDidSucceed',
|
684
|
+
REQUEST_WILL_FETCH: 'requestWillFetch'
|
685
|
+
};
|
686
|
+
|
687
|
+
/*
|
688
|
+
Copyright 2018 Google LLC
|
594
689
|
|
595
690
|
Use of this source code is governed by an MIT-style
|
596
691
|
license that can be found in the LICENSE file or at
|
597
692
|
https://opensource.org/licenses/MIT.
|
598
693
|
*/
|
694
|
+
const pluginUtils = {
|
695
|
+
filter: (plugins, callbackName) => {
|
696
|
+
return plugins.filter(plugin => callbackName in plugin);
|
697
|
+
}
|
698
|
+
};
|
599
699
|
|
600
700
|
/*
|
601
701
|
Copyright 2018 Google LLC
|
@@ -605,317 +705,285 @@ this.workbox.core = (function (exports) {
|
|
605
705
|
https://opensource.org/licenses/MIT.
|
606
706
|
*/
|
607
707
|
/**
|
608
|
-
*
|
609
|
-
*
|
610
|
-
*
|
708
|
+
* Wrapper around cache.put().
|
709
|
+
*
|
710
|
+
* Will call `cacheDidUpdate` on plugins if the cache was updated, using
|
711
|
+
* `matchOptions` when determining what the old entry is.
|
712
|
+
*
|
713
|
+
* @param {Object} options
|
714
|
+
* @param {string} options.cacheName
|
715
|
+
* @param {Request} options.request
|
716
|
+
* @param {Response} options.response
|
717
|
+
* @param {Event} [options.event]
|
718
|
+
* @param {Array<Object>} [options.plugins=[]]
|
719
|
+
* @param {Object} [options.matchOptions]
|
611
720
|
*
|
612
721
|
* @private
|
722
|
+
* @memberof module:workbox-core
|
613
723
|
*/
|
614
724
|
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
this._version = version;
|
631
|
-
this._onupgradeneeded = onupgradeneeded;
|
632
|
-
this._onversionchange = onversionchange; // If this is null, it means the database isn't open.
|
633
|
-
|
634
|
-
this._db = null;
|
725
|
+
const putWrapper = async ({
|
726
|
+
cacheName,
|
727
|
+
request,
|
728
|
+
response,
|
729
|
+
event,
|
730
|
+
plugins = [],
|
731
|
+
matchOptions
|
732
|
+
} = {}) => {
|
733
|
+
{
|
734
|
+
if (request.method && request.method !== 'GET') {
|
735
|
+
throw new WorkboxError('attempt-to-cache-non-get-request', {
|
736
|
+
url: getFriendlyURL(request.url),
|
737
|
+
method: request.method
|
738
|
+
});
|
739
|
+
}
|
635
740
|
}
|
636
|
-
/**
|
637
|
-
* Returns the IDBDatabase instance (not normally needed).
|
638
|
-
*
|
639
|
-
* @private
|
640
|
-
*/
|
641
741
|
|
742
|
+
const effectiveRequest = await _getEffectiveRequest({
|
743
|
+
plugins,
|
744
|
+
request,
|
745
|
+
mode: 'write'
|
746
|
+
});
|
642
747
|
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
* Opens a connected to an IDBDatabase, invokes any onupgradedneeded
|
648
|
-
* callback, and added an onversionchange callback to the database.
|
649
|
-
*
|
650
|
-
* @return {IDBDatabase}
|
651
|
-
* @private
|
652
|
-
*/
|
748
|
+
if (!response) {
|
749
|
+
{
|
750
|
+
logger.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(effectiveRequest.url)}'.`);
|
751
|
+
}
|
653
752
|
|
753
|
+
throw new WorkboxError('cache-put-with-no-response', {
|
754
|
+
url: getFriendlyURL(effectiveRequest.url)
|
755
|
+
});
|
756
|
+
}
|
654
757
|
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
// never never run. A timeout better handles all possible scenarios:
|
662
|
-
// https://github.com/w3c/IndexedDB/issues/223
|
663
|
-
let openRequestTimedOut = false;
|
664
|
-
setTimeout(() => {
|
665
|
-
openRequestTimedOut = true;
|
666
|
-
reject(new Error('The open request was blocked and timed out'));
|
667
|
-
}, this.OPEN_TIMEOUT);
|
668
|
-
const openRequest = indexedDB.open(this._name, this._version);
|
758
|
+
let responseToCache = await _isResponseSafeToCache({
|
759
|
+
event,
|
760
|
+
plugins,
|
761
|
+
response,
|
762
|
+
request: effectiveRequest
|
763
|
+
});
|
669
764
|
|
670
|
-
|
765
|
+
if (!responseToCache) {
|
766
|
+
{
|
767
|
+
logger.debug(`Response '${getFriendlyURL(effectiveRequest.url)}' will ` + `not be cached.`, responseToCache);
|
768
|
+
}
|
671
769
|
|
672
|
-
|
673
|
-
|
674
|
-
openRequest.transaction.abort();
|
675
|
-
evt.target.result.close();
|
676
|
-
} else if (this._onupgradeneeded) {
|
677
|
-
this._onupgradeneeded(evt);
|
678
|
-
}
|
679
|
-
};
|
770
|
+
return;
|
771
|
+
}
|
680
772
|
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
773
|
+
const cache = await caches.open(cacheName);
|
774
|
+
const updatePlugins = pluginUtils.filter(plugins, pluginEvents.CACHE_DID_UPDATE);
|
775
|
+
let oldResponse = updatePlugins.length > 0 ? await matchWrapper({
|
776
|
+
cacheName,
|
777
|
+
matchOptions,
|
778
|
+
request: effectiveRequest
|
779
|
+
}) : null;
|
685
780
|
|
686
|
-
|
687
|
-
|
688
|
-
} else {
|
689
|
-
db.onversionchange = this._onversionchange.bind(this);
|
690
|
-
resolve(db);
|
691
|
-
}
|
692
|
-
};
|
693
|
-
});
|
694
|
-
return this;
|
781
|
+
{
|
782
|
+
logger.debug(`Updating the '${cacheName}' cache with a new Response for ` + `${getFriendlyURL(effectiveRequest.url)}.`);
|
695
783
|
}
|
696
|
-
/**
|
697
|
-
* Polyfills the native `getKey()` method. Note, this is overridden at
|
698
|
-
* runtime if the browser supports the native method.
|
699
|
-
*
|
700
|
-
* @param {string} storeName
|
701
|
-
* @param {*} query
|
702
|
-
* @return {Array}
|
703
|
-
* @private
|
704
|
-
*/
|
705
784
|
|
785
|
+
try {
|
786
|
+
await cache.put(effectiveRequest, responseToCache);
|
787
|
+
} catch (error) {
|
788
|
+
// See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError
|
789
|
+
if (error.name === 'QuotaExceededError') {
|
790
|
+
await executeQuotaErrorCallbacks();
|
791
|
+
}
|
706
792
|
|
707
|
-
|
708
|
-
return (await this.getAllKeys(storeName, query, 1))[0];
|
793
|
+
throw error;
|
709
794
|
}
|
710
|
-
/**
|
711
|
-
* Polyfills the native `getAll()` method. Note, this is overridden at
|
712
|
-
* runtime if the browser supports the native method.
|
713
|
-
*
|
714
|
-
* @param {string} storeName
|
715
|
-
* @param {*} query
|
716
|
-
* @param {number} count
|
717
|
-
* @return {Array}
|
718
|
-
* @private
|
719
|
-
*/
|
720
|
-
|
721
795
|
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
796
|
+
for (let plugin of updatePlugins) {
|
797
|
+
await plugin[pluginEvents.CACHE_DID_UPDATE].call(plugin, {
|
798
|
+
cacheName,
|
799
|
+
event,
|
800
|
+
oldResponse,
|
801
|
+
newResponse: responseToCache,
|
802
|
+
request: effectiveRequest
|
726
803
|
});
|
727
804
|
}
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
includeKeys: true
|
745
|
-
})).map(({
|
746
|
-
key
|
747
|
-
}) => key);
|
748
|
-
}
|
749
|
-
/**
|
750
|
-
* Supports flexible lookup in an object store by specifying an index,
|
751
|
-
* query, direction, and count. This method returns an array of objects
|
752
|
-
* with the signature .
|
753
|
-
*
|
754
|
-
* @param {string} storeName
|
755
|
-
* @param {Object} [opts]
|
756
|
-
* @param {string} [opts.index] The index to use (if specified).
|
757
|
-
* @param {*} [opts.query]
|
758
|
-
* @param {IDBCursorDirection} [opts.direction]
|
759
|
-
* @param {number} [opts.count] The max number of results to return.
|
760
|
-
* @param {boolean} [opts.includeKeys] When true, the structure of the
|
761
|
-
* returned objects is changed from an array of values to an array of
|
762
|
-
* objects in the form {key, primaryKey, value}.
|
763
|
-
* @return {Array}
|
764
|
-
* @private
|
765
|
-
*/
|
805
|
+
};
|
806
|
+
/**
|
807
|
+
* This is a wrapper around cache.match().
|
808
|
+
*
|
809
|
+
* @param {Object} options
|
810
|
+
* @param {string} options.cacheName Name of the cache to match against.
|
811
|
+
* @param {Request} options.request The Request that will be used to look up
|
812
|
+
* cache entries.
|
813
|
+
* @param {Event} [options.event] The event that propted the action.
|
814
|
+
* @param {Object} [options.matchOptions] Options passed to cache.match().
|
815
|
+
* @param {Array<Object>} [options.plugins=[]] Array of plugins.
|
816
|
+
* @return {Response} A cached response if available.
|
817
|
+
*
|
818
|
+
* @private
|
819
|
+
* @memberof module:workbox-core
|
820
|
+
*/
|
766
821
|
|
767
822
|
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
823
|
+
const matchWrapper = async ({
|
824
|
+
cacheName,
|
825
|
+
request,
|
826
|
+
event,
|
827
|
+
matchOptions,
|
828
|
+
plugins = []
|
829
|
+
}) => {
|
830
|
+
const cache = await caches.open(cacheName);
|
831
|
+
const effectiveRequest = await _getEffectiveRequest({
|
832
|
+
plugins,
|
833
|
+
request,
|
834
|
+
mode: 'read'
|
835
|
+
});
|
836
|
+
let cachedResponse = await cache.match(effectiveRequest, matchOptions);
|
780
837
|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
838
|
+
{
|
839
|
+
if (cachedResponse) {
|
840
|
+
logger.debug(`Found a cached response in '${cacheName}'.`);
|
841
|
+
} else {
|
842
|
+
logger.debug(`No cached response found in '${cacheName}'.`);
|
843
|
+
}
|
844
|
+
}
|
785
845
|
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
value
|
796
|
-
} : value);
|
846
|
+
for (const plugin of plugins) {
|
847
|
+
if (pluginEvents.CACHED_RESPONSE_WILL_BE_USED in plugin) {
|
848
|
+
cachedResponse = await plugin[pluginEvents.CACHED_RESPONSE_WILL_BE_USED].call(plugin, {
|
849
|
+
cacheName,
|
850
|
+
event,
|
851
|
+
matchOptions,
|
852
|
+
cachedResponse,
|
853
|
+
request: effectiveRequest
|
854
|
+
});
|
797
855
|
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
856
|
+
{
|
857
|
+
if (cachedResponse) {
|
858
|
+
finalAssertExports.isInstance(cachedResponse, Response, {
|
859
|
+
moduleName: 'Plugin',
|
860
|
+
funcName: pluginEvents.CACHED_RESPONSE_WILL_BE_USED,
|
861
|
+
isReturnValueProblem: true
|
862
|
+
});
|
805
863
|
}
|
806
|
-
}
|
807
|
-
}
|
864
|
+
}
|
865
|
+
}
|
808
866
|
}
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
867
|
+
|
868
|
+
return cachedResponse;
|
869
|
+
};
|
870
|
+
/**
|
871
|
+
* This method will call cacheWillUpdate on the available plugins (or use
|
872
|
+
* status === 200) to determine if the Response is safe and valid to cache.
|
873
|
+
*
|
874
|
+
* @param {Object} options
|
875
|
+
* @param {Request} options.request
|
876
|
+
* @param {Response} options.response
|
877
|
+
* @param {Event} [options.event]
|
878
|
+
* @param {Array<Object>} [options.plugins=[]]
|
879
|
+
* @return {Promise<Response>}
|
880
|
+
*
|
881
|
+
* @private
|
882
|
+
* @memberof module:workbox-core
|
883
|
+
*/
|
826
884
|
|
827
885
|
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
886
|
+
const _isResponseSafeToCache = async ({
|
887
|
+
request,
|
888
|
+
response,
|
889
|
+
event,
|
890
|
+
plugins
|
891
|
+
}) => {
|
892
|
+
let responseToCache = response;
|
893
|
+
let pluginsUsed = false;
|
832
894
|
|
833
|
-
|
834
|
-
|
835
|
-
|
895
|
+
for (let plugin of plugins) {
|
896
|
+
if (pluginEvents.CACHE_WILL_UPDATE in plugin) {
|
897
|
+
pluginsUsed = true;
|
898
|
+
responseToCache = await plugin[pluginEvents.CACHE_WILL_UPDATE].call(plugin, {
|
899
|
+
request,
|
900
|
+
response: responseToCache,
|
901
|
+
event
|
902
|
+
});
|
836
903
|
|
837
|
-
|
904
|
+
{
|
905
|
+
if (responseToCache) {
|
906
|
+
finalAssertExports.isInstance(responseToCache, Response, {
|
907
|
+
moduleName: 'Plugin',
|
908
|
+
funcName: pluginEvents.CACHE_WILL_UPDATE,
|
909
|
+
isReturnValueProblem: true
|
910
|
+
});
|
911
|
+
}
|
912
|
+
}
|
838
913
|
|
839
|
-
|
840
|
-
|
914
|
+
if (!responseToCache) {
|
915
|
+
break;
|
916
|
+
}
|
917
|
+
}
|
841
918
|
}
|
842
|
-
/**
|
843
|
-
* Delegates async to a native IDBObjectStore method.
|
844
|
-
*
|
845
|
-
* @param {string} method The method name.
|
846
|
-
* @param {string} storeName The object store name.
|
847
|
-
* @param {string} type Can be `readonly` or `readwrite`.
|
848
|
-
* @param {...*} args The list of args to pass to the native method.
|
849
|
-
* @return {*} The result of the transaction.
|
850
|
-
* @private
|
851
|
-
*/
|
852
919
|
|
920
|
+
if (!pluginsUsed) {
|
921
|
+
{
|
922
|
+
if (!responseToCache.status === 200) {
|
923
|
+
if (responseToCache.status === 0) {
|
924
|
+
logger.warn(`The response for '${request.url}' is an opaque ` + `response. The caching strategy that you're using will not ` + `cache opaque responses by default.`);
|
925
|
+
} else {
|
926
|
+
logger.debug(`The response for '${request.url}' returned ` + `a status code of '${response.status}' and won't be cached as a ` + `result.`);
|
927
|
+
}
|
928
|
+
}
|
929
|
+
}
|
853
930
|
|
854
|
-
|
855
|
-
const callback = (txn, done) => {
|
856
|
-
txn.objectStore(storeName)[method](...args).onsuccess = ({
|
857
|
-
target
|
858
|
-
}) => {
|
859
|
-
done(target.result);
|
860
|
-
};
|
861
|
-
};
|
862
|
-
|
863
|
-
return await this.transaction([storeName], type, callback);
|
931
|
+
responseToCache = responseToCache.status === 200 ? responseToCache : null;
|
864
932
|
}
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
933
|
+
|
934
|
+
return responseToCache ? responseToCache : null;
|
935
|
+
};
|
936
|
+
/**
|
937
|
+
* Checks the list of plugins for the cacheKeyWillBeUsed callback, and
|
938
|
+
* executes any of those callbacks found in sequence. The final `Request` object
|
939
|
+
* returned by the last plugin is treated as the cache key for cache reads
|
940
|
+
* and/or writes.
|
941
|
+
*
|
942
|
+
* @param {Object} options
|
943
|
+
* @param {Request} options.request
|
944
|
+
* @param {string} options.mode
|
945
|
+
* @param {Array<Object>} [options.plugins=[]]
|
946
|
+
* @return {Promise<Request>}
|
947
|
+
*
|
948
|
+
* @private
|
949
|
+
* @memberof module:workbox-core
|
950
|
+
*/
|
871
951
|
|
872
952
|
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
* a new connection is somewhat slow.
|
881
|
-
* 2. Connections are automatically closed when the reference is
|
882
|
-
* garbage collected.
|
883
|
-
* The primary use case for needing to close a connection is when another
|
884
|
-
* reference (typically in another tab) needs to upgrade it and would be
|
885
|
-
* blocked by the current, open connection.
|
886
|
-
*
|
887
|
-
* @private
|
888
|
-
*/
|
953
|
+
const _getEffectiveRequest = async ({
|
954
|
+
request,
|
955
|
+
mode,
|
956
|
+
plugins
|
957
|
+
}) => {
|
958
|
+
const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, pluginEvents.CACHE_KEY_WILL_BE_USED);
|
959
|
+
let effectiveRequest = request;
|
889
960
|
|
961
|
+
for (const plugin of cacheKeyWillBeUsedPlugins) {
|
962
|
+
effectiveRequest = await plugin[pluginEvents.CACHE_KEY_WILL_BE_USED].call(plugin, {
|
963
|
+
mode,
|
964
|
+
request: effectiveRequest
|
965
|
+
});
|
890
966
|
|
891
|
-
|
892
|
-
|
893
|
-
|
967
|
+
if (typeof effectiveRequest === 'string') {
|
968
|
+
effectiveRequest = new Request(effectiveRequest);
|
969
|
+
}
|
894
970
|
|
895
|
-
|
971
|
+
{
|
972
|
+
finalAssertExports.isInstance(effectiveRequest, Request, {
|
973
|
+
moduleName: 'Plugin',
|
974
|
+
funcName: pluginEvents.CACHE_KEY_WILL_BE_USED,
|
975
|
+
isReturnValueProblem: true
|
976
|
+
});
|
896
977
|
}
|
897
978
|
}
|
898
979
|
|
899
|
-
|
900
|
-
// or global basis.
|
901
|
-
|
902
|
-
DBWrapper.prototype.OPEN_TIMEOUT = 2000; // Wrap native IDBObjectStore methods according to their mode.
|
903
|
-
|
904
|
-
const methodsToWrap = {
|
905
|
-
'readonly': ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],
|
906
|
-
'readwrite': ['add', 'put', 'clear', 'delete']
|
980
|
+
return effectiveRequest;
|
907
981
|
};
|
908
982
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
DBWrapper.prototype[method] = async function (storeName, ...args) {
|
914
|
-
return await this._call(method, storeName, mode, ...args);
|
915
|
-
};
|
916
|
-
}
|
917
|
-
}
|
918
|
-
}
|
983
|
+
const cacheWrapper = {
|
984
|
+
put: putWrapper,
|
985
|
+
match: matchWrapper
|
986
|
+
};
|
919
987
|
|
920
988
|
/*
|
921
989
|
Copyright 2018 Google LLC
|
@@ -925,413 +993,382 @@ this.workbox.core = (function (exports) {
|
|
925
993
|
https://opensource.org/licenses/MIT.
|
926
994
|
*/
|
927
995
|
/**
|
928
|
-
*
|
929
|
-
*
|
930
|
-
*
|
931
|
-
* reused in tests to delete databases without creating DBWrapper instances.
|
996
|
+
* A class that wraps common IndexedDB functionality in a promise-based API.
|
997
|
+
* It exposes all the underlying power and functionality of IndexedDB, but
|
998
|
+
* wraps the most commonly used features in a way that's much simpler to use.
|
932
999
|
*
|
933
|
-
* @param {string} name The database name.
|
934
1000
|
* @private
|
935
1001
|
*/
|
936
1002
|
|
937
|
-
|
938
|
-
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
943
|
-
|
944
|
-
|
945
|
-
|
1003
|
+
class DBWrapper {
|
1004
|
+
/**
|
1005
|
+
* @param {string} name
|
1006
|
+
* @param {number} version
|
1007
|
+
* @param {Object=} [callback]
|
1008
|
+
* @param {!Function} [callbacks.onupgradeneeded]
|
1009
|
+
* @param {!Function} [callbacks.onversionchange] Defaults to
|
1010
|
+
* DBWrapper.prototype._onversionchange when not specified.
|
1011
|
+
* @private
|
1012
|
+
*/
|
1013
|
+
constructor(name, version, {
|
1014
|
+
onupgradeneeded,
|
1015
|
+
onversionchange = this._onversionchange
|
1016
|
+
} = {}) {
|
1017
|
+
this._name = name;
|
1018
|
+
this._version = version;
|
1019
|
+
this._onupgradeneeded = onupgradeneeded;
|
1020
|
+
this._onversionchange = onversionchange; // If this is null, it means the database isn't open.
|
946
1021
|
|
947
|
-
|
948
|
-
|
949
|
-
|
1022
|
+
this._db = null;
|
1023
|
+
}
|
1024
|
+
/**
|
1025
|
+
* Returns the IDBDatabase instance (not normally needed).
|
1026
|
+
*
|
1027
|
+
* @private
|
1028
|
+
*/
|
950
1029
|
|
951
|
-
request.onsuccess = () => {
|
952
|
-
resolve();
|
953
|
-
};
|
954
|
-
});
|
955
|
-
};
|
956
1030
|
|
957
|
-
|
958
|
-
|
1031
|
+
get db() {
|
1032
|
+
return this._db;
|
1033
|
+
}
|
1034
|
+
/**
|
1035
|
+
* Opens a connected to an IDBDatabase, invokes any onupgradedneeded
|
1036
|
+
* callback, and added an onversionchange callback to the database.
|
1037
|
+
*
|
1038
|
+
* @return {IDBDatabase}
|
1039
|
+
* @private
|
1040
|
+
*/
|
959
1041
|
|
960
|
-
Use of this source code is governed by an MIT-style
|
961
|
-
license that can be found in the LICENSE file or at
|
962
|
-
https://opensource.org/licenses/MIT.
|
963
|
-
*/
|
964
|
-
const _cacheNameDetails = {
|
965
|
-
googleAnalytics: 'googleAnalytics',
|
966
|
-
precache: 'precache-v2',
|
967
|
-
prefix: 'workbox',
|
968
|
-
runtime: 'runtime',
|
969
|
-
suffix: self.registration.scope
|
970
|
-
};
|
971
1042
|
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
},
|
987
|
-
getPrecacheName: userCacheName => {
|
988
|
-
return userCacheName || _createCacheName(_cacheNameDetails.precache);
|
989
|
-
},
|
990
|
-
getPrefix: () => {
|
991
|
-
return _cacheNameDetails.prefix;
|
992
|
-
},
|
993
|
-
getRuntimeName: userCacheName => {
|
994
|
-
return userCacheName || _createCacheName(_cacheNameDetails.runtime);
|
995
|
-
},
|
996
|
-
getSuffix: () => {
|
997
|
-
return _cacheNameDetails.suffix;
|
998
|
-
}
|
999
|
-
};
|
1043
|
+
async open() {
|
1044
|
+
if (this._db) return;
|
1045
|
+
this._db = await new Promise((resolve, reject) => {
|
1046
|
+
// This flag is flipped to true if the timeout callback runs prior
|
1047
|
+
// to the request failing or succeeding. Note: we use a timeout instead
|
1048
|
+
// of an onblocked handler since there are cases where onblocked will
|
1049
|
+
// never never run. A timeout better handles all possible scenarios:
|
1050
|
+
// https://github.com/w3c/IndexedDB/issues/223
|
1051
|
+
let openRequestTimedOut = false;
|
1052
|
+
setTimeout(() => {
|
1053
|
+
openRequestTimedOut = true;
|
1054
|
+
reject(new Error('The open request was blocked and timed out'));
|
1055
|
+
}, this.OPEN_TIMEOUT);
|
1056
|
+
const openRequest = indexedDB.open(this._name, this._version);
|
1000
1057
|
|
1001
|
-
|
1002
|
-
Copyright 2018 Google LLC
|
1058
|
+
openRequest.onerror = () => reject(openRequest.error);
|
1003
1059
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
CACHED_RESPONSE_WILL_BE_USED: 'cachedResponseWillBeUsed',
|
1013
|
-
FETCH_DID_FAIL: 'fetchDidFail',
|
1014
|
-
FETCH_DID_SUCCEED: 'fetchDidSucceed',
|
1015
|
-
REQUEST_WILL_FETCH: 'requestWillFetch'
|
1016
|
-
};
|
1060
|
+
openRequest.onupgradeneeded = evt => {
|
1061
|
+
if (openRequestTimedOut) {
|
1062
|
+
openRequest.transaction.abort();
|
1063
|
+
evt.target.result.close();
|
1064
|
+
} else if (this._onupgradeneeded) {
|
1065
|
+
this._onupgradeneeded(evt);
|
1066
|
+
}
|
1067
|
+
};
|
1017
1068
|
|
1018
|
-
|
1019
|
-
|
1069
|
+
openRequest.onsuccess = ({
|
1070
|
+
target
|
1071
|
+
}) => {
|
1072
|
+
const db = target.result;
|
1020
1073
|
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1074
|
+
if (openRequestTimedOut) {
|
1075
|
+
db.close();
|
1076
|
+
} else {
|
1077
|
+
db.onversionchange = this._onversionchange.bind(this);
|
1078
|
+
resolve(db);
|
1079
|
+
}
|
1080
|
+
};
|
1081
|
+
});
|
1082
|
+
return this;
|
1028
1083
|
}
|
1029
|
-
|
1084
|
+
/**
|
1085
|
+
* Polyfills the native `getKey()` method. Note, this is overridden at
|
1086
|
+
* runtime if the browser supports the native method.
|
1087
|
+
*
|
1088
|
+
* @param {string} storeName
|
1089
|
+
* @param {*} query
|
1090
|
+
* @return {Array}
|
1091
|
+
* @private
|
1092
|
+
*/
|
1030
1093
|
|
1031
|
-
/*
|
1032
|
-
Copyright 2018 Google LLC
|
1033
1094
|
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1095
|
+
async getKey(storeName, query) {
|
1096
|
+
return (await this.getAllKeys(storeName, query, 1))[0];
|
1097
|
+
}
|
1098
|
+
/**
|
1099
|
+
* Polyfills the native `getAll()` method. Note, this is overridden at
|
1100
|
+
* runtime if the browser supports the native method.
|
1101
|
+
*
|
1102
|
+
* @param {string} storeName
|
1103
|
+
* @param {*} query
|
1104
|
+
* @param {number} count
|
1105
|
+
* @return {Array}
|
1106
|
+
* @private
|
1107
|
+
*/
|
1038
1108
|
|
1039
|
-
const getFriendlyURL = url => {
|
1040
|
-
const urlObj = new URL(url, location);
|
1041
1109
|
|
1042
|
-
|
1043
|
-
return
|
1110
|
+
async getAll(storeName, query, count) {
|
1111
|
+
return await this.getAllMatching(storeName, {
|
1112
|
+
query,
|
1113
|
+
count
|
1114
|
+
});
|
1044
1115
|
}
|
1116
|
+
/**
|
1117
|
+
* Polyfills the native `getAllKeys()` method. Note, this is overridden at
|
1118
|
+
* runtime if the browser supports the native method.
|
1119
|
+
*
|
1120
|
+
* @param {string} storeName
|
1121
|
+
* @param {*} query
|
1122
|
+
* @param {number} count
|
1123
|
+
* @return {Array}
|
1124
|
+
* @private
|
1125
|
+
*/
|
1045
1126
|
|
1046
|
-
return urlObj.href;
|
1047
|
-
};
|
1048
1127
|
|
1049
|
-
|
1050
|
-
|
1128
|
+
async getAllKeys(storeName, query, count) {
|
1129
|
+
return (await this.getAllMatching(storeName, {
|
1130
|
+
query,
|
1131
|
+
count,
|
1132
|
+
includeKeys: true
|
1133
|
+
})).map(({
|
1134
|
+
key
|
1135
|
+
}) => key);
|
1136
|
+
}
|
1137
|
+
/**
|
1138
|
+
* Supports flexible lookup in an object store by specifying an index,
|
1139
|
+
* query, direction, and count. This method returns an array of objects
|
1140
|
+
* with the signature .
|
1141
|
+
*
|
1142
|
+
* @param {string} storeName
|
1143
|
+
* @param {Object} [opts]
|
1144
|
+
* @param {string} [opts.index] The index to use (if specified).
|
1145
|
+
* @param {*} [opts.query]
|
1146
|
+
* @param {IDBCursorDirection} [opts.direction]
|
1147
|
+
* @param {number} [opts.count] The max number of results to return.
|
1148
|
+
* @param {boolean} [opts.includeKeys] When true, the structure of the
|
1149
|
+
* returned objects is changed from an array of values to an array of
|
1150
|
+
* objects in the form {key, primaryKey, value}.
|
1151
|
+
* @return {Array}
|
1152
|
+
* @private
|
1153
|
+
*/
|
1051
1154
|
|
1052
|
-
Use of this source code is governed by an MIT-style
|
1053
|
-
license that can be found in the LICENSE file or at
|
1054
|
-
https://opensource.org/licenses/MIT.
|
1055
|
-
*/
|
1056
|
-
/**
|
1057
|
-
* Wrapper around cache.put().
|
1058
|
-
*
|
1059
|
-
* Will call `cacheDidUpdate` on plugins if the cache was updated, using
|
1060
|
-
* `matchOptions` when determining what the old entry is.
|
1061
|
-
*
|
1062
|
-
* @param {Object} options
|
1063
|
-
* @param {string} options.cacheName
|
1064
|
-
* @param {Request} options.request
|
1065
|
-
* @param {Response} options.response
|
1066
|
-
* @param {Event} [options.event]
|
1067
|
-
* @param {Array<Object>} [options.plugins=[]]
|
1068
|
-
* @param {Object} [options.matchOptions]
|
1069
|
-
*
|
1070
|
-
* @private
|
1071
|
-
* @memberof module:workbox-core
|
1072
|
-
*/
|
1073
1155
|
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1085
|
-
|
1086
|
-
method: request.method
|
1087
|
-
});
|
1088
|
-
}
|
1089
|
-
}
|
1156
|
+
async getAllMatching(storeName, {
|
1157
|
+
index,
|
1158
|
+
query = null,
|
1159
|
+
// IE errors if query === `undefined`.
|
1160
|
+
direction = 'next',
|
1161
|
+
count,
|
1162
|
+
includeKeys
|
1163
|
+
} = {}) {
|
1164
|
+
return await this.transaction([storeName], 'readonly', (txn, done) => {
|
1165
|
+
const store = txn.objectStore(storeName);
|
1166
|
+
const target = index ? store.index(index) : store;
|
1167
|
+
const results = [];
|
1090
1168
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
});
|
1169
|
+
target.openCursor(query, direction).onsuccess = ({
|
1170
|
+
target
|
1171
|
+
}) => {
|
1172
|
+
const cursor = target.result;
|
1096
1173
|
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1174
|
+
if (cursor) {
|
1175
|
+
const {
|
1176
|
+
primaryKey,
|
1177
|
+
key,
|
1178
|
+
value
|
1179
|
+
} = cursor;
|
1180
|
+
results.push(includeKeys ? {
|
1181
|
+
primaryKey,
|
1182
|
+
key,
|
1183
|
+
value
|
1184
|
+
} : value);
|
1101
1185
|
|
1102
|
-
|
1103
|
-
|
1186
|
+
if (count && results.length >= count) {
|
1187
|
+
done(results);
|
1188
|
+
} else {
|
1189
|
+
cursor.continue();
|
1190
|
+
}
|
1191
|
+
} else {
|
1192
|
+
done(results);
|
1193
|
+
}
|
1194
|
+
};
|
1104
1195
|
});
|
1105
1196
|
}
|
1197
|
+
/**
|
1198
|
+
* Accepts a list of stores, a transaction type, and a callback and
|
1199
|
+
* performs a transaction. A promise is returned that resolves to whatever
|
1200
|
+
* value the callback chooses. The callback holds all the transaction logic
|
1201
|
+
* and is invoked with two arguments:
|
1202
|
+
* 1. The IDBTransaction object
|
1203
|
+
* 2. A `done` function, that's used to resolve the promise when
|
1204
|
+
* when the transaction is done, if passed a value, the promise is
|
1205
|
+
* resolved to that value.
|
1206
|
+
*
|
1207
|
+
* @param {Array<string>} storeNames An array of object store names
|
1208
|
+
* involved in the transaction.
|
1209
|
+
* @param {string} type Can be `readonly` or `readwrite`.
|
1210
|
+
* @param {!Function} callback
|
1211
|
+
* @return {*} The result of the transaction ran by the callback.
|
1212
|
+
* @private
|
1213
|
+
*/
|
1106
1214
|
|
1107
|
-
let responseToCache = await _isResponseSafeToCache({
|
1108
|
-
event,
|
1109
|
-
plugins,
|
1110
|
-
response,
|
1111
|
-
request: effectiveRequest
|
1112
|
-
});
|
1113
1215
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1216
|
+
async transaction(storeNames, type, callback) {
|
1217
|
+
await this.open();
|
1218
|
+
return await new Promise((resolve, reject) => {
|
1219
|
+
const txn = this._db.transaction(storeNames, type);
|
1118
1220
|
|
1119
|
-
|
1120
|
-
|
1221
|
+
txn.onabort = ({
|
1222
|
+
target
|
1223
|
+
}) => reject(target.error);
|
1121
1224
|
|
1122
|
-
|
1123
|
-
const updatePlugins = pluginUtils.filter(plugins, pluginEvents.CACHE_DID_UPDATE);
|
1124
|
-
let oldResponse = updatePlugins.length > 0 ? await matchWrapper({
|
1125
|
-
cacheName,
|
1126
|
-
matchOptions,
|
1127
|
-
request: effectiveRequest
|
1128
|
-
}) : null;
|
1225
|
+
txn.oncomplete = () => resolve();
|
1129
1226
|
|
1130
|
-
|
1131
|
-
|
1227
|
+
callback(txn, value => resolve(value));
|
1228
|
+
});
|
1132
1229
|
}
|
1230
|
+
/**
|
1231
|
+
* Delegates async to a native IDBObjectStore method.
|
1232
|
+
*
|
1233
|
+
* @param {string} method The method name.
|
1234
|
+
* @param {string} storeName The object store name.
|
1235
|
+
* @param {string} type Can be `readonly` or `readwrite`.
|
1236
|
+
* @param {...*} args The list of args to pass to the native method.
|
1237
|
+
* @return {*} The result of the transaction.
|
1238
|
+
* @private
|
1239
|
+
*/
|
1133
1240
|
|
1134
|
-
try {
|
1135
|
-
await cache.put(effectiveRequest, responseToCache);
|
1136
|
-
} catch (error) {
|
1137
|
-
// See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError
|
1138
|
-
if (error.name === 'QuotaExceededError') {
|
1139
|
-
await executeQuotaErrorCallbacks();
|
1140
|
-
}
|
1141
1241
|
|
1142
|
-
|
1242
|
+
async _call(method, storeName, type, ...args) {
|
1243
|
+
const callback = (txn, done) => {
|
1244
|
+
txn.objectStore(storeName)[method](...args).onsuccess = ({
|
1245
|
+
target
|
1246
|
+
}) => {
|
1247
|
+
done(target.result);
|
1248
|
+
};
|
1249
|
+
};
|
1250
|
+
|
1251
|
+
return await this.transaction([storeName], type, callback);
|
1143
1252
|
}
|
1253
|
+
/**
|
1254
|
+
* The default onversionchange handler, which closes the database so other
|
1255
|
+
* connections can open without being blocked.
|
1256
|
+
*
|
1257
|
+
* @private
|
1258
|
+
*/
|
1144
1259
|
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
event,
|
1149
|
-
oldResponse,
|
1150
|
-
newResponse: responseToCache,
|
1151
|
-
request: effectiveRequest
|
1152
|
-
});
|
1260
|
+
|
1261
|
+
_onversionchange() {
|
1262
|
+
this.close();
|
1153
1263
|
}
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
-
|
1167
|
-
* @private
|
1168
|
-
* @memberof module:workbox-core
|
1169
|
-
*/
|
1264
|
+
/**
|
1265
|
+
* Closes the connection opened by `DBWrapper.open()`. Generally this method
|
1266
|
+
* doesn't need to be called since:
|
1267
|
+
* 1. It's usually better to keep a connection open since opening
|
1268
|
+
* a new connection is somewhat slow.
|
1269
|
+
* 2. Connections are automatically closed when the reference is
|
1270
|
+
* garbage collected.
|
1271
|
+
* The primary use case for needing to close a connection is when another
|
1272
|
+
* reference (typically in another tab) needs to upgrade it and would be
|
1273
|
+
* blocked by the current, open connection.
|
1274
|
+
*
|
1275
|
+
* @private
|
1276
|
+
*/
|
1170
1277
|
|
1171
1278
|
|
1172
|
-
|
1173
|
-
|
1174
|
-
|
1175
|
-
event,
|
1176
|
-
matchOptions,
|
1177
|
-
plugins = []
|
1178
|
-
}) => {
|
1179
|
-
const cache = await caches.open(cacheName);
|
1180
|
-
const effectiveRequest = await _getEffectiveRequest({
|
1181
|
-
plugins,
|
1182
|
-
request,
|
1183
|
-
mode: 'read'
|
1184
|
-
});
|
1185
|
-
let cachedResponse = await cache.match(effectiveRequest, matchOptions);
|
1279
|
+
close() {
|
1280
|
+
if (this._db) {
|
1281
|
+
this._db.close();
|
1186
1282
|
|
1187
|
-
|
1188
|
-
if (cachedResponse) {
|
1189
|
-
logger.debug(`Found a cached response in '${cacheName}'.`);
|
1190
|
-
} else {
|
1191
|
-
logger.debug(`No cached response found in '${cacheName}'.`);
|
1283
|
+
this._db = null;
|
1192
1284
|
}
|
1193
1285
|
}
|
1194
1286
|
|
1195
|
-
|
1196
|
-
|
1197
|
-
cachedResponse = await plugin[pluginEvents.CACHED_RESPONSE_WILL_BE_USED].call(plugin, {
|
1198
|
-
cacheName,
|
1199
|
-
event,
|
1200
|
-
matchOptions,
|
1201
|
-
cachedResponse,
|
1202
|
-
request: effectiveRequest
|
1203
|
-
});
|
1287
|
+
} // Exposed to let users modify the default timeout on a per-instance
|
1288
|
+
// or global basis.
|
1204
1289
|
|
1205
|
-
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1209
|
-
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1290
|
+
DBWrapper.prototype.OPEN_TIMEOUT = 2000; // Wrap native IDBObjectStore methods according to their mode.
|
1291
|
+
|
1292
|
+
const methodsToWrap = {
|
1293
|
+
'readonly': ['get', 'count', 'getKey', 'getAll', 'getAllKeys'],
|
1294
|
+
'readwrite': ['add', 'put', 'clear', 'delete']
|
1295
|
+
};
|
1296
|
+
|
1297
|
+
for (const [mode, methods] of Object.entries(methodsToWrap)) {
|
1298
|
+
for (const method of methods) {
|
1299
|
+
if (method in IDBObjectStore.prototype) {
|
1300
|
+
// Don't use arrow functions here since we're outside of the class.
|
1301
|
+
DBWrapper.prototype[method] = async function (storeName, ...args) {
|
1302
|
+
return await this._call(method, storeName, mode, ...args);
|
1303
|
+
};
|
1214
1304
|
}
|
1215
1305
|
}
|
1306
|
+
}
|
1216
1307
|
|
1217
|
-
|
1218
|
-
|
1308
|
+
/*
|
1309
|
+
Copyright 2018 Google LLC
|
1310
|
+
|
1311
|
+
Use of this source code is governed by an MIT-style
|
1312
|
+
license that can be found in the LICENSE file or at
|
1313
|
+
https://opensource.org/licenses/MIT.
|
1314
|
+
*/
|
1219
1315
|
/**
|
1220
|
-
*
|
1221
|
-
*
|
1222
|
-
*
|
1223
|
-
*
|
1224
|
-
* @param {Request} options.request
|
1225
|
-
* @param {Response} options.response
|
1226
|
-
* @param {Event} [options.event]
|
1227
|
-
* @param {Array<Object>} [options.plugins=[]]
|
1228
|
-
* @return {Promise<Response>}
|
1316
|
+
* The Deferred class composes Promises in a way that allows for them to be
|
1317
|
+
* resolved or rejected from outside the constructor. In most cases promises
|
1318
|
+
* should be used directly, but Deferreds can be necessary when the logic to
|
1319
|
+
* resolve a promise must be separate.
|
1229
1320
|
*
|
1230
1321
|
* @private
|
1231
|
-
* @memberof module:workbox-core
|
1232
1322
|
*/
|
1233
1323
|
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
for (let plugin of plugins) {
|
1245
|
-
if (pluginEvents.CACHE_WILL_UPDATE in plugin) {
|
1246
|
-
pluginsUsed = true;
|
1247
|
-
responseToCache = await plugin[pluginEvents.CACHE_WILL_UPDATE].call(plugin, {
|
1248
|
-
request,
|
1249
|
-
response: responseToCache,
|
1250
|
-
event
|
1251
|
-
});
|
1252
|
-
|
1253
|
-
{
|
1254
|
-
if (responseToCache) {
|
1255
|
-
finalAssertExports.isInstance(responseToCache, Response, {
|
1256
|
-
moduleName: 'Plugin',
|
1257
|
-
funcName: pluginEvents.CACHE_WILL_UPDATE,
|
1258
|
-
isReturnValueProblem: true
|
1259
|
-
});
|
1260
|
-
}
|
1261
|
-
}
|
1262
|
-
|
1263
|
-
if (!responseToCache) {
|
1264
|
-
break;
|
1265
|
-
}
|
1266
|
-
}
|
1324
|
+
class Deferred {
|
1325
|
+
/**
|
1326
|
+
* Creates a promise and exposes its resolve and reject functions as methods.
|
1327
|
+
*/
|
1328
|
+
constructor() {
|
1329
|
+
this.promise = new Promise((resolve, reject) => {
|
1330
|
+
this.resolve = resolve;
|
1331
|
+
this.reject = reject;
|
1332
|
+
});
|
1267
1333
|
}
|
1268
1334
|
|
1269
|
-
|
1270
|
-
{
|
1271
|
-
if (!responseToCache.status === 200) {
|
1272
|
-
if (responseToCache.status === 0) {
|
1273
|
-
logger.warn(`The response for '${request.url}' is an opaque ` + `response. The caching strategy that you're using will not ` + `cache opaque responses by default.`);
|
1274
|
-
} else {
|
1275
|
-
logger.debug(`The response for '${request.url}' returned ` + `a status code of '${response.status}' and won't be cached as a ` + `result.`);
|
1276
|
-
}
|
1277
|
-
}
|
1278
|
-
}
|
1335
|
+
}
|
1279
1336
|
|
1280
|
-
|
1281
|
-
|
1337
|
+
/*
|
1338
|
+
Copyright 2018 Google LLC
|
1282
1339
|
|
1283
|
-
|
1284
|
-
|
1340
|
+
Use of this source code is governed by an MIT-style
|
1341
|
+
license that can be found in the LICENSE file or at
|
1342
|
+
https://opensource.org/licenses/MIT.
|
1343
|
+
*/
|
1285
1344
|
/**
|
1286
|
-
*
|
1287
|
-
*
|
1288
|
-
*
|
1289
|
-
*
|
1290
|
-
*
|
1291
|
-
* @param {Object} options
|
1292
|
-
* @param {Request} options.request
|
1293
|
-
* @param {string} options.mode
|
1294
|
-
* @param {Array<Object>} [options.plugins=[]]
|
1295
|
-
* @return {Promise<Request>}
|
1345
|
+
* Deletes the database.
|
1346
|
+
* Note: this is exported separately from the DBWrapper module because most
|
1347
|
+
* usages of IndexedDB in workbox dont need deleting, and this way it can be
|
1348
|
+
* reused in tests to delete databases without creating DBWrapper instances.
|
1296
1349
|
*
|
1350
|
+
* @param {string} name The database name.
|
1297
1351
|
* @private
|
1298
|
-
* @memberof module:workbox-core
|
1299
1352
|
*/
|
1300
1353
|
|
1354
|
+
const deleteDatabase = async name => {
|
1355
|
+
await new Promise((resolve, reject) => {
|
1356
|
+
const request = indexedDB.deleteDatabase(name);
|
1301
1357
|
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
const cacheKeyWillBeUsedPlugins = pluginUtils.filter(plugins, pluginEvents.CACHE_KEY_WILL_BE_USED);
|
1308
|
-
let effectiveRequest = request;
|
1309
|
-
|
1310
|
-
for (const plugin of cacheKeyWillBeUsedPlugins) {
|
1311
|
-
effectiveRequest = await plugin[pluginEvents.CACHE_KEY_WILL_BE_USED].call(plugin, {
|
1312
|
-
mode,
|
1313
|
-
request: effectiveRequest
|
1314
|
-
});
|
1315
|
-
|
1316
|
-
if (typeof effectiveRequest === 'string') {
|
1317
|
-
effectiveRequest = new Request(effectiveRequest);
|
1318
|
-
}
|
1319
|
-
|
1320
|
-
{
|
1321
|
-
finalAssertExports.isInstance(effectiveRequest, Request, {
|
1322
|
-
moduleName: 'Plugin',
|
1323
|
-
funcName: pluginEvents.CACHE_KEY_WILL_BE_USED,
|
1324
|
-
isReturnValueProblem: true
|
1325
|
-
});
|
1326
|
-
}
|
1327
|
-
}
|
1358
|
+
request.onerror = ({
|
1359
|
+
target
|
1360
|
+
}) => {
|
1361
|
+
reject(target.error);
|
1362
|
+
};
|
1328
1363
|
|
1329
|
-
|
1330
|
-
|
1364
|
+
request.onblocked = () => {
|
1365
|
+
reject(new Error('Delete blocked'));
|
1366
|
+
};
|
1331
1367
|
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1368
|
+
request.onsuccess = () => {
|
1369
|
+
resolve();
|
1370
|
+
};
|
1371
|
+
});
|
1335
1372
|
};
|
1336
1373
|
|
1337
1374
|
/*
|
@@ -1493,15 +1530,17 @@ this.workbox.core = (function (exports) {
|
|
1493
1530
|
*/
|
1494
1531
|
|
1495
1532
|
var _private = /*#__PURE__*/Object.freeze({
|
1496
|
-
DBWrapper: DBWrapper,
|
1497
|
-
deleteDatabase: deleteDatabase,
|
1498
|
-
WorkboxError: WorkboxError,
|
1499
1533
|
assert: finalAssertExports,
|
1500
1534
|
cacheNames: cacheNames,
|
1501
1535
|
cacheWrapper: cacheWrapper,
|
1536
|
+
DBWrapper: DBWrapper,
|
1537
|
+
Deferred: Deferred,
|
1538
|
+
deleteDatabase: deleteDatabase,
|
1539
|
+
executeQuotaErrorCallbacks: executeQuotaErrorCallbacks,
|
1502
1540
|
fetchWrapper: fetchWrapper,
|
1503
1541
|
getFriendlyURL: getFriendlyURL,
|
1504
|
-
logger: logger
|
1542
|
+
logger: logger,
|
1543
|
+
WorkboxError: WorkboxError
|
1505
1544
|
});
|
1506
1545
|
|
1507
1546
|
/*
|