UNPKG

14.7 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.broadcastUpdate = (function (exports,WorkboxError_mjs,logger_mjs,assert_mjs) {
3 'use strict';
4
5 try {
6 self.workbox.v['workbox:broadcast-cache-update:3.5.0'] = 1;
7 } catch (e) {} // eslint-disable-line
8
9 /*
10 Copyright 2016 Google Inc. All Rights Reserved.
11 Licensed under the Apache License, Version 2.0 (the "License");
12 you may not use this file except in compliance with the License.
13 You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 /**
25 * Given two `Response's`, compares several header values to see if they are
26 * the same or not.
27 *
28 * @param {Response} firstResponse
29 * @param {Response} secondResponse
30 * @param {Array<string>} headersToCheck
31 * @return {boolean}
32 *
33 * @memberof workbox.broadcastUpdate
34 * @private
35 */
36 const responsesAreSame = (firstResponse, secondResponse, headersToCheck) => {
37 {
38 if (!(firstResponse instanceof Response && secondResponse instanceof Response)) {
39 throw new WorkboxError_mjs.WorkboxError('invalid-responses-are-same-args');
40 }
41 }
42
43 const atLeastOneHeaderAvailable = headersToCheck.some(header => {
44 return firstResponse.headers.has(header) && secondResponse.headers.has(header);
45 });
46
47 if (!atLeastOneHeaderAvailable) {
48 {
49 logger_mjs.logger.warn(`Unable to determine where the response has been updated ` + `because none of the headers that would be checked are present.`);
50 logger_mjs.logger.debug(`Attempting to compare the following: `, firstResponse, secondResponse, headersToCheck);
51 }
52
53 // Just return true, indicating the that responses are the same, since we
54 // can't determine otherwise.
55 return true;
56 }
57
58 return headersToCheck.every(header => {
59 const headerStateComparison = firstResponse.headers.has(header) === secondResponse.headers.has(header);
60 const headerValueComparison = firstResponse.headers.get(header) === secondResponse.headers.get(header);
61
62 return headerStateComparison && headerValueComparison;
63 });
64 };
65
66 /*
67 Copyright 2016 Google Inc. All Rights Reserved.
68 Licensed under the Apache License, Version 2.0 (the "License");
69 you may not use this file except in compliance with the License.
70 You may obtain a copy of the License at
71
72 http://www.apache.org/licenses/LICENSE-2.0
73
74 Unless required by applicable law or agreed to in writing, software
75 distributed under the License is distributed on an "AS IS" BASIS,
76 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
77 See the License for the specific language governing permissions and
78 limitations under the License.
79 */
80
81 var messageTypes = {
82 CACHE_UPDATED: 'CACHE_UPDATED'
83 };
84
85 /*
86 Copyright 2016 Google Inc. All Rights Reserved.
87 Licensed under the Apache License, Version 2.0 (the "License");
88 you may not use this file except in compliance with the License.
89 You may obtain a copy of the License at
90
91 http://www.apache.org/licenses/LICENSE-2.0
92
93 Unless required by applicable law or agreed to in writing, software
94 distributed under the License is distributed on an "AS IS" BASIS,
95 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
96 See the License for the specific language governing permissions and
97 limitations under the License.
98 */
99
100 /**
101 * You would not normally call this method directly; it's called automatically
102 * by an instance of the {@link BroadcastCacheUpdate} class. It's exposed here
103 * for the benefit of developers who would rather not use the full
104 * `BroadcastCacheUpdate` implementation.
105 *
106 * Calling this will dispatch a message on the provided
107 * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel}
108 * to notify interested subscribers about a change to a cached resource.
109 *
110 * The message that's posted has a formation inspired by the
111 * [Flux standard action](https://github.com/acdlite/flux-standard-action#introduction)
112 * format like so:
113 *
114 * ```
115 * {
116 * type: 'CACHE_UPDATED',
117 * meta: 'workbox-broadcast-cache-update',
118 * payload: {
119 * cacheName: 'the-cache-name',
120 * updatedUrl: 'https://example.com/'
121 * }
122 * }
123 * ```
124 *
125 * (Usage of [Flux](https://facebook.github.io/flux/) itself is not at
126 * all required.)
127 *
128 * @param {BroadcastChannel} channel The `BroadcastChannel` to use.
129 * @param {string} cacheName The name of the cache in which the updated
130 * `Response` was stored.
131 * @param {string} url The URL associated with the updated `Response`.
132 * @param {string} source A string identifying this library as the source
133 * of the update message.
134 *
135 * @memberof workbox.broadcastUpdate
136 */
137 const broadcastUpdate = (channel, cacheName, url, source) => {
138 // There are browsers which support service workers but don't support the
139 // Broadcast Channel API.
140 // See https://github.com/GoogleChrome/workbox/issues/1304
141 if (!('BroadcastChannel' in self && channel)) {
142 {
143 logger_mjs.logger.debug(`${url} was updated, but the Broadcast Channel API is not ` + `available in the current browser.`);
144 }
145 return;
146 }
147
148 {
149 assert_mjs.assert.isInstance(channel, BroadcastChannel, {
150 moduleName: 'workbox-broadcast-cache-update',
151 className: '~',
152 funcName: 'broadcastUpdate',
153 paramName: 'channel'
154 });
155 assert_mjs.assert.isType(cacheName, 'string', {
156 moduleName: 'workbox-broadcast-cache-update',
157 className: '~',
158 funcName: 'broadcastUpdate',
159 paramName: 'cacheName'
160 });
161 assert_mjs.assert.isType(url, 'string', {
162 moduleName: 'workbox-broadcast-cache-update',
163 className: '~',
164 funcName: 'broadcastUpdate',
165 paramName: 'url'
166 });
167 assert_mjs.assert.isType(source, 'string', {
168 moduleName: 'workbox-broadcast-cache-update',
169 className: '~',
170 funcName: 'broadcastUpdate',
171 paramName: 'source'
172 });
173 }
174
175 channel.postMessage({
176 type: messageTypes.CACHE_UPDATED,
177 meta: source,
178 payload: {
179 cacheName: cacheName,
180 updatedUrl: url
181 }
182 });
183 };
184
185 /*
186 Copyright 2016 Google Inc. All Rights Reserved.
187 Licensed under the Apache License, Version 2.0 (the "License");
188 you may not use this file except in compliance with the License.
189 You may obtain a copy of the License at
190
191 http://www.apache.org/licenses/LICENSE-2.0
192
193 Unless required by applicable law or agreed to in writing, software
194 distributed under the License is distributed on an "AS IS" BASIS,
195 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
196 See the License for the specific language governing permissions and
197 limitations under the License.
198 */
199
200 /**
201 * Uses the [Broadcast Channel API]{@link https://developers.google.com/web/updates/2016/09/broadcastchannel}
202 * to notify interested parties when a cached response has been updated.
203 *
204 * For efficiency's sake, the underlying response bodies are not compared;
205 * only specific response headers are checked.
206 *
207 * @memberof workbox.broadcastUpdate
208 */
209 class BroadcastCacheUpdate {
210 /**
211 * Construct a BroadcastCacheUpdate instance with a specific `channelName` to
212 * broadcast messages on
213 *
214 * @param {string} channelName The name that will be used when creating
215 * the `BroadcastChannel`.
216 * @param {Object} options
217 * @param {Array<string>}
218 * [options.headersToCheck=['content-length', 'etag', 'last-modified']] A
219 * list of headers that will be used to determine whether the responses
220 * differ.
221 * @param {string} [options.source='workbox-broadcast-cache-update'] An
222 * attribution value that indicates where the update originated.
223 */
224 constructor(channelName, { headersToCheck, source } = {}) {
225 {
226 if (typeof channelName !== 'string' || channelName.length === 0) {
227 throw new WorkboxError_mjs.WorkboxError('channel-name-required');
228 }
229 }
230
231 this._channelName = channelName;
232 this._headersToCheck = headersToCheck || ['content-length', 'etag', 'last-modified'];
233 this._source = source || 'workbox-broadcast-cache-update';
234
235 // TODO assert typeof headersToCheck instanceof Array
236 }
237
238 /**
239 * @return {BroadcastChannel|undefined} The BroadcastChannel instance used for
240 * broadcasting updates, or undefined if the browser doesn't support the
241 * Broadcast Channel API.
242 *
243 * @private
244 */
245 _getChannel() {
246 if ('BroadcastChannel' in self && !this._channel) {
247 this._channel = new BroadcastChannel(this._channelName);
248 }
249 return this._channel;
250 }
251
252 /**
253 * Compare two [Responses](https://developer.mozilla.org/en-US/docs/Web/API/Response)
254 * and send a message via the
255 * {@link https://developers.google.com/web/updates/2016/09/broadcastchannel|Broadcast Channel API}
256 * if they differ.
257 *
258 * Neither of the Responses can be {@link http://stackoverflow.com/questions/39109789|opaque}.
259 *
260 * @param {Response} firstResponse First responses to compare.
261 * @param {Response} secondResponse Second responses to compare.
262 * @param {string} url The URL of the updated request.
263 * @param {string} cacheName Name of the cache the responses belong to.
264 * This is included in the message posted on the broadcast channel.
265 */
266 notifyIfUpdated(firstResponse, secondResponse, url, cacheName) {
267 if (!responsesAreSame(firstResponse, secondResponse, this._headersToCheck)) {
268 broadcastUpdate(this._getChannel(), cacheName, url, this._source);
269 }
270 }
271 }
272
273 /*
274 Copyright 2016 Google Inc. All Rights Reserved.
275 Licensed under the Apache License, Version 2.0 (the "License");
276 you may not use this file except in compliance with the License.
277 You may obtain a copy of the License at
278
279 http://www.apache.org/licenses/LICENSE-2.0
280
281 Unless required by applicable law or agreed to in writing, software
282 distributed under the License is distributed on an "AS IS" BASIS,
283 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
284 See the License for the specific language governing permissions and
285 limitations under the License.
286 */
287
288 /**
289 * This plugin will automatically broadcast a message whenever a cached response
290 * is updated.
291 *
292 * @memberof workbox.broadcastUpdate
293 */
294 class Plugin {
295 /**
296 * Construct a new instance with a specific `channelName` to
297 * broadcast messages on
298 *
299 * @param {string} channelName The name that will be used when creating
300 * the `BroadcastChannel`.
301 * @param {Object} options
302 * @param {Array<string>}
303 * [options.headersToCheck=['content-length', 'etag', 'last-modified']] A
304 * list of headers that will be used to determine whether the responses
305 * differ.
306 * @param {string} [options.source='workbox-broadcast-cache-update'] An
307 * attribution value that indicates where the update originated.
308 */
309 constructor(channelName, options) {
310 this._broadcastUpdate = new BroadcastCacheUpdate(channelName, options);
311 }
312 /**
313 * A "lifecycle" callback that will be triggered automatically by the
314 * `workbox-sw` and `workbox-runtime-caching` handlers when an entry is
315 * added to a cache.
316 *
317 * @private
318 * @param {Object} input The input object to this function.
319 * @param {string} input.cacheName Name of the cache the responses belong to.
320 * @param {Response} [input.oldResponse] The previous cached value, if any.
321 * @param {Response} input.newResponse The new value in the cache.
322 */
323 cacheDidUpdate({ cacheName, oldResponse, newResponse, request }) {
324 {
325 assert_mjs.assert.isType(cacheName, 'string', {
326 moduleName: 'workbox-broadcast-cache-update',
327 className: 'Plugin',
328 funcName: 'cacheDidUpdate',
329 paramName: 'cacheName'
330 });
331 assert_mjs.assert.isInstance(newResponse, Response, {
332 moduleName: 'workbox-broadcast-cache-update',
333 className: 'Plugin',
334 funcName: 'cacheDidUpdate',
335 paramName: 'newResponse'
336 });
337 assert_mjs.assert.isInstance(request, Request, {
338 moduleName: 'workbox-broadcast-cache-update',
339 className: 'Plugin',
340 funcName: 'cacheDidUpdate',
341 paramName: 'request'
342 });
343 }
344
345 if (!oldResponse) {
346 // Without a two responses there is nothing to compare.
347 return;
348 }
349
350 this._broadcastUpdate.notifyIfUpdated(oldResponse, newResponse, request.url, cacheName);
351 }
352 }
353
354 /*
355 Copyright 2017 Google Inc.
356
357 Licensed under the Apache License, Version 2.0 (the "License");
358 you may not use this file except in compliance with the License.
359 You may obtain a copy of the License at
360
361 https://www.apache.org/licenses/LICENSE-2.0
362
363 Unless required by applicable law or agreed to in writing, software
364 distributed under the License is distributed on an "AS IS" BASIS,
365 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
366 See the License for the specific language governing permissions and
367 limitations under the License.
368 */
369
370 /*
371 Copyright 2017 Google Inc.
372
373 Licensed under the Apache License, Version 2.0 (the "License");
374 you may not use this file except in compliance with the License.
375 You may obtain a copy of the License at
376
377 https://www.apache.org/licenses/LICENSE-2.0
378
379 Unless required by applicable law or agreed to in writing, software
380 distributed under the License is distributed on an "AS IS" BASIS,
381 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
382 See the License for the specific language governing permissions and
383 limitations under the License.
384 */
385
386 exports.BroadcastCacheUpdate = BroadcastCacheUpdate;
387 exports.Plugin = Plugin;
388 exports.broadcastUpdate = broadcastUpdate;
389 exports.messageTypes = messageTypes;
390
391 return exports;
392
393}({},workbox.core._private,workbox.core._private,workbox.core._private));
394
395//# sourceMappingURL=workbox-broadcast-cache-update.dev.js.map