UNPKG

39.4 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.strategies = (function (logger_mjs,assert_mjs,cacheNames_mjs,cacheWrapper_mjs,fetchWrapper_mjs,getFriendlyURL_mjs) {
3 'use strict';
4
5 try {
6 self.workbox.v['workbox:strategies:3.5.0'] = 1;
7 } catch (e) {} // eslint-disable-line
8
9 /*
10 Copyright 2018 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 const getFriendlyURL = url => {
25 const urlObj = new URL(url, location);
26 if (urlObj.origin === location.origin) {
27 return urlObj.pathname;
28 }
29 return urlObj.href;
30 };
31
32 var messages = {
33 strategyStart: (strategyName, request) => `Using ${strategyName} to ` + `respond to '${getFriendlyURL(request.url)}'`,
34 printFinalResponse: response => {
35 if (response) {
36 logger_mjs.logger.groupCollapsed(`View the final response here.`);
37 logger_mjs.logger.unprefixed.log(response);
38 logger_mjs.logger.groupEnd();
39 }
40 }
41 };
42
43 /*
44 Copyright 2018 Google Inc. All Rights Reserved.
45 Licensed under the Apache License, Version 2.0 (the "License");
46 you may not use this file except in compliance with the License.
47 You may obtain a copy of the License at
48
49 http://www.apache.org/licenses/LICENSE-2.0
50
51 Unless required by applicable law or agreed to in writing, software
52 distributed under the License is distributed on an "AS IS" BASIS,
53 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 See the License for the specific language governing permissions and
55 limitations under the License.
56 */
57
58 /**
59 * An implementation of a [cache-first]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network}
60 * request strategy.
61 *
62 * A cache first strategy is useful for assets that have been revisioned,
63 * such as URLs like `/styles/example.a8f5f1.css`, since they
64 * can be cached for long periods of time.
65 *
66 * @memberof workbox.strategies
67 */
68 class CacheFirst {
69 /**
70 * @param {Object} options
71 * @param {string} options.cacheName Cache name to store and retrieve
72 * requests. Defaults to cache names provided by
73 * [workbox-core]{@link workbox.core.cacheNames}.
74 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
75 * to use in conjunction with this caching strategy.
76 * @param {Object} options.fetchOptions Values passed along to the
77 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
78 * of all fetch() requests made by this strategy.
79 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
80 */
81 constructor(options = {}) {
82 this._cacheName = cacheNames_mjs.cacheNames.getRuntimeName(options.cacheName);
83 this._plugins = options.plugins || [];
84 this._fetchOptions = options.fetchOptions || null;
85 this._matchOptions = options.matchOptions || null;
86 }
87
88 /**
89 * This method will perform a request strategy and follows an API that
90 * will work with the
91 * [Workbox Router]{@link workbox.routing.Router}.
92 *
93 * @param {Object} input
94 * @param {FetchEvent} input.event The fetch event to run this strategy
95 * against.
96 * @return {Promise<Response>}
97 */
98 handle({ event }) {
99 var _this = this;
100
101 return babelHelpers.asyncToGenerator(function* () {
102 {
103 assert_mjs.assert.isInstance(event, FetchEvent, {
104 moduleName: 'workbox-strategies',
105 className: 'CacheFirst',
106 funcName: 'handle',
107 paramName: 'event'
108 });
109 }
110
111 return _this.makeRequest({
112 event,
113 request: event.request
114 });
115 })();
116 }
117
118 /**
119 * This method can be used to perform a make a standalone request outside the
120 * context of the [Workbox Router]{@link workbox.routing.Router}.
121 *
122 * See "[Advanced Recipes](https://developers.google.com/web/tools/workbox/guides/advanced-recipes#make-requests)"
123 * for more usage information.
124 *
125 * @param {Object} input
126 * @param {Request|string} input.request Either a
127 * [`Request`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Request}
128 * object, or a string URL, corresponding to the request to be made.
129 * @param {FetchEvent} [input.event] If provided, `event.waitUntil()` will be
130 * called automatically to extend the service worker's lifetime.
131 * @return {Promise<Response>}
132 */
133 makeRequest({ event, request }) {
134 var _this2 = this;
135
136 return babelHelpers.asyncToGenerator(function* () {
137 const logs = [];
138
139 if (typeof request === 'string') {
140 request = new Request(request);
141 }
142
143 {
144 assert_mjs.assert.isInstance(request, Request, {
145 moduleName: 'workbox-strategies',
146 className: 'CacheFirst',
147 funcName: 'makeRequest',
148 paramName: 'request'
149 });
150 }
151
152 let response = yield cacheWrapper_mjs.cacheWrapper.match(_this2._cacheName, request, _this2._matchOptions, _this2._plugins);
153
154 let error;
155 if (!response) {
156 {
157 logs.push(`No response found in the '${_this2._cacheName}' cache. ` + `Will respond with a network request.`);
158 }
159 try {
160 response = yield _this2._getFromNetwork(request, event);
161 } catch (err) {
162 error = err;
163 }
164
165 {
166 if (response) {
167 logs.push(`Got response from network.`);
168 } else {
169 logs.push(`Unable to get a response from the network.`);
170 }
171 }
172 } else {
173 {
174 logs.push(`Found a cached response in the '${_this2._cacheName}' cache.`);
175 }
176 }
177
178 {
179 logger_mjs.logger.groupCollapsed(messages.strategyStart('CacheFirst', request));
180 for (let log of logs) {
181 logger_mjs.logger.log(log);
182 }
183 messages.printFinalResponse(response);
184 logger_mjs.logger.groupEnd();
185 }
186
187 if (error) {
188 // Don't swallow error as we'll want it to throw and enable catch
189 // handlers in router.
190 throw error;
191 }
192
193 return response;
194 })();
195 }
196
197 /**
198 * Handles the network and cache part of CacheFirst.
199 *
200 * @param {Request} request
201 * @param {FetchEvent} [event]
202 * @return {Promise<Response>}
203 *
204 * @private
205 */
206 _getFromNetwork(request, event) {
207 var _this3 = this;
208
209 return babelHelpers.asyncToGenerator(function* () {
210 const response = yield fetchWrapper_mjs.fetchWrapper.fetch(request, _this3._fetchOptions, _this3._plugins, event ? event.preloadResponse : undefined);
211
212 // Keep the service worker while we put the request to the cache
213 const responseClone = response.clone();
214 const cachePutPromise = cacheWrapper_mjs.cacheWrapper.put(_this3._cacheName, request, responseClone, _this3._plugins);
215
216 if (event) {
217 try {
218 event.waitUntil(cachePutPromise);
219 } catch (error) {
220 {
221 logger_mjs.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_mjs.getFriendlyURL(event.request.url)}'.`);
222 }
223 }
224 }
225
226 return response;
227 })();
228 }
229 }
230
231 /*
232 Copyright 2018 Google Inc. All Rights Reserved.
233 Licensed under the Apache License, Version 2.0 (the "License");
234 you may not use this file except in compliance with the License.
235 You may obtain a copy of the License at
236
237 http://www.apache.org/licenses/LICENSE-2.0
238
239 Unless required by applicable law or agreed to in writing, software
240 distributed under the License is distributed on an "AS IS" BASIS,
241 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
242 See the License for the specific language governing permissions and
243 limitations under the License.
244 */
245
246 /**
247 * An implementation of a
248 * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}
249 * request strategy.
250 *
251 * This class is useful if you want to take advantage of any [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.
252 *
253 * @memberof workbox.strategies
254 */
255 class CacheOnly {
256 /**
257 * @param {Object} options
258 * @param {string} options.cacheName Cache name to store and retrieve
259 * requests. Defaults to cache names provided by
260 * [workbox-core]{@link workbox.core.cacheNames}.
261 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
262 * to use in conjunction with this caching strategy.
263 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
264 */
265 constructor(options = {}) {
266 this._cacheName = cacheNames_mjs.cacheNames.getRuntimeName(options.cacheName);
267 this._plugins = options.plugins || [];
268 this._matchOptions = options.matchOptions || null;
269 }
270
271 /**
272 * This method will perform a request strategy and follows an API that
273 * will work with the
274 * [Workbox Router]{@link workbox.routing.Router}.
275 *
276 * @param {Object} input
277 * @param {FetchEvent} input.event The fetch event to run this strategy
278 * against.
279 * @return {Promise<Response>}
280 */
281 handle({ event }) {
282 var _this = this;
283
284 return babelHelpers.asyncToGenerator(function* () {
285 {
286 assert_mjs.assert.isInstance(event, FetchEvent, {
287 moduleName: 'workbox-strategies',
288 className: 'CacheOnly',
289 funcName: 'handle',
290 paramName: 'event'
291 });
292 }
293
294 return _this.makeRequest({
295 event,
296 request: event.request
297 });
298 })();
299 }
300
301 /**
302 * This method can be used to perform a make a standalone request outside the
303 * context of the [Workbox Router]{@link workbox.routing.Router}.
304 *
305 * See "[Advanced Recipes](https://developers.google.com/web/tools/workbox/guides/advanced-recipes#make-requests)"
306 * for more usage information.
307 *
308 * @param {Object} input
309 * @param {Request|string} input.request Either a
310 * [`Request`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Request}
311 * object, or a string URL, corresponding to the request to be made.
312 * @param {FetchEvent} [input.event] If provided, `event.waitUntil()` will be
313 * called automatically to extend the service worker's lifetime.
314 * @return {Promise<Response>}
315 */
316 makeRequest({ event, request }) {
317 var _this2 = this;
318
319 return babelHelpers.asyncToGenerator(function* () {
320 if (typeof request === 'string') {
321 request = new Request(request);
322 }
323
324 {
325 assert_mjs.assert.isInstance(request, Request, {
326 moduleName: 'workbox-strategies',
327 className: 'CacheOnly',
328 funcName: 'makeRequest',
329 paramName: 'request'
330 });
331 }
332
333 const response = yield cacheWrapper_mjs.cacheWrapper.match(_this2._cacheName, request, _this2._matchOptions, _this2._plugins);
334
335 {
336 logger_mjs.logger.groupCollapsed(messages.strategyStart('CacheOnly', request));
337 if (response) {
338 logger_mjs.logger.log(`Found a cached response in the '${_this2._cacheName}'` + ` cache.`);
339 messages.printFinalResponse(response);
340 } else {
341 logger_mjs.logger.log(`No response found in the '${_this2._cacheName}' cache.`);
342 }
343 logger_mjs.logger.groupEnd();
344 }
345
346 return response;
347 })();
348 }
349 }
350
351 /*
352 Copyright 2016 Google Inc. All Rights Reserved.
353 Licensed under the Apache License, Version 2.0 (the "License");
354 you may not use this file except in compliance with the License.
355 You may obtain a copy of the License at
356
357 http://www.apache.org/licenses/LICENSE-2.0
358
359 Unless required by applicable law or agreed to in writing, software
360 distributed under the License is distributed on an "AS IS" BASIS,
361 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
362 See the License for the specific language governing permissions and
363 limitations under the License.
364 */
365
366 var cacheOkAndOpaquePlugin = {
367 /**
368 * Return return a response (i.e. allow caching) if the
369 * response is ok (i.e. 200) or is opaque.
370 *
371 * @param {Object} input
372 * @param {Response} input.response
373 * @return {Response|null}
374 *
375 * @private
376 */
377 cacheWillUpdate: ({ response }) => {
378 if (response.ok || response.status === 0) {
379 return response;
380 }
381 return null;
382 }
383 };
384
385 /*
386 Copyright 2018 Google Inc. All Rights Reserved.
387 Licensed under the Apache License, Version 2.0 (the "License");
388 you may not use this file except in compliance with the License.
389 You may obtain a copy of the License at
390
391 http://www.apache.org/licenses/LICENSE-2.0
392
393 Unless required by applicable law or agreed to in writing, software
394 distributed under the License is distributed on an "AS IS" BASIS,
395 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
396 See the License for the specific language governing permissions and
397 limitations under the License.
398 */
399
400 /**
401 * An implementation of a
402 * [network first]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-falling-back-to-cache}
403 * request strategy.
404 *
405 * By default, this strategy will cache responses with a 200 status code as
406 * well as [opaque responses]{@link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests}.
407 * Opaque responses are are cross-origin requests where the response doesn't
408 * support [CORS]{@link https://enable-cors.org/}.
409 *
410 * @memberof workbox.strategies
411 */
412 class NetworkFirst {
413 /**
414 * @param {Object} options
415 * @param {string} options.cacheName Cache name to store and retrieve
416 * requests. Defaults to cache names provided by
417 * [workbox-core]{@link workbox.core.cacheNames}.
418 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
419 * to use in conjunction with this caching strategy.
420 * @param {Object} options.fetchOptions Values passed along to the
421 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
422 * of all fetch() requests made by this strategy.
423 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
424 * @param {number} options.networkTimeoutSeconds If set, any network requests
425 * that fail to respond within the timeout will fallback to the cache.
426 *
427 * This option can be used to combat
428 * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}"
429 * scenarios.
430 */
431 constructor(options = {}) {
432 this._cacheName = cacheNames_mjs.cacheNames.getRuntimeName(options.cacheName);
433
434 if (options.plugins) {
435 let isUsingCacheWillUpdate = options.plugins.some(plugin => !!plugin.cacheWillUpdate);
436 this._plugins = isUsingCacheWillUpdate ? options.plugins : [cacheOkAndOpaquePlugin, ...options.plugins];
437 } else {
438 // No plugins passed in, use the default plugin.
439 this._plugins = [cacheOkAndOpaquePlugin];
440 }
441
442 this._networkTimeoutSeconds = options.networkTimeoutSeconds;
443 {
444 if (this._networkTimeoutSeconds) {
445 assert_mjs.assert.isType(this._networkTimeoutSeconds, 'number', {
446 moduleName: 'workbox-strategies',
447 className: 'NetworkFirst',
448 funcName: 'constructor',
449 paramName: 'networkTimeoutSeconds'
450 });
451 }
452 }
453
454 this._fetchOptions = options.fetchOptions || null;
455 this._matchOptions = options.matchOptions || null;
456 }
457
458 /**
459 * This method will perform a request strategy and follows an API that
460 * will work with the
461 * [Workbox Router]{@link workbox.routing.Router}.
462 *
463 * @param {Object} input
464 * @param {FetchEvent} input.event The fetch event to run this strategy
465 * against.
466 * @return {Promise<Response>}
467 */
468 handle({ event }) {
469 var _this = this;
470
471 return babelHelpers.asyncToGenerator(function* () {
472 {
473 assert_mjs.assert.isInstance(event, FetchEvent, {
474 moduleName: 'workbox-strategies',
475 className: 'NetworkFirst',
476 funcName: 'handle',
477 paramName: 'event'
478 });
479 }
480
481 return _this.makeRequest({
482 event,
483 request: event.request
484 });
485 })();
486 }
487
488 /**
489 * This method can be used to perform a make a standalone request outside the
490 * context of the [Workbox Router]{@link workbox.routing.Router}.
491 *
492 * See "[Advanced Recipes](https://developers.google.com/web/tools/workbox/guides/advanced-recipes#make-requests)"
493 * for more usage information.
494 *
495 * @param {Object} input
496 * @param {Request|string} input.request Either a
497 * [`Request`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Request}
498 * object, or a string URL, corresponding to the request to be made.
499 * @param {FetchEvent} [input.event] If provided, `event.waitUntil()` will be
500 * called automatically to extend the service worker's lifetime.
501 * @return {Promise<Response>}
502 */
503 makeRequest({ event, request }) {
504 var _this2 = this;
505
506 return babelHelpers.asyncToGenerator(function* () {
507 const logs = [];
508
509 if (typeof request === 'string') {
510 request = new Request(request);
511 }
512
513 {
514 assert_mjs.assert.isInstance(request, Request, {
515 moduleName: 'workbox-strategies',
516 className: 'NetworkFirst',
517 funcName: 'handle',
518 paramName: 'makeRequest'
519 });
520 }
521
522 const promises = [];
523 let timeoutId;
524
525 if (_this2._networkTimeoutSeconds) {
526 const { id, promise } = _this2._getTimeoutPromise(request, logs);
527 timeoutId = id;
528 promises.push(promise);
529 }
530
531 const networkPromise = _this2._getNetworkPromise(timeoutId, event, request, logs);
532 promises.push(networkPromise);
533
534 // Promise.race() will resolve as soon as the first promise resolves.
535 let response = yield Promise.race(promises);
536 // If Promise.race() resolved with null, it might be due to a network
537 // timeout + a cache miss. If that were to happen, we'd rather wait until
538 // the networkPromise resolves instead of returning null.
539 // Note that it's fine to await an already-resolved promise, so we don't
540 // have to check to see if it's still "in flight".
541 if (!response) {
542 response = yield networkPromise;
543 }
544
545 {
546 logger_mjs.logger.groupCollapsed(messages.strategyStart('NetworkFirst', request));
547 for (let log of logs) {
548 logger_mjs.logger.log(log);
549 }
550 messages.printFinalResponse(response);
551 logger_mjs.logger.groupEnd();
552 }
553
554 return response;
555 })();
556 }
557
558 /**
559 * @param {Request} request
560 * @param {Array} logs A reference to the logs array
561 * @return {Promise<Response>}
562 *
563 * @private
564 */
565 _getTimeoutPromise(request, logs) {
566 var _this3 = this;
567
568 let timeoutId;
569 const timeoutPromise = new Promise(resolve => {
570 const onNetworkTimeout = (() => {
571 var _ref = babelHelpers.asyncToGenerator(function* () {
572 {
573 logs.push(`Timing out the network response at ` + `${_this3._networkTimeoutSeconds} seconds.`);
574 }
575
576 resolve((yield _this3._respondFromCache(request)));
577 });
578
579 return function onNetworkTimeout() {
580 return _ref.apply(this, arguments);
581 };
582 })();
583
584 timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000);
585 });
586
587 return {
588 promise: timeoutPromise,
589 id: timeoutId
590 };
591 }
592
593 /**
594 * @param {number} timeoutId
595 * @param {FetchEvent|null} event
596 * @param {Request} request
597 * @param {Array} logs A reference to the logs Array.
598 * @return {Promise<Response>}
599 *
600 * @private
601 */
602 _getNetworkPromise(timeoutId, event, request, logs) {
603 var _this4 = this;
604
605 return babelHelpers.asyncToGenerator(function* () {
606 let error;
607 let response;
608 try {
609 response = yield fetchWrapper_mjs.fetchWrapper.fetch(request, _this4._fetchOptions, _this4._plugins, event ? event.preloadResponse : undefined);
610 } catch (err) {
611 error = err;
612 }
613
614 if (timeoutId) {
615 clearTimeout(timeoutId);
616 }
617
618 {
619 if (response) {
620 logs.push(`Got response from network.`);
621 } else {
622 logs.push(`Unable to get a response from the network. Will respond ` + `with a cached response.`);
623 }
624 }
625
626 if (error || !response) {
627 response = yield _this4._respondFromCache(request);
628 {
629 if (response) {
630 logs.push(`Found a cached response in the '${_this4._cacheName}'` + ` cache.`);
631 } else {
632 logs.push(`No response found in the '${_this4._cacheName}' cache.`);
633 }
634 }
635 } else {
636 // Keep the service worker alive while we put the request in the cache
637 const responseClone = response.clone();
638 const cachePut = cacheWrapper_mjs.cacheWrapper.put(_this4._cacheName, request, responseClone, _this4._plugins);
639
640 if (event) {
641 try {
642 // The event has been responded to so we can keep the SW alive to
643 // respond to the request
644 event.waitUntil(cachePut);
645 } catch (err) {
646 {
647 logger_mjs.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_mjs.getFriendlyURL(event.request.url)}'.`);
648 }
649 }
650 }
651 }
652
653 return response;
654 })();
655 }
656
657 /**
658 * Used if the network timeouts or fails to make the request.
659 *
660 * @param {Request} request The fetchEvent request to match in the cache
661 * @return {Promise<Object>}
662 *
663 * @private
664 */
665 _respondFromCache(request) {
666 return cacheWrapper_mjs.cacheWrapper.match(this._cacheName, request, this._matchOptions, this._plugins);
667 }
668 }
669
670 /*
671 Copyright 2018 Google Inc. All Rights Reserved.
672 Licensed under the Apache License, Version 2.0 (the "License");
673 you may not use this file except in compliance with the License.
674 You may obtain a copy of the License at
675
676 http://www.apache.org/licenses/LICENSE-2.0
677
678 Unless required by applicable law or agreed to in writing, software
679 distributed under the License is distributed on an "AS IS" BASIS,
680 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
681 See the License for the specific language governing permissions and
682 limitations under the License.
683 */
684
685 /**
686 * An implementation of a
687 * [network-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-only}
688 * request strategy.
689 *
690 * This class is useful if you want to take advantage of any [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.
691 *
692 * @memberof workbox.strategies
693 */
694 class NetworkOnly {
695 /**
696 * @param {Object} options
697 * @param {string} options.cacheName Cache name to store and retrieve
698 * requests. Defaults to cache names provided by
699 * [workbox-core]{@link workbox.core.cacheNames}.
700 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
701 * to use in conjunction with this caching strategy.
702 * @param {Object} options.fetchOptions Values passed along to the
703 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
704 * of all fetch() requests made by this strategy.
705 */
706 constructor(options = {}) {
707 this._cacheName = cacheNames_mjs.cacheNames.getRuntimeName(options.cacheName);
708 this._plugins = options.plugins || [];
709 this._fetchOptions = options.fetchOptions || null;
710 }
711
712 /**
713 * This method will perform a request strategy and follows an API that
714 * will work with the
715 * [Workbox Router]{@link workbox.routing.Router}.
716 *
717 * @param {Object} input
718 * @param {FetchEvent} input.event The fetch event to run this strategy
719 * against.
720 * @return {Promise<Response>}
721 */
722 handle({ event }) {
723 var _this = this;
724
725 return babelHelpers.asyncToGenerator(function* () {
726 {
727 assert_mjs.assert.isInstance(event, FetchEvent, {
728 moduleName: 'workbox-strategies',
729 className: 'NetworkOnly',
730 funcName: 'handle',
731 paramName: 'event'
732 });
733 }
734
735 return _this.makeRequest({
736 event,
737 request: event.request
738 });
739 })();
740 }
741
742 /**
743 * This method can be used to perform a make a standalone request outside the
744 * context of the [Workbox Router]{@link workbox.routing.Router}.
745 *
746 * See "[Advanced Recipes](https://developers.google.com/web/tools/workbox/guides/advanced-recipes#make-requests)"
747 * for more usage information.
748 *
749 * @param {Object} input
750 * @param {Request|string} input.request Either a
751 * [`Request`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Request}
752 * object, or a string URL, corresponding to the request to be made.
753 * @param {FetchEvent} [input.event] If provided, `event.waitUntil()` will be
754 * called automatically to extend the service worker's lifetime.
755 * @return {Promise<Response>}
756 */
757 makeRequest({ event, request }) {
758 var _this2 = this;
759
760 return babelHelpers.asyncToGenerator(function* () {
761 if (typeof request === 'string') {
762 request = new Request(request);
763 }
764
765 {
766 assert_mjs.assert.isInstance(request, Request, {
767 moduleName: 'workbox-strategies',
768 className: 'NetworkOnly',
769 funcName: 'handle',
770 paramName: 'request'
771 });
772 }
773
774 let error;
775 let response;
776 try {
777 response = yield fetchWrapper_mjs.fetchWrapper.fetch(request, _this2._fetchOptions, _this2._plugins, event ? event.preloadResponse : undefined);
778 } catch (err) {
779 error = err;
780 }
781
782 {
783 logger_mjs.logger.groupCollapsed(messages.strategyStart('NetworkOnly', request));
784 if (response) {
785 logger_mjs.logger.log(`Got response from network.`);
786 } else {
787 logger_mjs.logger.log(`Unable to get a response from the network.`);
788 }
789 messages.printFinalResponse(response);
790 logger_mjs.logger.groupEnd();
791 }
792
793 // If there was an error thrown, re-throw it to ensure the Routers
794 // catch handler is triggered.
795 if (error) {
796 throw error;
797 }
798
799 return response;
800 })();
801 }
802 }
803
804 /*
805 Copyright 2018 Google Inc. All Rights Reserved.
806 Licensed under the Apache License, Version 2.0 (the "License");
807 you may not use this file except in compliance with the License.
808 You may obtain a copy of the License at
809
810 http://www.apache.org/licenses/LICENSE-2.0
811
812 Unless required by applicable law or agreed to in writing, software
813 distributed under the License is distributed on an "AS IS" BASIS,
814 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
815 See the License for the specific language governing permissions and
816 limitations under the License.
817 */
818
819 /**
820 * An implementation of a
821 * [stale-while-revalidate]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#stale-while-revalidate}
822 * request strategy.
823 *
824 * Resources are requested from both the cache and the network in parallel.
825 * The strategy will respond with the cached version if available, otherwise
826 * wait for the network response. The cache is updated with the network response
827 * with each successful request.
828 *
829 * By default, this strategy will cache responses with a 200 status code as
830 * well as [opaque responses]{@link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests}.
831 * Opaque responses are are cross-origin requests where the response doesn't
832 * support [CORS]{@link https://enable-cors.org/}.
833 *
834 * @memberof workbox.strategies
835 */
836 class StaleWhileRevalidate {
837 /**
838 * @param {Object} options
839 * @param {string} options.cacheName Cache name to store and retrieve
840 * requests. Defaults to cache names provided by
841 * [workbox-core]{@link workbox.core.cacheNames}.
842 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
843 * to use in conjunction with this caching strategy.
844 * @param {Object} options.fetchOptions Values passed along to the
845 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
846 * of all fetch() requests made by this strategy.
847 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
848 */
849 constructor(options = {}) {
850 this._cacheName = cacheNames_mjs.cacheNames.getRuntimeName(options.cacheName);
851 this._plugins = options.plugins || [];
852
853 if (options.plugins) {
854 let isUsingCacheWillUpdate = options.plugins.some(plugin => !!plugin.cacheWillUpdate);
855 this._plugins = isUsingCacheWillUpdate ? options.plugins : [cacheOkAndOpaquePlugin, ...options.plugins];
856 } else {
857 // No plugins passed in, use the default plugin.
858 this._plugins = [cacheOkAndOpaquePlugin];
859 }
860
861 this._fetchOptions = options.fetchOptions || null;
862 this._matchOptions = options.matchOptions || null;
863 }
864
865 /**
866 * This method will perform a request strategy and follows an API that
867 * will work with the
868 * [Workbox Router]{@link workbox.routing.Router}.
869 *
870 * @param {Object} input
871 * @param {FetchEvent} input.event The fetch event to run this strategy
872 * against.
873 * @return {Promise<Response>}
874 */
875 handle({ event }) {
876 var _this = this;
877
878 return babelHelpers.asyncToGenerator(function* () {
879 {
880 assert_mjs.assert.isInstance(event, FetchEvent, {
881 moduleName: 'workbox-strategies',
882 className: 'StaleWhileRevalidate',
883 funcName: 'handle',
884 paramName: 'event'
885 });
886 }
887
888 return _this.makeRequest({
889 event,
890 request: event.request
891 });
892 })();
893 }
894
895 /**
896 * This method can be used to perform a make a standalone request outside the
897 * context of the [Workbox Router]{@link workbox.routing.Router}.
898 *
899 * See "[Advanced Recipes](https://developers.google.com/web/tools/workbox/guides/advanced-recipes#make-requests)"
900 * for more usage information.
901 *
902 * @param {Object} input
903 * @param {Request|string} input.request Either a
904 * [`Request`]{@link https://developer.mozilla.org/en-US/docs/Web/API/Request}
905 * object, or a string URL, corresponding to the request to be made.
906 * @param {FetchEvent} [input.event] If provided, `event.waitUntil()` will be
907 * called automatically to extend the service worker's lifetime.
908 * @return {Promise<Response>}
909 */
910 makeRequest({ event, request }) {
911 var _this2 = this;
912
913 return babelHelpers.asyncToGenerator(function* () {
914 const logs = [];
915
916 if (typeof request === 'string') {
917 request = new Request(request);
918 }
919
920 {
921 assert_mjs.assert.isInstance(request, Request, {
922 moduleName: 'workbox-strategies',
923 className: 'StaleWhileRevalidate',
924 funcName: 'handle',
925 paramName: 'request'
926 });
927 }
928
929 const fetchAndCachePromise = _this2._getFromNetwork(request, event);
930
931 let response = yield cacheWrapper_mjs.cacheWrapper.match(_this2._cacheName, request, _this2._matchOptions, _this2._plugins);
932
933 if (response) {
934 {
935 logs.push(`Found a cached response in the '${_this2._cacheName}'` + ` cache. Will update with the network response in the background.`);
936 }
937
938 if (event) {
939 try {
940 event.waitUntil(fetchAndCachePromise);
941 } catch (error) {
942 {
943 logger_mjs.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_mjs.getFriendlyURL(event.request.url)}'.`);
944 }
945 }
946 }
947 } else {
948 {
949 logs.push(`No response found in the '${_this2._cacheName}' cache. ` + `Will wait for the network response.`);
950 }
951 response = yield fetchAndCachePromise;
952 }
953
954 {
955 logger_mjs.logger.groupCollapsed(messages.strategyStart('StaleWhileRevalidate', request));
956 for (let log of logs) {
957 logger_mjs.logger.log(log);
958 }
959 messages.printFinalResponse(response);
960 logger_mjs.logger.groupEnd();
961 }
962
963 return response;
964 })();
965 }
966
967 /**
968 * @param {Request} request
969 * @param {FetchEvent} [event]
970 * @return {Promise<Response>}
971 *
972 * @private
973 */
974 _getFromNetwork(request, event) {
975 var _this3 = this;
976
977 return babelHelpers.asyncToGenerator(function* () {
978 const response = yield fetchWrapper_mjs.fetchWrapper.fetch(request, _this3._fetchOptions, _this3._plugins, event ? event.preloadResponse : undefined);
979
980 const cachePutPromise = cacheWrapper_mjs.cacheWrapper.put(_this3._cacheName, request, response.clone(), _this3._plugins);
981
982 if (event) {
983 try {
984 event.waitUntil(cachePutPromise);
985 } catch (error) {
986 {
987 logger_mjs.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_mjs.getFriendlyURL(event.request.url)}'.`);
988 }
989 }
990 }
991
992 return response;
993 })();
994 }
995 }
996
997 /*
998 Copyright 2017 Google Inc.
999
1000 Licensed under the Apache License, Version 2.0 (the "License");
1001 you may not use this file except in compliance with the License.
1002 You may obtain a copy of the License at
1003
1004 https://www.apache.org/licenses/LICENSE-2.0
1005
1006 Unless required by applicable law or agreed to in writing, software
1007 distributed under the License is distributed on an "AS IS" BASIS,
1008 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1009 See the License for the specific language governing permissions and
1010 limitations under the License.
1011 */
1012
1013 var publicAPI = /*#__PURE__*/Object.freeze({
1014 CacheFirst: CacheFirst,
1015 CacheOnly: CacheOnly,
1016 NetworkFirst: NetworkFirst,
1017 NetworkOnly: NetworkOnly,
1018 StaleWhileRevalidate: StaleWhileRevalidate
1019 });
1020
1021 /*
1022 Copyright 2016 Google Inc. All Rights Reserved.
1023 Licensed under the Apache License, Version 2.0 (the "License");
1024 you may not use this file except in compliance with the License.
1025 You may obtain a copy of the License at
1026
1027 http://www.apache.org/licenses/LICENSE-2.0
1028
1029 Unless required by applicable law or agreed to in writing, software
1030 distributed under the License is distributed on an "AS IS" BASIS,
1031 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1032 See the License for the specific language governing permissions and
1033 limitations under the License.
1034 */
1035
1036 /**
1037 * @function workbox.strategies.cacheFirst
1038 * @param {Object} options See the {@link workbox.strategies.CacheFirst}
1039 * constructor for more info.
1040 */
1041
1042 /**
1043 * @function workbox.strategies.cacheOnly
1044 * @param {Object} options See the {@link workbox.strategies.CacheOnly}
1045 * constructor for more info.
1046 */
1047
1048 /**
1049 * @function workbox.strategies.networkFirst
1050 * @param {Object} options See the {@link workbox.strategies.NetworkFirst}
1051 * constructor for more info.
1052 */
1053
1054 /**
1055 * @function workbox.strategies.networkOnly
1056 * @param {Object} options See the {@link workbox.strategies.NetworkOnly}
1057 * constructor for more info.
1058 */
1059
1060 /**
1061 * @function workbox.strategies.staleWhileRevalidate
1062 * @param {Object} options See the
1063 * {@link workbox.strategies.StaleWhileRevalidate} constructor for more info.
1064 */
1065
1066 const mapping = {
1067 cacheFirst: CacheFirst,
1068 cacheOnly: CacheOnly,
1069 networkFirst: NetworkFirst,
1070 networkOnly: NetworkOnly,
1071 staleWhileRevalidate: StaleWhileRevalidate
1072 };
1073
1074 const defaultExport = {};
1075 Object.keys(mapping).forEach(keyName => {
1076 defaultExport[keyName] = (options = {}) => {
1077 const StrategyClass = mapping[keyName];
1078 return new StrategyClass(Object.assign(options));
1079 };
1080 });
1081
1082 /*
1083 Copyright 2017 Google Inc.
1084
1085 Licensed under the Apache License, Version 2.0 (the "License");
1086 you may not use this file except in compliance with the License.
1087 You may obtain a copy of the License at
1088
1089 https://www.apache.org/licenses/LICENSE-2.0
1090
1091 Unless required by applicable law or agreed to in writing, software
1092 distributed under the License is distributed on an "AS IS" BASIS,
1093 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1094 See the License for the specific language governing permissions and
1095 limitations under the License.
1096 */
1097
1098 const finalExport = Object.assign(defaultExport, publicAPI);
1099
1100 return finalExport;
1101
1102}(workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private));
1103
1104//# sourceMappingURL=workbox-strategies.dev.js.map