UNPKG

29.7 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.strategies = (function (exports, assert_js, cacheNames_js, cacheWrapper_js, fetchWrapper_js, getFriendlyURL_js, logger_js, WorkboxError_js) {
3 'use strict';
4
5 try {
6 self['workbox:strategies:5.1.4'] && _();
7 } catch (e) {}
8
9 /*
10 Copyright 2018 Google LLC
11
12 Use of this source code is governed by an MIT-style
13 license that can be found in the LICENSE file or at
14 https://opensource.org/licenses/MIT.
15 */
16 const messages = {
17 strategyStart: (strategyName, request) => `Using ${strategyName} to respond to '${getFriendlyURL_js.getFriendlyURL(request.url)}'`,
18 printFinalResponse: response => {
19 if (response) {
20 logger_js.logger.groupCollapsed(`View the final response here.`);
21 logger_js.logger.log(response || '[No response returned]');
22 logger_js.logger.groupEnd();
23 }
24 }
25 };
26
27 /*
28 Copyright 2018 Google LLC
29
30 Use of this source code is governed by an MIT-style
31 license that can be found in the LICENSE file or at
32 https://opensource.org/licenses/MIT.
33 */
34 /**
35 * An implementation of a [cache-first]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-falling-back-to-network}
36 * request strategy.
37 *
38 * A cache first strategy is useful for assets that have been revisioned,
39 * such as URLs like `/styles/example.a8f5f1.css`, since they
40 * can be cached for long periods of time.
41 *
42 * If the network request fails, and there is no cache match, this will throw
43 * a `WorkboxError` exception.
44 *
45 * @memberof module:workbox-strategies
46 */
47
48 class CacheFirst {
49 /**
50 * @param {Object} options
51 * @param {string} options.cacheName Cache name to store and retrieve
52 * requests. Defaults to cache names provided by
53 * [workbox-core]{@link module:workbox-core.cacheNames}.
54 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
55 * to use in conjunction with this caching strategy.
56 * @param {Object} options.fetchOptions Values passed along to the
57 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
58 * of all fetch() requests made by this strategy.
59 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
60 */
61 constructor(options = {}) {
62 this._cacheName = cacheNames_js.cacheNames.getRuntimeName(options.cacheName);
63 this._plugins = options.plugins || [];
64 this._fetchOptions = options.fetchOptions;
65 this._matchOptions = options.matchOptions;
66 }
67 /**
68 * This method will perform a request strategy and follows an API that
69 * will work with the
70 * [Workbox Router]{@link module:workbox-routing.Router}.
71 *
72 * @param {Object} options
73 * @param {Request|string} options.request A request to run this strategy for.
74 * @param {Event} [options.event] The event that triggered the request.
75 * @return {Promise<Response>}
76 */
77
78
79 async handle({
80 event,
81 request
82 }) {
83 const logs = [];
84
85 if (typeof request === 'string') {
86 request = new Request(request);
87 }
88
89 {
90 assert_js.assert.isInstance(request, Request, {
91 moduleName: 'workbox-strategies',
92 className: 'CacheFirst',
93 funcName: 'makeRequest',
94 paramName: 'request'
95 });
96 }
97
98 let response = await cacheWrapper_js.cacheWrapper.match({
99 cacheName: this._cacheName,
100 request,
101 event,
102 matchOptions: this._matchOptions,
103 plugins: this._plugins
104 });
105 let error;
106
107 if (!response) {
108 {
109 logs.push(`No response found in the '${this._cacheName}' cache. ` + `Will respond with a network request.`);
110 }
111
112 try {
113 response = await this._getFromNetwork(request, event);
114 } catch (err) {
115 error = err;
116 }
117
118 {
119 if (response) {
120 logs.push(`Got response from network.`);
121 } else {
122 logs.push(`Unable to get a response from the network.`);
123 }
124 }
125 } else {
126 {
127 logs.push(`Found a cached response in the '${this._cacheName}' cache.`);
128 }
129 }
130
131 {
132 logger_js.logger.groupCollapsed(messages.strategyStart('CacheFirst', request));
133
134 for (const log of logs) {
135 logger_js.logger.log(log);
136 }
137
138 messages.printFinalResponse(response);
139 logger_js.logger.groupEnd();
140 }
141
142 if (!response) {
143 throw new WorkboxError_js.WorkboxError('no-response', {
144 url: request.url,
145 error
146 });
147 }
148
149 return response;
150 }
151 /**
152 * Handles the network and cache part of CacheFirst.
153 *
154 * @param {Request} request
155 * @param {Event} [event]
156 * @return {Promise<Response>}
157 *
158 * @private
159 */
160
161
162 async _getFromNetwork(request, event) {
163 const response = await fetchWrapper_js.fetchWrapper.fetch({
164 request,
165 event,
166 fetchOptions: this._fetchOptions,
167 plugins: this._plugins
168 }); // Keep the service worker while we put the request to the cache
169
170 const responseClone = response.clone();
171 const cachePutPromise = cacheWrapper_js.cacheWrapper.put({
172 cacheName: this._cacheName,
173 request,
174 response: responseClone,
175 event,
176 plugins: this._plugins
177 });
178
179 if (event) {
180 try {
181 event.waitUntil(cachePutPromise);
182 } catch (error) {
183 {
184 logger_js.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_js.getFriendlyURL(request.url)}'.`);
185 }
186 }
187 }
188
189 return response;
190 }
191
192 }
193
194 /*
195 Copyright 2018 Google LLC
196
197 Use of this source code is governed by an MIT-style
198 license that can be found in the LICENSE file or at
199 https://opensource.org/licenses/MIT.
200 */
201 /**
202 * An implementation of a
203 * [cache-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-only}
204 * request strategy.
205 *
206 * This class is useful if you want to take advantage of any
207 * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.
208 *
209 * If there is no cache match, this will throw a `WorkboxError` exception.
210 *
211 * @memberof module:workbox-strategies
212 */
213
214 class CacheOnly {
215 /**
216 * @param {Object} options
217 * @param {string} options.cacheName Cache name to store and retrieve
218 * requests. Defaults to cache names provided by
219 * [workbox-core]{@link module:workbox-core.cacheNames}.
220 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
221 * to use in conjunction with this caching strategy.
222 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
223 */
224 constructor(options = {}) {
225 this._cacheName = cacheNames_js.cacheNames.getRuntimeName(options.cacheName);
226 this._plugins = options.plugins || [];
227 this._matchOptions = options.matchOptions;
228 }
229 /**
230 * This method will perform a request strategy and follows an API that
231 * will work with the
232 * [Workbox Router]{@link module:workbox-routing.Router}.
233 *
234 * @param {Object} options
235 * @param {Request|string} options.request A request to run this strategy for.
236 * @param {Event} [options.event] The event that triggered the request.
237 * @return {Promise<Response>}
238 */
239
240
241 async handle({
242 event,
243 request
244 }) {
245 if (typeof request === 'string') {
246 request = new Request(request);
247 }
248
249 {
250 assert_js.assert.isInstance(request, Request, {
251 moduleName: 'workbox-strategies',
252 className: 'CacheOnly',
253 funcName: 'makeRequest',
254 paramName: 'request'
255 });
256 }
257
258 const response = await cacheWrapper_js.cacheWrapper.match({
259 cacheName: this._cacheName,
260 request,
261 event,
262 matchOptions: this._matchOptions,
263 plugins: this._plugins
264 });
265
266 {
267 logger_js.logger.groupCollapsed(messages.strategyStart('CacheOnly', request));
268
269 if (response) {
270 logger_js.logger.log(`Found a cached response in the '${this._cacheName}'` + ` cache.`);
271 messages.printFinalResponse(response);
272 } else {
273 logger_js.logger.log(`No response found in the '${this._cacheName}' cache.`);
274 }
275
276 logger_js.logger.groupEnd();
277 }
278
279 if (!response) {
280 throw new WorkboxError_js.WorkboxError('no-response', {
281 url: request.url
282 });
283 }
284
285 return response;
286 }
287
288 }
289
290 /*
291 Copyright 2018 Google LLC
292
293 Use of this source code is governed by an MIT-style
294 license that can be found in the LICENSE file or at
295 https://opensource.org/licenses/MIT.
296 */
297 const cacheOkAndOpaquePlugin = {
298 /**
299 * Returns a valid response (to allow caching) if the status is 200 (OK) or
300 * 0 (opaque).
301 *
302 * @param {Object} options
303 * @param {Response} options.response
304 * @return {Response|null}
305 *
306 * @private
307 */
308 cacheWillUpdate: async ({
309 response
310 }) => {
311 if (response.status === 200 || response.status === 0) {
312 return response;
313 }
314
315 return null;
316 }
317 };
318
319 /*
320 Copyright 2018 Google LLC
321
322 Use of this source code is governed by an MIT-style
323 license that can be found in the LICENSE file or at
324 https://opensource.org/licenses/MIT.
325 */
326 /**
327 * An implementation of a
328 * [network first]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-falling-back-to-cache}
329 * request strategy.
330 *
331 * By default, this strategy will cache responses with a 200 status code as
332 * well as [opaque responses]{@link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests}.
333 * Opaque responses are are cross-origin requests where the response doesn't
334 * support [CORS]{@link https://enable-cors.org/}.
335 *
336 * If the network request fails, and there is no cache match, this will throw
337 * a `WorkboxError` exception.
338 *
339 * @memberof module:workbox-strategies
340 */
341
342 class NetworkFirst {
343 /**
344 * @param {Object} options
345 * @param {string} options.cacheName Cache name to store and retrieve
346 * requests. Defaults to cache names provided by
347 * [workbox-core]{@link module:workbox-core.cacheNames}.
348 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
349 * to use in conjunction with this caching strategy.
350 * @param {Object} options.fetchOptions Values passed along to the
351 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
352 * of all fetch() requests made by this strategy.
353 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
354 * @param {number} options.networkTimeoutSeconds If set, any network requests
355 * that fail to respond within the timeout will fallback to the cache.
356 *
357 * This option can be used to combat
358 * "[lie-fi]{@link https://developers.google.com/web/fundamentals/performance/poor-connectivity/#lie-fi}"
359 * scenarios.
360 */
361 constructor(options = {}) {
362 this._cacheName = cacheNames_js.cacheNames.getRuntimeName(options.cacheName);
363
364 if (options.plugins) {
365 const isUsingCacheWillUpdate = options.plugins.some(plugin => !!plugin.cacheWillUpdate);
366 this._plugins = isUsingCacheWillUpdate ? options.plugins : [cacheOkAndOpaquePlugin, ...options.plugins];
367 } else {
368 // No plugins passed in, use the default plugin.
369 this._plugins = [cacheOkAndOpaquePlugin];
370 }
371
372 this._networkTimeoutSeconds = options.networkTimeoutSeconds || 0;
373
374 {
375 if (this._networkTimeoutSeconds) {
376 assert_js.assert.isType(this._networkTimeoutSeconds, 'number', {
377 moduleName: 'workbox-strategies',
378 className: 'NetworkFirst',
379 funcName: 'constructor',
380 paramName: 'networkTimeoutSeconds'
381 });
382 }
383 }
384
385 this._fetchOptions = options.fetchOptions;
386 this._matchOptions = options.matchOptions;
387 }
388 /**
389 * This method will perform a request strategy and follows an API that
390 * will work with the
391 * [Workbox Router]{@link module:workbox-routing.Router}.
392 *
393 * @param {Object} options
394 * @param {Request|string} options.request A request to run this strategy for.
395 * @param {Event} [options.event] The event that triggered the request.
396 * @return {Promise<Response>}
397 */
398
399
400 async handle({
401 event,
402 request
403 }) {
404 const logs = [];
405
406 if (typeof request === 'string') {
407 request = new Request(request);
408 }
409
410 {
411 assert_js.assert.isInstance(request, Request, {
412 moduleName: 'workbox-strategies',
413 className: 'NetworkFirst',
414 funcName: 'handle',
415 paramName: 'makeRequest'
416 });
417 }
418
419 const promises = [];
420 let timeoutId;
421
422 if (this._networkTimeoutSeconds) {
423 const {
424 id,
425 promise
426 } = this._getTimeoutPromise({
427 request,
428 event,
429 logs
430 });
431
432 timeoutId = id;
433 promises.push(promise);
434 }
435
436 const networkPromise = this._getNetworkPromise({
437 timeoutId,
438 request,
439 event,
440 logs
441 });
442
443 promises.push(networkPromise); // Promise.race() will resolve as soon as the first promise resolves.
444
445 let response = await Promise.race(promises); // If Promise.race() resolved with null, it might be due to a network
446 // timeout + a cache miss. If that were to happen, we'd rather wait until
447 // the networkPromise resolves instead of returning null.
448 // Note that it's fine to await an already-resolved promise, so we don't
449 // have to check to see if it's still "in flight".
450
451 if (!response) {
452 response = await networkPromise;
453 }
454
455 {
456 logger_js.logger.groupCollapsed(messages.strategyStart('NetworkFirst', request));
457
458 for (const log of logs) {
459 logger_js.logger.log(log);
460 }
461
462 messages.printFinalResponse(response);
463 logger_js.logger.groupEnd();
464 }
465
466 if (!response) {
467 throw new WorkboxError_js.WorkboxError('no-response', {
468 url: request.url
469 });
470 }
471
472 return response;
473 }
474 /**
475 * @param {Object} options
476 * @param {Request} options.request
477 * @param {Array} options.logs A reference to the logs array
478 * @param {Event} [options.event]
479 * @return {Promise<Response>}
480 *
481 * @private
482 */
483
484
485 _getTimeoutPromise({
486 request,
487 logs,
488 event
489 }) {
490 let timeoutId;
491 const timeoutPromise = new Promise(resolve => {
492 const onNetworkTimeout = async () => {
493 {
494 logs.push(`Timing out the network response at ` + `${this._networkTimeoutSeconds} seconds.`);
495 }
496
497 resolve(await this._respondFromCache({
498 request,
499 event
500 }));
501 };
502
503 timeoutId = setTimeout(onNetworkTimeout, this._networkTimeoutSeconds * 1000);
504 });
505 return {
506 promise: timeoutPromise,
507 id: timeoutId
508 };
509 }
510 /**
511 * @param {Object} options
512 * @param {number|undefined} options.timeoutId
513 * @param {Request} options.request
514 * @param {Array} options.logs A reference to the logs Array.
515 * @param {Event} [options.event]
516 * @return {Promise<Response>}
517 *
518 * @private
519 */
520
521
522 async _getNetworkPromise({
523 timeoutId,
524 request,
525 logs,
526 event
527 }) {
528 let error;
529 let response;
530
531 try {
532 response = await fetchWrapper_js.fetchWrapper.fetch({
533 request,
534 event,
535 fetchOptions: this._fetchOptions,
536 plugins: this._plugins
537 });
538 } catch (err) {
539 error = err;
540 }
541
542 if (timeoutId) {
543 clearTimeout(timeoutId);
544 }
545
546 {
547 if (response) {
548 logs.push(`Got response from network.`);
549 } else {
550 logs.push(`Unable to get a response from the network. Will respond ` + `with a cached response.`);
551 }
552 }
553
554 if (error || !response) {
555 response = await this._respondFromCache({
556 request,
557 event
558 });
559
560 {
561 if (response) {
562 logs.push(`Found a cached response in the '${this._cacheName}'` + ` cache.`);
563 } else {
564 logs.push(`No response found in the '${this._cacheName}' cache.`);
565 }
566 }
567 } else {
568 // Keep the service worker alive while we put the request in the cache
569 const responseClone = response.clone();
570 const cachePut = cacheWrapper_js.cacheWrapper.put({
571 cacheName: this._cacheName,
572 request,
573 response: responseClone,
574 event,
575 plugins: this._plugins
576 });
577
578 if (event) {
579 try {
580 // The event has been responded to so we can keep the SW alive to
581 // respond to the request
582 event.waitUntil(cachePut);
583 } catch (err) {
584 {
585 logger_js.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_js.getFriendlyURL(request.url)}'.`);
586 }
587 }
588 }
589 }
590
591 return response;
592 }
593 /**
594 * Used if the network timeouts or fails to make the request.
595 *
596 * @param {Object} options
597 * @param {Request} request The request to match in the cache
598 * @param {Event} [options.event]
599 * @return {Promise<Object>}
600 *
601 * @private
602 */
603
604
605 _respondFromCache({
606 event,
607 request
608 }) {
609 return cacheWrapper_js.cacheWrapper.match({
610 cacheName: this._cacheName,
611 request,
612 event,
613 matchOptions: this._matchOptions,
614 plugins: this._plugins
615 });
616 }
617
618 }
619
620 /*
621 Copyright 2018 Google LLC
622
623 Use of this source code is governed by an MIT-style
624 license that can be found in the LICENSE file or at
625 https://opensource.org/licenses/MIT.
626 */
627 /**
628 * An implementation of a
629 * [network-only]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#network-only}
630 * request strategy.
631 *
632 * This class is useful if you want to take advantage of any
633 * [Workbox plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}.
634 *
635 * If the network request fails, this will throw a `WorkboxError` exception.
636 *
637 * @memberof module:workbox-strategies
638 */
639
640 class NetworkOnly {
641 /**
642 * @param {Object} options
643 * @param {string} options.cacheName Cache name to store and retrieve
644 * requests. Defaults to cache names provided by
645 * [workbox-core]{@link module:workbox-core.cacheNames}.
646 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
647 * to use in conjunction with this caching strategy.
648 * @param {Object} options.fetchOptions Values passed along to the
649 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
650 * of all fetch() requests made by this strategy.
651 */
652 constructor(options = {}) {
653 this._plugins = options.plugins || [];
654 this._fetchOptions = options.fetchOptions;
655 }
656 /**
657 * This method will perform a request strategy and follows an API that
658 * will work with the
659 * [Workbox Router]{@link module:workbox-routing.Router}.
660 *
661 * @param {Object} options
662 * @param {Request|string} options.request The request to run this strategy for.
663 * @param {Event} [options.event] The event that triggered the request.
664 * @return {Promise<Response>}
665 */
666
667
668 async handle({
669 event,
670 request
671 }) {
672 if (typeof request === 'string') {
673 request = new Request(request);
674 }
675
676 {
677 assert_js.assert.isInstance(request, Request, {
678 moduleName: 'workbox-strategies',
679 className: 'NetworkOnly',
680 funcName: 'handle',
681 paramName: 'request'
682 });
683 }
684
685 let error;
686 let response;
687
688 try {
689 response = await fetchWrapper_js.fetchWrapper.fetch({
690 request,
691 event,
692 fetchOptions: this._fetchOptions,
693 plugins: this._plugins
694 });
695 } catch (err) {
696 error = err;
697 }
698
699 {
700 logger_js.logger.groupCollapsed(messages.strategyStart('NetworkOnly', request));
701
702 if (response) {
703 logger_js.logger.log(`Got response from network.`);
704 } else {
705 logger_js.logger.log(`Unable to get a response from the network.`);
706 }
707
708 messages.printFinalResponse(response);
709 logger_js.logger.groupEnd();
710 }
711
712 if (!response) {
713 throw new WorkboxError_js.WorkboxError('no-response', {
714 url: request.url,
715 error
716 });
717 }
718
719 return response;
720 }
721
722 }
723
724 /*
725 Copyright 2018 Google LLC
726
727 Use of this source code is governed by an MIT-style
728 license that can be found in the LICENSE file or at
729 https://opensource.org/licenses/MIT.
730 */
731 /**
732 * An implementation of a
733 * [stale-while-revalidate]{@link https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#stale-while-revalidate}
734 * request strategy.
735 *
736 * Resources are requested from both the cache and the network in parallel.
737 * The strategy will respond with the cached version if available, otherwise
738 * wait for the network response. The cache is updated with the network response
739 * with each successful request.
740 *
741 * By default, this strategy will cache responses with a 200 status code as
742 * well as [opaque responses]{@link https://developers.google.com/web/tools/workbox/guides/handle-third-party-requests}.
743 * Opaque responses are cross-origin requests where the response doesn't
744 * support [CORS]{@link https://enable-cors.org/}.
745 *
746 * If the network request fails, and there is no cache match, this will throw
747 * a `WorkboxError` exception.
748 *
749 * @memberof module:workbox-strategies
750 */
751
752 class StaleWhileRevalidate {
753 /**
754 * @param {Object} options
755 * @param {string} options.cacheName Cache name to store and retrieve
756 * requests. Defaults to cache names provided by
757 * [workbox-core]{@link module:workbox-core.cacheNames}.
758 * @param {Array<Object>} options.plugins [Plugins]{@link https://developers.google.com/web/tools/workbox/guides/using-plugins}
759 * to use in conjunction with this caching strategy.
760 * @param {Object} options.fetchOptions Values passed along to the
761 * [`init`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch#Parameters)
762 * of all fetch() requests made by this strategy.
763 * @param {Object} options.matchOptions [`CacheQueryOptions`](https://w3c.github.io/ServiceWorker/#dictdef-cachequeryoptions)
764 */
765 constructor(options = {}) {
766 this._cacheName = cacheNames_js.cacheNames.getRuntimeName(options.cacheName);
767 this._plugins = options.plugins || [];
768
769 if (options.plugins) {
770 const isUsingCacheWillUpdate = options.plugins.some(plugin => !!plugin.cacheWillUpdate);
771 this._plugins = isUsingCacheWillUpdate ? options.plugins : [cacheOkAndOpaquePlugin, ...options.plugins];
772 } else {
773 // No plugins passed in, use the default plugin.
774 this._plugins = [cacheOkAndOpaquePlugin];
775 }
776
777 this._fetchOptions = options.fetchOptions;
778 this._matchOptions = options.matchOptions;
779 }
780 /**
781 * This method will perform a request strategy and follows an API that
782 * will work with the
783 * [Workbox Router]{@link module:workbox-routing.Router}.
784 *
785 * @param {Object} options
786 * @param {Request|string} options.request A request to run this strategy for.
787 * @param {Event} [options.event] The event that triggered the request.
788 * @return {Promise<Response>}
789 */
790
791
792 async handle({
793 event,
794 request
795 }) {
796 const logs = [];
797
798 if (typeof request === 'string') {
799 request = new Request(request);
800 }
801
802 {
803 assert_js.assert.isInstance(request, Request, {
804 moduleName: 'workbox-strategies',
805 className: 'StaleWhileRevalidate',
806 funcName: 'handle',
807 paramName: 'request'
808 });
809 }
810
811 const fetchAndCachePromise = this._getFromNetwork({
812 request,
813 event
814 });
815
816 let response = await cacheWrapper_js.cacheWrapper.match({
817 cacheName: this._cacheName,
818 request,
819 event,
820 matchOptions: this._matchOptions,
821 plugins: this._plugins
822 });
823 let error;
824
825 if (response) {
826 {
827 logs.push(`Found a cached response in the '${this._cacheName}'` + ` cache. Will update with the network response in the background.`);
828 }
829
830 if (event) {
831 try {
832 event.waitUntil(fetchAndCachePromise);
833 } catch (error) {
834 {
835 logger_js.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_js.getFriendlyURL(request.url)}'.`);
836 }
837 }
838 }
839 } else {
840 {
841 logs.push(`No response found in the '${this._cacheName}' cache. ` + `Will wait for the network response.`);
842 }
843
844 try {
845 response = await fetchAndCachePromise;
846 } catch (err) {
847 error = err;
848 }
849 }
850
851 {
852 logger_js.logger.groupCollapsed(messages.strategyStart('StaleWhileRevalidate', request));
853
854 for (const log of logs) {
855 logger_js.logger.log(log);
856 }
857
858 messages.printFinalResponse(response);
859 logger_js.logger.groupEnd();
860 }
861
862 if (!response) {
863 throw new WorkboxError_js.WorkboxError('no-response', {
864 url: request.url,
865 error
866 });
867 }
868
869 return response;
870 }
871 /**
872 * @param {Object} options
873 * @param {Request} options.request
874 * @param {Event} [options.event]
875 * @return {Promise<Response>}
876 *
877 * @private
878 */
879
880
881 async _getFromNetwork({
882 request,
883 event
884 }) {
885 const response = await fetchWrapper_js.fetchWrapper.fetch({
886 request,
887 event,
888 fetchOptions: this._fetchOptions,
889 plugins: this._plugins
890 });
891 const cachePutPromise = cacheWrapper_js.cacheWrapper.put({
892 cacheName: this._cacheName,
893 request,
894 response: response.clone(),
895 event,
896 plugins: this._plugins
897 });
898
899 if (event) {
900 try {
901 event.waitUntil(cachePutPromise);
902 } catch (error) {
903 {
904 logger_js.logger.warn(`Unable to ensure service worker stays alive when ` + `updating cache for '${getFriendlyURL_js.getFriendlyURL(request.url)}'.`);
905 }
906 }
907 }
908
909 return response;
910 }
911
912 }
913
914 exports.CacheFirst = CacheFirst;
915 exports.CacheOnly = CacheOnly;
916 exports.NetworkFirst = NetworkFirst;
917 exports.NetworkOnly = NetworkOnly;
918 exports.StaleWhileRevalidate = StaleWhileRevalidate;
919
920 return exports;
921
922}({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private));
923