UNPKG

59.5 kBJavaScriptView Raw
1/* eslint-disable */
2// This is extracted from the Babel runtime (original source: https://github.com/babel/babel/blob/9e0f5235b1ca5167c368a576ad7c5af62d20b0e3/packages/babel-helpers/src/helpers.js#L240).
3// As part of the Rollup bundling process, it's injected once into workbox-core
4// and reused throughout all of the other modules, avoiding code duplication.
5// See https://github.com/GoogleChrome/workbox/pull/1048#issuecomment-344698046
6// for further background.
7self.babelHelpers = {
8 asyncToGenerator: function(fn) {
9 return function() {
10 var gen = fn.apply(this, arguments);
11 return new Promise(function(resolve, reject) {
12 function step(key, arg) {
13 try {
14 var info = gen[key](arg);
15 var value = info.value;
16 } catch (error) {
17 reject(error);
18 return;
19 }
20
21 if (info.done) {
22 resolve(value);
23 } else {
24 return Promise.resolve(value).then(function(value) {
25 step('next', value);
26 }, function(err) {
27 step('throw', err);
28 });
29 }
30 }
31
32 return step('next');
33 });
34 };
35 },
36};
37
38this.workbox = this.workbox || {};
39this.workbox.core = (function () {
40 'use strict';
41
42 try {
43 self.workbox.v['workbox:core:3.6.2'] = 1;
44 } catch (e) {} // eslint-disable-line
45
46 /*
47 Copyright 2017 Google Inc.
48
49 Licensed under the Apache License, Version 2.0 (the "License");
50 you may not use this file except in compliance with the License.
51 You may obtain a copy of the License at
52
53 https://www.apache.org/licenses/LICENSE-2.0
54
55 Unless required by applicable law or agreed to in writing, software
56 distributed under the License is distributed on an "AS IS" BASIS,
57 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
58 See the License for the specific language governing permissions and
59 limitations under the License.
60 */
61
62 /**
63 * The available log levels in Workbox: debug, log, warn, error and silent.
64 *
65 * @property {int} debug Prints all logs from Workbox. Useful for debugging.
66 * @property {int} log Prints console log, warn, error and groups. Default for
67 * debug builds.
68 * @property {int} warn Prints console warn, error and groups. Default for
69 * non-debug builds.
70 * @property {int} error Print console error and groups.
71 * @property {int} silent Force no logging from Workbox.
72 *
73 * @alias workbox.core.LOG_LEVELS
74 */
75
76 var LOG_LEVELS = {
77 debug: 0,
78 log: 1,
79 warn: 2,
80 error: 3,
81 silent: 4
82 };
83
84 /*
85 Copyright 2017 Google Inc.
86
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 https://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 // Safari doesn't print all console.groupCollapsed() arguments.
101 // Related bug: https://bugs.webkit.org/show_bug.cgi?id=182754
102 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
103
104 const GREY = `#7f8c8d`;
105 const GREEN = `#2ecc71`;
106 const YELLOW = `#f39c12`;
107 const RED = `#c0392b`;
108 const BLUE = `#3498db`;
109
110 const getDefaultLogLevel = () => LOG_LEVELS.log;
111
112 let logLevel = getDefaultLogLevel();
113 const shouldPrint = minLevel => logLevel <= minLevel;
114 const setLoggerLevel = newLogLevel => logLevel = newLogLevel;
115 const getLoggerLevel = () => logLevel;
116
117 // We always want groups to be logged unless logLevel is silent.
118 const groupLevel = LOG_LEVELS.error;
119
120 const _print = function (keyName, logArgs, levelColor) {
121 const logLevel = keyName.indexOf('group') === 0 ? groupLevel : LOG_LEVELS[keyName];
122 if (!shouldPrint(logLevel)) {
123 return;
124 }
125
126 if (!levelColor || keyName === 'groupCollapsed' && isSafari) {
127 console[keyName](...logArgs);
128 return;
129 }
130
131 const logPrefix = ['%cworkbox', `background: ${levelColor}; color: white; padding: 2px 0.5em; ` + `border-radius: 0.5em;`];
132 console[keyName](...logPrefix, ...logArgs);
133 };
134
135 const groupEnd = () => {
136 if (shouldPrint(groupLevel)) {
137 console.groupEnd();
138 }
139 };
140
141 const defaultExport = {
142 groupEnd,
143 unprefixed: {
144 groupEnd
145 }
146 };
147
148 const setupLogs = (keyName, color) => {
149 defaultExport[keyName] = (...args) => _print(keyName, args, color);
150 defaultExport.unprefixed[keyName] = (...args) => _print(keyName, args);
151 };
152
153 const levelToColor = {
154 debug: GREY,
155 log: GREEN,
156 warn: YELLOW,
157 error: RED,
158 groupCollapsed: BLUE
159 };
160 Object.keys(levelToColor).forEach(keyName => setupLogs(keyName, levelToColor[keyName]));
161
162 /*
163 Copyright 2017 Google Inc.
164
165 Licensed under the Apache License, Version 2.0 (the "License");
166 you may not use this file except in compliance with the License.
167 You may obtain a copy of the License at
168
169 https://www.apache.org/licenses/LICENSE-2.0
170
171 Unless required by applicable law or agreed to in writing, software
172 distributed under the License is distributed on an "AS IS" BASIS,
173 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174 See the License for the specific language governing permissions and
175 limitations under the License.
176 */
177
178 var messages = {
179 'invalid-value': ({ paramName, validValueDescription, value }) => {
180 if (!paramName || !validValueDescription) {
181 throw new Error(`Unexpected input to 'invalid-value' error.`);
182 }
183 return `The '${paramName}' parameter was given a value with an ` + `unexpected value. ${validValueDescription} Received a value of ` + `${JSON.stringify(value)}.`;
184 },
185
186 'not-in-sw': ({ moduleName }) => {
187 if (!moduleName) {
188 throw new Error(`Unexpected input to 'not-in-sw' error.`);
189 }
190 return `The '${moduleName}' must be used in a service worker.`;
191 },
192
193 'not-an-array': ({ moduleName, className, funcName, paramName }) => {
194 if (!moduleName || !className || !funcName || !paramName) {
195 throw new Error(`Unexpected input to 'not-an-array' error.`);
196 }
197 return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className}.${funcName}()' must be an array.`;
198 },
199
200 'incorrect-type': ({ expectedType, paramName, moduleName, className,
201 funcName }) => {
202 if (!expectedType || !paramName || !moduleName || !funcName) {
203 throw new Error(`Unexpected input to 'incorrect-type' error.`);
204 }
205 return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className ? className + '.' : ''}` + `${funcName}()' must be of type ${expectedType}.`;
206 },
207
208 'incorrect-class': ({ expectedClass, paramName, moduleName, className,
209 funcName, isReturnValueProblem }) => {
210 if (!expectedClass || !moduleName || !funcName) {
211 throw new Error(`Unexpected input to 'incorrect-class' error.`);
212 }
213
214 if (isReturnValueProblem) {
215 return `The return value from ` + `'${moduleName}.${className ? className + '.' : ''}${funcName}()' ` + `must be an instance of class ${expectedClass.name}.`;
216 }
217
218 return `The parameter '${paramName}' passed into ` + `'${moduleName}.${className ? className + '.' : ''}${funcName}()' ` + `must be an instance of class ${expectedClass.name}.`;
219 },
220
221 'missing-a-method': ({ expectedMethod, paramName, moduleName, className,
222 funcName }) => {
223 if (!expectedMethod || !paramName || !moduleName || !className || !funcName) {
224 throw new Error(`Unexpected input to 'missing-a-method' error.`);
225 }
226 return `${moduleName}.${className}.${funcName}() expected the ` + `'${paramName}' parameter to expose a '${expectedMethod}' method.`;
227 },
228
229 'add-to-cache-list-unexpected-type': ({ entry }) => {
230 return `An unexpected entry was passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' The entry ` + `'${JSON.stringify(entry)}' isn't supported. You must supply an array of ` + `strings with one or more characters, objects with a url property or ` + `Request objects.`;
231 },
232
233 'add-to-cache-list-conflicting-entries': ({ firstEntry, secondEntry }) => {
234 if (!firstEntry || !secondEntry) {
235 throw new Error(`Unexpected input to ` + `'add-to-cache-list-duplicate-entries' error.`);
236 }
237
238 return `Two of the entries passed to ` + `'workbox-precaching.PrecacheController.addToCacheList()' had matching ` + `URLs but different revision details. This means workbox-precaching ` + `is unable to determine cache the asset correctly. Please remove one ` + `of the entries.`;
239 },
240
241 'plugin-error-request-will-fetch': ({ thrownError }) => {
242 if (!thrownError) {
243 throw new Error(`Unexpected input to ` + `'plugin-error-request-will-fetch', error.`);
244 }
245
246 return `An error was thrown by a plugins 'requestWillFetch()' method. ` + `The thrown error message was: '${thrownError.message}'.`;
247 },
248
249 'invalid-cache-name': ({ cacheNameId, value }) => {
250 if (!cacheNameId) {
251 throw new Error(`Expected a 'cacheNameId' for error 'invalid-cache-name'`);
252 }
253
254 return `You must provide a name containing at least one character for ` + `setCacheDeatils({${cacheNameId}: '...'}). Received a value of ` + `'${JSON.stringify(value)}'`;
255 },
256
257 'unregister-route-but-not-found-with-method': ({ method }) => {
258 if (!method) {
259 throw new Error(`Unexpected input to ` + `'unregister-route-but-not-found-with-method' error.`);
260 }
261
262 return `The route you're trying to unregister was not previously ` + `registered for the method type '${method}'.`;
263 },
264
265 'unregister-route-route-not-registered': () => {
266 return `The route you're trying to unregister was not previously ` + `registered.`;
267 },
268
269 'queue-replay-failed': ({ name, count }) => {
270 return `${count} requests failed, while trying to replay Queue: ${name}.`;
271 },
272
273 'duplicate-queue-name': ({ name }) => {
274 return `The Queue name '${name}' is already being used. ` + `All instances of backgroundSync.Queue must be given unique names.`;
275 },
276
277 'expired-test-without-max-age': ({ methodName, paramName }) => {
278 return `The '${methodName}()' method can only be used when the ` + `'${paramName}' is used in the constructor.`;
279 },
280
281 'unsupported-route-type': ({ moduleName, className, funcName, paramName }) => {
282 return `The supplied '${paramName}' parameter was an unsupported type. ` + `Please check the docs for ${moduleName}.${className}.${funcName} for ` + `valid input types.`;
283 },
284
285 'not-array-of-class': ({ value, expectedClass,
286 moduleName, className, funcName, paramName }) => {
287 return `The supplied '${paramName}' parameter must be an array of ` + `'${expectedClass}' objects. Received '${JSON.stringify(value)},'. ` + `Please check the call to ${moduleName}.${className}.${funcName}() ` + `to fix the issue.`;
288 },
289
290 'max-entries-or-age-required': ({ moduleName, className, funcName }) => {
291 return `You must define either config.maxEntries or config.maxAgeSeconds` + `in ${moduleName}.${className}.${funcName}`;
292 },
293
294 'statuses-or-headers-required': ({ moduleName, className, funcName }) => {
295 return `You must define either config.statuses or config.headers` + `in ${moduleName}.${className}.${funcName}`;
296 },
297
298 'invalid-string': ({ moduleName, className, funcName, paramName }) => {
299 if (!paramName || !moduleName || !className || !funcName) {
300 throw new Error(`Unexpected input to 'invalid-string' error.`);
301 }
302 return `When using strings, the '${paramName}' parameter must start with ` + `'http' (for cross-origin matches) or '/' (for same-origin matches). ` + `Please see the docs for ${moduleName}.${className}.${funcName}() for ` + `more info.`;
303 },
304 'channel-name-required': () => {
305 return `You must provide a channelName to construct a ` + `BroadcastCacheUpdate instance.`;
306 },
307 'invalid-responses-are-same-args': () => {
308 return `The arguments passed into responsesAreSame() appear to be ` + `invalid. Please ensure valid Responses are used.`;
309 },
310 'expire-custom-caches-only': () => {
311 return `You must provide a 'cacheName' property when using the ` + `expiration plugin with a runtime caching strategy.`;
312 },
313 'unit-must-be-bytes': ({ normalizedRangeHeader }) => {
314 if (!normalizedRangeHeader) {
315 throw new Error(`Unexpected input to 'unit-must-be-bytes' error.`);
316 }
317 return `The 'unit' portion of the Range header must be set to 'bytes'. ` + `The Range header provided was "${normalizedRangeHeader}"`;
318 },
319 'single-range-only': ({ normalizedRangeHeader }) => {
320 if (!normalizedRangeHeader) {
321 throw new Error(`Unexpected input to 'single-range-only' error.`);
322 }
323 return `Multiple ranges are not supported. Please use a single start ` + `value, and optional end value. The Range header provided was ` + `"${normalizedRangeHeader}"`;
324 },
325 'invalid-range-values': ({ normalizedRangeHeader }) => {
326 if (!normalizedRangeHeader) {
327 throw new Error(`Unexpected input to 'invalid-range-values' error.`);
328 }
329 return `The Range header is missing both start and end values. At least ` + `one of those values is needed. The Range header provided was ` + `"${normalizedRangeHeader}"`;
330 },
331 'no-range-header': () => {
332 return `No Range header was found in the Request provided.`;
333 },
334 'range-not-satisfiable': ({ size, start, end }) => {
335 return `The start (${start}) and end (${end}) values in the Range are ` + `not satisfiable by the cached response, which is ${size} bytes.`;
336 },
337 'attempt-to-cache-non-get-request': ({ url, method }) => {
338 return `Unable to cache '${url}' because it is a '${method}' request and ` + `only 'GET' requests can be cached.`;
339 },
340 'cache-put-with-no-response': ({ url }) => {
341 return `There was an attempt to cache '${url}' but the response was not ` + `defined.`;
342 }
343 };
344
345 /*
346 Copyright 2017 Google Inc.
347
348 Licensed under the Apache License, Version 2.0 (the "License");
349 you may not use this file except in compliance with the License.
350 You may obtain a copy of the License at
351
352 https://www.apache.org/licenses/LICENSE-2.0
353
354 Unless required by applicable law or agreed to in writing, software
355 distributed under the License is distributed on an "AS IS" BASIS,
356 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
357 See the License for the specific language governing permissions and
358 limitations under the License.
359 */
360
361 const generatorFunction = (code, ...args) => {
362 const message = messages[code];
363 if (!message) {
364 throw new Error(`Unable to find message for code '${code}'.`);
365 }
366
367 return message(...args);
368 };
369
370 const exportedValue = generatorFunction;
371
372 /*
373 Copyright 2017 Google Inc.
374
375 Licensed under the Apache License, Version 2.0 (the "License");
376 you may not use this file except in compliance with the License.
377 You may obtain a copy of the License at
378
379 https://www.apache.org/licenses/LICENSE-2.0
380
381 Unless required by applicable law or agreed to in writing, software
382 distributed under the License is distributed on an "AS IS" BASIS,
383 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
384 See the License for the specific language governing permissions and
385 limitations under the License.
386 */
387
388 /**
389 * Workbox errors should be thrown with this class.
390 * This allows use to ensure the type easily in tests,
391 * helps developers identify errors from workbox
392 * easily and allows use to optimise error
393 * messages correctly.
394 *
395 * @private
396 */
397 class WorkboxError extends Error {
398 /**
399 *
400 * @param {string} errorCode The error code that
401 * identifies this particular error.
402 * @param {Object=} details Any relevant arguments
403 * that will help developers identify issues should
404 * be added as a key on the context object.
405 */
406 constructor(errorCode, details) {
407 let message = exportedValue(errorCode, details);
408
409 super(message);
410
411 this.name = errorCode;
412 this.details = details;
413 }
414 }
415
416 /*
417 Copyright 2017 Google Inc.
418
419 Licensed under the Apache License, Version 2.0 (the "License");
420 you may not use this file except in compliance with the License.
421 You may obtain a copy of the License at
422
423 https://www.apache.org/licenses/LICENSE-2.0
424
425 Unless required by applicable law or agreed to in writing, software
426 distributed under the License is distributed on an "AS IS" BASIS,
427 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
428 See the License for the specific language governing permissions and
429 limitations under the License.
430 */
431
432 /*
433 * This method returns true if the current context is a service worker.
434 */
435 const isSwEnv = moduleName => {
436 if (!('ServiceWorkerGlobalScope' in self)) {
437 throw new WorkboxError('not-in-sw', { moduleName });
438 }
439 };
440
441 /*
442 * This method throws if the supplied value is not an array.
443 * The destructed values are required to produce a meaningful error for users.
444 * The destructed and restructured object is so it's clear what is
445 * needed.
446 */
447 const isArray = (value, { moduleName, className, funcName, paramName }) => {
448 if (!Array.isArray(value)) {
449 throw new WorkboxError('not-an-array', {
450 moduleName,
451 className,
452 funcName,
453 paramName
454 });
455 }
456 };
457
458 const hasMethod = (object, expectedMethod, { moduleName, className, funcName, paramName }) => {
459 const type = typeof object[expectedMethod];
460 if (type !== 'function') {
461 throw new WorkboxError('missing-a-method', { paramName, expectedMethod,
462 moduleName, className, funcName });
463 }
464 };
465
466 const isType = (object, expectedType, { moduleName, className, funcName, paramName }) => {
467 if (typeof object !== expectedType) {
468 throw new WorkboxError('incorrect-type', { paramName, expectedType,
469 moduleName, className, funcName });
470 }
471 };
472
473 const isInstance = (object, expectedClass, { moduleName, className, funcName,
474 paramName, isReturnValueProblem }) => {
475 if (!(object instanceof expectedClass)) {
476 throw new WorkboxError('incorrect-class', { paramName, expectedClass,
477 moduleName, className, funcName, isReturnValueProblem });
478 }
479 };
480
481 const isOneOf = (value, validValues, { paramName }) => {
482 if (!validValues.includes(value)) {
483 throw new WorkboxError('invalid-value', {
484 paramName,
485 value,
486 validValueDescription: `Valid values are ${JSON.stringify(validValues)}.`
487 });
488 }
489 };
490
491 const isArrayOfClass = (value, expectedClass, { moduleName, className, funcName, paramName }) => {
492 const error = new WorkboxError('not-array-of-class', {
493 value, expectedClass,
494 moduleName, className, funcName, paramName
495 });
496 if (!Array.isArray(value)) {
497 throw error;
498 }
499
500 for (let item of value) {
501 if (!(item instanceof expectedClass)) {
502 throw error;
503 }
504 }
505 };
506
507 const finalAssertExports = {
508 hasMethod,
509 isArray,
510 isInstance,
511 isOneOf,
512 isSwEnv,
513 isType,
514 isArrayOfClass
515 };
516
517 /**
518 * Runs all of the callback functions, one at a time sequentially, in the order
519 * in which they were registered.
520 *
521 * @memberof workbox.core
522 * @private
523 */
524 let executeQuotaErrorCallbacks = (() => {
525 var _ref = babelHelpers.asyncToGenerator(function* () {
526 {
527 defaultExport.log(`About to run ${callbacks.size} callbacks to clean up caches.`);
528 }
529
530 for (const callback of callbacks) {
531 yield callback();
532 {
533 defaultExport.log(callback, 'is complete.');
534 }
535 }
536
537 {
538 defaultExport.log('Finished running callbacks.');
539 }
540 });
541
542 return function executeQuotaErrorCallbacks() {
543 return _ref.apply(this, arguments);
544 };
545 })();
546
547 const callbacks = new Set();
548
549 /**
550 * Adds a function to the set of callbacks that will be executed when there's
551 * a quota error.
552 *
553 * @param {Function} callback
554 * @memberof workbox.core
555 */
556 function registerQuotaErrorCallback(callback) {
557 {
558 finalAssertExports.isType(callback, 'function', {
559 moduleName: 'workbox-core',
560 funcName: 'register',
561 paramName: 'callback'
562 });
563 }
564
565 callbacks.add(callback);
566
567 {
568 defaultExport.log('Registered a callback to respond to quota errors.', callback);
569 }
570 }
571
572 /*
573 Copyright 2017 Google Inc.
574
575 Licensed under the Apache License, Version 2.0 (the "License");
576 you may not use this file except in compliance with the License.
577 You may obtain a copy of the License at
578
579 https://www.apache.org/licenses/LICENSE-2.0
580
581 Unless required by applicable law or agreed to in writing, software
582 distributed under the License is distributed on an "AS IS" BASIS,
583 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
584 See the License for the specific language governing permissions and
585 limitations under the License.
586 */
587
588 /**
589 * A class that wraps common IndexedDB functionality in a promise-based API.
590 * It exposes all the underlying power and functionality of IndexedDB, but
591 * wraps the most commonly used features in a way that's much simpler to use.
592 *
593 * @private
594 */
595 class DBWrapper {
596 /**
597 * @param {string} name
598 * @param {number} version
599 * @param {Object=} [callback]
600 * @param {function(this:DBWrapper, Event)} [callbacks.onupgradeneeded]
601 * @param {function(this:DBWrapper, Event)} [callbacks.onversionchange]
602 * Defaults to DBWrapper.prototype._onversionchange when not specified.
603 */
604 constructor(name, version, {
605 onupgradeneeded,
606 onversionchange = this._onversionchange
607 } = {}) {
608 this._name = name;
609 this._version = version;
610 this._onupgradeneeded = onupgradeneeded;
611 this._onversionchange = onversionchange;
612
613 // If this is null, it means the database isn't open.
614 this._db = null;
615 }
616
617 /**
618 * Opens a connected to an IDBDatabase, invokes any onupgradedneeded
619 * callback, and added an onversionchange callback to the database.
620 *
621 * @return {IDBDatabase}
622 *
623 * @private
624 */
625 open() {
626 var _this = this;
627
628 return babelHelpers.asyncToGenerator(function* () {
629 if (_this._db) return;
630
631 _this._db = yield new Promise(function (resolve, reject) {
632 // This flag is flipped to true if the timeout callback runs prior
633 // to the request failing or succeeding. Note: we use a timeout instead
634 // of an onblocked handler since there are cases where onblocked will
635 // never never run. A timeout better handles all possible scenarios:
636 // https://github.com/w3c/IndexedDB/issues/223
637 let openRequestTimedOut = false;
638 setTimeout(function () {
639 openRequestTimedOut = true;
640 reject(new Error('The open request was blocked and timed out'));
641 }, _this.OPEN_TIMEOUT);
642
643 const openRequest = indexedDB.open(_this._name, _this._version);
644 openRequest.onerror = function (evt) {
645 return reject(openRequest.error);
646 };
647 openRequest.onupgradeneeded = function (evt) {
648 if (openRequestTimedOut) {
649 openRequest.transaction.abort();
650 evt.target.result.close();
651 } else if (_this._onupgradeneeded) {
652 _this._onupgradeneeded(evt);
653 }
654 };
655 openRequest.onsuccess = function (evt) {
656 const db = evt.target.result;
657 if (openRequestTimedOut) {
658 db.close();
659 } else {
660 db.onversionchange = _this._onversionchange;
661 resolve(db);
662 }
663 };
664 });
665
666 return _this;
667 })();
668 }
669
670 /**
671 * Delegates to the native `get()` method for the object store.
672 *
673 * @param {string} storeName The name of the object store to put the value.
674 * @param {...*} args The values passed to the delegated method.
675 * @return {*} The key of the entry.
676 *
677 * @private
678 */
679 get(storeName, ...args) {
680 var _this2 = this;
681
682 return babelHelpers.asyncToGenerator(function* () {
683 return yield _this2._call('get', storeName, 'readonly', ...args);
684 })();
685 }
686
687 /**
688 * Delegates to the native `add()` method for the object store.
689 *
690 * @param {string} storeName The name of the object store to put the value.
691 * @param {...*} args The values passed to the delegated method.
692 * @return {*} The key of the entry.
693 *
694 * @private
695 */
696 add(storeName, ...args) {
697 var _this3 = this;
698
699 return babelHelpers.asyncToGenerator(function* () {
700 return yield _this3._call('add', storeName, 'readwrite', ...args);
701 })();
702 }
703
704 /**
705 * Delegates to the native `put()` method for the object store.
706 *
707 * @param {string} storeName The name of the object store to put the value.
708 * @param {...*} args The values passed to the delegated method.
709 * @return {*} The key of the entry.
710 *
711 * @private
712 */
713 put(storeName, ...args) {
714 var _this4 = this;
715
716 return babelHelpers.asyncToGenerator(function* () {
717 return yield _this4._call('put', storeName, 'readwrite', ...args);
718 })();
719 }
720
721 /**
722 * Delegates to the native `delete()` method for the object store.
723 *
724 * @param {string} storeName
725 * @param {...*} args The values passed to the delegated method.
726 *
727 * @private
728 */
729 delete(storeName, ...args) {
730 var _this5 = this;
731
732 return babelHelpers.asyncToGenerator(function* () {
733 yield _this5._call('delete', storeName, 'readwrite', ...args);
734 })();
735 }
736
737 /**
738 * Deletes the underlying database, ensuring that any open connections are
739 * closed first.
740 *
741 * @private
742 */
743 deleteDatabase() {
744 var _this6 = this;
745
746 return babelHelpers.asyncToGenerator(function* () {
747 _this6.close();
748 _this6._db = null;
749 yield new Promise(function (resolve, reject) {
750 const request = indexedDB.deleteDatabase(_this6._name);
751 request.onerror = function (evt) {
752 return reject(evt.target.error);
753 };
754 request.onblocked = function () {
755 return reject(new Error('Deletion was blocked.'));
756 };
757 request.onsuccess = function () {
758 return resolve();
759 };
760 });
761 })();
762 }
763
764 /**
765 * Delegates to the native `getAll()` or polyfills it via the `find()`
766 * method in older browsers.
767 *
768 * @param {string} storeName
769 * @param {*} query
770 * @param {number} count
771 * @return {Array}
772 *
773 * @private
774 */
775 getAll(storeName, query, count) {
776 var _this7 = this;
777
778 return babelHelpers.asyncToGenerator(function* () {
779 if ('getAll' in IDBObjectStore.prototype) {
780 return yield _this7._call('getAll', storeName, 'readonly', query, count);
781 } else {
782 return yield _this7.getAllMatching(storeName, { query, count });
783 }
784 })();
785 }
786
787 /**
788 * Supports flexible lookup in an object store by specifying an index,
789 * query, direction, and count. This method returns an array of objects
790 * with the signature .
791 *
792 * @param {string} storeName
793 * @param {Object} [opts]
794 * @param {IDBCursorDirection} [opts.direction]
795 * @param {*} [opts.query]
796 * @param {string} [opts.index] The index to use (if specified).
797 * @param {number} [opts.count] The max number of results to return.
798 * @param {boolean} [opts.includeKeys] When true, the structure of the
799 * returned objects is changed from an array of values to an array of
800 * objects in the form {key, primaryKey, value}.
801 * @return {Array}
802 *
803 * @private
804 */
805 getAllMatching(storeName, opts = {}) {
806 var _this8 = this;
807
808 return babelHelpers.asyncToGenerator(function* () {
809 return yield _this8.transaction([storeName], 'readonly', function (stores, done) {
810 const store = stores[storeName];
811 const target = opts.index ? store.index(opts.index) : store;
812 const results = [];
813
814 // Passing `undefined` arguments to Edge's `openCursor(...)` causes
815 // 'DOMException: DataError'
816 // Details in issue: https://github.com/GoogleChrome/workbox/issues/1509
817 const query = opts.query || null;
818 const direction = opts.direction || 'next';
819 target.openCursor(query, direction).onsuccess = function (evt) {
820 const cursor = evt.target.result;
821 if (cursor) {
822 const { primaryKey, key, value } = cursor;
823 results.push(opts.includeKeys ? { primaryKey, key, value } : value);
824 if (opts.count && results.length >= opts.count) {
825 done(results);
826 } else {
827 cursor.continue();
828 }
829 } else {
830 done(results);
831 }
832 };
833 });
834 })();
835 }
836
837 /**
838 * Accepts a list of stores, a transaction type, and a callback and
839 * performs a transaction. A promise is returned that resolves to whatever
840 * value the callback chooses. The callback holds all the transaction logic
841 * and is invoked with three arguments:
842 * 1. An object mapping object store names to IDBObjectStore values.
843 * 2. A `done` function, that's used to resolve the promise when
844 * when the transaction is done.
845 * 3. An `abort` function that can be called to abort the transaction
846 * at any time.
847 *
848 * @param {Array<string>} storeNames An array of object store names
849 * involved in the transaction.
850 * @param {string} type Can be `readonly` or `readwrite`.
851 * @param {function(Object, function(), function(*)):?IDBRequest} callback
852 * @return {*} The result of the transaction ran by the callback.
853 *
854 * @private
855 */
856 transaction(storeNames, type, callback) {
857 var _this9 = this;
858
859 return babelHelpers.asyncToGenerator(function* () {
860 yield _this9.open();
861 const result = yield new Promise(function (resolve, reject) {
862 const txn = _this9._db.transaction(storeNames, type);
863 const done = function (value) {
864 return resolve(value);
865 };
866 const abort = function () {
867 reject(new Error('The transaction was manually aborted'));
868 txn.abort();
869 };
870 txn.onerror = function (evt) {
871 return reject(evt.target.error);
872 };
873 txn.onabort = function (evt) {
874 return reject(evt.target.error);
875 };
876 txn.oncomplete = function () {
877 return resolve();
878 };
879
880 const stores = {};
881 for (const storeName of storeNames) {
882 stores[storeName] = txn.objectStore(storeName);
883 }
884 callback(stores, done, abort);
885 });
886 return result;
887 })();
888 }
889
890 /**
891 * Delegates async to a native IDBObjectStore method.
892 *
893 * @param {string} method The method name.
894 * @param {string} storeName The object store name.
895 * @param {string} type Can be `readonly` or `readwrite`.
896 * @param {...*} args The list of args to pass to the native method.
897 * @return {*} The result of the transaction.
898 *
899 * @private
900 */
901 _call(method, storeName, type, ...args) {
902 var _this10 = this;
903
904 return babelHelpers.asyncToGenerator(function* () {
905 yield _this10.open();
906 const callback = function (stores, done) {
907 stores[storeName][method](...args).onsuccess = function (evt) {
908 done(evt.target.result);
909 };
910 };
911
912 return yield _this10.transaction([storeName], type, callback);
913 })();
914 }
915
916 /**
917 * The default onversionchange handler, which closes the database so other
918 * connections can open without being blocked.
919 *
920 * @param {Event} evt
921 *
922 * @private
923 */
924 _onversionchange(evt) {
925 this.close();
926 }
927
928 /**
929 * Closes the connection opened by `DBWrapper.open()`. Generally this method
930 * doesn't need to be called since:
931 * 1. It's usually better to keep a connection open since opening
932 * a new connection is somewhat slow.
933 * 2. Connections are automatically closed when the reference is
934 * garbage collected.
935 * The primary use case for needing to close a connection is when another
936 * reference (typically in another tab) needs to upgrade it and would be
937 * blocked by the current, open connection.
938 *
939 * @private
940 */
941 close() {
942 if (this._db) this._db.close();
943 }
944 }
945
946 // Exposed to let users modify the default timeout on a per-instance
947 // or global basis.
948 DBWrapper.prototype.OPEN_TIMEOUT = 2000;
949
950 /*
951 Copyright 2017 Google Inc.
952
953 Licensed under the Apache License, Version 2.0 (the "License");
954 you may not use this file except in compliance with the License.
955 You may obtain a copy of the License at
956
957 https://www.apache.org/licenses/LICENSE-2.0
958
959 Unless required by applicable law or agreed to in writing, software
960 distributed under the License is distributed on an "AS IS" BASIS,
961 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
962 See the License for the specific language governing permissions and
963 limitations under the License.
964 */
965
966 const _cacheNameDetails = {
967 prefix: 'workbox',
968 suffix: self.registration.scope,
969 googleAnalytics: 'googleAnalytics',
970 precache: 'precache',
971 runtime: 'runtime'
972 };
973
974 const _createCacheName = cacheName => {
975 return [_cacheNameDetails.prefix, cacheName, _cacheNameDetails.suffix].filter(value => value.length > 0).join('-');
976 };
977
978 const cacheNames = {
979 updateDetails: details => {
980 Object.keys(_cacheNameDetails).forEach(key => {
981 if (typeof details[key] !== 'undefined') {
982 _cacheNameDetails[key] = details[key];
983 }
984 });
985 },
986 getGoogleAnalyticsName: userCacheName => {
987 return userCacheName || _createCacheName(_cacheNameDetails.googleAnalytics);
988 },
989 getPrecacheName: userCacheName => {
990 return userCacheName || _createCacheName(_cacheNameDetails.precache);
991 },
992 getRuntimeName: userCacheName => {
993 return userCacheName || _createCacheName(_cacheNameDetails.runtime);
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 pluginEvents = {
1014 CACHE_DID_UPDATE: 'cacheDidUpdate',
1015 CACHE_WILL_UPDATE: 'cacheWillUpdate',
1016 CACHED_RESPONSE_WILL_BE_USED: 'cachedResponseWillBeUsed',
1017 FETCH_DID_FAIL: 'fetchDidFail',
1018 REQUEST_WILL_FETCH: 'requestWillFetch'
1019 };
1020
1021 /*
1022 Copyright 2017 Google Inc.
1023
1024 Licensed under the Apache License, Version 2.0 (the "License");
1025 you may not use this file except in compliance with the License.
1026 You may obtain a copy of the License at
1027
1028 https://www.apache.org/licenses/LICENSE-2.0
1029
1030 Unless required by applicable law or agreed to in writing, software
1031 distributed under the License is distributed on an "AS IS" BASIS,
1032 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1033 See the License for the specific language governing permissions and
1034 limitations under the License.
1035 */
1036
1037 var pluginUtils = {
1038 filter: (plugins, callbackname) => {
1039 return plugins.filter(plugin => callbackname in plugin);
1040 }
1041 };
1042
1043 /*
1044 Copyright 2017 Google Inc.
1045
1046 Licensed under the Apache License, Version 2.0 (the "License");
1047 you may not use this file except in compliance with the License.
1048 You may obtain a copy of the License at
1049
1050 https://www.apache.org/licenses/LICENSE-2.0
1051
1052 Unless required by applicable law or agreed to in writing, software
1053 distributed under the License is distributed on an "AS IS" BASIS,
1054 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1055 See the License for the specific language governing permissions and
1056 limitations under the License.
1057 */
1058
1059 const getFriendlyURL = url => {
1060 const urlObj = new URL(url, location);
1061 if (urlObj.origin === location.origin) {
1062 return urlObj.pathname;
1063 }
1064 return urlObj.href;
1065 };
1066
1067 /*
1068 Copyright 2017 Google Inc.
1069
1070 Licensed under the Apache License, Version 2.0 (the "License");
1071 you may not use this file except in compliance with the License.
1072 You may obtain a copy of the License at
1073
1074 https://www.apache.org/licenses/LICENSE-2.0
1075
1076 Unless required by applicable law or agreed to in writing, software
1077 distributed under the License is distributed on an "AS IS" BASIS,
1078 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1079 See the License for the specific language governing permissions and
1080 limitations under the License.
1081 */
1082
1083 /**
1084 * Wrapper around cache.put().
1085 *
1086 * Will call `cacheDidUpdate` on plugins if the cache was updated.
1087 *
1088 * @param {Object} options
1089 * @param {string} options.cacheName
1090 * @param {Request} options.request
1091 * @param {Response} options.response
1092 * @param {Event} [options.event]
1093 * @param {Array<Object>} [options.plugins=[]]
1094 *
1095 * @private
1096 * @memberof module:workbox-core
1097 */
1098 const putWrapper = (() => {
1099 var _ref = babelHelpers.asyncToGenerator(function* ({
1100 cacheName,
1101 request,
1102 response,
1103 event,
1104 plugins = []
1105 } = {}) {
1106 if (!response) {
1107 {
1108 defaultExport.error(`Cannot cache non-existent response for ` + `'${getFriendlyURL(request.url)}'.`);
1109 }
1110
1111 throw new WorkboxError('cache-put-with-no-response', {
1112 url: getFriendlyURL(request.url)
1113 });
1114 }
1115
1116 let responseToCache = yield _isResponseSafeToCache({ request, response, event, plugins });
1117
1118 if (!responseToCache) {
1119 {
1120 defaultExport.debug(`Response '${getFriendlyURL(request.url)}' will not be ` + `cached.`, responseToCache);
1121 }
1122 return;
1123 }
1124
1125 {
1126 if (responseToCache.method && responseToCache.method !== 'GET') {
1127 throw new WorkboxError('attempt-to-cache-non-get-request', {
1128 url: getFriendlyURL(request.url),
1129 method: responseToCache.method
1130 });
1131 }
1132 }
1133
1134 const cache = yield caches.open(cacheName);
1135
1136 const updatePlugins = pluginUtils.filter(plugins, pluginEvents.CACHE_DID_UPDATE);
1137
1138 let oldResponse = updatePlugins.length > 0 ? yield matchWrapper({ cacheName, request }) : null;
1139
1140 {
1141 defaultExport.debug(`Updating the '${cacheName}' cache with a new Response for ` + `${getFriendlyURL(request.url)}.`);
1142 }
1143
1144 try {
1145 yield cache.put(request, responseToCache);
1146 } catch (error) {
1147 // See https://developer.mozilla.org/en-US/docs/Web/API/DOMException#exception-QuotaExceededError
1148 if (error.name === 'QuotaExceededError') {
1149 yield executeQuotaErrorCallbacks();
1150 }
1151 throw error;
1152 }
1153
1154 for (let plugin of updatePlugins) {
1155 yield plugin[pluginEvents.CACHE_DID_UPDATE].call(plugin, {
1156 cacheName,
1157 request,
1158 event,
1159 oldResponse,
1160 newResponse: responseToCache
1161 });
1162 }
1163 });
1164
1165 return function putWrapper() {
1166 return _ref.apply(this, arguments);
1167 };
1168 })();
1169
1170 /**
1171 * This is a wrapper around cache.match().
1172 *
1173 * @param {Object} options
1174 * @param {string} options.cacheName Name of the cache to match against.
1175 * @param {Request} options.request The Request that will be used to look up
1176 *. cache entries.
1177 * @param {Event} [options.event] The event that propted the action.
1178 * @param {Object} [options.matchOptions] Options passed to cache.match().
1179 * @param {Array<Object>} [options.plugins=[]] Array of plugins.
1180 * @return {Response} A cached response if available.
1181 *
1182 * @private
1183 * @memberof module:workbox-core
1184 */
1185 const matchWrapper = (() => {
1186 var _ref2 = babelHelpers.asyncToGenerator(function* ({
1187 cacheName,
1188 request,
1189 event,
1190 matchOptions,
1191 plugins = [] }) {
1192 const cache = yield caches.open(cacheName);
1193 let cachedResponse = yield cache.match(request, matchOptions);
1194 {
1195 if (cachedResponse) {
1196 defaultExport.debug(`Found a cached response in '${cacheName}'.`);
1197 } else {
1198 defaultExport.debug(`No cached response found in '${cacheName}'.`);
1199 }
1200 }
1201 for (let plugin of plugins) {
1202 if (pluginEvents.CACHED_RESPONSE_WILL_BE_USED in plugin) {
1203 cachedResponse = yield plugin[pluginEvents.CACHED_RESPONSE_WILL_BE_USED].call(plugin, {
1204 cacheName,
1205 request,
1206 event,
1207 matchOptions,
1208 cachedResponse
1209 });
1210 {
1211 if (cachedResponse) {
1212 finalAssertExports.isInstance(cachedResponse, Response, {
1213 moduleName: 'Plugin',
1214 funcName: pluginEvents.CACHED_RESPONSE_WILL_BE_USED,
1215 isReturnValueProblem: true
1216 });
1217 }
1218 }
1219 }
1220 }
1221 return cachedResponse;
1222 });
1223
1224 return function matchWrapper(_x) {
1225 return _ref2.apply(this, arguments);
1226 };
1227 })();
1228
1229 /**
1230 * This method will call cacheWillUpdate on the available plugins (or use
1231 * response.ok) to determine if the Response is safe and valid to cache.
1232 *
1233 * @param {Object} options
1234 * @param {Request} options.request
1235 * @param {Response} options.response
1236 * @param {Event} [options.event]
1237 * @param {Array<Object>} [options.plugins=[]]
1238 * @return {Promise<Response>}
1239 *
1240 * @private
1241 * @memberof module:workbox-core
1242 */
1243 const _isResponseSafeToCache = (() => {
1244 var _ref3 = babelHelpers.asyncToGenerator(function* ({ request, response, event, plugins }) {
1245 let responseToCache = response;
1246 let pluginsUsed = false;
1247 for (let plugin of plugins) {
1248 if (pluginEvents.CACHE_WILL_UPDATE in plugin) {
1249 pluginsUsed = true;
1250 responseToCache = yield plugin[pluginEvents.CACHE_WILL_UPDATE].call(plugin, {
1251 request,
1252 response: responseToCache,
1253 event
1254 });
1255
1256 {
1257 if (responseToCache) {
1258 finalAssertExports.isInstance(responseToCache, Response, {
1259 moduleName: 'Plugin',
1260 funcName: pluginEvents.CACHE_WILL_UPDATE,
1261 isReturnValueProblem: true
1262 });
1263 }
1264 }
1265
1266 if (!responseToCache) {
1267 break;
1268 }
1269 }
1270 }
1271
1272 if (!pluginsUsed) {
1273 {
1274 if (!responseToCache.ok) {
1275 if (responseToCache.status === 0) {
1276 defaultExport.warn(`The response for '${request.url}' is an opaque ` + `response. The caching strategy that you're using will not ` + `cache opaque responses by default.`);
1277 } else {
1278 defaultExport.debug(`The response for '${request.url}' returned ` + `a status code of '${response.status}' and won't be cached as a ` + `result.`);
1279 }
1280 }
1281 }
1282 responseToCache = responseToCache.ok ? responseToCache : null;
1283 }
1284
1285 return responseToCache ? responseToCache : null;
1286 });
1287
1288 return function _isResponseSafeToCache(_x2) {
1289 return _ref3.apply(this, arguments);
1290 };
1291 })();
1292
1293 const cacheWrapper = {
1294 put: putWrapper,
1295 match: matchWrapper
1296 };
1297
1298 /*
1299 Copyright 2017 Google Inc.
1300
1301 Licensed under the Apache License, Version 2.0 (the "License");
1302 you may not use this file except in compliance with the License.
1303 You may obtain a copy of the License at
1304
1305 https://www.apache.org/licenses/LICENSE-2.0
1306
1307 Unless required by applicable law or agreed to in writing, software
1308 distributed under the License is distributed on an "AS IS" BASIS,
1309 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310 See the License for the specific language governing permissions and
1311 limitations under the License.
1312 */
1313
1314 /**
1315 * Wrapper around the fetch API.
1316 *
1317 * Will call requestWillFetch on available plugins.
1318 *
1319 * @param {Object} options
1320 * @param {Request|string} options.request
1321 * @param {Object} [options.fetchOptions]
1322 * @param {Event} [options.event]
1323 * @param {Array<Object>} [options.plugins=[]]
1324 * @return {Promise<Response>}
1325 *
1326 * @private
1327 * @memberof module:workbox-core
1328 */
1329 const wrappedFetch = (() => {
1330 var _ref = babelHelpers.asyncToGenerator(function* ({
1331 request,
1332 fetchOptions,
1333 event,
1334 plugins = [] }) {
1335 // We *should* be able to call `await event.preloadResponse` even if it's
1336 // undefined, but for some reason, doing so leads to errors in our Node unit
1337 // tests. To work around that, explicitly check preloadResponse's value first.
1338 if (event && event.preloadResponse) {
1339 const possiblePreloadResponse = yield event.preloadResponse;
1340 if (possiblePreloadResponse) {
1341 {
1342 defaultExport.log(`Using a preloaded navigation response for ` + `'${getFriendlyURL(request.url)}'`);
1343 }
1344 return possiblePreloadResponse;
1345 }
1346 }
1347
1348 if (typeof request === 'string') {
1349 request = new Request(request);
1350 }
1351
1352 {
1353 finalAssertExports.isInstance(request, Request, {
1354 paramName: request,
1355 expectedClass: 'Request',
1356 moduleName: 'workbox-core',
1357 className: 'fetchWrapper',
1358 funcName: 'wrappedFetch'
1359 });
1360 }
1361
1362 const failedFetchPlugins = pluginUtils.filter(plugins, pluginEvents.FETCH_DID_FAIL);
1363
1364 // If there is a fetchDidFail plugin, we need to save a clone of the
1365 // original request before it's either modified by a requestWillFetch
1366 // plugin or before the original request's body is consumed via fetch().
1367 const originalRequest = failedFetchPlugins.length > 0 ? request.clone() : null;
1368
1369 try {
1370 for (let plugin of plugins) {
1371 if (pluginEvents.REQUEST_WILL_FETCH in plugin) {
1372 request = yield plugin[pluginEvents.REQUEST_WILL_FETCH].call(plugin, {
1373 request: request.clone(),
1374 event
1375 });
1376
1377 {
1378 if (request) {
1379 finalAssertExports.isInstance(request, Request, {
1380 moduleName: 'Plugin',
1381 funcName: pluginEvents.CACHED_RESPONSE_WILL_BE_USED,
1382 isReturnValueProblem: true
1383 });
1384 }
1385 }
1386 }
1387 }
1388 } catch (err) {
1389 throw new WorkboxError('plugin-error-request-will-fetch', {
1390 thrownError: err
1391 });
1392 }
1393
1394 // The request can be altered by plugins with `requestWillFetch` making
1395 // the original request (Most likely from a `fetch` event) to be different
1396 // to the Request we make. Pass both to `fetchDidFail` to aid debugging.
1397 const pluginFilteredRequest = request.clone();
1398
1399 try {
1400 const fetchResponse = yield fetch(request, fetchOptions);
1401 {
1402 defaultExport.debug(`Network request for ` + `'${getFriendlyURL(request.url)}' returned a response with ` + `status '${fetchResponse.status}'.`);
1403 }
1404 return fetchResponse;
1405 } catch (error) {
1406 {
1407 defaultExport.error(`Network request for ` + `'${getFriendlyURL(request.url)}' threw an error.`, error);
1408 }
1409
1410 for (let plugin of failedFetchPlugins) {
1411 yield plugin[pluginEvents.FETCH_DID_FAIL].call(plugin, {
1412 error,
1413 event,
1414 originalRequest: originalRequest.clone(),
1415 request: pluginFilteredRequest.clone()
1416 });
1417 }
1418
1419 throw error;
1420 }
1421 });
1422
1423 return function wrappedFetch(_x) {
1424 return _ref.apply(this, arguments);
1425 };
1426 })();
1427
1428 const fetchWrapper = {
1429 fetch: wrappedFetch
1430 };
1431
1432 /*
1433 Copyright 2017 Google Inc.
1434
1435 Licensed under the Apache License, Version 2.0 (the "License");
1436 you may not use this file except in compliance with the License.
1437 You may obtain a copy of the License at
1438
1439 https://www.apache.org/licenses/LICENSE-2.0
1440
1441 Unless required by applicable law or agreed to in writing, software
1442 distributed under the License is distributed on an "AS IS" BASIS,
1443 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1444 See the License for the specific language governing permissions and
1445 limitations under the License.
1446 */
1447
1448 var _private = /*#__PURE__*/Object.freeze({
1449 DBWrapper: DBWrapper,
1450 WorkboxError: WorkboxError,
1451 assert: finalAssertExports,
1452 cacheNames: cacheNames,
1453 cacheWrapper: cacheWrapper,
1454 fetchWrapper: fetchWrapper,
1455 getFriendlyURL: getFriendlyURL,
1456 logger: defaultExport
1457 });
1458
1459 /*
1460 Copyright 2017 Google Inc.
1461
1462 Licensed under the Apache License, Version 2.0 (the "License");
1463 you may not use this file except in compliance with the License.
1464 You may obtain a copy of the License at
1465
1466 https://www.apache.org/licenses/LICENSE-2.0
1467
1468 Unless required by applicable law or agreed to in writing, software
1469 distributed under the License is distributed on an "AS IS" BASIS,
1470 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1471 See the License for the specific language governing permissions and
1472 limitations under the License.
1473 */
1474
1475 /**
1476 * Logs a warning to the user recommending changing
1477 * to max-age=0 or no-cache.
1478 *
1479 * @param {string} cacheControlHeader
1480 *
1481 * @private
1482 */
1483 function showWarning(cacheControlHeader) {
1484 const docsUrl = 'https://developers.google.com/web/tools/workbox/guides/service-worker-checklist#cache-control_of_your_service_worker_file';
1485 defaultExport.warn(`You are setting a 'cache-control' header of ` + `'${cacheControlHeader}' on your service worker file. This should be ` + `set to 'max-age=0' or 'no-cache' to ensure the latest service worker ` + `is served to your users. Learn more here: ${docsUrl}`);
1486 }
1487
1488 /**
1489 * Checks for cache-control header on SW file and
1490 * warns the developer if it exists with a value
1491 * other than max-age=0 or no-cache.
1492 *
1493 * @return {Promise}
1494 * @private
1495 */
1496 function checkSWFileCacheHeaders() {
1497 // This is wrapped as an iife to allow async/await while making
1498 // rollup exclude it in builds.
1499 return babelHelpers.asyncToGenerator(function* () {
1500 try {
1501 const swFile = self.location.href;
1502 const response = yield fetch(swFile);
1503 if (!response.ok) {
1504 // Response failed so nothing we can check;
1505 return;
1506 }
1507
1508 if (!response.headers.has('cache-control')) {
1509 // No cache control header.
1510 return;
1511 }
1512
1513 const cacheControlHeader = response.headers.get('cache-control');
1514 const maxAgeResult = /max-age\s*=\s*(\d*)/g.exec(cacheControlHeader);
1515 if (maxAgeResult) {
1516 if (parseInt(maxAgeResult[1], 10) === 0) {
1517 return;
1518 }
1519 }
1520
1521 if (cacheControlHeader.indexOf('no-cache') !== -1) {
1522 return;
1523 }
1524
1525 if (cacheControlHeader.indexOf('no-store') !== -1) {
1526 return;
1527 }
1528
1529 showWarning(cacheControlHeader);
1530 } catch (err) {
1531 // NOOP
1532 }
1533 })();
1534 }
1535
1536 const finalCheckSWFileCacheHeaders = checkSWFileCacheHeaders;
1537
1538 /*
1539 Copyright 2017 Google Inc.
1540
1541 Licensed under the Apache License, Version 2.0 (the "License");
1542 you may not use this file except in compliance with the License.
1543 You may obtain a copy of the License at
1544
1545 https://www.apache.org/licenses/LICENSE-2.0
1546
1547 Unless required by applicable law or agreed to in writing, software
1548 distributed under the License is distributed on an "AS IS" BASIS,
1549 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1550 See the License for the specific language governing permissions and
1551 limitations under the License.
1552 */
1553
1554 /**
1555 * This class is never exposed publicly. Inidividual methods are exposed
1556 * using jsdoc alias commands.
1557 *
1558 * @memberof workbox.core
1559 * @private
1560 */
1561 class WorkboxCore {
1562 /**
1563 * You should not instantiate this object directly.
1564 *
1565 * @private
1566 */
1567 constructor() {
1568 // Give our version strings something to hang off of.
1569 try {
1570 self.workbox.v = self.workbox.v || {};
1571 } catch (err) {}
1572 // NOOP
1573
1574
1575 // A WorkboxCore instance must be exported before we can use the logger.
1576 // This is so it can get the current log level.
1577 {
1578 const padding = ' ';
1579 defaultExport.groupCollapsed('Welcome to Workbox!');
1580 defaultExport.unprefixed.log(`You are currently using a development build. ` + `By default this will switch to prod builds when not on localhost. ` + `You can force this with workbox.setConfig({debug: true|false}).`);
1581 defaultExport.unprefixed.log(`📖 Read the guides and documentation\n` + `${padding}https://developers.google.com/web/tools/workbox/`);
1582 defaultExport.unprefixed.log(`❓ Use the [workbox] tag on Stack Overflow to ask questions\n` + `${padding}https://stackoverflow.com/questions/ask?tags=workbox`);
1583 defaultExport.unprefixed.log(`🐛 Found a bug? Report it on GitHub\n` + `${padding}https://github.com/GoogleChrome/workbox/issues/new`);
1584 defaultExport.groupEnd();
1585
1586 if (typeof finalCheckSWFileCacheHeaders === 'function') {
1587 finalCheckSWFileCacheHeaders();
1588 }
1589 }
1590 }
1591
1592 /**
1593 * Get the current cache names used by Workbox.
1594 *
1595 * `cacheNames.precache` is used for precached assets,
1596 * `cacheNames.googleAnalytics` is used by `workbox-google-analytics` to
1597 * store `analytics.js`,
1598 * and `cacheNames.runtime` is used for everything else.
1599 *
1600 * @return {Object} An object with `precache` and `runtime` cache names.
1601 *
1602 * @alias workbox.core.cacheNames
1603 */
1604 get cacheNames() {
1605 return {
1606 googleAnalytics: cacheNames.getGoogleAnalyticsName(),
1607 precache: cacheNames.getPrecacheName(),
1608 runtime: cacheNames.getRuntimeName()
1609 };
1610 }
1611
1612 /**
1613 * You can alter the default cache names used by the Workbox modules by
1614 * changing the cache name details.
1615 *
1616 * Cache names are generated as `<prefix>-<Cache Name>-<suffix>`.
1617 *
1618 * @param {Object} details
1619 * @param {Object} details.prefix The string to add to the beginning of
1620 * the precache and runtime cache names.
1621 * @param {Object} details.suffix The string to add to the end of
1622 * the precache and runtime cache names.
1623 * @param {Object} details.precache The cache name to use for precache
1624 * caching.
1625 * @param {Object} details.runtime The cache name to use for runtime caching.
1626 * @param {Object} details.googleAnalytics The cache name to use for
1627 * `workbox-google-analytics` caching.
1628 *
1629 * @alias workbox.core.setCacheNameDetails
1630 */
1631 setCacheNameDetails(details) {
1632 {
1633 Object.keys(details).forEach(key => {
1634 finalAssertExports.isType(details[key], 'string', {
1635 moduleName: 'workbox-core',
1636 className: 'WorkboxCore',
1637 funcName: 'setCacheNameDetails',
1638 paramName: `details.${key}`
1639 });
1640 });
1641
1642 if ('precache' in details && details.precache.length === 0) {
1643 throw new WorkboxError('invalid-cache-name', {
1644 cacheNameId: 'precache',
1645 value: details.precache
1646 });
1647 }
1648
1649 if ('runtime' in details && details.runtime.length === 0) {
1650 throw new WorkboxError('invalid-cache-name', {
1651 cacheNameId: 'runtime',
1652 value: details.runtime
1653 });
1654 }
1655
1656 if ('googleAnalytics' in details && details.googleAnalytics.length === 0) {
1657 throw new WorkboxError('invalid-cache-name', {
1658 cacheNameId: 'googleAnalytics',
1659 value: details.googleAnalytics
1660 });
1661 }
1662 }
1663
1664 cacheNames.updateDetails(details);
1665 }
1666
1667 /**
1668 * Get the current log level.
1669 *
1670 * @return {number}.
1671 *
1672 * @alias workbox.core.logLevel
1673 */
1674 get logLevel() {
1675 return getLoggerLevel();
1676 }
1677
1678 /**
1679 * Set the current log level passing in one of the values from
1680 * [LOG_LEVELS]{@link module:workbox-core.LOG_LEVELS}.
1681 *
1682 * @param {number} newLevel The new log level to use.
1683 *
1684 * @alias workbox.core.setLogLevel
1685 */
1686 setLogLevel(newLevel) {
1687 {
1688 finalAssertExports.isType(newLevel, 'number', {
1689 moduleName: 'workbox-core',
1690 className: 'WorkboxCore',
1691 funcName: 'logLevel [setter]',
1692 paramName: `logLevel`
1693 });
1694 }
1695
1696 if (newLevel > LOG_LEVELS.silent || newLevel < LOG_LEVELS.debug) {
1697 throw new WorkboxError('invalid-value', {
1698 paramName: 'logLevel',
1699 validValueDescription: `Please use a value from LOG_LEVELS, i.e ` + `'logLevel = workbox.core.LOG_LEVELS.debug'.`,
1700 value: newLevel
1701 });
1702 }
1703
1704 setLoggerLevel(newLevel);
1705 }
1706 }
1707
1708 var defaultExport$1 = new WorkboxCore();
1709
1710 /*
1711 Copyright 2017 Google Inc.
1712
1713 Licensed under the Apache License, Version 2.0 (the "License");
1714 you may not use this file except in compliance with the License.
1715 You may obtain a copy of the License at
1716
1717 https://www.apache.org/licenses/LICENSE-2.0
1718
1719 Unless required by applicable law or agreed to in writing, software
1720 distributed under the License is distributed on an "AS IS" BASIS,
1721 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1722 See the License for the specific language governing permissions and
1723 limitations under the License.
1724 */
1725
1726 const finalExports = Object.assign(defaultExport$1, {
1727 _private,
1728 LOG_LEVELS,
1729 registerQuotaErrorCallback
1730 });
1731
1732 return finalExports;
1733
1734}());
1735
1736//# sourceMappingURL=workbox-core.dev.js.map